CMAKE-MODULES(7)
๐ NAME ๐
okay bestie, welcome to cmake-modules(7) โ the CMake Modules Reference โ and this is the part where we get into the utility modules that ship with CMake itself. โจ
The modules listed here are part of the CMake distribution. Projects may provide further modules; their location(s) can be specified in the CMAKE_MODULE_PATH variable.
โจ UTILITY MODULES โจ
These modules are loaded using the include() command.
๐ค AndroidTestUtilities ๐ค
Added in version 3.7.
This module provides a command to create a test that pushes data needed for testing an Android device behavior onto a connected Android device. ๐ซถ
Load this module in a CMake project with:
include(AndroidTestUtilities)
๐ ๏ธ Commands ๐ ๏ธ
This module provides the following command:
android_add_test_data โ Creates a test that automatically loads specified data onto an Android device:
android_add_test_data(
<test-name>
[FILES <files>...]
[FILES_DEST <device-dir>]
[LIBS <libs>...]
[LIBS_DEST <device-dir>]
DEVICE_OBJECT_STORE <device-dir>
DEVICE_TEST_DIR <device-dir>
[NO_LINK_REGEX <regexes>...]
)
This command accepts files and libraries needed to run project-specific tests as well as separate destinations for each. It will create a test that loads the files into a device object store and link to them from the specified destination. The files are only uploaded if they are not already in the object store. ๐
On the host operating system, files and libraries are copied at build time. For on-device testing, the files are loaded onto the device by the manufactured test at run time. ๐ฆ
This command accepts the following named parameters:
FILES <files>...โ Zero or more files needed for testing.FILES_DEST <device-dir>โ Absolute path where the data files are expected to be.LIBS <libs>...โ Zero or more libraries needed for testing.LIBS_DEST <device-dir>โ Absolute path where the libraries are expected to be.DEVICE_OBJECT_STORE <device-dir>โ Absolute path to the on-device location where the data files are initially stored.DEVICE_TEST_DIR <device-dir>โ Absolute path to the root directory of the on-device test location.NO_LINK_REGEX <regexes>...โ A list of regular expression patterns matching file names to be copied from the object store to the test directory, instead of being symlinked.
๐ธ Examples ๐ธ
The following example shows how to use this module to create a test named example_setup_test that prepares data during the build phase. This test can then be run using ctest(1) to load the data onto the Android device. ๐ญ๐
CMakeLists.txt
include(AndroidTestUtilities)
android_add_test_data(
example_setup_test
FILES data/protobuffer.p data/file.txt
LIBS libs/library_1 libs/library_2
DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA"
DEVICE_TEST_DIR "/data/local/tests/example"
)
๐ BundleUtilities ๐
This module provides utility commands for assembling standalone, bundle-style applications with CMake, such as macOS .app bundles or similar directory-based application bundles on other operating systems. periodt. ๐
Load this module in a CMake installation with:
include(BundleUtilities)
Note: Do not use this module at configure time (fromCMakeLists.txt). Instead, include it and invoke its commands from aninstall(CODE)orinstall(SCRIPT). ๐จ
๐งฐ Commands ๐งฐ
This module provides the following commands:
fixup_bundle()copy_and_fixup_bundle()verify_app()get_bundle_main_executable()get_dotapp_dir()get_bundle_and_executable()get_bundle_all_executables()get_item_key()get_item_rpaths()clear_bundle_keys()set_bundle_key_values()get_bundle_keys()copy_resolved_item_into_bundle()copy_resolved_framework_into_bundle()fixup_bundle_item()verify_bundle_prerequisites()verify_bundle_symlinks()
fixup_bundle โ Prepares a bundle for distribution by fixing up its internal dependencies:
fixup_bundle(<app> <libs> <dirs> [IGNORE_ITEM <files>...])
This command modifies the <app> bundle in-place to make it self-contained and portable, so that it can be drag-n-drop copied to another machine and run there, assuming all of the system libraries are compatible. ๐
This command collects all dependencies (keys) for the executables and libraries in the bundle. For each dependency, it copies the required files into the bundle and adjusts them according to their own prerequisites. Once complete, it clears the collected keys and invokes the verify_app() command to ensure the final bundle is truly standalone. ๐ฅ
The arguments are:
<app>โ The path to the bundle to fix. This can be an.appdirectory or direct path to an executable.<libs>โ A list of libraries that must be fixed up, but that cannot be automatically determined by the otool output analysis (i.e. plugins). If plugins are passed to this command as this parameter, they should be installed or copied into the bundle before calling this command.<dirs>โ A list of paths where libraries might be found. These paths are searched first when a target without any path info is given. Then standard system locations are also searched: PATH, Framework locations, /usr/lib, etc.IGNORE_ITEM <files>...โ Added in version 3.6. Optional list of file names to ignore (e.g.IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe").
copy_and_fixup_bundle โ Copies the bundle and fixes up the new copied bundle in-place:
copy_and_fixup_bundle(<src> <dst> <libs> <dirs>)
This command makes a copy of the bundle <src> at location <dst> and then fixes up the new copied bundle in-place at <dst>. ๐ซ
The arguments are:
<src>โ The directory of the bundle being copied.<dst>โ The destination directory of the bundle copy.<libs>โ A list of libraries that must be fixed up, but that cannot be automatically determined by the otool output analysis (i.e. plugins). If plugins are passed to this command as this parameter, they should be installed or copied into the bundle before calling this command.<dirs>โ A list of paths where libraries might be found. These paths are searched first when a target without any path info is given. Then standard system locations are also searched: PATH, Framework locations, /usr/lib, etc.
verify_app โ Verifies that an application bundle appears valid based on running analysis tools on it:
verify_app(<app> [IGNORE_ITEM <files>...])
If the application fails verification, a message(FATAL_ERROR) is issued, halting the installation process. ๐
The arguments are:
<app>โ The path to the application to verify. This can be a.appdirectory or a standalone executable.IGNORE_ITEM <files>...โ Added in version 3.6. Optional list of file names to ignore (e.g.IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe").
get_bundle_main_executable โ Retrieves the main executable within a given application bundle:
get_bundle_main_executable(<bundle> <result-var>)
The result is stored in a <result-var> variable and will contain a full path name of the bundle's main executable file, or an error: prefixed string if it could not be determined. ๐ฏ
get_dotapp_dir โ Locates the enclosing .app directory for the given executable:
get_dotapp_dir(<exe> <dotapp-dir-var>)
This command retrieves the nearest parent dir whose name ends with .app given the full path to an executable and stores it to the <dotapp-dir-var> variable. If there is no such parent dir, then it simply retrieves the directory containing the executable. ๐
The retrieved directory may or may not exist.
get_bundle_and_executable โ Takes either a .app directory name or the name of an executable nested inside a .app directory and retrieves the path to the .app directory and the path to its main executable:
get_bundle_and_executable(<app> <bundle-var> <executable-var> <valid-var>)
The arguments are:
<app>โ The name of the application being processed.<bundle-var>โ Variable name in which to store the resulting path to the.appdirectory. In case of any error, this variable will contain an error message prefixed with stringerror:.<executable-var>โ Variable name in which to store the resulting main executable. In case of any error, this variable will contain an error message prefixed with stringerror:.<valid-var>โ Variable name in which the boolean result is stored whether this command was successful or not.
get_bundle_all_executables โ Gets all executables of a given bundle:
get_bundle_all_executables(<bundle> <exes-var>)
This command scans <bundle> bundle recursively for all executable files and stores them into a variable <exes-var>. ๐ง
get_item_key โ Generates a unique key for the given item:
get_item_key(<item> <key-var>)
Given <item> file name, this command generates <key-var> key that should be unique considering the set of libraries that need copying or fixing up to make a bundle standalone. This is essentially the file name including extension with . replaced by _. ๐
This key is used as a prefix for CMake variables so that a set of variables can be associated with a given item based on its key.
get_item_rpaths โ Gets RPATHS (run-time search paths) for the given item:
get_item_rpaths(<item> <rpaths-var>)
Okay so this command gets RPATHS of the <item> file name and stores them to the variable with provided name <rpaths-var>. No cap, itโs literally just โgimme those run paths and put โem in a variable.โ ๐
โจ clear_bundle_keys โจ
Clears all variables associated with keys:
clear_bundle_keys(<keys-var>)
This command loops over the <keys-var> list of keys, clearing all the variables associated with each key. After the loop, it clears the list of keys itself. This command should be called after the get_bundle_keys() command, when done working with a list of keys. Think of it as the cleanup era: the keys had their moment, now theyโre getting cleared. ๐งนโจ
๐ set_bundle_key_values ๐
Adds a key to the list of keys:
set_bundle_key_values(
<keys-var>
<context>
<item>
<exepath>
<dirs>
<copyflag>
[<rpaths>]
)
This command adds the <keys-var> key to the list (if necessary) for the given item. If added, also set all the variables associated with that key. Itโs giving โset the whole vibe for this key,โ honestly. ๐
The arguments are:
<keys-var>โ Variable name holding the name of the key to be added to the list for the given item.<context>โ The path to the top level loading path used for@loader_pathreplacement on Apple operating systems. When resolving item,@loader_pathreferences will be resolved relative to the directory of the given context value (presumably another library).<item>โ The item for which to add the key.<exepath>โ The path to the top level executable used for@executable_pathreplacement on Apple operating systems.<dirs>โ A list of paths where libraries might be found. These paths are searched first when a target without any path info is given. Then standard system locations are also searched:PATH, Framework locations,/usr/lib, etc.<copyflag>โ If set to1library symlink structure will be preserved.<rpaths>โ Optional run-time search paths for an executable file or library to help find files.
๐ฆ get_bundle_keys ๐ฆ
Gets bundle keys:
get_bundle_keys(<app> <libs> <dirs> <keys-var> [IGNORE_ITEM <files>...])
This command loops over all the executable and library files within <app> bundle (and given as extra <libs>) and accumulate a list of keys representing them. It sets values associated with each key such that they can be looped over all of them and copies prerequisite libs into the bundle and then does appropriate install_name_tool fixups. Itโs the main-character command of the bundle-fixing saga, fr fr. ๐
The arguments are:
<app>โ The path to the bundle to fix. This can be an.appdirectory or direct path to an executable.<libs>โ A list of libraries that must be fixed up, but that cannot be automatically determined by theotooloutput analysis (i.e. plugins). If plugins are passed to this command as this parameter, they should be installed or copied into the bundle before calling this command.<dirs>โ A list of paths where libraries might be found. These paths are searched first when a target without any path info is given. Then standard system locations are also searched:PATH, Framework locations,/usr/lib, etc.<keys-var>โ Variable name holding a list of keys that represent all executable and library files within the bundle.IGNORE_ITEM <files>...โ Added in version 3.6. Optional list of file names to ignore (e.g.IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe"). These files get the โnot invited to the fixup partyโ treatment. ๐
๐ธ copy_resolved_item_into_bundle ๐ธ
Copies a resolved item into the bundle if necessary:
copy_resolved_item_into_bundle(<resolved-item> <resolved-embedded-item>)
Copy is not necessary, if the <resolved-item> is โthe same asโ the <resolved-embedded-item>. Like, if itโs already the same item, weโre not doing extra work for no reason. Periodt. ๐
๐ copy_resolved_framework_into_bundle ๐
Copies a resolved framework into the bundle if necessary:
copy_resolved_framework_into_bundle(<resolved-item> <resolved-embedded-item>)
Copy is not necessary, if the <resolved-item> is โthe same asโ the <resolved-embedded-item>.
The following variables can be set before invoking this command:
BU_COPY_FULL_FRAMEWORK_CONTENTSโ By default, this variable is not set. If full frameworks should be embedded in the bundles, set this variable to boolean true before calling thefixup_bundle()command. By default, this command copies the framework dylib itself plus the frameworkResourcesdirectory.
๐ฅ fixup_bundle_item ๐ฅ
Fixes up bundle item:
fixup_bundle_item(<resolved-embedded-item> <exepath> <dirs>)
This command gets the direct/non-system prerequisites of the <resolved-embedded-item> and for each prerequisite, it changes the way it is referenced to the value of the _EMBEDDED_ITEM keyed variable for that prerequisite. Most likely changing to an @executable_path style reference. Itโs literally rerouting the references so everything knows where home is. ๐ โจ
This command requires that the <resolved-embedded-item> be inside the bundle already. In other words, if plugins are passed to fixup_bundle() command as its <libs> parameter, they should be installed or copied into the bundle before calling the fixup_bundle() command. No sneaking in at the last second, bestie. ๐ซถ
Also, it changes the id of the item being fixed up to its own _EMBEDDED_ITEM value.
Changes are accumulated in a local variable and one call is made to install_name_tool command-line tool at the end of this command with all the changes at once. Efficiency slay. ๐
The arguments are:
<resolved-embedded-item>โ The bundle item to be fixed up.<exepath>โ The path to the top level executable used for@executable_pathreplacement on Apple operating systems.<dirs>โ A list of paths where libraries might be found. These paths are searched first when a target without any path info is given. Then standard system locations are also searched:PATH, Framework locations,/usr/lib, etc.
The following variables can be set before invoking this command:
BU_CHMOD_BUNDLE_ITEMSโ If this variable is set to boolean true value then bundle items will be marked writable beforeinstall_name_tooltool tries to change them.
๐ verify_bundle_prerequisites ๐
Verifies that the sum of all prerequisites of all files inside the bundle are contained within the bundle or are system libraries, presumed to exist everywhere:
verify_bundle_prerequisites(
<bundle>
<result-var>
<info-var>
[IGNORE_ITEM <files>...]
)
The arguments are:
<bundle>โ Name of the bundle being verified.<result-var>โ Name of the variable in which to store a boolean result of whether a verification was successful.<info-var>โ Name of the variable holding any informational messages produced by the verification.IGNORE_ITEM <files>...โ Added in version 3.6. Optional list of file names to ignore (e.g.IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe"). Same energy as before: these files are excused from the vibe check. ๐
๐ verify_bundle_symlinks ๐
Verifies that any symlinks found in the specified bundle point to other files that are already also in the bundle:
verify_bundle_symlinks(<bundle> <result-var> <info-var>)
Anything that points to an external file causes this command to fail the verification. So if a symlink is trying to link to somebody outside the bundle, itโs a no from the verification committee. ๐
The arguments are:
<bundle>โ Name of the bundle being verified.<result-var>โ Name of the variable in which to store a boolean result of whether a verification was successful.<info-var>โ Name of the variable holding any informational messages produced by the verification.
๐ง Examples ๐ง
Using this module inside the installation code that is executed at the installation phase:
CMakeLists.txt
# ...
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS TRUE)
fixup_bundle(
\"${fixup_exe}\"
\"${plugins}\"
\"${bin_dir};${library_dir};${binary_dir}\"
)
")
๐ CheckCCompilerFlag ๐
This module provides a command to check whether the C compiler supports a given flag. Itโs giving โdoes my compiler accept this flag or is it gonna be dramatic about it?โ energy. ๐ซถ
Load this module in a CMake project with:
include(CheckCCompilerFlag)
โจ Commands โจ
This module provides the following command:
check_c_compiler_flag
Checks once whether the C compiler supports a given flag:
check_c_compiler_flag(<flag> <variable>)
This command checks once that the <flag> is accepted by the C compiler without producing a diagnostic message. Multiple flags can be specified in one argument as a string using a semicolon-separated list <#cmake-language-lists>. Cute little list-in-one-argument moment. ๐
The result of the check is stored in the internal cache variable specified by <variable>, with boolean true for success and boolean false for failure.
A successful result only indicates that the compiler did not report an error when given the flag. Whether the flag has any effect, or the intended one, is outside the scope of this module. So likeโฆ it passed the vibe check, but that doesnโt mean itโs doing the thing you think itโs doing. ๐
Note: Since the underlyingtry_compile()<#command:try_compile>command also uses flags from variables likeCMAKE_<LANG>_FLAGS<#variable:CMAKE_<LANG>_FLAGS>, unknown or unsupported flags in those variables may result in a false negative for this check. So if the check is acting sus, check the surrounding flags too, iykyk. ๐ญ
๐ธ Variables Affecting the Check ๐ธ
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ extra flags you wanna hand the compiler, written as a space-separated string ๐ . A semicolon-separated list will not work here, bestie, I'm so serious. And heads up: the contents ofCMAKE_<LANG>_FLAGSand its config-specific siblingCMAKE_<LANG>_FLAGS_<CONFIG>get auto-prepended to the compiler command before whatever you put in this variable. Order matters, always does โจCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one shaped like-DFOOor-DFOO=bar๐. Oh and a definition for the name given by the result variable argument of the check command gets added automatically too, no need to ask.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler ๐ธ. And likeโฆ these will be the only header search paths used. The contents of theINCLUDE_DIRECTORIESdirectory property? Ignored. Fully ghosted ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (peeptry_compile()for the deets).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command ๐ฅ. These can be plain old system library names, or they can be Imported Targets (again,try_compile()has the full story).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details) ๐ฆ.CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all the status messages tied to the check get suppressed ๐คซ. Silence is golden, periodt.CMAKE_TRY_COMPILE_TARGET_TYPEโ under the hood the check uses thetry_compile()command, and this variable controls what type of target it creates ๐. Set it toEXECUTABLE(that's the default) and the check compiles and links the test source code as an executable program. Set it toSTATIC_LIBRARYand the test source gets compiled but not linked. That's it, that's the whole vibe.
Examples
Okay so here's the moment where it all clicks ๐. This example shows how to use the module to check support for the C compiler flag -fno-optimize-strlen โ which, fun fact, disables optimizations related to the strlen() C function in GCC and Clang compilers. The result lands in the internal cache variable HAVE_FNO_OPTIMIZE_STRLEN, and then the flag gets conditionally enabled with the target_compile_options() command. The $<COMPILE_LANGUAGE:...> generator expression is the little icon that makes sure the flag only hits C source files ๐ฏ
include(CheckCCompilerFlag)
check_c_compiler_flag(-fno-optimize-strlen HAVE_FNO_OPTIMIZE_STRLEN)
if(HAVE_FNO_OPTIMIZE_STRLEN)
target_compile_options(
example
PRIVATE $<$<COMPILE_LANGUAGE:C>:-fno-optimize-strlen>
)
endif()
See Also
- The
CheckCompilerFlagmodule ๐ โ it's the more general command for checking whether a compiler flag is supported. Like, if you want the glow-up version.
CheckCompilerFlag
Added in version 3.19. โจ
This module gives you a command to check whether the compiler supports a given flag. That's it. That's the whole module. And honestly? Iconic.
Load it into your CMake project like this:
include(CheckCompilerFlag)
Commands
Only one command in the bag:
check_compiler_flag
Checks once whether the compiler supports a given flag:
check_compiler_flag(<lang> <flag> <variable>)
This command checks once that the <flag> is accepted by the <lang> compiler without producing a diagnostic message ๐ฉบ. The result of the check is stored in the internal cache variable named by <variable>. One and done, no re-runs.
The arguments are:
<lang>โ the language of the compiler used for the check. Supported languages are:C,CXX,CUDA,Fortran,HIP,ISPC,OBJC, andOBJCXX, andSwift. So many options, so little time ๐- Added in version 3.21: Support for
HIPlanguage. - Added in version 3.26: Support for
Swiftlanguage.
- Added in version 3.21: Support for
<flag>โ the compiler flag(s) to check ๐ฅ. You can drop multiple flags into one argument as a string using a semicolon-separated list. Slay.<variable>โ variable name of an internal cache variable to store the result of the check, with boolean true for success and boolean false for failure ๐ซ. Binary. No nuance. We love a clear answer.
A successful result only indicates that the compiler did not report an error when given the flag. Whether the flag actually does anything, or does the thing you intended it to do โ that's outside the scope of this module, babe ๐. It just checks vibes, not results.
Note: Since the underlyingtry_compile()command also uses flags from variables likeCMAKE_<LANG>_FLAGS, unknown or unsupported flags chilling in those variables may result in a false negative for this check ๐ญ. Not the flag's fault, not yours, just how the guts work.
Variables Affecting the Check
Set any of these before calling the command and you change how the check runs ๐
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler ๐ . A semicolon-separated list will not work, I said what I said. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=barโจ. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler ๐ฆ. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. Sorry to that property.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command ๐. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details) ๐.CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed ๐ค.CMAKE_TRY_COMPILE_TARGET_TYPEโ internally, thetry_compile()command is used to perform the check, and this variable controls the type of target it creates ๐ฏ. If this variable is set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. If set toSTATIC_LIBRARY, the test source code is compiled but not linked.
Examples
Same energy, different command ๐. This one demonstrates using the module to check support for the C compiler flag -fno-optimize-strlen, the flag that disables optimizations related to the strlen() C function in GCC and Clang compilers. The result of the check is stored in the internal cache variable HAVE_FNO_OPTIMIZE_STRLEN, and the flag is conditionally enabled using the target_compile_options() command. And the $<COMPILE_LANGUAGE:...> generator expression makes sure the flag is added only to C source files ๐ธ
include(CheckCompilerFlag)
check_compiler_flag(C -fno-optimize-strlen HAVE_FNO_OPTIMIZE_STRLEN)
if(HAVE_FNO_OPTIMIZE_STRLEN)
target_compile_options(
example
PRIVATE $<$<COMPILE_LANGUAGE:C>:-fno-optimize-strlen>
)
endif()
See Also
- The
CheckLinkerFlagmodule ๐ซถ โ for checking whether a linker flag is supported by the compiler. Different body part, same energy.
CheckCSourceCompiles
This module provides a command to check whether a C source can be built ๐ ๏ธ. Like, will it actually compile? Let's find out together.
Load this module in a CMake project with:
include(CheckCSourceCompiles)
Commands
This module provides the following command:
check_c_source_compiles
Checks once whether the given C source code can be built:
check_c_source_compiles(<code> <variable> [FAIL_REGEX <regexes>...])
This command checks once that the source supplied in <code> can be compiled (and linked into an executable) ๐ฅ. The result of the check is stored in the internal cache variable specified by <variable>.
The arguments are:
<code>โ the actual C source code you want checked. Heads up: this has to be a whole entire program, like exactly what'd be sitting in a file containing the body block. Every symbol you use in there is expected to be declared the normal way in its corresponding headers, so don't get cute and skip your includes ๐<variable>โ the name of an internal cache variable where the result gets stashed.trueif the check slayed,falseif it flopped.FAIL_REGEX <regexes>...โ if you toss in one or more regular expression patterns here, then failure gets determined by checking whether anything in the compiler output matches any of the regexes you specified. Basically: if the output smells like one of these patterns, the check is a fail ๐
โจ Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to hand to the compiler. Important bestie: a semicolon-separated list will not work here, the semicolons just vibe uselessly. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. So your flags are literally not first in line, iykyk.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of them looking like-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically, so you don't gotta do that yourself ๐ซถCMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. And listen: these will be the only header search paths used. The contents of theINCLUDE_DIRECTORIESdirectory property get straight up ignored. Not consulted. Not even a little. ๐ญCMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. Silence. Peace. No crumbs of output ๐CMAKE_TRY_COMPILE_TARGET_TYPEโ so internally, thetry_compile()command is what actually performs the check, and this variable controls the type of target it creates. If this variable is set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. If set toSTATIC_LIBRARY, the test source code is compiled but not linked. Different energy entirely.
๐ธ Examples
Checking whether C source code containing an SSE2 intrinsic can be compiled and linked:
include(CheckCSourceCompiles)
check_c_source_compiles([[
#include <emmintrin.h>
int main(void)
{
__m128d a = _mm_setzero_pd();
(void)a;
return 0;
}
]] PROJECT_HAVE_SSE2_INTRINSICS)
๐ See Also
- The
CheckSourceCompilesmodule for a more general command to check whether source can be built. - The
CheckSourceRunsmodule to check whether source can be built and run.
๐ CheckCSourceRuns
This module provides a command to check whether a C source can be built and run. Two steps. Both required. No shortcuts ๐
Load this module in a CMake project with:
include(CheckCSourceRuns)
โจ Commands
This module provides the following command:
check_c_source_runs ๐ฆ
Checks once whether the given C source code compiles and links into an executable that can subsequently be run:
check_c_source_runs(<code> <variable>)
The C source supplied in <code> must contain at least a main() function. Non-negotiable, bestie. The result of the check is stored in the internal cache variable specified by <variable>. If the code builds and runs with exit code 0, success is indicated by a boolean true value. Failure to build or run is indicated by a boolean false value, such as an empty string or an error message ๐ซ
โจ Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. A semicolon-separated list will not work, bestie, I'm serious. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed ๐คซ
๐ธ Examples
The following example demonstrates how to use this module to check whether the C source code is supported and operational at runtime. The result of the check is stored in the internal cache variable HAVE_NORETURN.
include(CheckCSourceRuns)
check_c_source_runs([[
#include <stdlib.h>
#include <stdnoreturn.h>
noreturn void f(){ exit(0); }
int main(void) { f(); return 1; }
]] HAVE_NORETURN)
๐ See Also
- The
CheckSourceRunsmodule for a more general command syntax. - The
CheckSourceCompilesmodule to check whether a source code can be built.
๐ CheckCXXCompilerFlag
This module provides a command to check whether the C++ compiler supports a given flag. Like, does your compiler even know her? ๐ค
Load this module in a CMake project with:
include(CheckCXXCompilerFlag)
โจ Commands
This module provides the following command:
check_cxx_compiler_flag โญ
Checks once whether the C++ compiler supports a given flag:
check_cxx_compiler_flag(<flag> <variable>)
This command checks once that the <flag> is accepted by the CXX compiler without producing a diagnostic message. Multiple flags can be specified in one argument as a string using a semicolon-separated list ๐ซถ
The result of the check is stored in the internal cache variable specified by <variable>, with boolean true for success and boolean false for failure.
Fr fr, a successful result only indicates that the compiler did not report an error when given the flag. Whether the flag has any effect โ or the intended one โ is outside the scope of this module. We checked if she showed up. We did not check if she did anything ๐
Note: Since the underlyingtry_compile()command also uses flags from variables likeCMAKE_<LANG>_FLAGS, unknown or unsupported flags sitting in those variables may result in a false negative for this check. So your check can fail for reasons that have nothing to do with the flag you asked about. Rude, honestly ๐ญ
โจ Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one shaped like-DFOOor-DFOO=bar. ๐ and bestie, heads up: a definition for the name you passed as the result variable argument of the check command gets added automatically too. no cap.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to hand over to the compiler. ๐ฆ and here's the slay-but-also-be-careful part: these are the only header search paths used. the contents of theINCLUDE_DIRECTORIESdirectory property get ignored. like, fully ignored. ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list of options to add to the link command (go peek attry_compile()for the further details, iykyk). ๐ฅCMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. these can be plain old names of system libraries, or they can be Imported Targets (again,try_compile()has the further details). ๐CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details). ๐CMAKE_REQUIRED_QUIETโ Added in version 3.1. if this variable evaluates to a boolean true value, all status messages associated with the check get suppressed. silence. iconic. ๐คซCMAKE_TRY_COMPILE_TARGET_TYPEโ internally thetry_compile()command is what actually performs the check, and this variable controls the type of target it creates. if it's set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. if it's set toSTATIC_LIBRARY, the test source code gets compiled but not linked. ๐ง
โจ Examples
okay so the following example demonstrates how to use this module to check the C++ compiler flag -fsycl. ๐ซถ the result of the check gets stored in the internal cache variable HAVE_FSYCL_FLAG, and the flag is conditionally enabled using the target_compile_options() command. and the $<COMPILE_LANGUAGE:...> generator expression is what ensures the flag is added only to CXX source files. so clean.
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-fsycl HAVE_FSYCL_FLAG)
if(HAVE_FSYCL_FLAG)
target_compile_options(
example
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fsycl>
)
endif()
๐ See Also
- the
CheckCompilerFlagmodule, for a more general command to check whether a compiler flag is supported. ๐
๐ธ CheckCXXSourceCompiles ๐ธ
this module provides a command to check whether a C++ source can be built. ๐
load this module in a CMake project with:
include(CheckCXXSourceCompiles)
Commands
this module provides the following command:
check_cxx_source_compiles โ checks once whether the given C++ source code can be built: ๐
check_cxx_source_compiles(<code> <variable> [FAIL_REGEX <regexes>...])
this command checks once that the source supplied in <code> can be compiled (and linked into an executable, fr fr). the result of the check gets stored in the internal cache variable specified by <variable>. ๐ฆ
the arguments are:
<code>โ C++ source code to check. this must be an entire program, as written in a file containing the body block. all symbols used in the source code are expected to be declared as usual in their corresponding headers. no shortcuts, bestie. ๐<variable>โ variable name of an internal cache variable to store the result of the check, with boolean true for success and boolean false for failure. ๐FAIL_REGEX <regexes>...โ if one or more regular expression patterns are provided, then failure is determined by checking if anything in the compiler output matches any of the specified regular expressions. ๐
Variables Affecting the Check
the following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. โ ๏ธ a semicolon-separated list will not work, periodt. the contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. ๐ฅCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. a definition for the name specified by the result variable argument of the check command is also added automatically. ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. these will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list of options to add to the link command (seetry_compile()for further details). โจCMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. these can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details). ๐CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details). ๐CMAKE_REQUIRED_QUIETโ Added in version 3.1. if this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. ๐คซCMAKE_TRY_COMPILE_TARGET_TYPEโ internally, thetry_compile()command is used to perform the check, and this variable controls the type of target it creates. if this variable is set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. if set toSTATIC_LIBRARY, the test source code is compiled but not linked. ๐ง
โจ Examples
the following example demonstrates how to check whether the C++ compiler supports a specific language feature. in this case, the check verifies if the compiler supports C++11 lambda expressions. ๐ฆ the result is stored in the internal cache variable HAVE_CXX11_LAMBDAS:
include(CheckCXXSourceCompiles)
check_cxx_source_compiles([[
int main()
{
auto lambda = []() { return 42; };
return lambda();
}
]] HAVE_CXX11_LAMBDAS)
๐ See Also
- the
CheckSourceCompilesmodule, for a more general command to check whether source can be built. ๐ - the
CheckSourceRunsmodule, to check whether source can be built and run. ๐โโ๏ธ
๐ฆ CheckCXXSourceRuns ๐ฆ
this module provides a command to check whether a C++ source can be built and run. ๐
load this module in a CMake project with:
include(CheckCXXSourceRuns)
Commands
this module provides the following command:
check_cxx_source_runs โ checks once whether the given C++ source code compiles and links into an executable that can subsequently be run: ๐
check_cxx_source_runs(<code> <variable>)
the C++ source supplied in <code> must contain at least a main() function, no exceptions bestie. the result of the check is stored in the internal cache variable specified by <variable>. if the code builds and runs with exit code 0, success is indicated by a boolean true value. failure to build or run is indicated by a boolean false value, such as an empty string or an error message. ๐ญ
Variables Affecting the Check
the following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. โ ๏ธ a semicolon-separated list will not work. the contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. ๐ฅCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. a definition for the name specified by the result variable argument of the check command is also added automatically. ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. these will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. ๐CMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14 โจ. A semicolon-separated list of options you want chucked onto the link command (thetry_compile()docs have the deets, iykyk).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can literally just be system library names, or they can be Imported Targets ๐ (again,try_compile()for the full tea).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31 ๐ฆ. A semicolon-separated list of library search paths handed off to the linker (checktry_compile()for more).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this variable evaluates to a boolean true value, all the status messages tied to the check get suppressed. Silence. Peace. ๐คซ
Examples
Okay so here's a glow-up of how you'd check whether the C++ standard library is actually functional and whether std::vector works at runtime. If the source compiles, links, and runs successfully, the internal cache variable HAVE_WORKING_STD_VECTOR gets set to a boolean true value. The code is supplied using a Bracket Argument so embedded quotes are way easier to handle ๐:
include(CheckCXXSourceRuns)
check_cxx_source_runs([[
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {1, 2, 3};
if (v.size() != 3) return 1;
std::cout << "Vector works correctly." << std::endl;
return 0;
}
]] HAVE_WORKING_STD_VECTOR)
See Also
- The
CheckSourceRunsmodule โ if you want a more general command syntax, this is your girl ๐ซถ - The
CheckSourceCompilesmodule โ for checking whether a source code can even be built at all.
CheckCXXSymbolExists ๐
This module hands you a command to check whether a C++ symbol exists. No cap.
Load this module in a CMake project with:
include(CheckCXXSymbolExists)
Commands
This module provides the following command:
check_cxx_symbol_exists
Checks once whether a symbol exists as a function, variable, or preprocessor macro in C++:
check_cxx_symbol_exists(<symbol> <headers> <variable>)
This command checks whether the <symbol> is available after including the specified header file(s) <headers>, and stores the result in the internal cache variable <variable> โจ. Multiple header files can be specified in one argument as a string using a semicolon-separated list.
If the header files define the symbol as a macro, it's considered available and assumed to work. If the symbol is declared as a function or variable, the check also makes sure it links successfully โ meaning the symbol must exist in a linked library or object file. Periodt.
Symbols that are types, enum values, or C++ templates are not recognized ๐. For those, consider using theCheckTypeSizeorCheckSourceCompilesmodule instead.
This command is intended to check symbols as they appear in C++. For C symbols, use the CheckSymbolExists module instead.
Note: this command is unreliable for symbols that are (potentially) overloaded functions ๐ญ. Since there's no reliable way to predict whether a given function in the system environment may be defined as an overloaded function, or may be an overloaded function on other systems, or will become so in the future, the general advice is to use the CheckSourceCompiles module for checking any function symbol โ unless it's certain the checked function isn't overloaded on other systems and won't be in the future. Fr fr.
Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work ๐. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically. ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored ๐.CMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14 โจ. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets ๐ (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31 ๐ฆ. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed ๐คซ.
Examples
This next one demonstrates how to check for the presence of a preprocessor macro SEEK_SET and the C++ function std::fopen() from the <cstdio> header using this module ๐:
include(CheckCXXSymbolExists)
# Check for macro SEEK_SET
check_cxx_symbol_exists(SEEK_SET "cstdio" HAVE_SEEK_SET)
# Check for function std::fopen
check_cxx_symbol_exists(std::fopen "cstdio" HAVE_STD_FOPEN)
See Also
- The
CheckSymbolExistsmodule โ for checking whether a C symbol exists ๐ธ
CheckFortranCompilerFlag ๐ง
Added in version 3.3 โจ
This module provides a command to check whether the Fortran compiler supports a given flag. Iconic behaviour honestly.
Load this module in a CMake project with:
include(CheckFortranCompilerFlag)
Commands
This module provides the following command:
check_fortran_compiler_flag
Checks once whether the Fortran compiler supports a given flag:
check_fortran_compiler_flag(<flag> <variable>)
This command checks once that the <flag> is accepted by the Fortran compiler without producing a diagnostic message. Multiple flags can be specified in one argument as a string using a semicolon-separated list.
The result of the check is stored in the internal cache variable specified by <variable>, with boolean true for success and boolean false for failure ๐ฅ.
A successful result only indicates that the compiler didn't report an error when given the flag. Whether the flag has any effect โ or the intended one โ is outside the scope of this module. Not me checking the vibe instead of the function ๐.
Note: since the underlyingtry_compile()command also uses flags from variables likeCMAKE_<LANG>_FLAGS, unknown or unsupported flags in those variables may result in a false negative for this check ๐ญ.
Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable ๐.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored ๐CMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14 โจ. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries that get added to the link command. These can be plain system library names, or they can be Imported Targets (peeptry_compile()for the full lore).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths that get handed to the linker (again,try_compile()has the deets).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, every status message tied to the check gets suppressed. Silence. Blessed silence. ๐คซCMAKE_TRY_COMPILE_TARGET_TYPEโ so internally,try_compile()is what actually runs the check, and this variable decides what kind of target it builds. Set it toEXECUTABLE(the default) and the check compiles and links the test source code as an executable program. Set it toSTATIC_LIBRARYand the test source gets compiled but not linked. Choose wisely bestie ๐
Examples
Okay so this example is literally showing you how to check the Fortran compiler flag -fallow-argument-mismatch. The result of the check gets stashed in the internal cache variable HAVE_FORTRAN_FLAG, and then the flag is conditionally switched on with the target_compile_options() command. The $<COMPILE_LANGUAGE:...> generator expression is the โจmain characterโจ here โ it makes sure the flag only gets added to Fortran source files. Obsessed.
include(CheckFortranCompilerFlag)
check_fortran_compiler_flag(-fallow-argument-mismatch HAVE_FORTRAN_FLAG)
if(HAVE_FORTRAN_FLAG)
target_compile_options(
example
PRIVATE $<$<COMPILE_LANGUAGE:Fortran>:-fallow-argument-mismatch>
)
endif()
See Also
- The
CheckCompilerFlagmodule โ a more general command for checking whether a compiler flag is supported. iykyk ๐ฆ
CheckFortranFunctionExists
This module hands you a command to check whether a Fortran function exists. That's the whole vibe.
Load it into your CMake project with:
include(CheckFortranFunctionExists)
Commands
This module provides the following command:
check_fortran_function_exists
Checks once whether a Fortran function exists:
check_fortran_function_exists(<function> <variable>)
<function>โ the name of the Fortran function. ๐ง<variable>โ the name of the variable where the check result gets stored. This variable will be created as an internal cache variable.
Note ๐ซถ: this command does not detect functions provided by Fortran modules. In general, the recommendation is to use CheckSourceCompiles instead to figure out whether a Fortran function or subroutine is available. Not me warning you ahead of time so you don't get caught out ๐
Variables Affecting the Check
You can set these variables before calling the command to change up the way the check runs:
CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. Can be system library names, or Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).
Examples
Example: Isolated Check With Linked Libraries
In this example, the module teams up with the CMakePushCheckState module to temporarily modify the required linked libraries (via CMAKE_REQUIRED_LIBRARIES) and verify whether the Fortran function dgesv is available for linking. The result lands in the internal cache variable PROJECT_HAVE_DGESV. The way this is such a clean little sandwich of push/pop ๐ญ๐ฅ
include(CheckFortranFunctionExists)
include(CMakePushCheckState)
find_package(LAPACK)
if(TARGET LAPACK::LAPACK)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES LAPACK::LAPACK)
check_fortran_function_exists(dgesv PROJECT_HAVE_DGESV)
cmake_pop_check_state()
endif()
See Also
- The
CheckFunctionExistsmodule โ for checking whether a C function exists. Different language, same energy ๐ - The
CheckSourceCompilesmodule โ for checking whether source code can be compiled.
CheckFortranSourceCompiles
Added in version 3.1.
This module gives you a command to check whether a Fortran source can be built. Slay.
Load this module in a CMake project with:
include(CheckFortranSourceCompiles)
Commands
This module provides the following command:
check_fortran_source_compiles
Checks once whether the given Fortran source code can be built:
check_fortran_source_compiles(
<code>
<variable>
[FAIL_REGEX <regexes>...]
[SRC_EXT <extension>]
)
This command checks once that the source you supplied in <code> can be compiled (and linked into an executable). The result of the check is stored in the internal cache variable you name with <variable>. Iconic behaviour honestly.
The arguments are:
<code>โ the Fortran source code to check. This has to be an entire program, like what you'd write in a file containing the body block. All symbols used in the source code are expected to be declared as usual in their corresponding headers.<variable>โ variable name of an internal cache variable that stores the result of the check, with boolean true for success and boolean false for failure. ๐FAIL_REGEX<regexes>... โ if you pass this option with one or more regular expressions, then failure is determined by checking whether anything in the compiler output matches any of the specified regular expressions.SRC_EXT<extension>โ Added in version 3.7. By default, the test source file used for the check gets a.Ffile extension. This option overrides that with.<extension>instead โ.F90is a typical choice.
Variables Affecting the Check
Set these before calling the command if you want to modify the way the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work, fr fr. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables get automatically prepended to the compiler command before the contents of this variable. Order matters bestie ๐CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one in the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command also gets added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. Heads up: these will be the only header search paths used โ the contents of theINCLUDE_DIRECTORIESdirectory property get ignored. ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be system library names, or Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check get suppressed. Quiet mode activated ๐คซCMAKE_TRY_COMPILE_TARGET_TYPEโ internally,try_compile()is the command used to perform the check, and this variable controls the type of target it creates. If it's set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. Set it toSTATIC_LIBRARYand the test source code gets compiled but not linked. Same deal as before, no cap ๐ง
Examples
Checking whether the Fortran compiler supports the pure procedure attribute:
include(CheckFortranSourceCompiles)
check_fortran_source_compiles("
pure subroutine foo()
end subroutine
program test
call foo()
end
" HAVE_PURE SRC_EXT "F90")
Look at that multi-line string just vibing inside the call. Gorgeous ๐ธ
See Also ๐ซ
- The
CheckSourceCompilesmodule โ a more general command for checking whether source can be built. - The
CheckSourceRunsmodule โ to check whether source can be built and run.
CheckFortranSourceRuns ๐ง
Added in version 3.14.
Okay so this module gives you a command that checks whether a Fortran source can be built and run. Built and run, bestie โ like it actually gets executed. Love that for us.
Load it into your CMake project with:
include(CheckFortranSourceRuns)
Commands ๐
check_fortran_source_runs โจ
Checks once whether the given Fortran source compiles and links into an executable that can subsequently be run.
check_fortran_source_runs(<code> <variable> [SRC_EXT <extension>])
The Fortran source you pass in <code> must contain a Fortran program unit โ no exceptions, it's giving non-negotiable. The result of the check gets stored in the internal cache variable named by <variable>. If the code builds and runs with exit code 0, success is indicated by a boolean true value. If it fails to build or fails to run, you get a boolean false value, such as an empty string or an error message. ๐ญ
The options are:
SRC_EXT <extension>โ by default, the internal test source file used for the check gets a.F90file extension. This option lets you change the extension to.<extension>instead. Cute.
Variables Affecting the Check ๐ง
These can all be set before you call the command, to modify the way the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. Heads up: a semicolon-separated list will not work here. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables get automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command also gets added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property get ignored. Periodt.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check get suppressed. Silence. ๐คซ
Examples ๐ธ
This example shows how to use the module to check whether a Fortran source code runs, and to store the result of the check in an internal cache variable HAVE_COARRAY:
include(CheckFortranSourceRuns)
check_fortran_source_runs([[
program test
real :: x[*]
call co_sum(x)
end program
]] HAVE_COARRAY)
See Also ๐
- The
CheckSourceRunsmodule โ for a more general command syntax. - The
CheckSourceCompilesmodule โ to check whether a source code can be built.
CheckFunctionExists ๐ฆ
This module provides a command to check whether a C function exists. That's it, that's the vibe.
Load this module in a CMake project with:
include(CheckFunctionExists)
Commands ๐
check_function_exists โญ
Checks once whether a C function can be linked from system libraries:
check_function_exists(<function> <variable>)
This command checks whether the <function> is provided by libraries on the system, and stores the result in an internal cache variable <variable>.
Note: ๐ฅ Prefer using CheckSymbolExists or CheckSourceCompiles instead of this command, for the following reasons:
check_function_exists()can't detect functions that are inlined in headers or defined as preprocessor macros.check_function_exists()can't detect anything in the 32-bit versions of the Win32 API, because of a mismatch in calling conventions.check_function_exists()only verifies linking, it does not verify that the function is declared in system headers.
Variables Affecting the Check ๐ง
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed.
Examples ๐
Example: Basic Usage
In the following example, a check is performed to determine whether the linker sees the C function fopen(), and the result is stored in the HAVE_FOPEN internal cache variable:
include(CheckFunctionExists)
check_function_exists(fopen HAVE_FOPEN)
Example: Missing Declaration
As noted above, the CheckSymbolExists module is preferred for checking C functions, since it also verifies whether the function is declared or defined as a macro. In the following example, this module is used to check an edge case where a function may not be declared in system headers. For instance, on macOS, the fdatasync() function may be available in the C library, but its declaration is not provided in the unistd.h system header. ๐
CMakeLists.txt
include(CheckFunctionExists)
include(CheckSymbolExists)
check_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC)
# Check if fdatasync() is available in the C library.
if(NOT HAVE_FDATASYNC)
check_function_exists(fdatasync HAVE_FDATASYNC_WITHOUT_DECL)
endif()
In such a case, the project can provide its own declaration if missing:
example.c
#ifdef HAVE_FDATASYNC_WITHOUT_DECL
extern int fdatasync(int);
#endif
See Also ๐
- The
CheckSymbolExistsmodule โ to check whether a C symbol exists. - The
CheckSourceCompilesmodule โ to check whether a source code can be compiled. - The
CheckFortranFunctionExistsmodule โ to check whether a Fortran function exists.
CheckIncludeFile ๐
This module provides a command to check a C header file. Yup, just the one header, bestie.
Load this module in a CMake project with:
include(CheckIncludeFile)
Commands ๐
check_include_file ๐
Checks once whether a header file exists and can be included in C code:
check_include_file(<include> <variable> [<flags>])
The arguments are:
<include>โ a header file to be checked.<variable>โ the name of the variable to store the result of the check. This variable will be created as an internal cache variable.<flags>โ (optional) a space-separated string of extra compilation flags you want tacked onto the check. You can also pass flags in through theCMAKE_REQUIRED_FLAGSvariable (more on that literally right below ๐).
Variables Affecting the Check
okay bestie, these are the knobs ๐๏ธ โ set any of them before you call this command and they'll change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. ๐ซถ and yes, this one is picky: a semicolon-separated list will not work. Also, the contents ofCMAKE_<LANG>_FLAGSand its configuration-specific bestieCMAKE_<LANG>_FLAGS_<CONFIG>get automatically prepended to the compiler command before whatever's sitting in this variable. order matters, periodt.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each shaped like-DFOOor-DFOO=bar. A definition for the name you passed as the result variable argument gets added automatically too (sneaky but helpful ๐ ).CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. โ ๏ธ Heads up: these will be the only header search paths used โ the contents of theINCLUDE_DIRECTORIESdirectory property get completely ignored. it's giving "my way or the highway".CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (go peek attry_compile()for the full tea).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (again,try_compile()has the details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, every single status message tied to the check gets suppressed. silence is golden โจ
Added in version 3.12: theCMAKE_REQUIRED_LIBRARIESvariable โ but only if policyCMP0075is set toNEW. no cap.
Examples
Example: Checking C Header ๐ธ
Checking whether the C header <unistd.h> exists, and storing the check result in the HAVE_UNISTD_H cache variable:
include(CheckIncludeFile)
check_include_file(unistd.h HAVE_UNISTD_H)
Example: Isolated Check ๐ง
In the following example, this module is used together with the CMakePushCheckState module to temporarily modify the required compile definitions (via CMAKE_REQUIRED_DEFINITIONS) and verify whether the C header <ucontext.h> is available. The result gets stored in the internal cache variable HAVE_UCONTEXT_H.
For example, on macOS the ucontext API is deprecated, and headers may be hidden unless certain feature macros are defined. In particular, defining _XOPEN_SOURCE (without a value) can expose the necessary symbols without enabling broader POSIX or SUS (Single Unix Specification) features (values 500 or greater). iconic behavior honestly.
include(CheckIncludeFile)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE)
endif()
check_include_file(ucontext.h HAVE_UCONTEXT_H)
cmake_pop_check_state()
See Also
- The
CheckIncludeFileCXXmodule, for checking a single C++ header. ๐ - The
CheckIncludeFilesmodule, for checking one or more C or C++ headers at once. ๐ฆ
CheckIncludeFileCXX
This module hands you a command that checks a C++ header file. lowkey essential.
Load this module in a CMake project with:
include(CheckIncludeFileCXX)
Commands
This module provides the following command:
check_include_file_cxx
(okay it's not literally a heading level, but you get it ๐)
Checks once whether a header file exists and can be included in C++ code:
check_include_file_cxx(<include> <variable> [<flags>])
The arguments are:
<include>โ a header file to be checked. ๐<variable>โ the name of the variable that stores the result of the check. This variable gets created as an internal cache variable.<flags>โ (optional) a space-separated string of additional compilation flags to add to the check. Alternatively, flags can also be specified with theCMAKE_REQUIRED_FLAGSvariable below.
Variables Affecting the Check
same drill as before, bestie โ set any of these before calling the command to change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically. ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. โ ๏ธCMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. ๐คซ
Added in version 3.12: theCMAKE_REQUIRED_LIBRARIESvariable, if policyCMP0075is set toNEW.
Examples
Checking whether the C++23 header <stdfloat> exists and storing the check result in the HAVE_STDFLOAT_HEADER cache variable:
include(CheckIncludeFileCXX)
check_include_file_cxx(stdfloat HAVE_STDFLOAT_HEADER)
See Also
- The
CheckIncludeFilemodule, for checking a single C header. ๐ - The
CheckIncludeFilesmodule, for checking one or more C or C++ headers at once. ๐ธ
CheckIncludeFiles
This module provides a command to check one or more C/C++ header files. plural slay ๐
Load this module in a CMake project with:
include(CheckIncludeFiles)
Commands
This module provides the following command:
check_include_files
Checks once whether one or more header files exist and can be included together in C or C++ code:
check_include_files(<includes> <variable> [LANGUAGE <language>])
The arguments are:
<includes>โ a semicolon-separated list of header files to be checked. ๐<variable>โ the name of the variable to store the result of the check. This variable will be created as an internal cache variable.LANGUAGE <language>โ Added in version 3.11. If set, the specified<language>compiler will be used to perform the check. Acceptable values areCandCXX. If this option is not given, the C compiler will be used if enabled. If the C compiler is not enabled, the C++ compiler will be used if enabled. (it'll figure it out, she's smart like that โจ)
Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. ๐ซถCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths you hand to the compiler. And bestie, hear me: these will be the only header search paths used. The contents of theINCLUDE_DIRECTORIESdirectory property just get ignored entirely. Like, ghosted. ๐CMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14 โจ
A semicolon-separated list of options to add to the link command (peep try_compile() for the further details, iykyk).
CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be names of system libraries, or they can be Imported Targets (again,try_compile()has the full tea ๐ซ).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31 ๐
A semicolon-separated list of library search paths to pass to the linker (see try_compile() for further details, always try_compile()).
CMAKE_REQUIRED_QUIETโ added in version 3.1 ๐คซ
If this variable evaluates to a boolean true value, all the status messages associated with the check get suppressed. Silence. Iconic.
Added in version 3.12: The CMAKE_REQUIRED_LIBRARIES variable, if policy CMP0075 is set to NEW.
๐งช Examples
Checking one or more C headers and stashing the check result in cache variables, like a little detective:
include(CheckIncludeFiles)
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
if(HAVE_SYS_SOCKET_H)
# The <net/if.h> header on Darwin and BSD-like systems is not self-contained
# and also requires <sys/socket.h>
check_include_files("sys/socket.h;net/if.h" HAVE_NET_IF_H)
else()
check_include_files(net/if.h HAVE_NET_IF_H)
endif()
The LANGUAGE option is your girl for specifying which compiler to use ๐ฅ For example, checking multiple C++ headers when both C and CXX languages are enabled in the project:
include(CheckIncludeFiles)
check_include_files("header_1.hpp;header_2.hpp" HAVE_HEADERS LANGUAGE CXX)
๐ See Also
- The
CheckIncludeFilemodule, for checking a single C header. One. Uno. ๐ - The
CheckIncludeFileCXXmodule, for checking a single C++ header. Same energy, C++ flavoured. ๐ฆ
โก CheckIPOSupported
Added in version 3.9 โจ
This module hands you a command to check whether the compiler supports interprocedural optimization (IPO/LTO). Slay.
Load it into your CMake project with:
include(CheckIPOSupported)
So what even is interprocedural optimization? It's a compiler technique that performs optimizations across translation units (i.e., across source files), letting the compiler analyze and optimize the entire program as a whole rather than file-by-file. Main character energy, honestly โ the whole program, not just one little file. ๐ This can improve performance by enabling more aggressive inlining and dead code elimination. And when these optimizations get applied at link time, the process is typically referred to as link-time optimization (LTO), which is a common form of IPO. Two names, one vibe.
In CMake, you can enable interprocedural optimization on a per-target basis using the INTERPROCEDURAL_OPTIMIZATION target property, or for all targets in the current scope using the CMAKE_INTERPROCEDURAL_OPTIMIZATION variable.
Use this module before enabling the interprocedural optimization on targets, so you actually know the compiler supports IPO/LTO instead of just hoping and praying ๐
๐ Commands
This module provides the following command:
check_ipo_supported
Checks whether the compiler supports interprocedural optimization (IPO/LTO):
check_ipo_supported(
[RESULT <result-var>]
[OUTPUT <output-var>]
[LANGUAGES <lang>...]
)
Options are:
RESULT <result-var>โ set the<result-var>variable toYESif IPO is supported by the compiler andNOotherwise. If this option is not given, then the command will issue a fatal error if IPO is not supported. So like, no pressure, but do give it a result var if you're not in the mood for drama ๐OUTPUT <output-var>โ set the<output-var>variable with details about any error. Receipts. ๐งพLANGUAGES <lang>...โ specify languages whose compilers to check.
The following languages are supported:
CCXXCUDAโ added in version 3.25 ๐Fortran
If this option is not given, the default languages are picked from the current ENABLED_LANGUAGES global property. Vibes-based defaults, but make it official.
Note: to usecheck_ipo_supported(), policyCMP0069must be set toNEWโ otherwise, a fatal error will occur. Fr fr, it will Not Be Chill about it. ๐ญ
Added in version 3.13: Support for Visual Studio Generators. ๐
Added in version 3.24: The check uses the caller's CMAKE_<LANG>_FLAGS and CMAKE_<LANG>_FLAGS_<CONFIG> values. See policy CMP0138.
๐งช Examples
Checking whether the compiler supports IPO and emitting a fatal error if it isn't supported:
include(CheckIPOSupported)
check_ipo_supported() # fatal error if IPO is not supported
set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
The following example demonstrates how to use this module to enable IPO for the target only when it's supported by the compiler, and to issue a warning when it isn't. Additionally, projects may want to provide a configuration option to control when IPO is enabled. For example:
option(FOO_ENABLE_IPO "Enable IPO/LTO")
if(FOO_ENABLE_IPO)
include(CheckIPOSupported)
check_ipo_supported(RESULT result OUTPUT output)
if(result)
set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(WARNING "IPO is not supported: ${output}")
endif()
endif()
๐ CheckLanguage
This module provides a command to check whether a language can be enabled using the enable_language() or project() commands.
Load this module in a CMake project with:
include(CheckLanguage)
This module is genuinely useful when a project doesn't always need a specific language but might need to enable it for certain parts. Lowkey the most relatable module tbh ๐ซถ
๐ Commands
This module provides the following command:
check_language
Checks whether a language can be enabled in a CMake project:
check_language(<lang>)
This command attempts to enable the language <lang> in a test project and records the results in the following cache variables:
CMAKE_<LANG>_COMPILERโ if the language can be enabled, this variable is set to the compiler that was found. If the language cannot be enabled, this variable is set toNOTFOUND.
If this variable is already set, either explicitly or cached by a previous call, the check is skipped. Already know her, no need to re-introduce her. ๐
CMAKE_<LANG>_HOST_COMPILERโ this variable is set when<lang>isCUDAorHIP.
If the check detects an explicit host compiler that is required for compilation, this variable will be set to that compiler. If the check detects that no explicit host compiler is needed, this variable will be cleared.
If this variable is already set, its value is preserved only if CMAKE_<LANG>_COMPILER is also set. Otherwise, the check runs and overwrites CMAKE_<LANG>_HOST_COMPILER with a new result. Note that CMAKE_<LANG>_HOST_COMPILER documents it should not be set without also setting CMAKE_<LANG>_COMPILER to a NVCC compiler. Rules are rules, bestie ๐
CMAKE_<LANG>_PLATFORMโ this variable is set to the detected GPU platform when<lang>isHIP.
If this variable is already set, its value is always preserved. Only compatible values will be considered for CMAKE_<LANG>_COMPILER. Loyalty. ๐
๐งช Examples
The following example checks for the availability of the Fortran language and enables it if possible:
include(CheckLanguage)
check_language(Fortran)
if(CMAKE_Fortran_COMPILER)
enable_language(Fortran)
else()
message(STATUS "No Fortran support")
endif()
๐ CheckLibraryExists
This module provides a command to check whether a C library exists. Does she exist? Let's find out ๐
Load this module in a CMake project with:
include(CheckLibraryExists)
๐ Commands
This module provides the following command:
check_library_exists
Checks once whether a specified library exists and a given C function is available:
check_library_exists(<library> <function> <location> <variable>)
This command attempts to link a test executable that uses the specified C <function> to verify that it's provided by either a system or user-provided <library>. A whole little test build, just for you. Obsessed. ๐
The arguments are:
<library>โ the name of the library, a full path to a library file, or an Imported Target. Flexible queen ๐ธ<function>โ the name of a function that should be available in the system or user-provided library<library>. The whole point of the check, honestly.<location>โ the directory containing the library file. It is added to the link search path during the check. If this is an empty string, only the default library search paths are used. Empty string = default paths, periodt.<variable>โ the name of the variable in which to store the check result. This variable will be created as an internal cache variable. ๐
Note: this one is for basic sanity checks, bestie โ it just confirms your library actually does the thing you think it does, or that CMake found the right library and not some chaotic impostor. But listen: it only checks that a function symbol can be linked successfully. It does not make sure the function is declared in the library headers, and it straight-up cannot detect functions that are inlined or defined as preprocessor macros. ๐ญ So if you want the robust, no-notes version of function detection, go useCheckSymbolExistsorCheckSourceCompilesinstead. Periodt.
๐ธ Variables Affecting the Check ๐ธ
Set any of these before you call this command to change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. And no, a semicolon-separated list will not work here, that's the whole vibe. The contents ofCMAKE_<LANG>_FLAGSand its config-specific bestieCMAKE_<LANG>_FLAGS_<CONFIG>get automatically prepended to the compiler command before whatever's in this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one shaped like-DFOOor-DFOO=bar. A definition for the name you gave as the check command's result variable argument is also added automatically. ๐ซถCMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14. A semicolon-separated list of options to add to the link command (peeptry_compile()for the deets).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be system library names, or they can be Imported Targets (again,try_compile()has the full story).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this evaluates to a boolean true value, every status message associated with the check gets suppressed. Silence, iconically. ๐คซ
โจ Examples โจ
Checking if the curl library exists in the default paths and has the curl_easy_perform() function:
include(CheckLibraryExists)
check_library_exists(curl curl_easy_perform "" HAVE_LIBRARY_CURL)
To check if a library exists in a specific non-standard location and has a specified function:
include(CheckLibraryExists)
check_library_exists(curl curl_easy_perform "/opt/curl/lib" HAVE_LIBRARY_CURL)
Also, Imported Targets (like, from a find_package() call) can be used, and honestly? Slay:
find_package(CURL)
# ...
if(TARGET CURL::libcurl)
include(CheckLibraryExists)
check_library_exists(CURL::libcurl curl_easy_perform "" HAVE_LIBRARY_CURL)
endif()
๐ฆ See Also ๐ฆ
- The
CheckSymbolExistsmodule โ for checking whether a C symbol exists. ๐
๐ CheckLinkerFlag ๐
Added in version 3.18.
This module hands you a command to check whether a given link flag is even supported by your compiler. Vibe check for flags, basically.
Load it into your CMake project with:
include(CheckLinkerFlag)
Commands
This module provides the following command:
check_linker_flag(<lang> <flag> <variable>)โ checks once whether the compiler supports a given link flag.
This command checks once whether the linker flag <flag> is accepted by the <lang> compiler without producing a diagnostic message. No drama, no warnings, just vibes.
The arguments are:
<lang>โ the language of the compiler used for the check. Supported languages areC,CXX,CUDA,Fortran,HIP,OBJC,OBJCXX, andSwift.- Added in version 3.19: support for
CUDAlanguage. - Added in version 3.21: support for
HIPlanguage. - Added in version 3.26: support for
Swiftlanguage.
- Added in version 3.19: support for
<flag>โ linker flag(s) to check. Multiple flags can be specified in one argument as a string using a semicolon-separated list. ๐
The underlying implementation uses the LINK_OPTIONS target property to test the specified flag. The LINKER: (and SHELL:) prefixes may be used, as described in the Handling Compiler Driver Differences section below.
<variable>โ the name of the variable to store the check result. This variable will be created as an internal cache variable.
This command temporarily sets the CMAKE_REQUIRED_LINK_OPTIONS variable and calls the check_source_compiles() command from the CheckSourceCompiles module.
Heads up: a successful result only indicates that the compiler did not report an error when given the link flag. Whether the flag has any effect, or the intended effect, is outside the scope of this module. It's giving "no errors โ did anything". ๐
Note: since the underlyingtry_compile()command also uses flags from variables likeCMAKE_<LANG>_FLAGS, unknown or unsupported flags hanging out in those variables may result in a false negative for this check. Not me warning you twice. ๐
๐ Variables Affecting the Check ๐
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used โ the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. Like, fully ignored. ๐CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed.
๐ง Handling Compiler Driver Differences ๐ง
Okay so to pass options to the linker tool, every compiler driver has its own little syntax situation. The LINKER: prefix and , separator let you specify, in a portable way, options to pass to the linker tool. LINKER: gets replaced by the appropriate driver option and , by the appropriate driver separator. The driver prefix and driver separator are given by the values of the CMAKE_<LANG>_LINKER_WRAPPER_FLAG and CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP variables. iykyk.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC. Same flag, different fits. ๐
The LINKER: prefix can be specified as part of a SHELL: prefix expression.
The LINKER: prefix also supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. That previous example then becomes "LINKER:SHELL:-z defs".
Note: specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Don't try it, bestie, it's not going to eat. ๐ญ
โญ Examples โญ
Example: Checking Linker Flag
The following example shows how to use this module to check the -z relro linker flag, which is supported on many Unix-like systems to enable read-only relocations for improved binary security. If the flag is supported by the linker, it is conditionally added to the executable target using target_link_options(). The LINKER: prefix is used to pass the flag to the linker in a portable and compiler-independent way. Security and portability? We love to see it. ๐
include(CheckLinkerFlag)
check_linker_flag(C "LINKER:-z,relro" HAVE_Z_RELRO)
add_executable(example main.c)
if(HAVE_Z_RELRO)
target_link_options(example PRIVATE "LINKER:-z,relro")
endif()
Example: Checking Multiple Flags
In the following example, multiple linker flags are checked simultaneously:
include(CheckLinkerFlag)
check_linker_flag(C "LINKER:-z,relro;LINKER:-z,now" HAVE_FLAGS)
add_executable(example main.c)
if(HAVE_FLAGS)
target_link_options(example PRIVATE LINKER:-z,relro LINKER:-z,now)
endif()
๐ธ See Also ๐ธ
- The
CMAKE_LINKER_TYPEvariable to specify the linker, which will be used also by this module. ๐ซถ - The
CheckCompilerFlagmodule, for checking whether a compiler flag is supported (it's the general-purpose one, and yes she's iconic).
๐ฆ CheckOBJCCompilerFlag ๐ฆ
Added in version 3.16.
Okay so this module hands you a whole command whose only job is asking "hey, does the Objective-C compiler actually support this flag?" ๐
Load it into your CMake project like this, bestie:
include(CheckOBJCCompilerFlag)
โจ Commands โจ
This module gives you exactly one command:
check_objc_compiler_flagโ checks once whether the Objective-C compiler supports the flag you hand it:
check_objc_compiler_flag(<flag> <variable>)
So what it does: it checks once that <flag> is accepted by the OBJC compiler without producing a diagnostic message. You can sneak multiple flags into one argument as a string using a semicolon-separated list. ๐
The result of the check gets stashed in the internal cache variable you name with <variable> โ boolean true if it slayed, boolean false if it flopped.
Heads up though: a successful result only means the compiler didn't report an error when given the flag. Whether the flag actually does anything, or does the thing you wanted โ that's lowkey outside the scope of this module. ๐คทโโ๏ธ
Note: since the underlyingtry_compile()command also uses flags from variables likeCMAKE_<LANG>_FLAGS, unknown or unsupported flags chilling in those variables can give you a false negative on this check. Not the vibe, but that's the deal. ๐
๐ Variables Affecting the Check ๐
Set any of these before calling the command and they'll change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. A semicolon-separated list will not work (fr fr, don't do it). The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables get automatically prepended to the compiler command, ahead of whatever's in this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each shaped like-DFOOor-DFOO=bar. A definition for the name you passed as the result variable argument of the check command also gets added automatically. ๐ซถCMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These are the only header search paths used โ the contents of theINCLUDE_DIRECTORIESdirectory property get fully ignored. ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (peeptry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be names of system libraries, or they can be Imported Targets (again,try_compile()has further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check get suppressed. Silence. Peace. Zen. ๐งCMAKE_TRY_COMPILE_TARGET_TYPEโ internally,try_compile()is what actually performs the check, and this variable controls what type of target it creates. If it's set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. If it's set toSTATIC_LIBRARY, the test source code is compiled but not linked.
๐ธ Examples ๐ธ
This example is literally showing you how to check the Objective-C compiler flag -fobjc-arc. The result lands in the internal cache variable HAVE_OBJC_ARC, and then the flag gets conditionally enabled with target_compile_options(). The $<COMPILE_LANGUAGE:...> generator expression is the main character here โ she makes sure the flag only gets added to OBJC source files. ๐
include(CheckOBJCCompilerFlag)
check_objc_compiler_flag(-fobjc-arc HAVE_OBJC_ARC)
if(HAVE_OBJC_ARC)
target_compile_options(
example
PRIVATE $<$<COMPILE_LANGUAGE:OBJC>:-fobjc-arc>
)
endif()
โญ See Also โญ
- The
CheckCompilerFlagmodule โ for a more general command to check whether a compiler flag is supported.
๐ CheckOBJCSourceCompiles ๐
Added in version 3.16.
This one's the module that gives you a command to check whether an Objective-C source can actually be built. Big "will it compile or will it humiliate me" energy. ๐ญ
Load it with:
include(CheckOBJCSourceCompiles)
โจ Commands โจ
One command, coming right up:
check_objc_source_compilesโ checks once whether the given Objective-C source code can be built:
check_objc_source_compiles(<code> <variable> [FAIL_REGEX <regexes>...])
It checks once that the source you supplied in <code> can be compiled (and linked into an executable). The result of the check goes into the internal cache variable you name with <variable>. ๐ซถ
The arguments, bestie:
<code>โ the source code to check. This has to be an entire program, as written in a file containing the body block. All symbols used in the source code are expected to be declared as usual in their corresponding headers. No guessing games. ๐<variable>โ the variable name of an internal cache variable that stores the result of the check, with boolean true for success and boolean false for failure.FAIL_REGEX <regexes>...โ if you provide this option with one or more regular expressions, then failure is determined by checking if anything in the compiler output matches any of the specified regular expressions. So even if it "compiles", a match still means fail. Sneaky but fair. ๐
๐ Variables Affecting the Check ๐
Set these before calling the command to modify how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically. ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. ๐คซCMAKE_TRY_COMPILE_TARGET_TYPEโ internally,try_compile()is used to perform the check, and this variable controls the type of target it creates. If this variable is set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. If set toSTATIC_LIBRARY, the test source code is compiled but not linked.
๐ธ Examples ๐ธ
Down here we're using the module to check whether the provided Objective-C source code compiles and links. The result of the check is stored in the internal cache variable HAVE_WORKING_CODE. Look at her go. โจ
include(CheckOBJCSourceCompiles)
check_objc_source_compiles("
#import <Foundation/Foundation.h>
int main()
{
NSObject *foo;
return 0;
}
" HAVE_WORKING_CODE)
โญ See Also โญ
- The
CheckSourceCompilesmodule โ for a more general command to check whether source can be built. - The
CheckSourceRunsmodule to check whether source can be built and run.
CheckOBJCSourceRuns
Added in version 3.16.
Okay so this module hands you a command that checks whether an Objective-C source can actually be built and run. Like, compile it, link it, execute it, see if it survives. ๐
Load this module in a CMake project with:
include(CheckOBJCSourceRuns)
Commands
This module provides the following command:
check_objc_source_runs
Checks once whether the given Objective-C source code compiles and links into an executable that can subsequently be run:
check_objc_source_runs(<code> <variable>)
The Objective-C source supplied in <code> must contain at least a main() function โ non-negotiable, bestie, it's an executable check so it needs an entry point. The result of the check is stored in the internal cache variable specified by <variable>. If the code builds and runs with exit code 0, success is indicated by a boolean true value. Failure to build or run is indicated by a boolean false value, such as an empty string or an error message. ๐ญ
Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ A space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work here (fr fr, spaces only). The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ A semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically. โจCMAKE_REQUIRED_INCLUDESโ A semicolon-separated list of header search paths to pass to the compiler. Heads up: these will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ A semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. ๐คซ
Examples
In the following example, this module is used to check whether the provided Objective-C source code builds and runs. Result of the check is stored in an internal cache variable HAVE_WORKING_CODE.
include(CheckOBJCSourceRuns)
check_objc_source_runs("
#import <Foundation/Foundation.h>
int main()
{
NSObject *foo;
return 0;
}
" HAVE_WORKING_CODE)
See Also
- The
CheckSourceRunsmodule for a more general command syntax. - The
CheckSourceCompilesmodule to check whether a source code can be built.
CheckOBJCXXCompilerFlag
Added in version 3.16.
This module provides a command to check whether the Objective-C++ compiler supports a given flag. Compiler flag detective work, but make it Objective-C++. ๐ต๏ธโโ๏ธ
Load this module in a CMake project with:
include(CheckOBJCXXCompilerFlag)
Commands
This module provides the following command:
check_objcxx_compiler_flag
Checks once whether the Objective-C++ compiler supports a given flag:
check_objcxx_compiler_flag(<flag> <variable>)
This command checks once that the <flag> is accepted by the OBJCXX compiler without producing a diagnostic message. Multiple flags can be specified in one argument as a string using a semicolon-separated list. ๐
The result of the check is stored in the internal cache variable specified by <variable>, with boolean true for success and boolean false for failure.
A successful result only indicates that the compiler did not report an error when given the flag. Whether the flag has any effect, or the intended one, is outside the scope of this module. So likeโฆ it said yes, it didn't say why. ๐
Note: Since the underlyingtry_compile()command also uses flags from variables likeCMAKE_<LANG>_FLAGS, unknown or unsupported flags in those variables may result in a false negative for this check. Yeah, that's the sneaky one โ your own leftover flags can sabotage the vibe check. ๐
Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ A space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ A semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ A semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ A semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed.CMAKE_TRY_COMPILE_TARGET_TYPEโ Internally, thetry_compile()command is used to perform the check, and this variable controls the type of target it creates. If this variable is set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. If set toSTATIC_LIBRARY, the test source code is compiled but not linked.
Examples
The following example demonstrates how to use this module to check the Objective-C++ compiler flag -fobjc-arc. The result of the check is stored in the internal cache variable HAVE_OBJC_ARC, and the flag is conditionally enabled using the target_compile_options() command. The $<COMPILE_LANGUAGE:...> generator expression ensures that the flag is added only to OBJCXX source files. Slay. ๐ฅ
include(CheckOBJCXXCompilerFlag)
check_objcxx_compiler_flag(-fobjc-arc HAVE_OBJC_ARC)
if(HAVE_OBJC_ARC)
target_compile_options(
example
PRIVATE $<$<COMPILE_LANGUAGE:OBJCXX>:-fobjc-arc>
)
endif()
See Also
- The
CheckCompilerFlagmodule for a more general command to check whether a compiler flag is supported.
CheckOBJCXXSourceCompiles
Added in version 3.16.
This module provides a command to check whether an Objective-C++ source can be built. Just built, no running required โ that's a whole different module's job. ๐ฆ
Load this module in a CMake project with:
include(CheckOBJCXXSourceCompiles)
Commands
This module provides the following command:
check_objcxx_source_compiles
Checks once whether the given Objective-C++ source code can be built:
check_objcxx_source_compiles(<code> <variable> [FAIL_REGEX <regexes>...])
This command checks once that the source supplied in <code> can be compiled (and linked into an executable). The result of the check is stored in the internal cache variable specified by <variable>.
The arguments are:
<code>โ Objective-C++ source code to check. This must be an entire program, as written in a file containing the body block. All symbols used in the source code are expected to be declared as usual in their corresponding headers.<variable>โ the name of an internal cache variable where we stash the check result, bestie: boolean true means slay success, boolean false means it flopped ๐FAIL_REGEX <regexes>...โ if you pass one or more regexes here, then failure is decided by checking whether anything in the compiler output matches any of those regexes. It's giving "we're looking for red flags" energy ๐ฉ
Variables Affecting the Check
The following variables can be set before you call this command to tweak how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. A semicolon-separated list will not work, so don't try it ๐ The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. It's giving automatic VIP treatment โจCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one shaped like-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically. Free bonus definition, no cap ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. So if you're like "why isn't it finding my headers", check this list first, bestie ๐ญCMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details). Linker era, let's go ๐CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details). Imported Targets are lowkey iconic ๐CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details). Fresh out of 3.31, we love to see it ๐CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. Silence is golden, periodt ๐คซCMAKE_TRY_COMPILE_TARGET_TYPEโ internally, thetry_compile()command is used to perform the check, and this variable controls the type of target it creates. If this variable is set toEXECUTABLE(the default), the check compiles and links the test source code as an executable program. If set toSTATIC_LIBRARY, the test source code is compiled but not linked. Choose your fighter ๐ฅ
Examples
In the following example, this module is used to check whether the provided Objective-C++ source code can be compiled and linked. Result of the check is stored in the internal cache variable HAVE_WORKING_CODE.
include(CheckOBJCXXSourceCompiles)
check_objcxx_source_compiles("
#include <vector>
#import <Foundation/Foundation.h>
int main()
{
std::vector<int> v;
NSObject *foo;
return 0;
}
" HAVE_WORKING_CODE)
See Also
- The
CheckSourceCompiles <#module:CheckSourceCompiles>module for a more general command to check whether source can be built. It's giving "we made it general purpose" energy ๐ - The
CheckSourceRuns <#module:CheckSourceRuns>module to check whether source can be built and run. Because sometimes compiling isn't enough, bestie ๐โโ๏ธ
CheckOBJCXXSourceRuns ๐ฆ
Added in version 3.16.
This module provides a command to check whether an Objective-C++ source can be built and run. It's the "does it actually work when you press play" check โถ๏ธ
Load this module in a CMake project with:
include(CheckOBJCXXSourceRuns)
Commands
This module provides the following command:
check_objcxx_source_runs โ checks once whether the given Objective-C++ source code compiles and links into an executable that can subsequently be run:
check_objcxx_source_runs(<code> <variable>)
The Objective-C++ source supplied in <code> must contain at least a main() function. The result of the check is stored in the internal cache variable specified by <variable>. If the code builds and runs with exit code 0, success is indicated by a boolean true value. Failure to build or run is indicated by a boolean false value, such as an empty string or an error message. So basically: exit code zero = slay, anything else = bestie no ๐ญ
Variables Affecting the Check
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. Same energy as before, no cap โจCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically. Automatic add-on, we love her ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. So don't come for her unless you set these, bestie ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details). Linker girlies rise ๐CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details). Imported Targets are literally main character energy ๐CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details). New in 3.31, fresh drop ๐CMAKE_REQUIRED_QUIETโ Added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. Shhh, we're being quiet ๐คซ
Examples
In the following example, this module is used to check whether the provided Objective-C++ source code builds and runs. Result of the check is stored in an internal cache variable HAVE_WORKING_CODE.
include(CheckOBJCXXSourceRuns)
check_objcxx_source_runs("
#include <vector>
#import <Foundation/Foundation.h>
int main()
{
std::vector<int> v;
NSObject *foo;
return 0;
}
" HAVE_WORKING_CODE)
See Also
- The
CheckSourceRuns <#module:CheckSourceRuns>module for a more general command syntax. General queen ๐ - The
CheckSourceCompiles <#module:CheckSourceCompiles>module to check whether a source code can be built. Compile-only vibes ๐ธ
CheckPIESupported ๐
Added in version 3.14.
This module provides a command to check whether the linker supports Position Independent Code (PIE) or No Position Independent Code (NO_PIE) for executables. It's giving "can your linker handle this" realness ๐
Load this module in a CMake project with:
include(CheckPIESupported)
When setting the POSITION_INDEPENDENT_CODE target property, PIC-related compile and link options are added when building library objects, and PIE-related compile options are added when building objects of executable targets, regardless of this module. Use this module to ensure that the POSITION_INDEPENDENT_CODE target property for executables is also honored at link time. So this module is the one that makes sure the link step also gets the memo, bestie ๐ซถ
Commands
This module provides the following command:
check_pie_supported โ checks for PIE/NO_PIE support and prepares all executables to have link time PIE options enabled:
check_pie_supported([OUTPUT_VARIABLE <output>] [LANGUAGES <langs>...])
Options are:
OUTPUT_VARIABLE <output>โ set the<output>variable with details about any error. If the check is bypassed because it uses cached results from a previous call, the output will be empty even if errors were present in the previous call. Cached results said "we already did this", so no new tea ๐ตLANGUAGES <langs>...โ check the linkers used for each of the specified languages. If this option is not provided, the command checks all enabled languages. C, CXX, Fortran are supported. Added in version 3.23: OBJC, OBJCXX, CUDA, and HIP are supported. So many languages, so little time ๐
Note: To usecheck_pie_supported(), policyCMP0083 <#policy:CMP0083>must be set toNEW; otherwise, a fatal error will occur. Do not skip this, bestie โ it will literally explode ๐
Variables
For each language checked, the check_pie_supported() command defines two boolean cache variables:
CMAKE_<lang>_LINK_PIE_SUPPORTEDโ set to true if PIE is supported by the linker and false otherwise. PIE girlies stay winning ๐ฅงCMAKE_<lang>_LINK_NO_PIE_SUPPORTEDโ set to true if NO_PIE is supported by the linker and false otherwise. NO_PIE also gets a moment, we love inclusivity ๐
Examples ๐
okay so bestie, if you wanna actually enable PIE on an executable target at link time too (not just compile time, no cap), you gotta include this module and call check_pie_supported() before you set that POSITION_INDEPENDENT_CODE target property. that call is the whole vibe check โ it figures out whether the linker for each checked language actually supports the PIE-related link options. like:
add_executable(foo ...)
include(CheckPIESupported)
check_pie_supported()
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
and lowkey, since not every linker even requires or supports PIE-related link options (looking at you, MSVC ๐), grabbing any error messages can be super useful for logging. like this:
add_executable(foo ...)
message(CHECK_START "Checking for C linker PIE support")
include(CheckPIESupported)
check_pie_supported(OUTPUT_VARIABLE output LANGUAGES C)
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
if(CMAKE_C_LINK_PIE_SUPPORTED)
message(CHECK_PASS "yes")
else()
message(CHECK_FAIL "no")
message(VERBOSE "PIE is not supported at link time:\n${output}"
"PIE link options will not be passed to linker.")
endif()
and here's the thing โ if you set the POSITION_INDEPENDENT_CODE target property on an executable without using this module, you'll get the PIE-related compile options but not the PIE-related link options. which, bestie, might not be enough in certain cases ๐ญ. like:
add_executable(foo ...)
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
๐ง CheckPrototypeDefinition
this module gives you a command to check if a C function has the prototype you expect. iconic, honestly.
load it into your CMake project with:
include(CheckPrototypeDefinition)
Commands โจ
this module provides the following command:
check_prototype_definition
checks whether a C function has the expected prototype:
check_prototype_definition(<function> <prototype> <return> <headers> <variable>)
<function>โ the name of the function whose prototype is being checked. the main character of the operation ๐ .<prototype>โ the expected prototype of the function, handed to you as a string.<return>โ the return value of the function. this gets used as the return value in the function definition body of the generated test program, so it can verify the function's return type actually matches what you expected. slay.<headers>โ a semicolon-separated list<#cmake-language-lists>of header file names required for checking the function prototype.<variable>โ the name of the variable that stores the check result. it gets created as an internal cache variable.
so what happens under the hood: this command generates a test program and verifies it builds without errors. the generated test program includes the specified <headers>, defines a function with the given literal <prototype> and <return> value, and then uses the specified <function>. the simplified test program looks like:
#include <headers>
// ...
<prototype> { return <return>; }
int main(...) { ...<function>()... }
Variables Affecting the Check ๐
you can set these variables before calling the command to change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. a semicolon-separated list<#cmake-language-lists>will not work, bestie โ don't try it. the contents ofCMAKE_<LANG>_FLAGS<#variable:CMAKE_<LANG>_FLAGS>and its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG><#variable:CMAKE_<LANG>_FLAGS_<CONFIG>>variables get automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list<#cmake-language-lists>of compiler definitions, each either-DFOOor-DFOO=barshaped. a definition for the name specified by the result variable argument of the check command is also added automatically โจ.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list<#cmake-language-lists>of header search paths to pass to the compiler. heads up: these will be the only header search paths used โ the contents of theINCLUDE_DIRECTORIES<#prop_dir:INCLUDE_DIRECTORIES>directory property get ignored. periodt.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list<#cmake-language-lists>of options to add to the link command (peeptry_compile()<#command:try_compile>for the deets).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list<#cmake-language-lists>of libraries to add to the link command. these can be system library names, or they can be Imported Targets<#imported-targets>(again,try_compile()<#command:try_compile>has the details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list<#cmake-language-lists>of library search paths to pass to the linker (seetry_compile()<#command:try_compile>for more).CMAKE_REQUIRED_QUIETโ Added in version 3.1. if this variable evaluates to a boolean true value, all the status messages associated with the check get suppressed ๐คซ.
Examples ๐ธ
checking whether the getpwent_r() function on Solaris/illumos systems has the expected prototype:
include(CheckPrototypeDefinition)
check_prototype_definition(
getpwent_r
"struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
"NULL"
"unistd.h;pwd.h"
HAVE_SOLARIS_GETPWENT_R
)
๐ฆ CheckSourceCompiles
Added in version 3.19.
this module provides a command that checks whether a chunk of source code can actually be built for a given language. extremely useful, ngl.
load it in like:
include(CheckSourceCompiles)
Commands ๐
this module provides the following command:
check_source_compiles
checks once whether the given source code can be built for the given language:
check_source_compiles(
<lang>
<code>
<variable>
[FAIL_REGEX <regexes>...]
[SRC_EXT <extension>]
)
this command checks once that the source supplied in <code> can be compiled (and linked into an executable) for the code language <lang>. the result of the check gets stored in an internal cache variable specified by <variable>. love that for us ๐.
the arguments are:
<lang>โ the language of the source code to check. supported languages are:C,CXX,CUDA,Fortran,HIP,ISPC,OBJC,OBJCXX, andSwift.- Added in version 3.21: support for the HIP language.
- Added in version 3.26: support for the Swift language.
<code>โ the source code to check. this must be an entire program, just like you'd write in a file containing the body block. all symbols used in the source code are expected to be declared as usual in their corresponding headers.<variable>โ variable name of an internal cache variable to store the check result, with boolean true for success and boolean false for failure. simple as that โจ.FAIL_REGEX <regexes>...โ if one or more regular expression patterns are provided, then failure is determined by checking whether anything in the compiler output matches any of the specified regular expressions. detective mode ๐.SRC_EXT <extension>โ by default, the internal test source file used for the check gets a file extension that matches the requested language (like.cfor C,.cxxfor C++,.F90for Fortran, etc.). this option overrides that with.<extension>instead.
Variables Affecting the Check ๐
you can set these variables before calling the command to change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. a semicolon-separated list<#cmake-language-lists>will not work, bestie. the contents ofCMAKE_<LANG>_FLAGS<#variable:CMAKE_<LANG>_FLAGS>and its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG><#variable:CMAKE_<LANG>_FLAGS_<CONFIG>>variables get automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list<#cmake-language-lists>of compiler definitions, each of the form-DFOOor-DFOO=bar. a definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list<#cmake-language-lists>of header search paths to pass to the compiler. these will be the only header search paths used; the contents of theINCLUDE_DIRECTORIES<#prop_dir:INCLUDE_DIRECTORIES>directory property get ignored.CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list<#cmake-language-lists>of options to add to the link command (seetry_compile()<#command:try_compile>for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list<#cmake-language-lists>of libraries to add to the link command. these can be the names of system libraries, or they can be Imported Targets<#imported-targets>(seetry_compile()<#command:try_compile>for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list<#cmake-language-lists>of library search paths to pass to the linker (seetry_compile()<#command:try_compile>for further details).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this variable evaluates to a boolean true value, literally every status message that'd normally come out of the check gets suppressed. silence, bestie ๐คซ๐CMAKE_TRY_COMPILE_TARGET_TYPEโ okay so under the hood the whole check is performed by thetry_compile()command, and this variable decides what kind of target it makes. Set it toEXECUTABLE(that's the default, no cap) and the check compiles and links your test source into a full executable program. Set it toSTATIC_LIBRARYand the test source gets compiled but not linked. that's the whole vibe ๐ซถ
Example: Basic Usage
This one shows you how to use the module to check whether the C++ compiler supports a specific language feature โ here the check verifies if the compiler supports C++11 lambda expressions. The result lands in the internal cache variable HAVE_CXX11_LAMBDAS:
include(CheckSourceCompiles)
check_source_compiles(CXX [[
int main()
{
auto lambda = []() { return 42; };
return lambda();
}
]] HAVE_CXX11_LAMBDAS)
Example: Checking Code With Bracket Argument
Here we're checking whether the C compiler supports the noreturn attribute. The code is supplied using the Bracket Argument, because it makes handling embedded quotes so much easier ๐
include(CheckSourceCompiles)
check_source_compiles(C [[
#if !__has_c_attribute(noreturn)
# error "No noreturn attribute"
#endif
int main(void) { return 0; }
]] HAVE_NORETURN)
Example: Performing a Check Without Linking
In this one the module does a compile-only check of Fortran source code โ does the compiler support the pure procedure attribute? Notice the CMAKE_TRY_COMPILE_TARGET_TYPE glow-up inside a block():
include(CheckSourceCompiles)
block()
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
check_source_compiles(
Fortran
"pure subroutine foo()
end subroutine"
HAVE_PURE
)
endblock()
Example: Isolated Check
This example teams up with the CMakePushCheckState module to swap out the required libraries while checking whether the PostgreSQL PGVerbosity enum contains PQERRORS_SQLSTATE (which is available as of PostgreSQL version 12). isolated check, contained mess, we love to see it ๐
include(CheckSourceCompiles)
include(CMakePushCheckState)
find_package(PostgreSQL)
if(TARGET PostgreSQL::PostgreSQL)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES PostgreSQL::PostgreSQL)
check_source_compiles(C [[
#include <libpq-fe.h>
int main(void)
{
PGVerbosity e = PQERRORS_SQLSTATE;
(void)e;
return 0;
}
]] HAVE_PQERRORS_SQLSTATE)
cmake_pop_check_state()
endif()
๐ฆ SEE ALSO ๐ฆ
- The
CheckSourceRunsmodule โ for when you need to check whether the source code can be built and also run. ๐
๐ CheckSourceRuns ๐
Added in version 3.19 โจ
This module hands you a command to check whether some source code can be built and run. like, actually executed. icon behavior ngl ๐ฅ
Load this module in a CMake project with:
include(CheckSourceRuns)
๐ COMMANDS ๐
This module provides the following command:
check_source_runsโ checks once whether the given source code compiles and links into an executable that can subsequently be run. one shot, one check, periodt ๐
check_source_runs(<lang> <code> <variable> [SRC_EXT <extension>])
So this command checks once that the <lang> source code you supplied in <code> can be built, linked as an executable, and then run. The result of the check is stored in the internal cache variable you specify with <variable>.
The arguments are:
<lang>โ the programming language of the source<code>you're checking. Supported languages are:C,CXX,CUDA,Fortran,HIP,OBJC, andOBJCXX.
Added in version 3.21: support for the HIP language.
<code>โ the source code to be tested. It must contain a valid source program. For example, it must contain at least amain()function (in C/C++), or a program unit (in Fortran). don't come in empty-handed bestie ๐ญ<variable>โ name of the internal cache variable that holds the result of the check. If the code builds and runs with exit code 0, success is indicated by a boolean true value. Failure to build or run is indicated by a boolean false value, such as an empty string or an error message.SRC_EXT <extension>โ by default, the internal test source file used for the check gets a file extension that matches the requested language (e.g.,.cfor C,.cxxfor C++,.F90for Fortran, etc.). This option lets you override that with.<extension>instead. your file, your rules ๐
๐ธ Variables Affecting the Check ๐ธ
The following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work โ fr fr, don't try it ๐. The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. yeah, ignored-ignored ๐CMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14. A semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. shhh ๐คซ
โจ EXAMPLES โจ
Example: Basic Usage
This example demonstrates how to use the module to check whether the C source code is supported and operational at runtime. The result of the check is stored in the internal cache variable HAVE_NORETURN:
include(CheckSourceRuns)
check_source_runs(C [[
#include <stdlib.h>
#include <stdnoreturn.h>
noreturn void f(){ exit(0); }
int main(void) { f(); return 1; }
]] HAVE_NORETURN)
Example: Checking Fortran Code
Checking if Fortran source code runs successfully โ coarrays edition ๐ง:
include(CheckSourceRuns)
check_source_runs(Fortran [[
program test
real :: x[*]
call co_sum(x)
end program
]] HAVE_COARRAY)
Example: Checking C++ Code With Bracket Argument
This one demonstrates checking whether the C++ standard library is functional and std::vector actually works at runtime. If the source compiles, links, and runs successfully, the internal cache variable HAVE_WORKING_STD_VECTOR gets set to a boolean true value. The code is supplied using the Bracket Argument for easier embedded quotes handling:
include(CheckSourceRuns)
check_source_runs(CXX [[
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {1, 2, 3};
if (v.size() != 3) return 1;
std::cout << "Vector works correctly." << std::endl;
return 0;
}
]] HAVE_WORKING_STD_VECTOR)
Example: Isolated Check
Here the module pairs up with the CMakePushCheckState module to modify required compile definitions and libraries while checking whether the C function sched_getcpu() is supported and operational at runtime. Because โ plot twist ๐ญ โ on some systems the sched_getcpu() function may be available at compile time but not actually implemented by the kernel. In those cases it returns -1 and sets errno to ENOSYS. This check verifies that sched_getcpu() runs successfully and stores a boolean result in the internal cache variable HAVE_SCHED_GETCPU:
include(CheckSourceRuns)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
if(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
set(CMAKE_REQUIRED_LIBRARIES gnu)
endif()
check_source_runs(C [[
#include <sched.h>
int main(void)
{
if (sched_getcpu() == -1) {
return 1;
}
return 0;
}
]] HAVE_SCHED_GETCPU)
cmake_pop_check_state()
๐ฆ SEE ALSO ๐ฆ
- The
CheckSourceCompilesmodule โ for when you just need to check whether a source code can be built. ๐จ
๐ง CheckStructHasMember ๐ง
This module provides a command to check whether a struct or class has a specified member variable. very "do you have this field tho" energy ๐
Load this module in a CMake project with:
include(CheckStructHasMember)
๐ Commands
okay so this module hands you exactly one command, and honestly? it's a good one:
check_struct_has_member
it checks once whether the struct or class you point at has the member variable you're looking for. one and done. no cap:
check_struct_has_member(
<struct>
<member>
<headers>
<variable>
[LANGUAGE <language>]
)
so what it does: it checks once whether the struct or class <struct> actually contains the specified <member>, after it includes the header(s) <headers> โ the place where the prototype is supposed to be declared, bestie. and like, you can pass multiple header files in one single argument as a string using a semicolon-separated list. the result gets stashed in an internal cache variable <variable>. ๐ซถ
the options are:
LANGUAGE <language>โ uses the<language>compiler to run the check. acceptable values areCandCXX. if you don't say anything, it defaults toC. no judgment,Cis a vibe.
Variables Affecting the Check ๐
these variables can be set before you call the command to change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to pass to the compiler. real talk: a semicolon-separated list will not work here. the contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables get automatically prepended to the compiler command before the contents of this variable. so your flags are like, second in line. โจCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one shaped like-DFOOor-DFOO=bar. a definition for the name specified by the result variable argument of the check command also gets added automatically. free of charge. ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. and listen: these will be the only header search paths used. the contents of theINCLUDE_DIRECTORIESdirectory property get ignored entirely. it's giving main character energy, honestly. ๐CMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list of options to add to the link command (peeptry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. these can be the names of system libraries, or they can be Imported Targets (again,try_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. if this variable evaluates to a boolean true value, all status messages associated with the check get suppressed. silence. peace. ๐คซ
๐ธ Examples
Example: Checking C Struct Member
in this one, the module checks if the C struct timeval has a member variable tv_sec after including the <sys/select.h> header. the result lands in the internal cache variable HAVE_TIMEVAL_TV_SEC. she ate:
include(CheckStructHasMember)
check_struct_has_member(
"struct timeval"
tv_sec
sys/select.h
HAVE_TIMEVAL_TV_SEC
)
Example: Checking C++ Struct Member
here we're checking if the C++ struct std::tm has a member variable tm_gmtoff after including the <ctime> header. result goes into HAVE_TM_GMTOFF. note the LANGUAGE CXX โ you gotta say it, C is the default remember? ๐
include(CheckStructHasMember)
check_struct_has_member(
std::tm
tm_gmtoff
ctime
HAVE_TM_GMTOFF
LANGUAGE CXX
)
Example: Isolated Check With Compile Definitions
this one does the check with temporarily modified compile definitions, using the CMakePushCheckState module. push, set, check, pop. clean. iconic. ๐ฆ
include(CheckStructHasMember)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_struct_has_member(
"struct utsname"
domainname
sys/utsname.h
HAVE_UTSNAME_DOMAINNAME
)
cmake_pop_check_state()
๐ CheckSymbolExists
this module provides a command to check whether a C symbol exists. that's literally the whole vibe.
load this module in a CMake project with:
include(CheckSymbolExists)
Commands
this module provides the following command:
check_symbol_exists
checks once whether a symbol exists as a function, variable, or preprocessor macro in C:
check_symbol_exists(<symbol> <headers> <variable>)
so it checks whether <symbol> is available after including the specified header file(s) <headers>, and stores the result in the internal cache variable <variable>. multiple header files can be specified in one argument as a string using a semicolon-separated list. ๐
here's the nuanced part, don't skip it:
- if the header files define the symbol as a macro, it's considered available and assumed to work.
- if the symbol is declared as a function or variable, the check also makes sure it links successfully โ like, the symbol must exist in a linked library or object file. fr fr.
- compiler intrinsics may not be detected, because they're not always linkable or explicitly declared in headers. ๐ญ
symbols that are types, enum values, or compiler intrinsics are not recognized. for those, consider using the CheckTypeSize or CheckSourceCompiles module instead. consider it a redirect, bestie.
also important: this command is intended to check symbols as they appear in C. for C++ symbols, use the CheckCXXSymbolExists module instead. different language, different module. okurrr.
Variables Affecting the Check
the following variables may be set before calling this command to modify the way the check is run:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. a semicolon-separated list will not work. the contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable. โจCMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each of the form-DFOOor-DFOO=bar. a definition for the name specified by the result variable argument of the check command is also added automatically.CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. these will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property will be ignored. ๐ซถCMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list of options to add to the link command (seetry_compile()for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. these can be the names of system libraries, or they can be Imported Targets (seetry_compile()for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ Added in version 3.1. if this variable evaluates to a boolean true value, all status messages associated with the check will be suppressed. ๐คซ
Examples
this example shows you how to check for a preprocessor macro SEEK_SET and the C function fopen() from the <stdio.h> header, all with this module. two checks, one include, slay:
include(CheckSymbolExists)
# Check for macro SEEK_SET
check_symbol_exists(SEEK_SET "stdio.h" HAVE_SEEK_SET)
# Check for function fopen
check_symbol_exists(fopen "stdio.h" HAVE_FOPEN)
See Also
- the
CheckCXXSymbolExistsmodule โ for when you need to check whether a C++ symbol exists. ๐
๐ CheckTypeSize
this module provides a command to check the size of a C/C++ type or expression. yes, expression. she's flexible.
load this module in a CMake project with:
include(CheckTypeSize)
Commands
this module provides the following command:
check_type_size
checks once whether the C/C++ type or expression exists, and then determines its size:
check_type_size(
<type>
<size-var>
[RESULT_VARIABLE <result-var>]
[BUILTIN_TYPES_ONLY]
[LANGUAGE <language>]
)
the arguments are:
<type>โ the type or expression being checked. ๐<size-var>โ the name of the internal cache variable for storing the size of the type or expression<type>. this name is also used as a prefix, as explained below. remember that, it comes back around. ๐ฅRESULT_VARIABLE <result-var>โ Added in version 4.2.RESULT_VARIABLE <result-var>โ the name of the internal cache variable that holds a boolean value telling you whether the type or expression<type>exists. If you don't give it, the command just goes ahead and defines an internal cache variable namedHAVE_<size-var>by default instead ๐BUILTIN_TYPES_ONLYโ if you pass this, only compiler-builtin types get supported in the check. If you don't pass it, the command also checks for the common headers<sys/types.h>,<stdint.h>, and<stddef.h>, and saves the results in theHAVE_SYS_TYPES_H,HAVE_STDINT_H, andHAVE_STDDEF_Hinternal cache variables. And for C++std::types,<cstdint>and<cstddef>are checked too, withHAVE_CSTDINTandHAVE_CSTDDEFdefined respectively. The command automatically includes the available headers in the type size check, which is how it supports checking types that are defined in those headers ๐ซถLANGUAGE <language>โ uses the<language>compiler to run the check. Acceptable values areCandCXX. If you don't specify, it defaults toC, no cap โจ
๐ Result Variables ๐
Results get reported in these variables, bestie:
<size-var>โ internal cache variable that holds one of the following values:<size>โ if the type or expression<type>exists, it'll have a non-zero size<size>in bytes ๐0โ when the type has an architecture-dependent size. This can happen whenCMAKE_OSX_ARCHITECTUREShas multiple architectures. In that case the<size-var>_KEYSvariable is also defined, and the<size-var>_CODEvariable contains preprocessor tests mapping, as explained down below ๐""(empty string) โ when the type or expression<type>does not exist ๐ญ
HAVE_<size-var>โ internal cache variable holding a boolean value indicating whether the type or expression<type>exists. This variable gets defined when theRESULT_VARIABLEargument is not used.<result-var>โ added in version 4.2. Internal cache variable defined when theRESULT_VARIABLEargument is used. It holds a boolean value indicating whether the type or expression<type>exists (same value asHAVE_<size-var>). In this case, theHAVE_<size-var>variable is not defined. It's giving "one or the other, never both" ๐ฆ<size-var>_CODEโ CMake variable that holds preprocessor code to define the macro<size-var>to the size of the type, or to leave the macro undefined if the type doesn't exist.
When the type has an architecture-dependent size (<size-var> value is 0), this variable contains preprocessor tests mapping from each architecture macro to the corresponding type size ๐ฅ
<size-var>_KEYSโ CMake variable that's defined only when the type has an architecture-dependent size (<size-var>value is0), and it contains a list of architecture macros. The value for each key is stored in<size-var>-<key>variables.
๐ Variables Affecting the Check ๐
You can set these variables before calling this command to change how the check runs:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list will not work, so don't try it ๐ The contents ofCMAKE_<LANG>_FLAGSand its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG>variables are automatically prepended to the compiler command before the contents of this variable, though.CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one in the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command also gets added automatically โจCMAKE_REQUIRED_INCLUDESโ a semicolon-separated list of header search paths to pass to the compiler. Heads up: these will be the only header search paths used; the contents of theINCLUDE_DIRECTORIESdirectory property get ignored ๐CMAKE_REQUIRED_LINK_OPTIONSโ added in version 3.14. A semicolon-separated list of options to add to the link command (peeptry_compile()for more deets).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets (again,try_compile()has the full tea โ).CMAKE_REQUIRED_LINK_DIRECTORIESโ added in version 3.31. A semicolon-separated list of library search paths to pass to the linker (seetry_compile()for further details).CMAKE_REQUIRED_QUIETโ added in version 3.1. If this variable evaluates to a boolean true value, all the status messages associated with the check get suppressed ๐คซCMAKE_EXTRA_INCLUDE_FILESโ a semicolon-separated list of extra header files to include when performing the check.
๐ธ Examples ๐ธ
Consider this code, bestie:
include(CheckTypeSize)
# Check for size of long.
check_type_size(long SIZEOF_LONG)
message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
message("SIZEOF_LONG: ${SIZEOF_LONG}")
message("SIZEOF_LONG_CODE: ${SIZEOF_LONG_CODE}")
On a 64-bit architecture, the output may look something like this:
HAVE_SIZEOF_LONG: TRUE
SIZEOF_LONG: 8
SIZEOF_LONG_CODE: #define SIZEOF_LONG 8
On Apple platforms, when CMAKE_OSX_ARCHITECTURES has multiple architectures, types may have architecture-dependent sizes. For example, with this code:
include(CheckTypeSize)
check_type_size(long SIZEOF_LONG)
message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
message("SIZEOF_LONG: ${SIZEOF_LONG}")
foreach(key IN LISTS SIZEOF_LONG_KEYS)
message("key: ${key}")
message("value: ${SIZEOF_LONG-${key}}")
endforeach()
message("SIZEOF_LONG_CODE:\n${SIZEOF_LONG_CODE}")
the result may be:
HAVE_SIZEOF_LONG: TRUE
SIZEOF_LONG: 0
key: __i386
value: 4
key: __x86_64
value: 8
SIZEOF_LONG_CODE:
#if defined(__i386)
# define SIZEOF_LONG 4
#elif defined(__x86_64)
# define SIZEOF_LONG 8
#else
# error SIZEOF_LONG unknown
#endif
Example: Configuration Header ๐
The next example demonstrates how the result variables can be used in a configuration header:
include(CheckTypeSize)
check_type_size(long SIZEOF_LONG)
configure_file(config.h.in config.h @ONLY)
config.h.in
/* Define whether the type 'long' exists. */
#cmakedefine HAVE_SIZEOF_LONG
/* The size of 'long', as computed by sizeof. */
@SIZEOF_LONG_CODE@
Example: Checking Complex Expressions ๐
Despite the name of this module, you can also use it to determine the size of more complex expressions. For example, to check the size of a struct member:
include(CheckTypeSize)
check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)
Example: Isolated Check ๐ง
In the following example, the check is performed with temporarily modified additional headers, using the CMAKE_EXTRA_INCLUDE_FILES variable and the CMakePushCheckState module. The result of the check is stored in HAVE_SIZEOF_UNION_SEMUN, and the size is stored in SIZEOF_UNION_SEMUN internal cache variables.
include(CheckTypeSize)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/ipc.h sys/sem.h)
check_type_size("union semun" SIZEOF_UNION_SEMUN)
cmake_pop_check_state()
Example: Customizing Result Variable ๐
Since CMake 4.2, you can customize the HAVE_<size-var> variable name using the RESULT_VARIABLE argument. In the following example, this module is used to check whether the struct flock exists, and the result is stored in the MyProj_HAVE_STRUCT_FLOCK internal cache variable:
cmake_minimum_required(VERSION 4.2)
# ...
include(CheckTypeSize)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_EXTRA_INCLUDE_FILES "fcntl.h")
check_type_size(
"struct flock"
MyProj_SIZEOF_STRUCT_FLOCK
RESULT_VARIABLE MyProj_HAVE_STRUCT_FLOCK
)
cmake_pop_check_state()
๐ CheckVariableExists ๐
This module provides a command to check whether a C variable exists.
Load this module in a CMake project with:
include(CheckVariableExists)
โจ Commands โจ
This module provides the following command:
check_variable_exists
Checks once if a C variable exists:
check_variable_exists(<var> <variable>)
This command attempts to compile and link a test C program that references the specified C variable <var>. A boolean result of whether the check was successful gets stored in an internal cache variable <variable> ๐ซถ
Note: prefer usingCheckSymbolExistsorCheckSourceCompilesinstead of this command for more robust detection, ngl. This command performs a link-only check and doesn't detect whether a variable is also declared in system or library headers. Neither can it detect variables that might be defined as preprocessor macros ๐ญ
๐ Variables Affecting the Check ๐
(the deets keep going from here, bestie โ stay with me ๐ )
okay so before you even call this command, you can set any of these variables to change how the check runs โ think of them as the settings you tweak first, no cap:
CMAKE_REQUIRED_FLAGSโ a space-separated string of extra flags to hand to the compiler. โ ๏ธ heads up: a semicolon-separated list will not work, so please don't try it bestie. also the contents ofCMAKE_<LANG>_FLAGSand its configuration-specific bestieCMAKE_<LANG>_FLAGS_<CONFIG>get automatically prepended to the compiler command before whatever you put in this variable. it's giving "the compiler already has opinions before you even speak". ๐CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list of compiler definitions, each one shaped like-DFOOor-DFOO=bar. and yes, a definition for the name given by the result variable argument of the check command also gets added automatically, because the module is an overachiever like that. โจCMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. a semicolon-separated list of options to add to the link command (peeptry_compile()for the further details, iykyk).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list of libraries to add to the link command. these can be the names of system libraries, or they can be Imported Targets (again,try_compile()has the details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31. a semicolon-separated list of library search paths to pass to the linker (details intry_compile(), you know the drill).CMAKE_REQUIRED_QUIETโ Added in version 3.1. if this variable evaluates to a boolean true value, all the status messages associated with the check get suppressed. it's giving "mute the group chat while I think". ๐คซ
โจ Examples โจ
Example: Basic Usage
in the following example, a check is performed whether the linker sees the C variable tzname and stores the check result in the PROJECT_HAVE_TZNAME internal cache variable:
include(CheckVariableExists)
check_variable_exists(tzname PROJECT_HAVE_TZNAME)
Example: Isolated Check With Linked Libraries
in the following example, this module is used in combination with the CMakePushCheckState module to link an additional required library using the CMAKE_REQUIRED_LIBRARIES variable. for example, in a find module, to check whether the Net-SNMP library has the usmHMAC192SHA256AuthProtocol array:
include(CheckVariableExists)
include(CMakePushCheckState)
find_library(SNMP_LIBRARY NAMES netsnmp)
if(SNMP_LIBRARY)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES ${SNMP_LIBRARY})
check_variable_exists(usmHMAC192SHA256AuthProtocol SNMP_HAVE_SHA256)
cmake_pop_check_state()
endif()
๐ธ See Also ๐ธ
- the
CheckSymbolExistsmodule, for checking whether a C symbol exists. sibling energy fr.
๐ฆ CMakeAddFortranSubdirectory ๐ฆ
this module provides a command to add a Fortran project that lives in a subdirectory. yes, Fortran. it's iconic, it's vintage, it's still running half the scientific world. periodt. ๐
load this module in a CMake project with:
include(CMakeAddFortranSubdirectory)
โจ Commands โจ
this module provides the following command:
cmake_add_fortran_subdirectory โ adds a Fortran-only subproject from subdirectory to the current project:
cmake_add_fortran_subdirectory(
<subdir>
PROJECT <project-name>
ARCHIVE_DIR <dir>
RUNTIME_DIR <dir>
LIBRARIES <libs>...
LINK_LIBRARIES
[LINK_LIBS <lib> <deps>...]...
[CMAKE_COMMAND_LINE <flags>...]
NO_EXTERNAL_INSTALL
)
this command checks whether the current compiler supports Fortran, or attempts to locate a Fortran compiler. if a compatible Fortran compiler is found, the Fortran project located in <subdir> is added as a subdirectory to the current project. slay. ๐
if no Fortran compiler is found and the compiler is MSVC, it searches for the MinGW gfortran compiler. in this case, the Fortran project is built as an external project using MinGW tools, and Fortran-related imported targets are created. ngl this setup works only if the Fortran code is built as a shared DLL library, so the BUILD_SHARED_LIBS variable is enabled in the external project. additionally, the CMAKE_GNUtoMS variable is set to ON to ensure that Microsoft-compatible .lib files are created. look at it adapting, main character energy honestly.
the options are:
PROJECTโ the name of the Fortran project as defined in the top-levelCMakeLists.txtlocated in<subdir>.ARCHIVE_DIRโ directory where the project places.libarchive files. a relative path is interpreted as relative toCMAKE_CURRENT_BINARY_DIR.RUNTIME_DIRโ directory where the project places.dllruntime files. a relative path is interpreted as relative toCMAKE_CURRENT_BINARY_DIR. (yes, same rule as above, they're matching.) ๐LIBRARIESโ names of library targets to create or import into the current project.LINK_LIBRARIESโ specifies link interface libraries forLIBRARIES. this option expects a list ofLINK_LIBS <lib> <deps>...items, where:LINK_LIBSmarks the start of a new pair<lib>is a library target<deps>...represents one or more dependencies required by<lib>
CMAKE_COMMAND_LINEโ additional command-line flags passed to thecmake(1)command when configuring the Fortran subproject.NO_EXTERNAL_INSTALLโ prevents installation of the external project.
note: theNO_EXTERNAL_INSTALLoption is required for forward compatibility with a future version that supports installation of the external project binaries duringmake install. so like, don't skip it, it's future-proofing and it's free. ๐ซถ
๐ฅ Examples ๐ฅ
adding a Fortran subdirectory to a project can be done by including this module and calling the cmake_add_fortran_subdirectory() command. in the following example, a Fortran project provides the hello library and its dependent world library:
include(CMakeAddFortranSubdirectory)
cmake_add_fortran_subdirectory(
fortran-subdir
PROJECT FortranHelloWorld
ARCHIVE_DIR lib
RUNTIME_DIR bin
LIBRARIES hello world
LINK_LIBRARIES
LINK_LIBS hello world # hello library depends on the world library
NO_EXTERNAL_INSTALL
)
# The Fortran target can be then linked to the main project target.
add_executable(main main.c)
target_link_libraries(main PRIVATE hello)
the way hello depends on world and it all justโฆ links. we love a functional build. ๐
โญ See Also โญ
there are multiple ways to integrate Fortran libraries. alternative approaches include:
- the
add_subdirectory()command, to add the subdirectory directly to the build. - the
export()command can be used in the subproject to provide Imported Targets or similar for integration with other projects. - the
FetchContentorExternalProjectmodules when working with external dependencies.
๐ CMakeBackwardCompatibilityCXX ๐
this module defines several backward compatibility cache variables for the CXX language to support early C++ (pre-C++98, ANSI C++). it's giving "digging up the archives", and honestly? respect. ๐
load this module in a CMake project with:
include(CMakeBackwardCompatibilityCXX)
the following modules are included by this module:
TestForANSIForScopeTestForANSIStreamHeadersTestForSSTREAMTestForSTDNamespace
additionally, the following cache variable may be defined:
CMAKE_ANSI_CXXFLAGSโ a space-separated string of compiler options for enabling ANSI C++ mode, if available.
note: this module is intended for C++ code written before C++ 98. as of the C++ 98 standard, these issues have been formally addressed, making such checks obsolete. so likeโฆ it's a museum piece bestie, visit it but don't move in. ๐
๐ธ Examples ๐ธ
including this module provides backward compatibility cache variables, which can be used in C++. for example:
CMakeLists.txt
include(CMakeBackwardCompatibilityCXX)
file(
CONFIGURE
OUTPUT config.h
CONTENT [[
#cmakedefine CMAKE_NO_ANSI_FOR_SCOPE
#cmakedefine CMAKE_NO_ANSI_STRING_STREAM
#cmakedefine CMAKE_NO_ANSI_STREAM_HEADERS
#cmakedefine CMAKE_NO_STD_NAMESPACE
]]
)
๐ฆ CMakeDependentOption ๐ฆ
this module provides a command to define boolean options whose availability and default values depend on specified conditions or other options. it helps keep your configuration interface clean by only showing the options that are actually relevant to the current settings. it's giving "curated feed" and honestly the GUI needed it. โจ
load this module in CMake with:
include(CMakeDependentOption)
โจ Commands โจ
this module provides the following command:
cmake_dependent_option โ provides a boolean option that depends on a set of conditions:
cmake_dependent_option(<variable> <help> <value> <condition> <else-value>)
this command creates a boolean <variable> and makes it available to the user in the GUI (such as cmake-gui(1) or ccmake(1)), if a set of conditions evaluates to boolean true. conditional visibility? we stan. ๐
the arguments are:
<variable>โ the name of a variable that stores the option value.<help>โ a brief description of the option. this string is typically a short line of text and is displayed in the GUI.<value>โ boolean value for the<variable>, when<condition>evaluates to boolean true.
<condition> ๐ธ โ the thing that decides whether <variable> gets set and shows up in the GUI. Basically a vibe check for your option:
- If
<condition>evaluates to boolean false, the option is hidden from the user in the GUI, and a local variable<variable>is set to<else-value>. - If
<condition>evaluates to boolean true, a boolean cache variable named<variable>is created with default<value>, and the option is shown in the GUI, letting the user enable or disable it. โจ - If
<condition>later evaluates to boolean false (on a consecutive configuration run), the option is hidden from the user in the GUI and the<variable>type is changed to an internal cache variable. In that case, a local variable of the same name is set to<else-value>. - If
<condition>becomes true again in consecutive configuration runs, the user's previously set value is preserved. ๐
The <condition> argument can be:
- A single condition (such as a variable name).
- A semicolon-separated list of multiple conditions.
- Added in version 3.22: a full Condition Syntax, exactly like the one used in an
if(<condition>)clause. See policyCMP0127. This unlocks the whole condition syntax โ yes, even grouping conditions with parens and all that cute stuff. ๐
<else-value> โ the value that gets assigned to a local variable named <variable> whenever <condition> evaluates to boolean false.
Ok so important: in CMake project mode, boolean cache variables are created the way we just described. In CMake script mode, boolean variables are just set instead. Different mode, different move. ๐
Examples
Example: Basic Usage
Using this module in a project to conditionally set an option:
CMakeLists.txt
include(CMakeDependentOption)
cmake_dependent_option(USE_SSL_GNUTLS "Use GnuTLS for SSL" ON USE_SSL OFF)
Example: Enabling/Disabling Dependent Option
Extending the previous example, this shows how the module gives you user-configurable options based on a condition during the configuration phase:
CMakeLists.txt
include(CMakeDependentOption)
option(USE_SSL "Enable SSL in the project" OFF)
cmake_dependent_option(USE_SSL_GNUTLS "Use GnuTLS for SSL" ON USE_SSL OFF)
message(STATUS "USE_SSL: ${USE_SSL}")
message(STATUS "USE_SSL_GNUTLS: ${USE_SSL_GNUTLS}")
On the first configuration run, a boolean cache variable USE_SSL is set to OFF, and a local variable USE_SSL_GNUTLS is set to OFF:
$ cmake -B build-dir
-- USE_SSL: OFF
-- USE_SSL_GNUTLS: OFF
Running CMake with USE_SSL=ON sets both USE_SSL and USE_SSL_GNUTLS boolean cache variables to ON:
$ cmake -B build-dir -D USE_SSL=ON
-- USE_SSL: ON
-- USE_SSL_GNUTLS: ON
On a subsequent configuration run with USE_SSL=OFF, USE_SSL_GNUTLS follows suit. But!! its value is preserved in the internal cache while being overridden locally:
$ cmake -B build-dir -D USE_SSL=OFF
-- USE_SSL: OFF
-- USE_SSL_GNUTLS: OFF
Example: Semicolon-separated List of Conditions
The <condition> argument can also be a semicolon-separated list of conditions. In the example below, if the variable USE_BAR is ON and the variable USE_ZOT is OFF, the option USE_FOO is available and defaults to ON. Otherwise, USE_FOO is set to OFF and hidden from the user.
If the values of USE_BAR or USE_ZOT change in future configuration runs, the previous value of USE_FOO is preserved, so that when it becomes available again it retains its last set value. ๐ซถ
CMakeLists.txt
include(CMakeDependentOption)
cmake_dependent_option(USE_FOO "Use Foo" ON "USE_BAR;NOT USE_ZOT" OFF)
Example: Full Condition Syntax
As of CMake 3.22, cmake_dependent_option() supports full condition syntax. ๐
In the following example, if the condition evaluates to true, the option USE_FOO is available and set to ON. Otherwise, it's set to OFF and hidden in the GUI. The value of USE_FOO is preserved across configuration runs, similar to the previous example.
CMakeLists.txt
include(CMakeDependentOption)
cmake_dependent_option(USE_FOO "Use Foo" ON "USE_A AND (USE_B OR USE_C)" OFF)
Another example showing how an option can be conditionally available based on the target system:
CMakeLists.txt
include(CMakeDependentOption)
cmake_dependent_option(
ENABLE_FOO
"Enable feature Foo (this option is available when building for Windows)"
ON
[[CMAKE_SYSTEM_NAME STREQUAL "Windows"]]
OFF
)
See Also
- The
option()command, for providing a boolean option that the user can optionally select.
๐ฆ CMakeFindDependencyMacro
This module hands you a command implemented as a macro that finds a dependency for a package. Iconic behaviour, tbh.
Load this module in a CMake package configuration file with:
FooConfig.cmake or foo-config.cmake:
include(CMakeFindDependencyMacro)
Note: This module is designed to be used in a Package Configuration File (<PackageName>Config.cmake).
Commands
This module provides the following command:
find_dependency
The find_dependency() macro wraps a find_package() call for a package dependency:
find_dependency(<dep> [...])
It's designed to be used in a Package Configuration File (<PackageName>Config.cmake). find_dependency forwards the correct parameters for QUIET and REQUIRED that were passed to the original find_package() call. Any additional arguments you specify get forwarded to find_package() too. โจ
If the dependency could not be found, it sets an informative diagnostic message and calls return() to end processing of the calling package configuration file and return to the find_package() command that loaded it.
Note: That call to return() is exactly why this macro is not suitable to call from Find Modules. Important!!
Package Dependency Search Optimizations
If find_dependency is called with arguments identical to a previous call in the same directory โ maybe because of diamond-shaped package dependencies โ the underlying call to find_package() is optimized out. This optimization is lowkey important: it supports large package dependency graphs while avoiding a combinatorial explosion of repeated searches. But the heuristic can't account for ambient variables that affect package behavior, like <PackageName>_USE_STATIC_LIBS, which some packages offer. So package configuration files should avoid setting such variables before their calls to find_dependency. ๐
Changed in version 3.15: Previously, the underlying call to find_package() was always optimized out if the package had already been found. CMake 3.15 removed that optimization to support cases where find_dependency call arguments request different components.
Changed in version 3.26: The pre-3.15 optimization was restored, but with the above-described heuristic so varying find_dependency call arguments are accounted for. ๐
๐ CMakePackageConfigHelpers
This module provides helper commands for creating config files that other projects can include to find and use a package.
Load this module in a CMake project with:
include(CMakePackageConfigHelpers)
Generating a Package Configuration File
configure_package_config_file
Create a config file for a project:
configure_package_config_file(<input> <output>
INSTALL_DESTINATION <path>
[PATH_VARS <var1> <var2> ... <varN>]
[NO_SET_AND_CHECK_MACRO]
[NO_CHECK_REQUIRED_COMPONENTS_MACRO]
[INSTALL_PREFIX <path>]
)
You should use configure_package_config_file() instead of the plain configure_file() command whenever you create the <PackageName>Config.cmake or <PackageName>-config.cmake file for installing a project or library. Why? Because it helps make the resulting package relocatable by avoiding hardcoded paths in the installed <PackageName>Config.cmake file. Slay. ๐
In a FooConfig.cmake file there may be code like this to make the install destinations known to the using project:
set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
#...logic to determine installedPrefix from the own location...
set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
All four options shown above are not sufficient. ๐ญ The first three hardcode the absolute directory locations. The fourth case works only if the logic to determine the installedPrefix is correct, and if CONFIG_INSTALL_DIR contains a relative path โ which in general cannot be guaranteed. The effect of all this is that the resulting FooConfig.cmake file would work poorly under Windows and macOS, where users are used to choosing the install location of a binary package at install time, independent from how CMAKE_INSTALL_PREFIX was set at build/cmake time.
Using configure_package_config_file() helps. If used correctly, it makes the resulting FooConfig.cmake file relocatable. Usage:
- Write a
FooConfig.cmake.infile as you are used to. - Insert a line at the top containing only the string
@PACKAGE_INIT@. - Instead of
set(FOO_DIR "@SOME_INSTALL_DIR@"), useset(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")(this must be after the@PACKAGE_INIT@line). - Instead of using the normal
configure_file()command, useconfigure_package_config_file().
The <input> and <output> arguments are the input and output file, the same way as in configure_file(). ๐
The <path> given to INSTALL_DESTINATION must be the destination where the FooConfig.cmake file will be installed to. This path can either be absolute, or relative to the INSTALL_PREFIX path.
The variables <var1> to <varN> that you hand over as PATH_VARS are the ones holding your install destinations, okay? For each of them the macro spins up a lil helper variable called PACKAGE_<var...> โ and those helper variables are literally the whole point, you have to use them in your FooConfig.cmake.in file when you set the installed location. They get calculated by configure_package_config_file() so they're always relative to wherever the package actually landed. Works for relative locations and absolute ones ๐ซถ โ but absolute only slays if the absolute location is a subdirectory of INSTALL_PREFIX. That's the catch, bestie.
Added in version 3.30: the variable PACKAGE_PREFIX_DIR is always defined after the @PACKAGE_INIT@ line. It holds the value of the base install location. Generally you should be using the variables defined through the PATH_VARS mechanism instead, but PACKAGE_PREFIX_DIR is there for the cases PATH_VARS can't easily handle โ like files installed straight into the base install location instead of some subdirectory of it. ๐
Note: when consumers of the generated file are on CMake 3.29 or older, the value ofPACKAGE_PREFIX_DIRcan get changed by a call tofind_dependency()orfind_package(). So if your project relies onPACKAGE_PREFIX_DIR, it is the project's responsibility to make sure that value is preserved across any such calls โ or any other calls that might pull in another file generated byconfigure_package_config_file(). No cap, guard it. ๐
Added in version 3.1: if you pass the INSTALL_PREFIX argument, it gets used as the base path for calculating all the relative paths. The <path> argument has to be an absolute path, no exceptions. If you don't pass it, the CMAKE_INSTALL_PREFIX variable is used instead. The default value is a vibe when you're generating a FooConfig.cmake file to use your package from the install tree โ but when you're generating one to use your package from the build tree, you should definitely pass this option. โจ
By default, configure_package_config_file() also generates two helper macros into the FooConfig.cmake file: set_and_check() and check_required_components().
set_and_check() should be used instead of the normal set() command whenever you're setting directories and file locations. Besides setting the variable, it also checks that the file or directory you referenced actually exists and fails with a fatal error if it doesn't ๐ญ โ which is exactly how you keep your generated FooConfig.cmake file from containing wrong references. Add the NO_SET_AND_CHECK_MACRO option to stop the set_and_check() macro from being generated into the FooConfig.cmake file.
check_required_components(<PackageName>) should be called at the end of the FooConfig.cmake file. This macro checks whether all the requested, non-optional components have been found, and if not, it sets the Foo_FOUND variable to FALSE so the package is considered not found. It does that by testing the Foo_<Component>_FOUND variables for all requested required components. Call this macro even if your package doesn't provide any components, so users can't erroneously specify components and get away with it. ๐จ Add the NO_CHECK_REQUIRED_COMPONENTS_MACRO option to stop the check_required_components() macro from being generated in the FooConfig.cmake file.
See also Example Generating Package Files. ๐
๐ Generating a Package Version File ๐
write_basic_package_version_file โ creates a version file for a project, iconic behaviour only:
write_basic_package_version_file(<filename>
[VERSION <major.minor.patch>]
COMPATIBILITY <AnyNewerVersion|SameMajorVersion|SameMinorVersion|
SamePatchVersion|SameFullVersion|SemanticVersion|
ExactVersion>
[ARCH_INDEPENDENT] )
Writes a file to <filename> for use as a <PackageName>ConfigVersion.cmake file. Check the docs for find_package() if you wanna know the details on files like this. โจ
<filename> is the output filename, and it should be in the build tree. <major.minor.patch> is the version number of the project you're installing.
If you don't give a VERSION, the PROJECT_VERSION variable gets used. And if that hasn't been set? It errors out. Periodt. ๐
The COMPATIBILITY modes, from least to most picky โ buckle up:
- The
AnyNewerVersionmode means the installed package version is considered compatible if it's newer than or exactly the same as the requested version. Use this one for packages that are fully backward compatible, even across major versions. - If
SameMajorVersionis used instead, the behavior differs fromAnyNewerVersionin that the major version number must be the same as requested โ e.g. version2.0will not be considered compatible if1.0is requested. Use this for packages that guarantee backward compatibility within the same major version. - If
SameMinorVersionis used, the behavior is the same asSameMajorVersion, but both major and minor version have to be the same as requested โ e.g. version0.2will not be compatible if0.1is requested. - If
SamePatchVersionis used, the package is only considered compatible if the requested version matches exactly through the patch version, ignoring any tweak version. For example, version1.2.3.4of a package is considered compatible with requested version1.2.3.5, but not with requested version1.2.4. - If
SameFullVersionis used, the package is only considered compatible if the requested version matches exactly through all specified version components. For example, version1.2.3.4of a package is only considered compatible with requested version1.2.3.4. Missing version components are not treated as implicit zeroes, so version1.2.3is not considered compatible with requested version1.2.3.0. ๐ซ - If
SemanticVersionis used, behavior follows the usual semantic versioning interpretation: when the installed package version has a major component greater than zero, the behavior is the same asSameMajorVersion. When the installed package version has a major component zero, the behavior is the same asSameMinorVersion. - If
ExactVersionis used, the behavior is the same asSamePatchVersion.
If your project has more elaborate version matching rules, you're gonna need to write your own custom <PackageName>ConfigVersion.cmake file instead of using this macro. Custom era. ๐
Added in version 3.11: the SameMinorVersion compatibility mode.
Added in version 3.14: if ARCH_INDEPENDENT is given, the installed package version will be considered compatible even if it was built for a different architecture than the requested one. Otherwise an architecture check gets performed, and the package is only considered compatible if the architecture matches exactly. For example, if the package is built for a 32-bit architecture, the package is only considered compatible if it's used on a 32-bit architecture โ unless ARCH_INDEPENDENT is given, in which case it's considered compatible on any architecture. Slay. ๐
Note: ARCH_INDEPENDENT is intended for header-only libraries or similar packages with no binaries.
Added in version 3.19: the version file generated by the AnyNewerVersion, SameMajorVersion and SameMinorVersion arguments of COMPATIBILITY handles the version range, if one is specified (see the find_package() command for the details). ExactVersion mode is incompatible with version ranges and will display an author warning if one is specified. โ ๏ธ
Added in version 4.4: the SamePatchVersion, SameFullVersion, and SemanticVersion compatibility modes.
The version file generated by SemanticVersion handles version ranges if one is specified (see the find_package() command for the details). SamePatchVersion and SameFullVersion modes are incompatible with version ranges and will display an author warning if one is specified.
Deprecated since version 4.4: the ExactVersion compatibility mode. Use SamePatchVersion or SameFullVersion instead, depending on whether the tweak version should be ignored. ๐
Internally, this macro executes configure_file() to create the resulting version file. Depending on the COMPATIBILITY, the corresponding BasicConfigVersion-<COMPATIBILITY>.cmake.in file is used. Please note that these files are internal to CMake โ do not call configure_file() on them yourself ๐
โโ๏ธ โ but they can be used as a starting point to create more sophisticated custom <PackageName>ConfigVersion.cmake files.
๐ฆ Generating an Apple Platform Selection File ๐ฆ
generate_apple_platform_selection_file
Added in version 3.29.
Create an Apple platform selection file, like so:
generate_apple_platform_selection_file(<filename>
INSTALL_DESTINATION <path>
[INSTALL_PREFIX <path>]
[MACOS_INCLUDE_FILE <file>]
[IOS_INCLUDE_FILE <file>]
[IOS_SIMULATOR_INCLUDE_FILE <file>]
[IOS_CATALYST_INCLUDE_FILE <file>]
[TVOS_INCLUDE_FILE <file>]
[TVOS_SIMULATOR_INCLUDE_FILE <file>]
[WATCHOS_INCLUDE_FILE <file>]
[WATCHOS_SIMULATOR_INCLUDE_FILE <file>]
[VISIONOS_INCLUDE_FILE <file>]
[VISIONOS_SIMULATOR_INCLUDE_FILE <file>]
[ERROR_VARIABLE <variable>]
)
Writes a file that includes an Apple-platform-specific .cmake file โ e.g. for use as <PackageName>Config.cmake. This can be used together with the XCFRAMEWORK_LOCATION argument of export(SETUP) to export packages in a way that a project built for any Apple platform can use them. So versatile, we love to see it. ๐โจ
INSTALL_DESTINATION <path> Path to which the generated file will be installed by the caller, e.g. via install(FILES). The path may be either relative to the INSTALL_PREFIX or absolute.
INSTALL_PREFIX <path> Path prefix to which the package will be installed by the caller. The <path> argument must be an absolute path, fr fr. If this argument is not passed, the CMAKE_INSTALL_PREFIX variable will be used instead.
MACOS_INCLUDE_FILE <file> File to include if the platform is macOS.
IOS_INCLUDE_FILE <file> File to include if the platform is iOS.
IOS_SIMULATOR_INCLUDE_FILE <file> File to include if the platform is iOS Simulator.
IOS_CATALYST_INCLUDE_FILE <file> Added in version 3.31.
File to include if the platform is iOS Catalyst.
TVOS_INCLUDE_FILE <file>โ the file we pull in when the platform is tvOS ๐บTVOS_SIMULATOR_INCLUDE_FILE <file>โ same deal but for tvOS Simulator, bestie ๐ซถWATCHOS_INCLUDE_FILE <file>โ the file for when the platform is watchOS โWATCHOS_SIMULATOR_INCLUDE_FILE <file>โ and this one for watchOS Simulator ๐ซVISIONOS_INCLUDE_FILE <file>โ the file for visionOS, yes we're doing spatial computing now ๐ฅฝVISIONOS_SIMULATOR_INCLUDE_FILE <file>โ and the visionOS Simulator version, periodt โจERROR_VARIABLE <variable>โ okay so if the consuming project is being built for a platform we don't support, this sets<variable>to an error message. The includer can then use that info to ~pretend~ the package was never found (gaslight, gatekeep, girlboss ๐ ). If you don't pass this option, the default behavior is to issue a fatal error. So like, no chill mode by default ๐ญ
Heads up: if any of those optional include files is left unspecified, and the consuming project is built for its corresponding platform, the generated file will consider that platform to be unsupported. What happens next is decided by the ERROR_VARIABLE option. iykyk โ ๏ธ
โจ Generating an Apple Architecture Selection File โจ
๐ generate_apple_architecture_selection_file
Added in version 3.29.
This one creates an Apple architecture selection file for you:
generate_apple_architecture_selection_file(<filename>
INSTALL_DESTINATION <path>
[INSTALL_PREFIX <path>]
[SINGLE_ARCHITECTURES <arch>...
SINGLE_ARCHITECTURE_INCLUDE_FILES <file>...]
[UNIVERSAL_ARCHITECTURES <arch>...
UNIVERSAL_INCLUDE_FILE <file>]
[ERROR_VARIABLE <variable>]
)
So what it does is write a file that includes an Apple-architecture-specific .cmake file, chosen based on CMAKE_OSX_ARCHITECTURES <#variable:CMAKE_OSX_ARCHITECTURES>. Like, for inclusion from an Apple-specific <PackageName>Config.cmake file. Slay ๐
INSTALL_DESTINATION <path>โ the path the caller will install the generated file to, e.g. viainstall(FILES)<#files>. This path can be either relative to theINSTALL_PREFIXor absolute. Your call, main character ๐INSTALL_PREFIX <path>โ the path prefix the caller will install the package to. The<path>argument must be an absolute path (no exceptions, don't try it ๐). If you don't pass this argument, theCMAKE_INSTALL_PREFIX<#variable:CMAKE_INSTALL_PREFIX> variable gets used instead. Default behavior, love that for us ๐SINGLE_ARCHITECTURES <arch>...โ the architectures provided by the entries ofSINGLE_ARCHITECTURE_INCLUDE_FILES.SINGLE_ARCHITECTURE_INCLUDE_FILES <file>...โ the architecture-specific files. One of them gets loaded whenCMAKE_OSX_ARCHITECTURES<#variable:CMAKE_OSX_ARCHITECTURES> contains a single architecture matching the corresponding entry ofSINGLE_ARCHITECTURES. One-to-one vibes ๐ฅUNIVERSAL_ARCHITECTURES <arch>...โ the architectures provided by theUNIVERSAL_INCLUDE_FILE.
The list may include$(ARCHS_STANDARD)to support consumption using theXcode<#generator:Xcode> generator, but the architectures should always be listed individually too. Do both. It's giving overachiever and we respect it ๐
UNIVERSAL_INCLUDE_FILE <file>โ a file to load whenCMAKE_OSX_ARCHITECTURES<#variable:CMAKE_OSX_ARCHITECTURES> contains a (non-strict) subset of theUNIVERSAL_ARCHITECTURESand does not match any one of theSINGLE_ARCHITECTURES.ERROR_VARIABLE <variable>โ if the consuming project is built for an unsupported architecture,<variable>gets set to an error message. The includer may use that to pretend the package wasn't found ๐. If you skip this option, the default behavior is to issue a fatal error. Dramatic but fair ๐
๐ธ Example Generating Package Files ๐ธ
Okay bestie, here's an example using both the configure_package_config_file() and write_basic_package_version_file() commands. Two icons, one example ๐
CMakeLists.txt
include(GNUInstallDirs)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/Foo
CACHE PATH "Location of header files" )
set(SYSCONFIG_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR}/foo
CACHE PATH "Location of configuration files" )
#...
include(CMakePackageConfigHelpers)
configure_package_config_file(FooConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo
PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
VERSION 1.2.3
COMPATIBILITY SameMajorVersion )
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo )
FooConfig.cmake.in
set(FOO_VERSION x.y.z)
...
@PACKAGE_INIT@
...
set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
check_required_components(Foo)
๐ฆ CMakePrintHelpers ๐ฆ
This module hands you convenience commands โ primarily intended for debugging โ to print out the values of properties and variables. It's literally your print-statement era, but make it CMake ๐
Load this module in CMake with:
include(CMakePrintHelpers)
๐ Commands
This module provides the following commands:
cmake_print_properties
Prints the values of properties for the specified targets, source files, directories, tests, or cache entries:
cmake_print_properties(
<TARGETS [<targets>...] |
SOURCES [<sources>...] |
DIRECTORIES [<dirs>...] |
TESTS [<tests>...] |
CACHE_ENTRIES [<entries>...] >
PROPERTIES [<properties>...]
)
Exactly one of the scope keywords must be specified. And the scope keyword plus its arguments have to come before the PROPERTIES keyword in the argument list. Order matters, bestie, don't fight it ๐
cmake_print_variables
Prints each variable name followed by its value:
cmake_print_variables([<vars>...])
๐ Examples
Printing the LOCATION and INTERFACE_INCLUDE_DIRECTORIES properties for both targets foo and bar:
include(CMakePrintHelpers)
cmake_print_properties(
TARGETS foo bar
PROPERTIES LOCATION INTERFACE_INCLUDE_DIRECTORIES
)
Gives:
--
Properties for TARGET foo:
foo.LOCATION = "/usr/lib/libfoo.so"
foo.INTERFACE_INCLUDE_DIRECTORIES = "/usr/include;/usr/include/foo"
Properties for TARGET bar:
bar.LOCATION = "/usr/lib/libbar.so"
bar.INTERFACE_INCLUDE_DIRECTORIES = "/usr/include;/usr/include/bar"
And printing given variables:
include(CMakePrintHelpers)
cmake_print_variables(CMAKE_C_COMPILER CMAKE_MAJOR_VERSION NOT_EXISTS)
Gives:
-- CMAKE_C_COMPILER="/usr/bin/cc" ; CMAKE_MAJOR_VERSION="3" ; NOT_EXISTS=""
๐ CMakePrintSystemInformation ๐
This module can be used for diagnostics to print system information. It's the "tell me everything about this machine" module and honestly? Obsessed ๐ฅ๏ธ
Load this module in a CMake project with:
include(CMakePrintSystemInformation)
โญ Examples
For example, including this module in a project:
CMakeLists.txt
project(Example)
# ...
include(CMakePrintSystemInformation)
prints various CMake variables:
CMAKE_SYSTEM is Linux-6.11.0-17-generic Linux 6.11.0-17-generic x86_64
CMAKE_SYSTEM file is Platform/Linux
CMAKE_C_COMPILER is /usr/bin/cc
CMAKE_CXX_COMPILER is /usr/bin/c++
CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS is -shared
CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS is -shared
...
๐ง CMakePushCheckState ๐ง
This module provides commands for managing the state of variables that influence how the various CMake check commands get performed (e.g., check_symbol_exists() <#command:check_symbol_exists>, etc.). It's the save-scumming of build systems and I love it ๐พโจ
Load this module in a CMake project with:
include(CMakePushCheckState)
This module provides the following commands, which are useful for scoped configuration โ for example, in CMake modules, or when you're performing checks in a controlled environment โ ensuring that your temporary modifications stay isolated to the scope of the check and don't leak out and propagate into other parts of the build system. Boundaries, bestie ๐ซถ
cmake_push_check_state()cmake_reset_check_state()cmake_pop_check_state()
๐ Affected Variables
The following CMake variables are saved, reset, and restored by this module's commands:
CMAKE_REQUIRED_FLAGSโ a space-separated string of additional flags to pass to the compiler. A semicolon-separated list <#cmake-language-lists> will not work (fr fr, don't do it ๐). The contents ofCMAKE_<LANG>_FLAGS<#variable:CMAKE_<LANG>_FLAGS> and its associated configuration-specificCMAKE_<LANG>_FLAGS_<CONFIG><#variable:CMAKE_<LANG>_FLAGS_<CONFIG>> variables are automatically prepended to the compiler command before the contents of this variable. Prepended, not appended, noted ๐CMAKE_REQUIRED_DEFINITIONSโ a semicolon-separated list <#cmake-language-lists> of compiler definitions, each one of the form-DFOOor-DFOO=bar. A definition for the name specified by the result variable argument of the check command also gets added automatically. Built-in bonus ๐CMAKE_REQUIRED_INCLUDESโ a semicolon-separated list <#cmake-language-lists> of header search paths to pass to the compiler. These will be the only header search paths used; the contents of theINCLUDE_DIRECTORIES<#prop_dir:INCLUDE_DIRECTORIES> directory property will be ignored. Like, fully ignored. Ghosted ๐ปCMAKE_REQUIRED_LINK_OPTIONSโ Added in version 3.14. A semicolon-separated list <#cmake-language-lists> of options to add to the link command (seetry_compile()<#command:try_compile> for further details).CMAKE_REQUIRED_LIBRARIESโ a semicolon-separated list <#cmake-language-lists> of libraries to add to the link command. These can be the names of system libraries, or they can be Imported Targets <#imported-targets> (seetry_compile()<#command:try_compile> for further details).CMAKE_REQUIRED_LINK_DIRECTORIESโ Added in version 3.31.
Semicolon-separated list of library search paths that get passed straight to the linker (peep try_compile() if u want the full lore on that one ๐).
CMAKE_REQUIRED_QUIET
Added in version 3.1.
If this variable evaluates to a boolean true value, all the status messages that come with the check get silenced. Full mute mode ๐คซ.
CMAKE_EXTRA_INCLUDE_FILES
Added in version 3.6: Previously this was already used by the check_type_size() command, and now this module supports it too โจ.
A semicolon-separated list of extra header files to #include when the check runs. Like, bring ur extra headers to the function, bestie ๐.
Note ๐ซถ: Other CMake variables โ like CMAKE_<LANG>_FLAGS โ propagate to every check no matter which commands this module gives you, because those fundamental variables are literally designed to influence the global state of the build system. They're main character variables, we don't gatekeep them ๐
.
๐ Commands
cmake_push_check_state
Pushes (saves) the current states of all those variables above onto a stack ๐ฅ:
cmake_push_check_state([RESET])
Use this command to preserve the current configuration before u make temporary modifications for specific checks. Snapshot first, chaos later ๐ธ.
RESETโ when this option is specified, the command doesn't just save the current states of the listed variables, it also resets them to empty, so they can be reconfigured from a clean state. Fresh start energy โจ.
cmake_reset_check_state
Resets (clears) the contents of the variables listed above to empty states:
cmake_reset_check_state()
Use this command when ur doing multiple sequential checks that each need entirely new configurations, so no previous configuration accidentally carries over like a bad vibe ๐.
cmake_pop_check_state
Restores the states of the variables listed above to whatever their values were at the time of the most recent cmake_push_check_state() call:
cmake_pop_check_state()
Use this command to revert the temporary changes u made during a check. And to avoid unexpected behaviour โ no cap โ pair every cmake_push_check_state() with a corresponding cmake_pop_check_state() ๐ซถ.
๐งช Examples
๐ Example: Isolated Check With Compile Definitions
In this example, a check for the C symbol memfd_create() is performed with an extra _GNU_SOURCE compile definition, without touching the global compile flags at all. The RESET option is there to make sure any prior values of the check-related variables get explicitly cleared before the check even starts ๐งผ.
include(CMakePushCheckState)
# Save and reset the current state
cmake_push_check_state(RESET)
# Perform check with specific compile definitions
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
include(CheckSymbolExists)
check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
# Restore the original state
cmake_pop_check_state()
๐ธ Example: Nested Configuration Scopes
Here the variable states get pushed onto the stack multiple times, so u can do sequential or nested checks. Each cmake_pop_check_state() restores the most recently pushed states โ stack behaviour, iconic ๐ฅ.
include(CMakePushCheckState)
# Save and reset the current state
cmake_push_check_state(RESET)
# Perform the first check with additional libraries
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
include(CheckSymbolExists)
check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN)
# Save current state
cmake_push_check_state()
# Perform the second check with libraries and additional compile definitions
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_symbol_exists(dladdr "dlfcn.h" HAVE_DLADDR)
message(STATUS "${CMAKE_REQUIRED_DEFINITIONS}")
# Output: -D_GNU_SOURCE
# Restore the previous state
cmake_pop_check_state()
message(STATUS "${CMAKE_REQUIRED_DEFINITIONS}")
# Output here is empty
# Reset variables to prepare for the next check
cmake_reset_check_state()
# Perform the next check only with additional compile definitions
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_symbol_exists(dl_iterate_phdr "link.h" HAVE_DL_ITERATE_PHDR)
# Restore the original state
cmake_pop_check_state()
๐ CMakeVerifyManifest
This module is meant to be used in command-line mode via cmake -P, to verify that the embedded manifests and the side-by-side manifests for a project actually match each other ๐ต๏ธโโ๏ธ.
Load this module in a CMake script with:
include(CMakeVerifyManifest)
So first, the module recursively globs *.manifest files from the current source directory and builds up a list of allowed versions ๐.
Then, the script globs all *.exe and *.dll files. Each .exe and .dll file gets scanned for embedded manifests, and the versions of CRT are checked to be in that list of allowed versions. Every single one, no skipping ๐
.
๐ฅ Input Variables
This module accepts the following variables:
allow_versionsโ u can pass extra versions by setting theallow_versionsvariable from the invocation command. This lets a project use additional embedded manifest versions even if that version was not found in a.manifestfile ๐.
๐ Examples
To use this module in ur project, make a local command-line script (for example, in the project's subdirectory cmake/scripts) and include the module:
cmake/scripts/verify-manifest.cmake
include(CMakeVerifyManifest)
Then run that local script from the command line, and, for example, specify an additional embedded manifest of 8.0.50608.0 to be used in the project:
cmake -Dallow_versions=8.0.50608.0 -Pcmake/scripts/verify-manifest.cmake
๐ฆ CPack
This module configures generators for binary installers and source packages ๐.
Load this module in a CMake project with:
include(CPack)
๐ซ Introduction
The CPack module generates the configuration files CPackConfig.cmake and CPackSourceConfig.cmake. They're intended for use in a subsequent run of the cpack program, where they steer the generation of installers or/and source packages โจ.
Depending on the CMake generator, the CPack module may also add two new build targets, package and package_source. See the packaging targets section below for the deets ๐.
The generated binary installers will contain all the files that have been installed via CMake's install() command (and the deprecated commands install_files(), install_programs(), and install_targets()). Just know that the DESTINATION option of the install() command must be a relative path โ otherwise installed files get ignored by CPack ๐ญ.
Certain kinds of binary installers can be configured so that users get to pick individual application components to install. See the CPackComponent module for further details ๐งฉ.
Source packages (configured through CPackSourceConfig.cmake and generated by the CPack Archive Generator) will contain all source files in the project directory except the ones specified in CPACK_SOURCE_IGNORE_FILES ๐
โโ๏ธ.
๐ CPack Generators
The CPACK_GENERATOR variable has different meanings in different contexts. In a CMakeLists.txt file, CPACK_GENERATOR is a list of generators: and when cpack is run with no other arguments, it'll iterate over that list and produce one package for each generator. In a CPACK_PROJECT_CONFIG_FILE, CPACK_GENERATOR is a string naming a single generator. So if u need per-cpack-generator logic to control other cpack settings, that's exactly when u need a CPACK_PROJECT_CONFIG_FILE. If it's set, the CPACK_PROJECT_CONFIG_FILE gets included automatically on a per-generator basis. It only needs to contain overrides ๐.
Here's how it works:
cpackruns- it includes
CPackConfig.cmake - it iterates over the generators given by the
-Gcommand line option, or, if no such option was specified, over the list of generators given by theCPACK_GENERATORvariable set in theCPackConfig.cmakeinput file - foreach generator, it then
- sets
CPACK_GENERATORto the one currently being iterated - includes the
CPACK_PROJECT_CONFIG_FILE - produces the package for that generator
- sets
This is the key ๐: for each generator listed in CPACK_GENERATOR in CPackConfig.cmake, cpack will reset CPACK_GENERATOR internally to the one currently being used, and then include the CPACK_PROJECT_CONFIG_FILE.
For a list of available generators, see cpack-generators(7) ๐.
๐ฏ Targets package and package_source
If CMake is run with the Makefile, Ninja, or Xcode generator, then include(CPack) generates a target package. This makes it possible to build a binary installer from CMake, Make, or Ninja: instead of cpack, u can call cmake --build . --target package or make package or ninja package. The VS generator creates an uppercase target PACKAGE ๐
If CMake is run with the Makefile or Ninja generator, then include(CPack) also generates a target package_source. To build a source package, instead of cpack -G TGZ --config CPackSourceConfig.cmake, u can call cmake --build . --target package_source, make package_source, or ninja package_source ๐ฆ.
๐งธ Variables common to all CPack Generators
Before including this CPack module in ur CMakeLists.txt file, there's a whole variety of variables u can set to customise the resulting installers. The most commonly-used ones are:
CPACK_PACKAGE_NAMEโ the name of the package (or application). If it's not specified, it defaults to the project name ๐ท๏ธ.CPACK_PACKAGE_VENDORโ the name of the package vendor (e.g.,"Kitware"). The default is"Humanity"๐ซถ.CPACK_PACKAGE_DIRECTORYโ the directory where CPack does its packaging. If it's not set then this defaults (internally) to the build dir. This variable may be defined in a CPack config file or from thecpackcommand line option-B. If it's set, the command line option overrides the value found in the config file ๐.CPACK_PACKAGE_VERSION_MAJORโ the package's major version. This one is always set, bestie โ no vibes of it ever being empty โ but its default depends on whether you fed version details to theproject()command in your top-levelCMakeLists.txt. Gave version details? Then the default isCMAKE_PROJECT_VERSION_MAJOR. Gave nothing at all? Then CMake just assumes a default version of0.1.1, which meansCPACK_PACKAGE_VERSION_MAJORdefaults to0.CPACK_PACKAGE_VERSION_MINORโ the package's minor version. The default is again a whole "did you tellproject()about your version or not" situation in that top-levelCMakeLists.txt. If version details were given, the default isCMAKE_PROJECT_VERSION_MINORโ but if there was no minor version component specified, thenCPACK_PACKAGE_VERSION_MINORis left unset. ๐ And if you gave no project version at all, CMake assumes0.1.1, so the default lands on1.CPACK_PACKAGE_VERSION_PATCHโ the package's patch version, same deal as above: it hinges on whether version details went toproject()in the top-levelCMakeLists.txt. With version details, the default isCMAKE_PROJECT_VERSION_PATCH, but if no patch component was specified thenCPACK_PACKAGE_VERSION_PATCHstays unset. No project version at all? Default version0.1.1gets assumed, so this defaults to1. โจCPACK_PACKAGE_DESCRIPTIONโ a description of the project, used in places like the intro screen of CPack-generated Windows installers. If you don't set it, the value gets populated for you from the file named byCPACK_PACKAGE_DESCRIPTION_FILE.CPACK_PACKAGE_DESCRIPTION_FILEโ a text file used to describe the project whenCPACK_PACKAGE_DESCRIPTIONisn't explicitly set. The default points to a built-in template file,Templates/CPack.GenericDescription.txt. ๐CPACK_PACKAGE_DESCRIPTION_SUMMARYโ short description of the project (like, only a few words, keep it cute and brief ๐ ). If theCMAKE_PROJECT_DESCRIPTIONvariable is set, that's used as the default value; otherwise the default is a string CMake generates based onCMAKE_PROJECT_NAME.CPACK_PACKAGE_HOMEPAGE_URLโ the project homepage URL. ๐ The default is taken from theCMAKE_PROJECT_HOMEPAGE_URLvariable, which gets set by the top-levelproject()command โ or else the default is just empty if no URL was passed toproject().CPACK_PACKAGE_FILE_NAMEโ the name of the package file to generate, not including the extension. For example,cmake-2.6.1-Linux-i686. The default value is:
${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}
CPACK_PACKAGE_INSTALL_DIRECTORYโ installation directory on the target system. Some CPack generators, like NSIS, use this to create an install directory โ e.g."CMake 2.5"below the installation prefix. All installed elements get put inside this directory. ๐๏ธCPACK_PACKAGE_ICONโ a branding image that gets displayed inside the installer (used by the GUI installers, so likeโฆ the pretty ones). ๐ผ๏ธCPACK_PACKAGE_CHECKSUMโ Added in version 3.7. One or multiple algorithms used to generate additional files containing the checksum of the package. The output file names will be:
${CPACK_PACKAGE_FILE_NAME}.${CPACK_PACKAGE_CHECKSUM}
The supported algorithms are the ones listed by the string(<HASH>) command. Changed in version 4.2: the variable accepts a list of algorithms โ yes bestie, plural, go off. ๐ฅ
CPACK_PROJECT_CONFIG_FILEโ the CPack-time project CPack configuration file. This file gets included at cpack time, once per generator, after CPack has setCPACK_GENERATORto the actual generator being used. It's the moment for per-generator setting ofCPACK_*variables at cpack time. โจCPACK_RESOURCE_FILE_LICENSEโ license to be embedded in the installer. It typically gets displayed to the user by the produced installer (often with an explicit "Accept" button, for the graphical installers) prior to installation. Lowkey important: this license file is NOT added to the installed files โ it's just used by some CPack generators like NSIS. If you want to use UTF-8 characters, the file needs to be encoded in UTF-8 BOM. And if you want to actually install a license file (maybe the same one as this) along with your project, you must add an appropriate CMakeinstall()command in yourCMakeLists.txt. ๐CPACK_RESOURCE_FILE_READMEโ ReadMe file to be embedded in the installer. It typically describes the purpose of the project in some detail during the installation. Not all CPack generators use this file, so don't come for me if it's ignored. ๐CPACK_RESOURCE_FILE_WELCOMEโ Welcome file to be embedded in the installer. It welcomes users to this installer ๐ซถ โ typically used in the graphical installers on Windows and Mac OS X.CPACK_MONOLITHIC_INSTALLโ disables the component-based installation mechanism. When it's set, the component specification is ignored and all installed items go into a single"MONOLITHIC"package. Some CPack generators do monolithic packaging by default, and can be asked to do component packaging by settingCPACK_<GENNAME>_COMPONENT_INSTALLtoTRUE.CPACK_GENERATORโ the list of CPack generators to use. If you don't specify it, CPack will create a set of options following the naming patternCPACK_BINARY_<GENNAME>(e.g.CPACK_BINARY_NSIS), which lets the user enable/disable individual generators. And heads up: if the-Goption is given on thecpack(1)command line, it overrides this variable and anyCPACK_BINARY_<GENNAME>options. ๐CPACK_OUTPUT_CONFIG_FILEโ the name of the CPack binary configuration file. This is the CPack configuration generated by the CPack module for binary installers. Defaults toCPackConfig.cmake.CPACK_PACKAGE_EXECUTABLESโ lists each of the executables and the associated text label used to create Start Menu shortcuts. For example, setting this to the listccmake;CMakewill create a shortcut named "CMake" that executes the installed executableccmake. Not all CPack generators use it โ at least NSIS, Inno Setup and WIX do. ๐CPACK_STRIP_FILESโ list of files to be stripped. Starting with CMake 2.6.0,CPACK_STRIP_FILESis a boolean variable which enables stripping of all files (a list of files evaluates toTRUEin CMake, so this change is compatible, no cap). ๐งCPACK_VERBATIM_VARIABLESโ Added in version 3.4. If set toTRUE, values of variables prefixed withCPACK_get escaped before being written to the configuration files, so that thecpackprogram receives them exactly as they were specified. If not, characters like quotes and backslashes can cause parsing errors or alter the valuecpackreceives. Defaults toFALSEfor backwards compatibility.CPACK_THREADSโ Added in version 3.20. Number of threads to use when performing parallelized operations, like compressing the installer package.
Some compression methods used by CPack generators such as Debian or Archive may take advantage of multiple CPU cores to speed up compression. CPACK_THREADS can be set to specify how many threads get used for compression.
- A positive integer specifies an exact desired thread count.
- A negative integer makes CPack use the absolute value as the upper limit, but it may choose a lower value based on the available hardware concurrency.
0makes CPack try to use all available CPU cores.
By default CPACK_THREADS is set to 1.
The following compression methods may take advantage of multiple cores:
xzโ supported if CMake is built with a liblzma that supports parallel compression.- Added in version 3.21: official CMake binaries available on
cmake.orgnow ship with a liblzma that supports parallel compression. Older versions did not.
- Added in version 3.21: official CMake binaries available on
zstdโ Added in version 3.24. Supported if CMake is built with libarchive 3.6 or higher. Official CMake binaries available oncmake.orgsupport it.
Other compression methods ignore this value and use only one thread. ๐
CPACK_COMPRESSION_LEVELโ Added in version 4.3. Select the compression level to use when it's applicable, like when compressing the installer package.
Some compression methods used by CPack generators such as Debian or Archive may take advantage of different compression levels. The accepted values are in the range 0 to 9. If you select the zstd compression method, you can select the compression level between 0 and 19, except the zip archive format. ๐ญ
By default CPACK_COMPRESSION_LEVEL is set to 0, which selects the default compression level. It's selected automatically by the archive library backend and not directly set by CMake itself. The default compression level may vary between archive formats, platforms, etc.
๐ฆ Variables for Source Package Generators ๐ฆ
The following CPack variables are specific to source packages, and will not affect binary packages:
CPACK_SOURCE_PACKAGE_FILE_NAMEโ the name of the source package. For examplecmake-2.6.1. ๐CPACK_SOURCE_STRIP_FILESโ the list of files in your source tree that get stripped ๐ . Okay so plot twist: starting with CMake 2.6.0,CPACK_SOURCE_STRIP_FILESis a boolean variable that turns on stripping for all the files (a list of files evaluates toTRUEin CMake, so this glow-up is fully backwards-compatible, no cap).CPACK_SOURCE_GENERATORโ the list of generators used for your source packages โจ. Same energy asCPACK_GENERATOR: if you don't specify it, CPack will spin up a whole set of options (likeCPACK_SOURCE_ZIP) so users can pick which packages get generated ๐.CPACK_SOURCE_OUTPUT_CONFIG_FILEโ the name of the CPack source configuration file ๐๏ธ. This is the CPack config that the CPack module generates for source installers, and it defaults toCPackSourceConfig.cmake.CPACK_SOURCE_IGNORE_FILESโ pattern of files in the source tree that won't be packaged when you build a source package ๐. It's a list of regular expression patterns (and they must be properly escaped, bestie, don't skip that part), e.g./CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*.
๐ฅ Variables for Advanced Use ๐ฅ
The following variables are for the advanced girlies using CPack:
CPACK_CMAKE_GENERATORโ what CMake generator should be used if the project is a CMake project ๐. Defaults to the value ofCMAKE_GENERATOR. Lowkey, very few users will ever want to change this setting.CPACK_INSTALL_CMAKE_PROJECTSโ a list of four values that specifies what project to install ๐ซถ. The four values are: Build directory, Project Name, Project Component, Directory. If you omit this, CPack will build an installer that installs literally everything.CPACK_SYSTEM_NAMEโ the system name โญ. It defaults to the value ofCMAKE_SYSTEM_NAME, except on Windows where it'll bewin32orwin64.CPACK_PACKAGE_VERSIONโ the package full version, used internally ๐. By default it's built fromCPACK_PACKAGE_VERSION_MAJOR,CPACK_PACKAGE_VERSION_MINOR, andCPACK_PACKAGE_VERSION_PATCH.CPACK_TOPLEVEL_TAGโ directory for the installed files ๐.CPACK_INSTALL_COMMANDSโ extra commands to install components ๐ซ. Heads up: the environment variableCMAKE_INSTALL_PREFIXis set to the temporary install directory during execution.CPACK_INSTALL_SCRIPTSโ Added in version 3.16. Extra CMake scripts executed by CPack during its local staging installation ๐ง. They run before installing the files to be packaged, and they are not called by a standalone install (e.g.make install). For every script, these variables will be set:CMAKE_CURRENT_SOURCE_DIR,CMAKE_CURRENT_BINARY_DIR, andCMAKE_INSTALL_PREFIX(which gets set to the staging install directory). The singular formCMAKE_INSTALL_SCRIPTis supported as an alternative variable for historical reasons, but its value is ignored ifCMAKE_INSTALL_SCRIPTSis set โ and a warning will be issued ๐ญ. See alsoCPACK_PRE_BUILD_SCRIPTSandCPACK_POST_BUILD_SCRIPTS, which you can use to specify scripts that get executed later in the packaging process.CPACK_PRE_BUILD_SCRIPTSโ Added in version 3.19. List of CMake scripts to execute after CPack has installed the files to be packaged into a staging directory and before producing the package(s) from those files ๐ธ. See alsoCPACK_INSTALL_SCRIPTSandCPACK_POST_BUILD_SCRIPTS.CPACK_POST_BUILD_SCRIPTSโ Added in version 3.19. List of CMake scripts to execute after CPack has produced the resultant packages and before copying them back to the build directory ๐. See alsoCPACK_INSTALL_SCRIPTS,CPACK_PRE_BUILD_SCRIPTS, andCPACK_PACKAGE_FILES.CPACK_PACKAGE_FILESโ Added in version 3.19. List of package files created in the staging directory, with each file given as a full absolute path ๐ฅ. CPack populates this variable right before invoking the post-build scripts listed inCPACK_POST_BUILD_SCRIPTS. It's the preferred way for the post-build scripts to know the set of package files to operate on. Projects should not try to set this variable themselves โ hands off, bestie ๐ซ.CPACK_INSTALLED_DIRECTORIESโ extra directories to install ๐.CPACK_PACKAGE_INSTALL_REGISTRY_KEYโ the registry key used when installing this project ๐๏ธ. This is only used by installers for Windows, and the default value is based on the installation directory.CPACK_CREATE_DESKTOP_LINKSโ list of desktop links to create ๐ฅ๏ธ. Each desktop link requires a corresponding start menu shortcut, as created byCPACK_PACKAGE_EXECUTABLES.CPACK_BINARY_<GENNAME>โ CPack generated options for binary generators ๐ . TheCPack.cmakemodule generates (whenCPACK_GENERATORis not set) a set of CMake options (see theoption()command) which you can then use to select the CPack generator(s) to use when building the package target, or when runningcpackwithout the-Goption.CPACK_READELF_EXECUTABLEโ Added in version 3.25. Specify thereadelfexecutable path used by CPack ๐. The default value gets taken from theCMAKE_READELFvariable if it's set, which may be populated by CMake when enabling languages. IfCMAKE_READELFisn't set, CPack will usefind_program()to figure out thereadelfpath when needed.CPACK_OBJCOPY_EXECUTABLEโ Added in version 3.25. Specify theobjcopyexecutable path used by CPack ๐ ๏ธ. The default value gets taken from theCMAKE_OBJCOPYvariable if it's set, which may be populated by CMake when enabling languages. IfCMAKE_OBJCOPYisn't set, CPack will usefind_program()to determine theobjcopypath when needed.CPACK_OBJDUMP_EXECUTABLEโ Added in version 3.25. Specify theobjdumpexecutable path used by CPack ๐. The default value gets taken from theCMAKE_OBJDUMPvariable, which may be populated by CMake when enabling languages. IfCMAKE_OBJDUMPisn't set, CPack will usefind_program()to determine theobjdumppath when needed.
๐งฉ CPackComponent ๐งฉ
This module provides commands to configure components for binary installers and source packages ๐.
Load this module in a CMake project with:
include(CPackComponent)
๐ Introduction ๐
This module is also automatically included by CPack โจ.
Certain binary installers (especially the graphical ones, you know the vibe) generated by CPack let users select individual application components to install ๐ซถ. This module lets developers configure the packaging of those components.
Contents is assigned to components by the COMPONENT argument of CMake's install() command ๐ธ. Components can be annotated with user-friendly names and descriptions, inter-component dependencies, etc., and grouped in various ways to customize the resulting installer, using the commands described below.
To specify different groupings for different CPack generators, use a CPACK_PROJECT_CONFIG_FILE ๐
.
๐ Variables ๐
The following variables influence the component-specific packaging:
CPACK_COMPONENTS_ALLโ the list of component to install ๐.
The default value of this variable is computed by CPack and contains all components defined by the project. The user may set it to only include the specified components.
Instead of specifying all the desired components, you can obtain a list of all defined components and then remove the unwanted ones from that list ๐ง. The get_cmake_property() command can be used to obtain the COMPONENTS property, then the list(REMOVE_ITEM) command can be used to remove the unwanted ones. For example, to use all defined components except foo and bar:
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "foo" "bar")
CPACK_<GENNAME>_COMPONENT_INSTALLโ enable/disable component install for CPack generator<GENNAME>๐ฅ.
Each CPack Generator (RPM, DEB, ARCHIVE, NSIS, DMG, etc...) has a legacy default behavior. e.g. RPM builds monolithic whereas NSIS builds component ๐. You can change the default behavior by setting this variable to 0/1 or OFF/ON.
CPACK_COMPONENTS_GROUPINGโ specify how components get grouped for multi-package component-aware CPack generators ๐.
Some generators like RPM or ARCHIVE (TGZ, ZIP, ...) may generate several package files when there are components, depending on the value of this variable:
ONE_PER_GROUP(default): create one package per component groupIGNORE: create one package per component (ignore the groups)ALL_COMPONENTS_IN_ONE: create a single package with all requested components
CPACK_COMPONENT_<compName>_DISPLAY_NAMEโ the name to be displayed for a component โญ.CPACK_COMPONENT_<compName>_DESCRIPTIONโ the description of a component ๐.CPACK_COMPONENT_<compName>_GROUPโ the group of a component ๐๏ธ.CPACK_COMPONENT_<compName>_DEPENDSโ the dependencies (list of components) on which this component depends ๐.CPACK_COMPONENT_<compName>_HIDDENโ true if this component is hidden from the user ๐.CPACK_COMPONENT_<compName>_REQUIREDโ true if this component is required ๐ฏ.CPACK_COMPONENT_<compName>_DISABLEDโ true if this component is not selected to be installed by default ๐ซ.
๐ ๏ธ Commands ๐ ๏ธ
โ Add component โ
cpack_add_component
Describe an installation component ๐.
cpack_add_component(compname
[DISPLAY_NAME name]
[DESCRIPTION description]
[HIDDEN | REQUIRED | DISABLED ]
[GROUP group]
[DEPENDS comp1 comp2 ... ]
[INSTALL_TYPES type1 type2 ... ]
[DOWNLOADED]
[ARCHIVE_FILE filename]
[PLIST filename])
compnameโ the name of an installation component, exactly as you defined it in theCOMPONENTargument of one or moreinstall()commands. With thecpack_add_componentcommand you get to set a name, a description, and other attributes of an installation component, and you can also assign a component to a component group. ๐DISPLAY_NAMEโ the displayed name of the component, used in graphical installers to display the component name. This value can be any string, no cap.DESCRIPTIONโ an extended description of the component, used in graphical installers to give the user additional information about the component. Descriptions can span multiple lines using\nas the line separator. Typically, these descriptions should be no more than a few lines long. Keep it cute and short bestie โจHIDDENโ says this component will be hidden in the graphical installer, so the user cannot directly change whether it is installed or not. ๐REQUIREDโ this component is required, and therefore will always be installed. It will be visible in the graphical installer, but it cannot be unselected. (Typically, required components are shown grayed out.)DISABLEDโ this component should be disabled (unselected) by default. The user is free to select this component for installation, unless it is alsoHIDDEN.DEPENDSโ lists the components on which this component depends. If this component is selected, then each of the components listed must also be selected. The dependency information is encoded within the installer itself, so that users cannot install inconsistent sets of components. fr fr it keeps everything consistent ๐ฅGROUPโ names the component group of which this component is a part. If not provided, the component will be a standalone component, not part of any component group. Component groups are described with thecpack_add_component_groupcommand, detailed below.INSTALL_TYPESโ lists the installation types of which this component is a part. When one of these installation types is selected, this component will automatically be selected. Installation types are described with thecpack_add_install_typecommand, detailed below.DOWNLOADEDโ this component should be downloaded on-the-fly by the installer, rather than packaged in with the installer itself. For more information, see thecpack_configure_downloadscommand.ARCHIVE_FILEโ provides a name for the archive file created by CPack to be used for downloaded components. If not supplied, CPack will create a file with some name based onCPACK_PACKAGE_FILE_NAMEand the name of the component. Seecpack_configure_downloadsfor more information.PLISTโ gives a filename that is passed topkgbuildwith the--component-plistargument when using theproductbuildgenerator.
๐งฉ Add component group ๐งฉ
cpack_add_component_group
Describes a group of related CPack installation components. It's giving organized queen energy ๐
cpack_add_component_group(groupname
[DISPLAY_NAME name]
[DESCRIPTION description]
[PARENT_GROUP parent]
[EXPANDED]
[BOLD_TITLE])
The cpack_add_component_group command describes a group of installation components, which will be placed together within the listing of options. Typically, component groups allow the user to select/deselect all of the components within a single group via a single group-level option. Use component groups to reduce the complexity of installers with many options. groupname is an arbitrary name used to identify the group in the GROUP argument of the cpack_add_component command, which is used to place a component in a group. The name of the group must not conflict with the name of any component.
DISPLAY_NAMEโ the displayed name of the component group, used in graphical installers to display the component group name. This value can be any string.DESCRIPTIONโ an extended description of the component group, used in graphical installers to give the user additional information about the components within that group. Descriptions can span multiple lines using\nas the line separator. Typically, these descriptions should be no more than a few lines long.PARENT_GROUPโ if supplied, names the parent group of this group. Parent groups are used to establish a hierarchy of groups, providing an arbitrary hierarchy of groups.EXPANDEDโ indicates that, by default, the group should show up as "expanded", so that the user immediately sees all of the components within the group. Otherwise, the group will initially show up as a single entry.BOLD_TITLEโ indicates that the group title should appear in bold, to call the user's attention to the group. Main character energy for real ๐
๐ Add installation type ๐
cpack_add_install_type
Add a new installation type containing a set of predefined component selections to the graphical installer.
cpack_add_install_type(typename
[DISPLAY_NAME name])
The cpack_add_install_type command identifies a set of preselected components that represents a common use case for an application. For example, a "Developer" install type might include an application along with its header and library files, while an "End user" install type might just include the application's executable. Each component identifies itself with one or more install types via the INSTALL_TYPES argument to cpack_add_component.
DISPLAY_NAMEโ the displayed name of the install type, which will typically show up in a drop-down box within a graphical installer. This value can be any string.
๐ฆ Configure downloads ๐ฆ
cpack_configure_downloads
Configure CPack to download selected components on-the-fly as part of the installation process. Obsessed with this one ngl ๐
cpack_configure_downloads(site
[UPLOAD_DIRECTORY dirname]
[ALL]
[ADD_REMOVE|NO_ADD_REMOVE])
The cpack_configure_downloads command configures installation-time downloads of selected components. For each downloadable component, CPack will create an archive containing the contents of that component, which should be uploaded to the given site. When the user selects that component for installation, the installer will download and extract the component in place. This feature is useful for creating small installers that only download the requested components, saving bandwidth. Additionally, the installers are small enough that they will be installed as part of the normal installation process, and the "Change" button in Windows Add/Remove Programs control panel will allow one to add or remove parts of the application after the original installation. On Windows, the downloaded-components functionality requires the ZipDLL plug-in for NSIS, available at:
http://nsis.sourceforge.net/ZipDLL_plug-in
On macOS, installers that download components on-the-fly can only be built and installed on system using macOS 10.5 or later.
The site argument is a URL where the archives for downloadable components will reside, e.g., https://cmake.org/files/v3.25/ All of the archives produced by CPack should be uploaded to that location.
UPLOAD_DIRECTORYโ the local directory where CPack will create the various archives for each of the components. The contents of this directory should be uploaded to a location accessible by the URL given in thesiteargument. If omitted, CPack will use the directoryCPackUploadsinside the CMake binary directory to store the generated archives.ALLโ indicates that all components be downloaded. Otherwise, only those components explicitly marked asDOWNLOADEDor that have a specifiedARCHIVE_FILEwill be downloaded. Additionally, theALLoption impliesADD_REMOVE(unlessNO_ADD_REMOVEis specified).ADD_REMOVEโ indicates that CPack should install a copy of the installer that can be called from Windows' Add/Remove Programs dialog (via the "Modify" button) to change the set of installed components.NO_ADD_REMOVEturns off this behavior. This option is ignored on Mac OS X.
๐ธ CPackIFW ๐ธ
Added in version 3.1.
This module looks for the location of the command-line utilities supplied with the Qt Installer Framework (https://doc.qt.io/qtinstallerframework/index.html) (QtIFW). Iconic behavior tbh ๐
Load this module in a CMake project with:
include(CPackIFW)
The module also defines several commands to control the behavior of the CPack IFW Generator.
โจ Commands โจ
The module defines the following commands:
cpack_ifw_configure_component
Sets the arguments specific to the CPack IFW generator. So specific, so slay ๐
cpack_ifw_configure_component(<compname> [COMMON] [ESSENTIAL] [VIRTUAL]
[FORCED_INSTALLATION] [REQUIRES_ADMIN_RIGHTS]
[NAME <name>]
[DISPLAY_NAME <display_name>] # Note: Internationalization supported
[DESCRIPTION <description>] # Note: Internationalization supported
[UPDATE_TEXT <update_text>]
[VERSION <version>]
[RELEASE_DATE <release_date>]
[SCRIPT <script>]
[PRIORITY|SORTING_PRIORITY <sorting_priority>] # Note: PRIORITY is deprecated
[DEPENDS|DEPENDENCIES <com_id> ...]
[AUTO_DEPEND_ON <comp_id> ...]
[LICENSES <display_name> <file_path> ...]
[DEFAULT <value>]
[USER_INTERFACES <file_path> <file_path> ...]
[TRANSLATIONS <file_path> <file_path> ...]
[REPLACES <comp_id> ...]
[CHECKABLE <value>])
This command should be called after the cpack_add_component() command. Order matters bestie โจ
COMMONโ if set, then the component will be packaged and installed as part of a group to which it belongs.ESSENTIALโ Added in version 3.6. If set, then the package manager stays disabled until that component is updated.VIRTUALโ Added in version 3.8. If set, then the component will be hidden from the installer. It is a equivalent of theHIDDENoption from thecpack_add_component()command.FORCED_INSTALLATIONโ Added in version 3.8.
if set, then the component must always be installed โ it's literally the equivalent of the REQUIRED option from the cpack_add_component() command. ๐
REQUIRES_ADMIN_RIGHTSโ Added in version 3.8. set this if the component needs to be installed with elevated permissions. admin energy only, bestie ๐NAMEโ used to create a domain-like identification for this component. by default it uses the origin component name ๐ท๏ธDISPLAY_NAMEโ Added in version 3.8. set it to rewrite the original name configured by thecpack_add_component()command.DESCRIPTIONโ Added in version 3.8. set it to rewrite the original description configured by thecpack_add_component()command.UPDATE_TEXTโ Added in version 3.8. gets added to the component description if this is an update to the component. โจVERSIONโ the version of the component. by default it usesCPACK_PACKAGE_VERSION.RELEASE_DATEโ Added in version 3.8. keep it empty and it auto-generates, iconic ๐SCRIPTโ a relative or absolute path to the operations script for this component.SORTING_PRIORITYโ Added in version 3.8. the priority of the component in the tree. ๐ณPRIORITYโ Deprecated since version 3.8: old name forSORTING_PRIORITY. it's giving legacy, use the new one ๐DEPENDS,DEPENDENCIESโ Added in version 3.8. list of dependency component or component group identifiers in QtIFW style.
Added in version 3.21. component or group names listed as dependencies may contain hyphens. this requires QtIFW 3.1 or later. ๐ซถ
AUTO_DEPEND_ONโ Added in version 3.8. list of identifiers of a component or component group, in QtIFW style, that this component has an automatic dependency on.LICENSESโ a pair of<display_name>and<file_path>of license text for this component. you can specify more then one license, no cap ๐DEFAULTโ Added in version 3.8. possible values are:TRUE,FALSE, andSCRIPT. set it toFALSEto disable the component in the installer, or toSCRIPTto have it resolved during runtime (don't forget to add the file of the script as a value of theSCRIPToption!). ๐USER_INTERFACESโ Added in version 3.7. a list of<file_path>('.ui'files) representing pages to load.TRANSLATIONSโ Added in version 3.8. a list of<file_path>('.qm'files) representing translations to load. ๐REPLACESโ Added in version 3.10. list of identifiers of component or component group to replace.CHECKABLEโ Added in version 3.10. possible values are:TRUE,FALSE. set it toFALSEif you want to hide the checkbox for an item. this is useful when only a few subcomponents should be selected instead of all. โ
cpack_ifw_configure_component_group ๐
sets the arguments specific to the CPack IFW generator. it's the group-level twin of the command above, periodt.
cpack_ifw_configure_component_group(<groupname> [VIRTUAL]
[FORCED_INSTALLATION] [REQUIRES_ADMIN_RIGHTS]
[NAME <name>]
[DISPLAY_NAME <display_name>] # Note: Internationalization supported
[DESCRIPTION <description>] # Note: Internationalization supported
[UPDATE_TEXT <update_text>]
[VERSION <version>]
[RELEASE_DATE <release_date>]
[SCRIPT <script>]
[PRIORITY|SORTING_PRIORITY <sorting_priority>] # Note: PRIORITY is deprecated
[DEPENDS|DEPENDENCIES <com_id> ...]
[AUTO_DEPEND_ON <comp_id> ...]
[LICENSES <display_name> <file_path> ...]
[DEFAULT <value>]
[USER_INTERFACES <file_path> <file_path> ...]
[TRANSLATIONS <file_path> <file_path> ...]
[REPLACES <comp_id> ...]
[CHECKABLE <value>])
this command should be called after the cpack_add_component_group() command. order matters, bestie, don't skip steps ๐ซก
VIRTUALโ Added in version 3.8. if set, then the group will be hidden from the installer. note that setting this on a root component does not work โ it's giving invisible but not that invisible ๐FORCED_INSTALLATIONโ Added in version 3.8. if set, then the group must always be installed. no takebacks โREQUIRES_ADMIN_RIGHTSโ Added in version 3.8. set it if the component group needs to be installed with elevated permissions. ๐NAMEโ used to create a domain-like identification for this component group. by default it uses the origin component group name.DISPLAY_NAMEโ Added in version 3.8. set it to rewrite the original name configured by thecpack_add_component_group()command.DESCRIPTIONโ Added in version 3.8. set it to rewrite the original description configured by thecpack_add_component_group()command.UPDATE_TEXTโ Added in version 3.8. gets added to the component group description if this is an update to the component group.VERSIONโ the version of the component group. by default it usesCPACK_PACKAGE_VERSION.RELEASE_DATEโ Added in version 3.8. keep it empty to auto generate ๐SCRIPTโ a relative or absolute path to the operations script for this component group.SORTING_PRIORITYโ the priority of the component group in the tree ๐ณPRIORITYโ Deprecated since version 3.8: old name forSORTING_PRIORITY. yeah it's the same deal as before, don't use it ๐DEPENDS,DEPENDENCIESโ Added in version 3.8. list of dependency component or component group identifiers in QtIFW style.
Added in version 3.21. component or group names listed as dependencies may contain hyphens. this requires QtIFW 3.1 or later. ๐ซถ
AUTO_DEPEND_ONโ Added in version 3.8. list of identifiers of a component or component group, in QtIFW style, that this component group has an automatic dependency on.LICENSESโ a pair of<display_name>and<file_path>of license text for this component group. you can specify more then one license ๐DEFAULTโ Added in version 3.8. possible values are:TRUE,FALSE, andSCRIPT. set it toTRUEto preselect the group in the installer (this takes effect only on groups that have no visible child components) or toSCRIPTto have it resolved during runtime (don't forget to add the file of the script as a value of theSCRIPToption!). note that this one isTRUE, notFALSElike the component version โ read carefully bestie ๐USER_INTERFACESโ Added in version 3.7. a list of<file_path>('.ui'files) representing pages to load.TRANSLATIONSโ Added in version 3.8. a list of<file_path>('.qm'files) representing translations to load ๐REPLACESโ Added in version 3.10. list of identifiers of component or component group to replace.CHECKABLEโ Added in version 3.10. possible values are:TRUE,FALSE. set it toFALSEif you want to hide the checkbox for an item. this is useful when only a few subcomponents should be selected instead of all. โ
cpack_ifw_add_repository ๐ฆ
adds a QtIFW-specific remote repository to the binary installer. remote girlies rise ๐ซถ
cpack_ifw_add_repository(<reponame> [DISABLED]
URL <url>
[USERNAME <username>]
[PASSWORD <password>]
[DISPLAY_NAME <display_name>])
this command will also add the <reponame> repository to a variable CPACK_IFW_REPOSITORIES_ALL. sneaky double duty, love that for us โจ
DISABLEDโ if set, then the repository will be disabled by default.URLโ points to a list of available components.USERNAMEโ used as the user on a protected repository. ๐PASSWORDโ the password to use on a protected repository.DISPLAY_NAMEโ a string to display instead of the URL. so much cuter than raw links ๐
cpack_ifw_update_repository โญ
Added in version 3.6. updates a QtIFW-specific repository from a remote repository.
cpack_ifw_update_repository(<reponame>
[[ADD|REMOVE] URL <url>]|
[REPLACE OLD_URL <old_url> NEW_URL <new_url>]]
[USERNAME <username>]
[PASSWORD <password>]
[DISPLAY_NAME <display_name>])
this command will also add the <reponame> repository to a variable CPACK_IFW_REPOSITORIES_ALL. yes, same flex as above ๐
URLโ points to a list of available components.OLD_URLโ points to a list that will be replaced.NEW_URLโ points to a list that will replace it.USERNAMEโ used as the user on a protected repository. ๐PASSWORDโ the password you use on a repository that's password-protected. ๐DISPLAY_NAMEโ the string that gets shown instead of the URL. so if the URL is giving ugly, this is the glow-up โจ
cpack_ifw_add_package_resourcesโ Added in version 3.8.</p>
bestie this one drops extra resources right into the installer binary ๐
cpack_ifw_add_package_resources(<file_path> <file_path> ...)
it also tosses the files you listed into a variable called CPACK_IFW_PACKAGE_RESOURCES. two birds, one slay. ๐ฆ
๐ CPackIFWConfigureFile ๐
Added in version 3.8.
okay so this module hands you a command that's basically configure_file()'s cooler cousin โ it's for configuring file templates that were prepped in QtIFW/SDK/Creator style. ๐ง
load it into your CMake project like this:
include(CPackIFWConfigureFile)
๐ Commands ๐
this module gives you exactly one command, and she's iconic:
cpack_ifw_configure_fileโ copies a file template over to the output file, and swaps out variable values that are referenced as%{VAR}or%VAR%from the input file template content:
cpack_ifw_configure_file(<input> <output>)
<input>โ the input file template. if you hand it a relative path, it's interpreted as relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR). ๐<output>โ the output file. if you hand it a relative path, it's interpreted as relative to the current binary directory (CMAKE_CURRENT_BINARY_DIR). ๐
so here's the lore: Qt Installer Framework (QtIFW) uses @ characters to embed predefined variables (TargetDir, StartMenuDir, etc.) inside Qt installer scripts, like this:
example.qs
component.addOperation(
"CreateShortcut",
"@TargetDir@/example.com.html",
"@StartMenuDir@/Example Web Site.lnk"
);
the whole reason this command exists is to preserve those QtIFW predefined variables that have the @ characters (@VAR@), and use % characters for the template placeholders instead (%VAR%, %{VAR}) in Qt/IFW/SDK/Creator templates. because the configure_file() command would otherwise go and replace every variable reference that contains @ characters ๐ญ which is NOT the vibe.
every variable reference gets replaced with the current value of that variable โ or, if the variable isn't defined, with an empty string. ๐ซถ
๐ธ Examples ๐ธ
in this example the module is used to create an IFW component script from a template file qt.tools.foo.qs.in, where the %FOO_DOC_DIR% variable reference gets replaced by the value of the FOO_DOC_DIR CMake variable. periodt.
CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(Foo)
# ...
include(CPackIFWConfigureFile)
set(FOO_DOC_DIR "doc/foo")
cpack_ifw_configure_file(qt.tools.foo.qs.in qt.tools.foo.qs)
qt.tools.foo.qs.in
function Component()
{
}
Component.prototype.createOperations = function()
{
if (installer.value("os") === "win") {
component.addOperation(
"CreateShortcut",
"@TargetDir@/%FOO_DOC_DIR%/example.com.html",
"@StartMenuDir@/Example Web Site.lnk"
);
}
component.createOperations();
}
// ...
๐ See Also ๐
- The CPack IFW Generator. ๐ฅ
- The
CPackIFWmodule.
๐ CSharpUtilities ๐
Added in version 3.8.
this utility module is literally here to make configuring CSharp/.NET targets easier โ it's a whole little collection of commands for managing CSharp targets with Visual Studio Generators, version 2010 and newer. ๐
load her up in a CMake project with:
include(CSharpUtilities)
โจ Commands โจ
this module provides the following commands:
Main Commands ๐
csharp_set_windows_forms_properties()csharp_set_designer_cs_properties()csharp_set_xaml_cs_properties()
Helper Commands ๐ ๏ธ
csharp_get_filename_keys()csharp_get_filename_key_base()csharp_get_dependentupon_name()
๐ Main Commands ๐
csharp_set_windows_forms_propertiesโ sets source file properties so you can use Windows Forms:
csharp_set_windows_forms_properties([<files>...])
<files>...โ a list of zero or more source files that matter for setting theVS_CSHARP_<tagname>source file properties. this typically includes files with.cs,.resx, and.Designer.csextensions.
use this one when a CSharp target in your project uses Windows Forms. ๐ช
it searches the list of files you gave it for pairs of related files ending in .Designer.cs (designer files) or .resx (resource files). for each of those, it looks for a corresponding base .cs file (same base name). when it finds one, the VS_CSHARP_<tagname> source file properties get set like this:
- For the
.csfile:VS_CSHARP_SubType "Form"
- For the
.Designer.csfile (if it exists):VS_CSHARP_DependentUpon <cs-filename>VS_CSHARP_DesignTime ""(the tag gets removed if it was previously defined)VS_CSHARP_AutoGen ""(the tag gets removed if it was previously defined)
- For the
.resxfile (if it exists):VS_RESOURCE_GENERATOR ""(the tag gets removed if it was previously defined)VS_CSHARP_DependentUpon <cs-filename>VS_CSHARP_SubType "Designer"
csharp_set_designer_cs_propertiesโ sets source file properties for.Designer.csfiles, based on their sibling filenames:
csharp_set_designer_cs_properties([<files>...])
<files>...โ a list of zero or more source files that matter for setting theVS_CSHARP_<tagname>source file properties. this typically includes files with.resx,.settings, and.Designer.csextensions.
use this command if the CSharp target does not use Windows Forms (for Windows Forms, use csharp_set_windows_forms_properties() instead, bestie, don't mix them up ๐).
it searches the list you provided for files ending in .Designer.cs (designer files). for each one, it hunts for sibling files with the same base name but different extensions. if it finds a matching file, the right source file properties get set on the corresponding .Designer.cs file, based on which extension matched:
- If the match is a
.resxfile:VS_CSHARP_AutoGen "True"VS_CSHARP_DesignTime "True"VS_CSHARP_DependentUpon <resx-filename>
- If the match is a
.csfile:VS_CSHARP_DependentUpon <cs-filename>
- If the match is a
.settingsfile:VS_CSHARP_AutoGen "True"VS_CSHARP_DesignTimeSharedInput "True"VS_CSHARP_DependentUpon <settings-filename>
Note: because the source file properties of the.Designer.csfile get set according to whatever matches were found โ and every single match sets theVS_CSHARP_DependentUponsource file property โ there should only be one match for eachDesigner.csfile. one. not two. not three. one. ๐
csharp_set_xaml_cs_propertiesโ sets source file properties so you can use Windows Presentation Foundation (WPF) and XAML:
csharp_set_xaml_cs_properties([<files>...])
use this command if the CSharp target uses WPF/XAML. ๐ฆ
<files>...โ a list of zero or more source files that matter for setting theVS_CSHARP_<tagname>source file properties. this typically includes files with.cs,.xaml, and.xaml.csextensions.
it searches the file list you gave it for files ending in .xaml.cs. for each of those XAML code-behind files, it looks for a corresponding .xaml file with the same base name. if it finds one, the following source file property gets set on the .xaml.cs file:
VS_CSHARP_DependentUpon <xaml-filename>
๐ ๏ธ Helper Commands ๐ ๏ธ
these commands get used by the main commands above, so you typically won't reach for them directly โ they're the backstage crew, not the main character ๐
csharp_get_filename_keysโ computes a normalized list of key values so you can identify source files independently of whether CMake was given relative or absolute paths, and so it stops caring about case sensitivity:
csharp_get_filename_keys(<variable> [<files>...])
<variable>โ the name of the variable where the list of computed keys gets stored.<files>...โ zero or more source file paths, exactly as given to a CSharp target using commands likeadd_library()oradd_executable().
this command canonicalizes file paths so source files get identified consistently. super useful when source files are added to a target using different path forms. because without normalization, CMake may treat paths like myfile.Designer.cs and ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs as two different files ๐ญ which then causes chaos when you're setting source file properties.
for example, the following code will fail to set properties, because the file paths don't match exactly:
add_library(lib myfile.cs ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs)
set_source_files_properties(
myfile.Designer.cs
PROPERTIES VS_CSHARP_DependentUpon myfile.cs
)
csharp_get_filename_key_baseโ returns the full filepath and name without the extension, for a given key:
csharp_get_filename_key_base(<base> <key>)
<base>โ the name of the variable holding the computed base value of the<key>, without the file extension.<key>โ the key whose base will be computed. it's expected to be an uppercase full filename coming out ofcsharp_get_filename_keys().
csharp_get_dependentupon_nameโ computes a string that can be used as the value for the source file propertyVS_CSHARP_<tagname>, where<tagname>isDependentUpon:<variable>โ the name of the variable that'll hold the result ๐. Its value is the name of<file>with the directory part yeeted out.<file>โ the filename you're converting so it can be used as the value of theVS_CSHARP_DependentUponsource file property.
๐งช CTest
Configure a whole project for testing with CTest/CDash โ the classic glow-up for your build ๐
Drop this module into the top CMakeLists.txt file of a project to enable testing with CTest and dashboard submissions to CDash:
project(MyProject)
...
include(CTest)
The module automatically creates this variable:
BUILD_TESTING โ an option that selects whether include(CTest) calls enable_testing(). It's ON by default when created by the module. โจ
After including the module, use code like this:
if(BUILD_TESTING)
# ... CMake code to create tests ...
endif()
โฆto actually make tests when testing is enabled, bestie. Then to enable submissions to a CDash server, create a CTestConfig.cmake file at the top of the project with content such as:
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject")
The CDash server can hand that file to a project administrator who configures MyProject. Settings in the config file are shared by both this CTest module and the ctest(1) command-line Dashboard Client mode (ctest -S). Sharing is caring, fr fr ๐
While building a project for submission to CDash, CTest scans the build output for errors and warnings and reports them with surrounding context from the build log. This generic approach works for all build tools, but lowkey it does not give details about the command invocation that produced a given problem. You can get more detailed reports by setting the CTEST_USE_LAUNCHERS variable:
set(CTEST_USE_LAUNCHERS 1)
โฆin the CTestConfig.cmake file. Iconic behaviour honestly.
๐ CTestCoverageCollectGCOV
Added in version 3.2. ๐ฆ
This module is intended for use in CTest dashboard scripts and provides a command to generate a tarball containing code coverage reports.
Load this module in a CTest script with:
include(CTestCoverageCollectGCOV)
Commands
This module provides the following command:
ctest_coverage_collect_gcov โ runs gcov and packages a tar file for CDash:
ctest_coverage_collect_gcov(
TARBALL <tar-file>
[TARBALL_COMPRESSION <compression>]
[SOURCE <source-dir>]
[BUILD <build-dir>]
[GCOV_COMMAND <gcov-command>]
[GCOV_OPTIONS <options>...]
[GLOB]
[DELETE]
[QUIET]
)
This command runs gcov on all .gcda files found in the binary tree and packages the resulting .gcov files into a tar file, along with the following โจ:
data.jsonfile that defines the source and build directories for use by CDash.Labels.jsonfiles that indicate anyLABELSthat have been set on the source files.- The
uncovereddirectory containing any uncovered files found byCTEST_EXTRA_COVERAGE_GLOB.
The resulting tar file can be submitted to CDash for display using the ctest_submit(CDASH_UPLOAD) command. ๐ซถ
The arguments are:
TARBALL <tar-file>โ specify the location of the.tarfile to be created for later upload to CDash. Relative paths will be interpreted with respect to the top-level build directory.TARBALL_COMPRESSION <compression>โ Added in version 3.18. Specify a compression algorithm for theTARBALLdata file. Using this option reduces the size of the data file before it is submitted to CDash.<compression>should be one of the following:GZIPBZIP2LZMAโ Added in version 4.3.LZMA2โ Added in version 4.3. This is an alias forXZ.XZZSTDFROM_EXT- An expression that CMake evaluates as
FALSE
The default value is BZIP2.
If FROM_EXT is specified, the resulting file will be compressed based on the file extension of the <tar-file> (i.e. .tar.gz will use GZIP compression). File extensions that will produce compressed output include:
.tar.gz.tgz.tar.bzip2.tbz.tar.xz.txz.tar.lzmaโ Added in version 4.3..tlzmaโ Added in version 4.3..tar.zstโ Added in version 4.3..tzstโ Added in version 4.3.
SOURCE <source-dir>โ specify the top-level source directory for the build. Default is the value ofCTEST_SOURCE_DIRECTORY.BUILD <build-dir>โ specify the top-level build directory for the build. Default is the value ofCTEST_BINARY_DIRECTORY.GCOV_COMMAND <gcov-command>โ specify the full path to thegcovcommand on the machine. Default is the value ofCTEST_COVERAGE_COMMAND.GCOV_OPTIONS <options>...โ specify options to be passed togcov. Thegcovcommand is run asgcov <options>... -o <gcov-dir> <file>.gcda. If not specified, the default option is just-b -x.GLOBโ Added in version 3.6. Recursively search for.gcdafiles in<build-dir>rather than determining search locations by readingCMakeFiles/TargetDirectories.txt(file generated by CMake at the generation phase).DELETEโ Added in version 3.6. Delete coverage files after they've been packaged into the.tar.QUIETโ suppress non-error messages that otherwise would have been printed out by this command. ๐คซ
Added in version 3.3: added support for the CTEST_CUSTOM_COVERAGE_EXCLUDE variable.
Examples
Generating code coverage data packaged as a .tar.gz file in a ctest -S script:
script.cmake
include(CTestCoverageCollectGCOV)
ctest_coverage_collect_gcov(
TARBALL "${CTEST_BINARY_DIRECTORY}/gcov.tar.gz"
TARBALL_COMPRESSION "GZIP"
)
๐ CTestUseLaunchers
This module sets the RULE_LAUNCH_* global properties when the CTEST_USE_LAUNCHERS variable is set to a true-like value (e.g., ON):
RULE_LAUNCH_COMPILERULE_LAUNCH_CUSTOMRULE_LAUNCH_LINK
Load this module in a CMake project with:
include(CTestUseLaunchers)
The CTestUseLaunchers module is automatically included by the CTest module when include(CTest) is called. However, it's provided as a separate module so that projects can use the CTEST_USE_LAUNCHERS functionality independently. Independence queen ๐
To use launchers, set the CTEST_USE_LAUNCHERS variable to a true-like value in a ctest -S dashboard script, and then also set the CTEST_USE_LAUNCHERS cache variable in the configured project. Both cmake and ctest must be aware of its value for the launchers to function correctly:
cmakeneeds it to generate the appropriate build rulesctestrequires it for accurate error and warning analysis
For convenience, the environment variable CTEST_USE_LAUNCHERS_DEFAULT may be set in the ctest -S script. Then, as long as the CMakeLists.txt includes the CTest or CTestUseLaunchers module, it will use the value of the environment variable to initialize a CTEST_USE_LAUNCHERS cache variable. This cache variable initialization only occurs if CTEST_USE_LAUNCHERS is not already defined. ๐ธ
Added in version 3.8: ifCTEST_USE_LAUNCHERSis set to a true-like value in actest -Sscript, thectest_configure()command will add-DCTEST_USE_LAUNCHERS:BOOL=TRUEto thecmakecommand when configuring the project.
Examples
set(CTEST_USE_LAUNCHERS ON)
include(CTestUseLaunchers)
๐ง DeployQt4
Note: this module is for Qt version 4. New code should follow the cmake-qt(7) instead of using this module. It's giving legacy, bestie โ retire it gracefully ๐
This module provides a collection of CMake utility commands useful for assembling and deploying standalone Qt4 executables.
Load this module in a CMake project with:
include(DeployQt4)
Commands
This module provides the following commands:
write_qt4_conf()resolve_qt4_paths()fixup_qt4_executable()install_qt4_plugin_path()install_qt4_plugin()install_qt4_executable()
write_qt4_conf โ creates a Qt configuration file:
write_qt4_conf(<qt-conf-dir> <qt-conf-contents>)
This command writes a qt.conf file with the <qt-conf-contents> into the <qt-conf-dir> directory. โจ
resolve_qt4_paths โ resolves relative paths to absolute:
resolve_qt4_paths(<paths-var> [<executable-path>])
This command loops through the <paths-var> list and if any path doesn't exist, it resolves them relative to the <executable-path> (if supplied) or the CMAKE_INSTALL_PREFIX. ๐
fixup_qt4_executable โ fixes up a Qt4 executable:
fixup_qt4_executable(
<executable>
[<qtplugins> <libs> <dirs> <plugins-dir> <request-qt-conf>]
)
This command is basically the full glow-up routine for a Qt4 executable: it copies your Qt plugins, writes a Qt configuration file (but only if it's actually needed, ngl) and fixes up a Qt4 executable using the BundleUtilities module so it comes out fully standalone โ like, drag-and-drop-it-onto-another-machine standalone, as long as all of the system libraries are compatible. โจ
<executable>โ point this at the executable getting the fix-up treatment. That's the main character here.<qtplugins>โ a list of the names or paths of any Qt plugins you want installed.<libs>โ gets passed straight through to theBundleUtilitiesmodule, and should be a list of any already-installed plugins, libraries or executables that also need fixing up.<dirs>โ also passed to theBundleUtilitiesmodule; these are the directories it searches to find library dependencies.<plugins-dir>โ lets you use a custom plugins directory if the default one isn't the vibe.<request-qt-conf>โ forces aqt.conffile to be written even when it isn't needed.
install_qt4_plugin_path
Installs a resolved Qt4 plugin ๐
install_qt4_plugin_path(
<plugin>
<executable>
<copy>
<installed-plugin-path-var>
[<plugins-dir> <component> <configurations>]
)
So what it does: it installs (or copies, depends) a resolved <plugin> into the default plugins directory โ or into <plugins-dir> if you passed one โ relative to <executable>, and it stashes the result in the variable named by <installed-plugin-path-var>. ๐ซถ
- If
<copy>is set toTRUE, the plugins get copied instead of installed. That's the whole point โ it lets you use this module at CMake time instead of waiting for install time. - If
<component>is set, anything installed uses thatCOMPONENT.
install_qt4_plugin
Installs an unresolved Qt4 plugin ๐
install_qt4_plugin(
<plugin>
<executable>
<copy>
<installed-plugin-path-var>
[<plugins-dir> <component>]
)
Same energy as above but for an unresolved <plugin>: it installs (or copies) it to the default plugins directory (or <plugins-dir>) relative to <executable> and stores the result in <installed-plugin-path-var>. For the other arguments, literally just go read install_qt4_plugin_path() โ they're the same deal.
install_qt4_executable
Installs Qt plugins, writes a Qt configuration file (if needed) and fixes up a Qt4 executable โ the full combo meal ๐ฅ
install_qt4_executable(
<executable>
[<qtplugins> <libs> <dirs> <plugins-dir> <request-qt-conf> <component>]
)
This one leans on the BundleUtilities module so the executable ends up standalone and can be drag-and-drop copied to another machine as long as all of the system libraries are compatible. The fix-up happens at install time. The <component> is the COMPONENT used for bundle fixup and plugin installation. For the rest of the arguments, see fixup_qt4_executable() โ same cast of characters, no cap.
ExternalData
This module hands you commands to manage data files that live outside the source tree. ๐ฆ
Load it into a CMake project like this:
include(ExternalData)
Introduction
Use this module when you want to unambiguously reference data files stored outside the source tree, and then fetch them at build time from arbitrary local and remote content-addressed locations. The functions it gives you recognize arguments written as DATA{<name>}, treat them as references to external data, swap them out for full paths to local copies of that data, and set up build rules to fetch and update those local copies. Iconic behaviour, honestly. โจ
For example:
include(ExternalData)
set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)"
"file:////host/share/%(algo)/%(hash)"
"http://data.org/%(algo)/%(hash)")
ExternalData_Add_Test(MyData
NAME MyTest
COMMAND MyExe DATA{MyInput.png}
)
ExternalData_Add_Target(MyData)
When the test MyTest runs, that DATA{MyInput.png} argument gets replaced by the full path to a real instance of the data file MyInput.png sitting on disk. And if your source tree contains a content link like MyInput.png.md5, then the MyData target creates a real MyInput.png in the build tree. Slay. ๐
Module Functions
ExternalData_Expand_Arguments
The ExternalData_Expand_Arguments function evaluates DATA{} references inside its arguments and builds you a brand-new list of arguments:
ExternalData_Expand_Arguments(
<target> # Name of data management target
<outVar> # Output variable
[args...] # Input arguments, DATA{} allowed
)
It replaces every DATA{} reference in an argument with the full path of a real data file on disk โ one that will exist after <target> builds. ๐
ExternalData_Add_Test
The ExternalData_Add_Test function wraps around the CMake add_test() command, except it actually supports DATA{} references in its arguments:
ExternalData_Add_Test(
<target> # Name of data management target
... # Arguments of add_test(), DATA{} allowed
)
It pushes its arguments through ExternalData_Expand_Arguments and then calls add_test() with the results.
Changed in version 3.31: if the arguments after<target>define a test whose executable is a CMake target, then empty values in that target'sTEST_LAUNCHERandCROSSCOMPILING_EMULATORproperties are preserved. See policyCMP0178. ๐
ExternalData_Add_Target
The ExternalData_Add_Target function creates a custom target that manages the local instances of your externally stored data files:
ExternalData_Add_Target(
<target> # Name of data management target
[SHOW_PROGRESS <ON|OFF>] # Show progress during the download
)
It creates custom commands inside the target as needed to make data files available for each DATA{} reference that other functions from this module already evaluated. Data files can be fetched from one of the URL templates listed in the ExternalData_URL_TEMPLATES variable, or they can be found locally in one of the paths listed in the ExternalData_OBJECT_STORES variable. ๐
Added in version 3.20: you can pass theSHOW_PROGRESSargument to suppress progress info while objects download. If you don't pass it, it defaults toOFFfor theNinjaandNinja Multi-Configgenerators, andONfor everything else.
Typically you only need one target to manage all the external data in a project โ call this function once, at the end of configuration, after all the data references have been processed. Periodt.
Module Variables
The following variables configure how this thing behaves. Set them before you call any of the functions this module provides. ๐ซถ
ExternalData_BINARY_ROOT
You can set ExternalData_BINARY_ROOT to the directory that holds the real data files named by expanded DATA{} references. Default is CMAKE_BINARY_DIR. The directory layout mirrors the layout of content links under ExternalData_SOURCE_ROOT.
ExternalData_CUSTOM_SCRIPT_<key>
Added in version 3.2.
Give this a full path to a .cmake custom fetch script, identified by <key> in entries of the ExternalData_URL_TEMPLATES list. See Custom Fetch Scripts.
ExternalData_HTTPHEADERS
Added in version 4.0.
Use ExternalData_HTTPHEADERS to supply a list of headers, where each element contains one header in the form Key: Value. See the HTTPHEADER option of the file(DOWNLOAD) command. ๐ธ
ExternalData_LINK_CONTENT
Set ExternalData_LINK_CONTENT to the name of a supported hash algorithm to turn on automatic conversion of real data files referenced by the DATA{} syntax into content links. For each such <file>, a content link named <file><ext> gets created. The original file is renamed to the form .ExternalData_<algo>_<hash> so it's staged for future transmission to one of the locations in the list of URL templates (by means outside the scope of this module, iykyk). The data fetch rule created for the content link will use that staged object if the file can't be found using any URL template.
ExternalData_NO_SYMLINKS
Added in version 3.3.
On some platforms, the real data files named by expanded DATA{} references may be made available under ExternalData_BINARY_ROOT using symbolic links. Set ExternalData_NO_SYMLINKS to disable symbolic links and use copies instead. ๐ฆ
ExternalData_STATE_ROOT
Added in version 4.4.
Set ExternalData_STATE_ROOT to place module-managed metadata outside ExternalData_BINARY_ROOT. When it's set, ExternalData stores its hash records under this directory while still materializing the real data files under ExternalData_BINARY_ROOT. By default, hash records keep being placed right next to the materialized data, just like before.
ExternalData_LINK_MODE
Added in version 4.4.
ExternalData_LINK_MODE picks how real data files are exposed under ExternalData_BINARY_ROOT. ๐ซ
The value can be one of:
autoโ try each of the supported modes until one succeeds. The default order ishardlink->symlink->copyon Windows, andsymlink->hardlink->copyon other platforms.hardlinkโ materialize paths as hard links to the real files.symlinkโ materialize paths as symbolic links to the real files.copyโ materialize paths as copies of the real files.
Or the value can be a semicolon-separated list of hardlink, symlink, and copy โ then it tries those modes in the order you specified until one succeeds. โญ
When ExternalData_NO_SYMLINKS is set, the symlink mode gets dropped from automatic selection and you cannot request it explicitly. Not even a little. ๐
ExternalData_OBJECT_STORESโ set this to a list of local directories that stash objects using the layout<dir>/%(algo)/%(hash). These get searched first whenever an object is needed. If none of your stores have it, the thing gets fetched remotely through the URL templates and then dropped into the first local store you listed. No stores at all? Then the default is a location inside the build tree. โจExternalData_SERIES_PARSE,ExternalData_SERIES_PARSE_PREFIX,ExternalData_SERIES_PARSE_NUMBER,ExternalData_SERIES_PARSE_SUFFIX,ExternalData_SERIES_MATCHโ all five of these legends are explained over in Referencing File Series. Go look ๐ExternalData_SOURCE_ROOTโ this one you set to the highest source directory that contains any path named by aDATA{}reference. Default isCMAKE_SOURCE_DIR. Heads up though:ExternalData_SOURCE_ROOTandCMAKE_SOURCE_DIRhave to refer to directories inside a single source distribution (like, they come together in one tarball) ๐ซถExternalData_TIMEOUT_ABSOLUTEโ sets the download absolute timeout, in seconds, defaulting to300seconds. Set it to0to disable enforcement entirely.ExternalData_TIMEOUT_INACTIVITYโ sets the download inactivity timeout, in seconds, defaulting to60seconds. Set it to0to disable enforcement entirely.ExternalData_URL_ALGO_<algo>_<key>โ Added in version 3.3.
Use this to specify a custom URL component that gets substituted for URL template placeholders of the form %(algo:<key>), where <key> is a valid C identifier, when you're fetching an object referenced via hash algorithm <algo>. If you don't define it, the default URL component is just <algo> for any <key>. Slay, defaults ๐
ExternalData_URL_TEMPLATESโ set this to a list of URL templates, each one using the placeholders%(algo)and%(hash). The data fetch rules try each URL template in order, substituting the hash algorithm name in for%(algo)and the hash value in for%(hash). Alternatively you can use%(algo:<key>)together with theExternalData_URL_ALGO_<algo>_<key>variables for extra flexibility in your remote URLs. Big brain move ๐ฅ
โจ Referencing Files
๐ธ Referencing Single Files
The DATA{} syntax is literal, and the <name> is a full or relative path inside the source tree. That source tree has to contain either a real data file at <name> or a "content link" at <name><ext> holding a hash of the real file, using a hash algorithm that corresponds to <ext>. So like, the argument DATA{img.png} can be satisfied by a real img.png file sitting in the current source directory, or by an img.png.md5 file containing its MD5 sum. Either way she's covered ๐
Added in version 3.8: multiple content links of the same name with different hash algorithms are supported (think img.png.sha256 and img.png.sha1) as long as they all correspond to the same real file. This is what lets objects be fetched from sources indexed by different hash algorithms. Iconic.
๐ฆ Referencing File Series
You can tell the DATA{} syntax to fetch a whole file series with the form DATA{<name>,:}, where that : is literal. If the source tree has a group of files or content links named like a series, then referencing one member adds rules to fetch all of them. And yes โ even though every member of the series gets fetched, only the file originally named by the DATA{} argument is substituted in for it. Ngl that's kind of the whole point ๐
The default config recognizes file series names ending with #.ext, _#.ext, .#.ext, or -#.ext, where # is a sequence of decimal digits and .ext is any single extension. Configure it with a regex that parses the <number> and <suffix> parts off the end of <name>:
ExternalData_SERIES_PARSE - regex of the form (<number>)(<suffix>)$.
For the more complicated cases, set these:
ExternalData_SERIES_PARSEโ regex with at least two()groups.ExternalData_SERIES_PARSE_PREFIXโ regex group number of the<prefix>, if any.ExternalData_SERIES_PARSE_NUMBERโ regex group number of the<number>.ExternalData_SERIES_PARSE_SUFFIXโ regex group number of the<suffix>.
Then configure series number matching with a regex that matches the <number> part of series members named <prefix><number><suffix>:
ExternalData_SERIES_MATCH - regex matching <number> in all series members
Quick note bestie: the <suffix> of a series does not include a hash-algorithm extension. Don't get it twisted ๐
๐ Referencing Associated Files
The DATA{} syntax can also match files associated with the named file, living in that same directory. Associated files get specified by options using the syntax DATA{<name>,<opt1>,<opt2>,...}. Each option can specify one file by name, or specify a regular expression to match file names using the syntax REGEX:<regex>. For example, these arguments:
DATA{MyData/MyInput.mhd,MyInput.img} # File pair
DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series
will pass MyInput.mha and MyFrames00.png on the command line, but also make sure the associated files are present right next to them. Best of both worlds, fr fr ๐ซถ
๐ Referencing Directories
DATA{} can reference a directory too, using a trailing slash plus a list of associated files. The form DATA{<name>/,<opt1>,<opt2>,...} adds rules to fetch any files in the directory that match one of the associated file options. So for example, the argument DATA{MyDataDir/,REGEX:.*} passes the full path to a MyDataDir directory on the command line and ensures that directory contains files corresponding to every file or content link in the MyDataDir source directory. Obsessed with the efficiency ๐
Added in version 3.3: to match associated files in subdirectories, specify a RECURSE: option, e.g. DATA{MyDataDir/,RECURSE:,REGEX:.*}. It goes deeper. It always goes deeper ๐ง
๐ Hash Algorithms
These are the hash algorithms that are supported:
%(algo)=MD5,<ext>=.md5โ Message-Digest Algorithm 5, RFC 1321%(algo)=SHA1,<ext>=.sha1โ US Secure Hash Algorithm 1, RFC 3174%(algo)=SHA224,<ext>=.sha224โ US Secure Hash Algorithms, RFC 4634%(algo)=SHA256,<ext>=.sha256โ US Secure Hash Algorithms, RFC 4634%(algo)=SHA384,<ext>=.sha384โ US Secure Hash Algorithms, RFC 4634%(algo)=SHA512,<ext>=.sha512โ US Secure Hash Algorithms, RFC 4634%(algo)=SHA3_224,<ext>=.sha3-224โ Keccak SHA-3%(algo)=SHA3_256,<ext>=.sha3-256โ Keccak SHA-3%(algo)=SHA3_384,<ext>=.sha3-384โ Keccak SHA-3%(algo)=SHA3_512,<ext>=.sha3-512โ Keccak SHA-3
Added in version 3.8: the SHA3_* hash algorithms were added โจ
Keep in mind the hashes are used only for unique data identification and download verification. That's it. They're not doing anything else for you, bestie ๐
โญ Custom Fetch Scripts
Added in version 3.2.
When a data file has to be fetched from one of the URL templates you listed in ExternalData_URL_TEMPLATES, it normally gets downloaded using the file(DOWNLOAD) command. But you can specify a custom fetch script instead, using a URL template of the form ExternalDataCustomScript://<key>/<loc>. The <key> has to be a C identifier, and the <loc> has to contain the %(algo) and %(hash) placeholders. A variable matching that key, ExternalData_CUSTOM_SCRIPT_<key>, must be set to the full path of a .cmake script file. That script gets included to do the actual fetching, and it's handed the following variables:
ExternalData_CUSTOM_LOCATIONโ when a custom fetch script is loaded, this variable is set to the location part of the URL, which contains the substituted hash algorithm name and content hash value.ExternalData_CUSTOM_FILEโ when a custom fetch script is loaded, this variable is set to the full path of a file where the script must store the fetched content. The name of that file is unspecified, so don't you dare interpret it in any way ๐
The custom fetch script is expected to store the fetched content in that file, or set a variable:
ExternalData_CUSTOM_ERRORโ when a custom fetch script fails to fetch the requested content, it must set this variable to a short one-line message describing why it failed. Keep it cute, keep it one line.
๐ ExternalProject
This module gives you commands to download and build external projects as part of the CMake build phase. Real main character energy for your dependencies ๐ฅ
Load this module in a CMake project with:
include(ExternalProject)
๐ External Project Definition ๐
โจ ExternalProject_Add โจ
Okay bestie, so ExternalProject_Add() is literally the main character here โ it creates a custom target that drives the whole life of an external project: download, update/patch, configure, build, install, and test. Every step. The whole glow-up.
ExternalProject_Add(<name> [<option>...])
And the vibe? If you need to, the individual steps within the process can be driven independently (like for CDash submission, iykyk), plus you can define extra custom steps and control the step dependencies. The directory structure used for managing the external project is customizable too. This function supports a huge number of options so you can tailor the external project behavior however you want. Obsessed.
๐ Directory Options ๐
Most of the time the default directory layout is perfectly fine and you don't need to touch it โ it's largely an implementation detail that the main project usually doesn't need to change. But in some circumstances, control over the directory layout is useful or even necessary. And honestly these options are potentially more useful from the angle that the main build can use ExternalProject_Get_Property() to grab their values โ which lets the main project refer to build artifacts of the external project. Slay.
PREFIX <dir>โ root directory for the external project. Unless noted otherwise below, all the other directories associated with the external project get created under here.TMP_DIR <dir>โ directory where temporary files live.STAMP_DIR <dir>โ directory where the timestamps of each step are stored. Log files from individual steps also get created in here unless overridden byLOG_DIR(see Logging Options below).LOG_DIR <dir>โ Added in version 3.14. Directory where the logs of each step are stored.DOWNLOAD_DIR <dir>โ directory where downloaded files go before they're unpacked. This directory is only used by the URL download method; all other download methods useSOURCE_DIRdirectly instead.SOURCE_DIR <dir>โ source directory into which downloaded contents get unpacked, or, for non-URL download methods, the directory where the repository should be checked out, cloned, etc. If no download method is specified, this has to point to an existing directory where the external project has already been unpacked or cloned/checked out.
Note: if a download method is specified, any existing contents of the source directory may be deleted ๐. Only the URL download method checks whether this directory is either missing or empty before initiating the download, and it stops with an error if it's not empty. All the other download methods silently discard any previous contents of the source directory. No cap.
BINARY_DIR <dir>โ specifies the build directory location. This option is ignored ifBUILD_IN_SOURCEis enabled.INSTALL_DIR <dir>โ installation prefix to be placed in the<INSTALL_DIR>placeholder. This does not actually configure the external project to install to the given prefix โ you have to do that by passing appropriate arguments to the external project configuration step, e.g. using<INSTALL_DIR>.
If any of the above ..._DIR options aren't specified, their defaults get computed like this. If the PREFIX option is given or the EP_PREFIX directory property is set, then an external project is built and installed under the specified prefix:
TMP_DIR = <prefix>/tmp
STAMP_DIR = <prefix>/src/<name>-stamp
DOWNLOAD_DIR = <prefix>/src
SOURCE_DIR = <prefix>/src/<name>
BINARY_DIR = <prefix>/src/<name>-build
INSTALL_DIR = <prefix>
LOG_DIR = <STAMP_DIR>
Otherwise, if the EP_BASE directory property is set, then components of an external project are stored under the specified base:
TMP_DIR = <base>/tmp/<name>
STAMP_DIR = <base>/Stamp/<name>
DOWNLOAD_DIR = <base>/Download/<name>
SOURCE_DIR = <base>/Source/<name>
BINARY_DIR = <base>/Build/<name>
INSTALL_DIR = <base>/Install/<name>
LOG_DIR = <STAMP_DIR>
If no PREFIX, EP_PREFIX, or EP_BASE is specified, then the default is to set PREFIX to <name>-prefix. Relative paths are interpreted with respect to CMAKE_CURRENT_BINARY_DIR at the point where ExternalProject_Add() is called. Iconic.
๐ฅ Download Step Options ๐ฅ
A download method can be omitted if the SOURCE_DIR option is used to point to an existing non-empty directory. Otherwise, one of the download methods below must be specified (multiple download methods should not be given) or a custom DOWNLOAD_COMMAND provided.
DOWNLOAD_COMMAND <cmd>...โ overrides the command used for the download step (generator expressions are supported โจ). If this option is specified, all other download options will be ignored. Providing an empty string for<cmd>effectively disables the download step.
๐ฆ URL ๐ฆ
URL <url1> [<url2>...]โ list of paths and/or URL(s) of the external project's source. When more than one URL is given, they're tried in turn until one succeeds. A URL may be an ordinary path in the local file system (in which case it must be the only URL provided) or any downloadable URL supported by thefile(DOWNLOAD)command. A local filesystem path may refer to either an existing directory or to an archive file, whereas a URL is expected to point to a file which can be treated as an archive. When an archive is used, it will be unpacked automatically unless theDOWNLOAD_NO_EXTRACToption is set to prevent it. The archive type is determined by inspecting the actual content rather than using logic based on the file extension. Changed in version 3.7: multiple URLs are allowed.URL_HASH <algo>=<hashValue>โ hash of the archive file to be downloaded. The argument should be of the form<algo>=<hashValue>wherealgocan be any of the hashing algorithms supported by thefile()command. Specifying this option is strongly recommended for URL downloads, because it ensures the integrity of the downloaded content. It's also used as a check for a previously downloaded file, letting the connection to the remote location be avoided altogether if the local directory already has a file from an earlier download that matches the specified hash. Protect your peace ๐ .URL_MD5 <md5>โ equivalent toURL_HASH MD5=<md5>.DOWNLOAD_NAME <fname>โ file name to use for the downloaded file. If not given, the end of the URL is used to determine the file name. This option is rarely needed โ the default name is generally suitable and isn't normally used outside of code internal to theExternalProjectmodule.DOWNLOAD_EXTRACT_TIMESTAMP <bool>โ Added in version 3.24. When specified with a true value, the timestamps of the extracted files will match those in the archive. When false, the timestamps of the extracted files will reflect the time at which the extraction was performed. If the download URL changes, timestamps based off those in the archive can result in dependent targets not being rebuilt when they potentially should have been. So unless the file timestamps are significant to the project in some way, use a false value for this option. IfDOWNLOAD_EXTRACT_TIMESTAMPisn't given, the default is false. See policyCMP0135.DOWNLOAD_NO_EXTRACT <bool>โ Added in version 3.6. Lets you disable the extraction part of the download step by passing a boolean true value for this option. If this option isn't given, the downloaded contents get unpacked automatically if required. If extraction has been disabled, the full path to the downloaded file is available as<DOWNLOADED_FILE>in subsequent steps, or as the propertyDOWNLOADED_FILEwith theExternalProject_Get_Property()command.DOWNLOAD_NO_PROGRESS <bool>โ can be used to disable logging the download progress. If this option isn't given, download progress messages will be logged.TIMEOUT <seconds>โ maximum time allowed for file download operations.INACTIVITY_TIMEOUT <seconds>โ Added in version 3.19. Terminate the operation after a period of inactivity.HTTP_USERNAME <username>โ Added in version 3.7. Username for the download operation if authentication is required.HTTP_PASSWORD <password>โ Added in version 3.7. Password for the download operation if authentication is required.HTTP_HEADER <header1> [<header2>...]โ Added in version 3.7. Provides an arbitrary list of HTTP headers for the download operation. This can be useful for accessing content in systems like AWS, etc.TLS_VERSION <min>โ Added in version 3.30. Specify minimum TLS version forhttps://URLs. If this option isn't provided, the value of theCMAKE_TLS_VERSIONvariable or theCMAKE_TLS_VERSIONenvironment variable will be used instead (seefile(DOWNLOAD)).
This option also applies to git clone invocations, although the default behavior is different. If none of the TLS_VERSION option, CMAKE_TLS_VERSION variable, or CMAKE_TLS_VERSION environment variable is specified, the behavior will be determined by git's default or a http.sslVersion git config option the user may have set at a global level.
TLS_VERIFY <bool>โ specifies whether certificate verification should be performed forhttps://URLs. If this option isn't provided, the value of theCMAKE_TLS_VERIFYvariable or theCMAKE_TLS_VERIFYenvironment variable will be used instead (seefile(DOWNLOAD)). If neither of those is set, certificate verification will not be performed. In situations whereURL_HASHcannot be provided, this option can be an alternative verification measure ๐ซถ.
This option also applies to git clone invocations, ngl the default behavior is a little different there. If none of the TLS_VERIFY option, the CMAKE_TLS_VERIFY variable, or the CMAKE_TLS_VERIFY environment variable is specified, then the behavior gets decided by git's own default (which is true) or by a http.sslVerify git config option the user might have set at a global level. iykyk ๐
Changed in version 3.6 (๐ซ glow-up alert): back in the day, this option did not apply to git clone invocations. Now it does.
Changed in version 3.30 (another glow-up โจ): previously the CMAKE_TLS_VERIFY environment variable was not checked at all. Now it is, bestie.
TLS_CAINFO <file>โ drop a custom certificate authority file here, but only ifTLS_VERIFYis enabled ๐. If you don't specify this option, the value of theCMAKE_TLS_CAINFOvariable gets used instead (peepfile(DOWNLOAD)for the deets).NETRC <level>โ Added in version 3.11. Tells CMake whether the.netrcfile should be used for the operation ๐ฅ. If you don't specify this option, the value of theCMAKE_NETRCvariable is used instead (again, seefile(DOWNLOAD)). The valid levels are, in order:IGNOREDโ the.netrcfile is ignored. This is literally the default, periodt.OPTIONALโ the.netrcfile is optional, and info in the URL is preferred ๐. The file gets scanned to find whichever info isn't already in the URL.REQUIREDโ the.netrcfile is required, and info in the URL is ignored. No file, no deal ๐.
NETRC_FILE <file>โ Added in version 3.11. Use this to point at an alternative.netrcfile instead of the one chillin' in your home directory, but only if theNETRClevel isOPTIONALorREQUIRED๐ฆ. If you don't specify this option, the value of theCMAKE_NETRC_FILEvariable is used instead (seefile(DOWNLOAD)).
Added in version 3.1: support for tbz2, .tar.xz, .txz, and .7z extensions got added, slay ๐
.
Added in version 4.1: literally every archive type that cmake -E tar can extract is supported now, regardless of the file extension. No cap, the extension doesn't even matter anymore ๐
๐ง Git
NOTE: you need a git version of 1.6.5 or later if you're using this download method. older than that? not today, bestie ๐
GIT_REPOSITORY <url>โ the URL of the git repository. Any URL that thegitcommand understands is fair game ๐ซถ.
Changed in version 3.27: a relative URL will be resolved based on the parent project's remote, subject to CMP0150 ๐ค. Go read the policy documentation for how the remote gets selected โ including the conditions where the remote selection can just fail. And listen: local filesystem remotes should always use absolute paths. always. ๐
GIT_TAG <tag>โ a git branch name, tag, or commit hash ๐ธ. Heads up: branch names and tags should generally be specified as remote names (i.e.origin/myBranchrather than justmyBranch). Why? Because this ensures that if the remote end has its tag moved or its branch rebased or its history rewritten, your local clone still gets updated correctly ๐. In general, though, specifying a commit hash should be preferred, for a bunch of reasons:- If the local clone already has the commit corresponding to the hash, no
git fetchneeds to happen to check for changes each time CMake is re-run ๐โโ๏ธ. This can result in a significant speed up if lots of external projects are being used. iconic. - Using a specific git hash ensures that the main project's own history is fully traceable to a specific point in the external project's evolution ๐. If a branch or tag name is used instead, then checking out a specific commit of the main project doesn't necessarily pin the whole build to a specific point in the life of the external project. The lack of such deterministic behavior makes the main project lose traceability and repeatability. and we hate losing traceability ๐ญ
- If the local clone already has the commit corresponding to the hash, no
If GIT_SHALLOW is enabled then GIT_TAG works only with branch names and tags โ a commit hash is not allowed ๐ซ.
Also note: if not provided, GIT_TAG defaults to master, not the default Git branch name. yeah. it's giving legacy vibes ๐
GIT_REMOTE_NAME <name>โ the optional name of the remote ๐. If you don't specify it, it defaults toorigin.GIT_SUBMODULES <module>...โ the specific git submodules that should also be updated ๐ฆ. If you don't provide this option, all git submodules get updated.
Changed in version 3.16: whenCMP0097is set toNEW, if this value is set to an empty string then no submodules are initialized or updated. zero. none. zip. โจ
GIT_SUBMODULES_RECURSE <bool>โ Added in version 3.17. Specify whether git submodules (if there are any) should update recursively by passing the--recursiveflag togit submodule update๐. If not specified, the default ison.GIT_SHALLOW <bool>โ Added in version 3.6. When this option is enabled, thegit cloneoperation gets handed the--depth 1option ๐โโ๏ธ. This performs a shallow clone, which avoids downloading the whole entire history and instead retrieves just the commit denoted by theGIT_TAGoption. so efficient. so demure.GIT_PROGRESS <bool>โ Added in version 3.8. When enabled, this option instructs thegit cloneoperation to report its progress by passing it the--progressoption ๐. Without this option, the clone step for large projects may appear to make the build stall, since nothing gets logged until the clone operation finishes ๐ด. While this option can be used to provide progress and prevent that "is it frozen??" appearance, it may also make the build overly noisy if lots of external projects are used. pick your fighter ๐GIT_CONFIG <option1> [<option2>...]โ Added in version 3.8. Specify a list of config options to pass togit clone๐. Each option listed gets transformed into its own--config <option>on thegit clonecommand line, and each option is required to be in the formkey=value.GIT_REMOTE_UPDATE_STRATEGY <strategy>โ Added in version 3.18. WhenGIT_TAGrefers to a remote branch, this option lets you specify how the update step behaves ๐ค. The<strategy>must be one of the following:CHECKOUTโ ignore the local branch and always checkout the branch specified byGIT_TAG. simple. clean. โจREBASEโ try to rebase the current branch onto the one specified byGIT_TAG๐. If there are local uncommitted changes, they will be stashed first and popped again after rebasing. If rebasing or popping the stashed changes fails, abort the rebase and halt with an error ๐. WhenGIT_REMOTE_UPDATE_STRATEGYis not present, this is the default strategy โ unless the default has been overridden withCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY(see below). Note that if the branch specified inGIT_TAGis different from the upstream branch currently being tracked, it is not safe to perform a rebase. In that situation,REBASEwill silently be treated asCHECKOUTinstead. sneaky but ok ๐REBASE_CHECKOUTโ same asREBASE, except if the rebase fails, an annotated tag will be created at the originalHEADposition from before the rebase, and then it'll checkoutGIT_TAGjust like theCHECKOUTstrategy ๐. The message stored on the annotated tag gives information about what was attempted and the tag name will include a timestamp so that each failed run adds a new tag โฐ. This strategy ensures no changes will be lost, but updates should always succeed ifGIT_TAGrefers to a valid ref โ unless there are uncommitted changes that cannot be popped successfully ๐ญ.
The variable CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY can be set to override the default strategy. This variable should not be set by a project โ it's intended for the user to set ๐โโ๏ธ. It's primarily intended for use in continuous integration scripts, to ensure that when history is rewritten on a remote branch, the build doesn't end up with unintended changes or failed builds resulting from conflicts during rebase operations. protect the pipeline at all costs ๐ฅ
The following variables can be set to control the retry behavior for git clone operations:
CMAKE_EP_GIT_CLONE_RETRY_COUNTโ Added in version 4.4. Specifies the number of times to retry agit cloneoperation if it fails ๐ซถ. The default is2retries. The first attempt is not counted as a retry, so the total number of attempts is the retry count plus one ๐งฎ. This variable should not be set by a project โ it's intended for the user to set. It's primarily useful when dealing with intermittent network issues or rate limiting from git hosting services. (looking at you, every git host ever ๐)CMAKE_EP_GIT_CLONE_RETRY_DELAYโ Added in version 4.4. Specifies the delay in seconds between retry attempts forgit cloneoperations โณ. The default is0seconds (no delay between retries). This variable should not be set by a project โ it's intended for the user to set. Setting a delay can be helpful when dealing with rate limiting from git hosting services, where immediate retries would also get rejected ๐ซ. be patient, bestie ๐งโโ๏ธ
๐ Subversion
SVN_REPOSITORY <url>โ the URL of the Subversion repository ๐.SVN_REVISION -r<rev>โ the revision to checkout from the Subversion repository ๐.SVN_USERNAME <username>โ username for the Subversion checkout and update ๐โโ๏ธ.SVN_PASSWORD <password>โ password for the Subversion checkout and update ๐.SVN_TRUST_CERT <bool>โ specifies whether to trust the Subversion server site certificate ๐ก๏ธ. If enabled, the--trust-server-certoption gets passed to thesvn checkoutandupdatecommands.
๐ฆ Mercurial
HG_REPOSITORY <url>โ the URL of the mercurial repository ๐.HG_TAG <tag>โ mercurial branch name, tag, or commit id ๐ท๏ธ.
๐ CVS
CVS_REPOSITORY <cvsroot>โ theCVSROOTof the CVS repository ๐ธ.CVS_MODULE <mod>โ the module to checkout from the CVS repository ๐ฆ.CVS_TAG <tag>โ the tag to checkout from the CVS repository ๐ท๏ธ.
๐ธ Update Step Options ๐ธ
ok so every time CMake gets re-run, bestie, the external project's sources get updated by default โ but only if the download method actually supports updates (think: a git repo gets checked, as long as the GIT_TAG doesn't point at one specific commit). Slay.
UPDATE_COMMAND <cmd>...โ swaps out the download method's update step for a custom command of your own. The command can use generator expressions <#manual:cmake-generator-expressions(7)>.UPDATE_DISCONNECTED <bool>โ Added in version 3.2.
turn this on and the update step gets skipped entirely (tho see below, because there's a whole "changed behavior where this is not the case" situation going on ๐). It does not stop the download step. The update step can still be added as a step target (see ExternalProject_Add_StepTargets()) and called manually. This is lowkey the move if you want devs to be able to build when they're off the network (the network might still be needed for the download step tho, no cap).
Changed in version 3.27: when UPDATE_DISCONNECTED is true, the update step will be executed if any details about the update or download step change. Also, if you're using the git download/update method, the update logic gets modified to skip attempts to contact the remote. And if the GIT_TAG mentions a ref that isn't known locally, the update step just halts with a fatal error. ๐
When this option is present, it's generally advisable to make the value a cache variable under the developer's control rather than hard-coding it. If the option isn't present, the default value comes from the EP_UPDATE_DISCONNECTED directory property. If that's also not defined, updates are performed as normal. The EP_UPDATE_DISCONNECTED directory property is intended as a convenience for controlling the UPDATE_DISCONNECTED behavior for an entire section of a project's directory hierarchy, and it may be a more convenient way to give developers control over whether or not to perform updates (assuming the project also provides a cache variable or some other convenient method for setting the directory property).
heads up: this may cause a step target to be created automatically for the download step. See policy CMP0114 <#policy:CMP0114>.
๐ Patch Step Options ๐
PATCH_COMMAND <cmd>...โ gives you a custom command to patch the sources after an update. By default, no patch command is defined. But ngl, it can be genuinely difficult to define an appropriate patch command that performs robustly โ especially for download methods like git, where changing theGIT_TAGwon't discard changes from a previous patch, but the patch command will get called again after updating to the new tag. ๐ญ so like, be careful with this one.
โจ Configure Step Options โจ
The configure step runs after the download and update steps. By default, the external project is assumed to be a CMake project, but you can override that if you need to.
CONFIGURE_COMMAND <cmd>...โ the default configure command runs CMake with a few options based on the main project. The options added are typically only those needed to use the same generator as the main project, but theCMAKE_GENERATORoption can be given to override this. The project is responsible for adding any toolchain details, flags or other settings it wants to reuse from the main project or otherwise specify (seeCMAKE_ARGS,CMAKE_CACHE_ARGSandCMAKE_CACHE_DEFAULT_ARGSbelow).
For non-CMake external projects, you must use CONFIGURE_COMMAND to override the default configure command (generator expressions <#manual:cmake-generator-expressions(7)> are supported). And for projects that need no configure step at all? Just specify this option with an empty string as the command to execute. iconic.
CMAKE_COMMAND /.../cmakeโ specify an alternativecmakeexecutable for the configure step (use an absolute path, bestie). This is generally not recommended, since it's usually desirable to use the same CMake version throughout the whole build. Ignored if a custom configure command was specified withCONFIGURE_COMMAND.CMAKE_GENERATOR <gen>โ override the CMake generator used for the configure step. Without this option, the same generator as the main build is used. Ignored if a custom configure command was specified with theCONFIGURE_COMMANDoption.CMAKE_GENERATOR_PLATFORM <platform>โ Added in version 3.1.
passes a generator-specific platform name to the CMake command (see CMAKE_GENERATOR_PLATFORM <#variable:CMAKE_GENERATOR_PLATFORM>). It is an error to provide this option without the CMAKE_GENERATOR option. periodt.
CMAKE_GENERATOR_TOOLSET <toolset>โ passes a generator-specific toolset name to the CMake command (seeCMAKE_GENERATOR_TOOLSET<#variable:CMAKE_GENERATOR_TOOLSET>). It is an error to provide this option without theCMAKE_GENERATORoption.CMAKE_GENERATOR_INSTANCE <instance>โ Added in version 3.11.
passes a generator-specific instance selection to the CMake command (see CMAKE_GENERATOR_INSTANCE <#variable:CMAKE_GENERATOR_INSTANCE>). It is an error to provide this option without the CMAKE_GENERATOR option.
CMAKE_ARGS <arg>...โ the arguments you specify get passed to thecmakecommand line. They can be any argument thecmakecommand understands, not just cache values defined by-D...arguments (see also CMake Options <#manual:cmake(1)>).
Added in version 3.3: arguments may use generator expressions <#manual:cmake-generator-expressions(7)>.
CMAKE_CACHE_ARGS <arg>...โ an alternate way of specifying cache variables for when command line length issues might become a problem. The arguments are expected to be in the form-Dvar:STRING=value, which are then transformed into CMakeset()<#command:set> commands with theFORCEoption used. Theseset()commands are written to a pre-load script, which is then applied using thecmake -C<#manual:cmake(1)> command line option.
Added in version 3.3: arguments may use generator expressions <#manual:cmake-generator-expressions(7)>.
CMAKE_CACHE_DEFAULT_ARGS <arg>...โ Added in version 3.2.
same as the CMAKE_CACHE_ARGS option, except the set() commands do not include the FORCE keyword. That means the values act as initial defaults only and will not override any variables already set from a previous run. Use this option with care, bestie โ it can lead to different behavior depending on whether the build starts from a fresh build directory or reuses previous build contents. ๐ซถ
Added in version 3.15: if the CMake generator is the Green Hills MULTI and not overridden, the original project's settings for the GHS toolset and target system customization cache variables are propagated into the external project.
SOURCE_SUBDIR <dir>โ Added in version 3.7.
when no CONFIGURE_COMMAND option is specified, the configure step assumes the external project has a CMakeLists.txt file at the top of its source tree (i.e. in SOURCE_DIR). The SOURCE_SUBDIR option points to an alternative directory within the source tree to use as the top of the CMake source tree instead. This must be a relative path, and it'll be interpreted as being relative to SOURCE_DIR.
Added in version 3.14: when the BUILD_IN_SOURCE option is enabled, the BUILD_COMMAND is used to point to an alternative directory within the source tree.
CONFIGURE_HANDLED_BY_BUILD <bool>โ Added in version 3.20.
enabling this relaxes the configure step's dependencies on other external projects to order-only. Meaning: the configure step will be executed after its external project dependencies are built, but it will not be marked dirty when one of its external project dependencies is rebuilt. Enable this when the build step is smart enough to figure out if the configure step needs to be rerun. CMake and Meson are examples of build systems whose build step is smart enough to know if the configure step needs to be rerun. big brain energy honestly.
CONFIGURE_ENVIRONMENT_MODIFICATION <modification>...โ Added in version 4.2.
specifies environment variables that should be modified for the configure step.
set a semicolon-separated list <#cmake-language-lists> of environment variables and values of the form MYVAR=OP:VALUE, where MYVAR is the case-sensitive name of an environment variable to be modified. Entries are considered in the order specified in the property's value. The OP may be one of:
reset: reset to the unmodified value, ignoring all modifications toMYVARprior to this entry. Note that this will reset the variable to the value set byENVIRONMENT<#prop_test:ENVIRONMENT>, if it was set, and otherwise to its state from the rest of the CTest execution.set: replaces the current value ofMYVARwithVALUE.unset: unsets the current value ofMYVAR.string_append: appends singularVALUEto the current value ofMYVAR.string_prepend: prepends singularVALUEto the current value ofMYVAR.path_list_append: appends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).path_list_prepend: prepends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).cmake_list_append: appends singularVALUEto the current value ofMYVARusing;as the separator.cmake_list_prepend: prepends singularVALUEto the current value ofMYVARusing;as the separator.
like, for example:
ExternalProject_Add(example
... # Download options, etc...
CONFIGURE_ENVIRONMENT_MODIFICATION
SDKROOT=set:macosx
PKG_CONFIG_PATH=set:$ENV{PKG_CONFIG_PATH}
)
cute, right? ๐
This snippet is doing the absolute most in the best way: it defines two environment variables when configuring the example project. SDKROOT gets set to macosx, and the value of PKG_CONFIG_PATH gets forwarded to the external project. ๐ซถ
Environment modifications team up with LIST_SEPARATOR to swap that separator for a ; inside the environment variable:
ExternalProject_Add(example
... # Download options, etc...
LIST_SEPARATOR ,
CONFIGURE_ENVIRONMENT_MODIFICATION
LIST_VAR=set:a,b,c
)
So this snippet means the environment variable LIST_VAR is passed to the configure command invocation with the value a;b;c. iconic behavior tbh ๐
โจ Build Step Options โจ
If the configure step assumed the external project uses CMake as its build system, then the build step assumes that too. Otherwise, the build step assumes a Makefile-based build and just runs make with no arguments as the default build step. You can override that with custom build commands if you need to.
If both the main project and the external project use make as their build tool, the external project's build step gets invoked as a recursive make using $(MAKE). That passes some build tool settings from the main project over to the external project. But if either the main project or the external project isn't using make, then no build tool settings get passed to the external project other than the ones established by the configure step. Like, running ninja -v in the main project will not pass -v to the external project's build step, even if the external project also uses ninja as its build tool. no cap ๐ญ
BUILD_COMMAND <cmd>...โ overrides the default build command (generator expressions fromcmake-generator-expressions(7)are supported). If you don't give this option, the default build command gets picked to integrate with the main build in the most appropriate way (e.g. recursivemakefor Makefile generators, orcmake --buildif the project uses a CMake build). You can also pass an empty string as the command to make the build step do absolutely nothing. ๐BUILD_IN_SOURCE <bool>โ when this is enabled, the build happens directly inside the external project's source tree. Generally you should avoid this โ a separate build directory is usually preferred โ but it's lowkey useful when the external project assumes an in-source build. Don't specify theBINARY_DIRoption if you're building in-source, bestie.BUILD_ALWAYS <bool>โ enabling this forces the build step to always run. Honestly this can be the easiest way to robustly make sure the external project's own build dependencies get evaluated, instead of relying on the default success timestamp-based method. You don't normally need it unless developers are expected to modify something the external project's build depends on in a way that isn't detectable through the step target dependencies (e.g.SOURCE_DIRis used without a download method and developers might modify the sources inSOURCE_DIR). ๐งBUILD_BYPRODUCTS <file>...โ added in version 3.2. Specifies files that will be generated by the build command but which might or might not have their modification time updated by subsequent builds. This may also be required to explicitly declare dependencies when you're using theNinjagenerator. These ultimately get passed through asBYPRODUCTSto the build step's own underlying call toadd_custom_command(), which has additional documentation. โญBUILD_JOB_SERVER_AWARE <bool>โ added in version 3.28. Specifies that the build step is aware of the GNU Make job server. See theadd_custom_command()documentation of itsJOB_SERVER_AWAREoption for the details. This option is relevant only when an explicitBUILD_COMMANDis specified. ๐BUILD_ENVIRONMENT_MODIFICATION <modification>...โ added in version 4.2. Specify environment variables that should be modified for the build step.
Set a semicolon-separated list of environment variables and values of the form MYVAR=OP:VALUE, where MYVAR is the case-sensitive name of an environment variable to be modified. Entries are considered in the order specified in the property's value. OP may be one of:
reset: Reset to the unmodified value, ignoring all modifications toMYVARprior to this entry. Note that this will reset the variable to the value set byENVIRONMENT, if it was set, and otherwise to its state from the rest of the CTest execution.set: Replaces the current value ofMYVARwithVALUE.unset: Unsets the current value ofMYVAR.string_append: Appends singularVALUEto the current value ofMYVAR.string_prepend: Prepends singularVALUEto the current value ofMYVAR.path_list_append: Appends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).path_list_prepend: Prepends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).cmake_list_append: Appends singularVALUEto the current value ofMYVARusing;as the separator.cmake_list_prepend: Prepends singularVALUEto the current value ofMYVARusing;as the separator.
๐ Install Step Options ๐
If the configure step assumed the external project uses CMake as its build system, the install step will too. Otherwise, the install step assumes a Makefile-based build and just runs make install as the default build step. You can override that with custom install commands if you need to. ๐
INSTALL_COMMAND <cmd>...โ the external project's own install step is invoked as part of the main project's build. It happens after the external project's build step and may be before or after the external project's test step (see theTEST_BEFORE_INSTALLoption below). The external project's install rules are not part of the main project's install rules, so if anything from the external project should be installed as part of the main build, you need to specify those in the main build as additionalinstall()commands. The default install step builds the install target of the external project, but you can override it with a custom command using this option (generator expressions fromcmake-generator-expressions(7)are supported). Passing an empty string as the<cmd>makes the install step do nothing. ๐INSTALL_BYPRODUCTS <file>...โ added in version 3.26. Specifies files that will be generated by the install command but which might or might not have their modification time updated by subsequent installs. This may also be required to explicitly declare dependencies when using theNinjagenerator. These ultimately get passed through asBYPRODUCTSto the install step's own underlying call toadd_custom_command(), which has additional documentation. ๐ธINSTALL_JOB_SERVER_AWARE <bool>โ added in version 4.0. Specifies that the install step is aware of the GNU Make job server. See theadd_custom_command()documentation of itsJOB_SERVER_AWAREoption for details. This option is relevant only when an explicitINSTALL_COMMANDis specified. ๐ฅ
Note: If theCMAKE_INSTALL_MODEenvironment variable is set when the main project is built, it will only have an effect if these conditions are met: - The main project's configure step assumed the external project uses CMake as its build system. - The external project's install command actually runs. Note that because of the wayExternalProjectmay use timestamps internally, if nothing the install step depends on needs to be re-executed, the install command might also not need to run. Also note thatExternalProjectdoes not check whether theCMAKE_INSTALL_MODEenvironment variable changes from one run to another. ๐ฌ
INSTALL_ENVIRONMENT_MODIFICATION <modification>...โ added in version 4.2. Specify environment variables that should be modified for the install step.
Set a semicolon-separated list of environment variables and values of the form MYVAR=OP:VALUE, where MYVAR is the case-sensitive name of an environment variable to be modified. Entries are considered in the order specified in the property's value. OP may be one of:
reset: Reset to the unmodified value, ignoring all modifications toMYVARprior to this entry. Note that this will reset the variable to the value set byENVIRONMENT, if it was set, and otherwise to its state from the rest of the CTest execution.set: Replaces the current value ofMYVARwithVALUE.unset: Unsets the current value ofMYVAR.string_append: Appends singularVALUEto the current value ofMYVAR.string_prepend: Prepends singularVALUEto the current value ofMYVAR.path_list_append: Appends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).path_list_prepend: Prepends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).cmake_list_append: Appends singularVALUEto the current value ofMYVARusing;as the separator.cmake_list_prepend: Prepends singularVALUEto the current value ofMYVARusing;as the separator.
๐ฆ Test Step Options ๐ฆ
The test step is only defined if you provide at least one of the following TEST_... options. iykyk ๐
TEST_COMMAND <cmd>...โ okay so this one overrides the default test command (generator expressions, like the ones incmake-generator-expressions(7), are supported ๐ ). If you donโt give this option, the test step just builds the external projectโs own test target, which is the default vibe. You can also pass<cmd>as an empty string, which keeps the test step defined but makes it do absolutely nothing. Do not specify any of the otherTEST_...options when you pass an empty string as the test command โ and honestly, if the test step target isnโt needed, just omit all theTEST_...options altogether.TEST_BEFORE_INSTALL <bool>โ when this is enabled, the test step runs before the install step. The default behavior is for the test step to run after install.TEST_AFTER_INSTALL <bool>โ this is mainly useful when you want to say โyes, I want the test stepโ but all the default behavior is already enough. Setting it to a boolean true value ensures the test step is defined and that it comes after the install step. If bothTEST_BEFORE_INSTALLandTEST_AFTER_INSTALLare enabled, the latter is silently ignored ๐.TEST_EXCLUDE_FROM_MAIN <bool>โ Added in version 3.2. If enabled, the main buildโs defaultALLtarget will not depend on the test step. This is a handy way to make sure the test step is defined but only gets invoked when you manually ask for it. It may cause a step target to be created automatically for either the install or build step. See policyCMP0114๐ซถ.TEST_ENVIRONMENT_MODIFICATION <modification>...โ Added in version 4.2. Specify environment variables that should be modified for the test step. You set a semicolon-separated list of environment variables and values of the formMYVAR=OP:VALUE, whereMYVARis the case-sensitive name of an environment variable to be modified. Entries are considered in the order specified in the propertyโs value. TheOPmay be one of:reset: Reset to the unmodified value, ignoring all modifications toMYVARprior to this entry. Note that this will reset the variable to the value set byENVIRONMENT, if it was set, and otherwise to its state from the rest of the CTest execution.set: Replaces the current value ofMYVARwithVALUE.unset: Unsets the current value ofMYVAR.string_append: Appends singularVALUEto the current value ofMYVAR.string_prepend: Prepends singularVALUEto the current value ofMYVAR.path_list_append: Appends singularVALUEto the current value ofMYVARusing the host platformโs path list separator (;on Windows and:elsewhere).path_list_prepend: Prepends singularVALUEto the current value ofMYVARusing the host platformโs path list separator (;on Windows and:elsewhere).cmake_list_append: Appends singularVALUEto the current value ofMYVARusing;as the separator.cmake_list_prepend: Prepends singularVALUEto the current value ofMYVARusing;as the separator.
๐ธ Output Logging Options ๐ธ
Each of the following LOG_... options can be used to wrap the relevant step in a script to capture its output to files. The log files will be created in LOG_DIR if supplied, or otherwise in the STAMP_DIR directory with step-specific file names โจ.
LOG_DOWNLOAD <bool>โ when enabled, the output of the download step is logged to files.LOG_UPDATE <bool>โ when enabled, the output of the update step is logged to files.LOG_PATCH <bool>โ Added in version 3.14. When enabled, the output of the patch step is logged to files.LOG_CONFIGURE <bool>โ when enabled, the output of the configure step is logged to files.LOG_BUILD <bool>โ when enabled, the output of the build step is logged to files.LOG_INSTALL <bool>โ when enabled, the output of the install step is logged to files.LOG_TEST <bool>โ when enabled, the output of the test step is logged to files.LOG_MERGED_STDOUTERR <bool>โ Added in version 3.14. When enabled, stdout and stderr will be merged for any step whose output is being logged to files.LOG_OUTPUT_ON_FAILURE <bool>โ Added in version 3.14. This option only has an effect if at least one of the otherLOG_<step>options is enabled. If an error occurs for a step which has logging to file enabled, that stepโs output will be printed to the console ifLOG_OUTPUT_ON_FAILUREis set to true. For cases where a large amount of output is recorded, just the end of that output may be printed to the console.
๐ฅ๏ธ Terminal Access Options ๐ฅ๏ธ
Added in version 3.4. Steps can be given direct access to the terminal in some cases. Giving a step access to the terminal may allow it to receive terminal input if required, such as for authentication details not provided by other options. With the Ninja generator, these options place the steps in the console job pool (JOB_POOLS). Each step can be given access to the terminal individually via the following options:
USES_TERMINAL_DOWNLOAD <bool>โ give the download step access to the terminal.USES_TERMINAL_UPDATE <bool>โ give the update step access to the terminal.USES_TERMINAL_PATCH <bool>โ Added in version 3.23. Give the patch step access to the terminal.USES_TERMINAL_CONFIGURE <bool>โ give the configure step access to the terminal.USES_TERMINAL_BUILD <bool>โ give the build step access to the terminal.USES_TERMINAL_INSTALL <bool>โ give the install step access to the terminal.USES_TERMINAL_TEST <bool>โ give the test step access to the terminal.
๐ฏ Target Options ๐ฏ
DEPENDS <targets>...โ specify other targets on which the external project depends. Those other targets will be brought up to date before any of the external projectโs steps are executed. Because the external project uses additional custom targets internally for each step, theDEPENDSoption is the most convenient way to ensure all of those steps depend on the other targets. Simply doingadd_dependencies(<name> <targets>)will not make any of the steps dependent on<targets>โ no cap, thatโs just how it is ๐ญ.EXCLUDE_FROM_ALL <bool>โ when enabled, this option excludes the external project from the defaultALLtarget of the main build.STEP_TARGETS <step-target>...โ generate custom targets for the specified steps. This is required if the steps need to be triggered manually or if they need to be used as dependencies of other targets. If this option is not specified, the default value is taken from theEP_STEP_TARGETSdirectory property. SeeExternalProject_Add_StepTargets()below for further discussion of the effects of this option.INDEPENDENT_STEP_TARGETS <step-target>...โ Deprecated since version 3.19: This is allowed only if policyCMP0114is not set toNEW. Generates custom targets for the specified steps and prevents these targets from having the usual dependencies applied to them. If this option is not specified, the default value is taken from theEP_INDEPENDENT_STEP_TARGETSdirectory property. This option is mostly useful for allowing individual steps to be driven independently, such as for a CDash setup where each step should be initiated and reported individually rather than as one whole build. SeeExternalProject_Add_StepTargets()below for further discussion of the effects of this option.
๐ง Miscellaneous Options ๐ง
LIST_SEPARATOR <sep>โ for any of the various..._COMMANDoptions,CMAKE_ARGS, and..._ENVIRONMENT_MODIFICATIONoperations, ExternalProject will replace<sep>with;in the specified command lines. This can be used to ensure a command has a literal;in it where direct usage would otherwise be interpreted as argument separators to CMake APIs instead. Note that the separator should be chosen to avoid being confused for non-list-separator usages of the sequence. For example, usingLIST_SEPARATORallows for passing list values to CMake cache variables on the command line:
ExternalProject_Add(example
... # Download options, etc.
LIST_SEPARATOR ","
CMAKE_ARGS "-DCMAKE_PREFIX_PATH:STRING=${first_prefix},${second_prefix}"
)
COMMAND <cmd>...โ any of the other..._COMMANDoptions can have additional commands appended to them by following them with as manyCOMMAND ...options as needed (generator expressions are supported). For example:
ExternalProject_Add(example
... # Download options, etc.
BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build"
COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>
COMMAND ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete"
)
It should also be noted that each build step is created via a call to ExternalProject_Add_Step(). See that commandโs documentation for the automatic substitutions that are supported for some options.
๐ Obtaining Project Properties ๐
ExternalProject_Get_Propertyโ theExternalProject_Get_Property()function retrieves external project target properties:
ExternalProject_Get_Property(<name> <prop1> [<prop2>...])
The function stores property values in variables of the same name. Property names correspond to the keyword argument names of ExternalProject_Add(). For example, the source directory might be retrieved like so:
ExternalProject_Get_property(myExtProj SOURCE_DIR)
message("Source dir of myExtProj = ${SOURCE_DIR}")
๐ Explicit Step Management ๐
So like, ExternalProject_Add() on its own is often literally all you need to fold an external project into your main build โ iconic, no notes. But bestie, sometimes the scenario is spicy and you need some extra work to get the exact behavior you want, like adding in a custom step or making steps available as manually triggerable targets. That's where ExternalProject_Add_Step(), ExternalProject_Add_StepTargets() and ExternalProject_Add_StepDependencies come in โ they're the lower level control squad you need to implement those step-level capabilities. ๐ซถ
๐ธ ExternalProject_Add_Step ๐ธ
The ExternalProject_Add_Step() function specifies an additional custom step for an external project that was defined by an earlier call to ExternalProject_Add():
ExternalProject_Add_Step(<name> <step> [<option>...])
<name> is the same as the name you passed to that original ExternalProject_Add() call. Heads up though: the <step> you specify must not be one of the pre-defined steps (mkdir, download, update, patch, configure, build, install or test). Those ones are taken, okay? ๐ซ
The supported options are:
COMMAND <cmd>...โ the command line to be executed by this custom step (generator expressions are supported). You can repeat this option multiple times to specify multiple commands, and they'll be executed in order. โจCOMMENT "<text>..."โ text to be printed when the custom step executes. A little hype message for your build log, love that.DEPENDEES <step>...โ other steps (custom or pre-defined) on which this step depends.DEPENDERS <step>...โ other steps (custom or pre-defined) that depend on this new custom step. It's giving main character energy โ everyone's waiting on it.DEPENDS <file>...โ files on which this custom step depends.ENVIRONMENT_MODIFICATION <modification>...โ Added in version 4.2. ๐
Specify environment variables that should be modified while running the commands in the external project step.
Set a semicolon-separated list of environment variables and values of the form MYVAR=OP:VALUE, where MYVAR is the case-sensitive name of an environment variable to be modified. Entries are considered in the order specified in the property's value. The OP may be one of:
reset: Reset to the unmodified value, ignoring all modifications toMYVARprior to this entry. Note that this will reset the variable to the value set byENVIRONMENT, if it was set, and otherwise to its state from the rest of the CTest execution.set: Replaces the current value ofMYVARwithVALUE.unset: Unsets the current value ofMYVAR.string_append: Appends singularVALUEto the current value ofMYVAR.string_prepend: Prepends singularVALUEto the current value ofMYVAR.path_list_append: Appends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).path_list_prepend: Prepends singularVALUEto the current value ofMYVARusing the host platform's path list separator (;on Windows and:elsewhere).cmake_list_append: Appends singularVALUEto the current value ofMYVARusing;as the separator.cmake_list_prepend: Prepends singularVALUEto the current value ofMYVARusing;as the separator.
INDEPENDENT <bool>โ Added in version 3.19.
Specifies whether this step is independent of the external dependencies specified by the ExternalProject_Add()'s DEPENDS option. The default is FALSE. Steps marked as independent may depend only on other steps marked independent. See policy CMP0114. ๐
Note that this use of the term "independent" refers only to independence from external targets specified by the DEPENDS option and is orthogonal to a step's dependencies on other steps. Ik it's a vibe, but them's the rules.
If a step target is created for an independent step by the ExternalProject_Add() STEP_TARGETS option or by the ExternalProject_Add_StepTargets() function, it will not depend on the external targets, but may depend on targets for other steps.
BYPRODUCTS <file>...โ Added in version 3.2.
Files that will be generated by this custom step but which might or might not have their modification time updated by subsequent builds. This may also be required to explicitly declare dependencies when you're using the Ninja generator. This list of files will ultimately be passed through as the BYPRODUCTS option to the add_custom_command() used to implement the custom step internally, and that has additional documentation. ๐
ALWAYS <bool>โ when enabled, this option specifies that the custom step should always be run (i.e. that it is always considered out of date). Never beating the "still needs to run" allegations, fr fr.JOB_SERVER_AWARE <bool>โ Added in version 3.28.
Specifies that the custom step is aware of the GNU Make job server. See the add_custom_command() documentation of its JOB_SERVER_AWARE option for details.
EXCLUDE_FROM_MAIN <bool>โ when enabled, this option specifies that the external project's main target does not depend on the custom step. This may cause step targets to be created automatically for the steps on which this step depends. See policyCMP0114.WORKING_DIRECTORY <dir>โ specifies the working directory to set before running the custom step's command. If this option is not specified, the directory will be the value ofCMAKE_CURRENT_BINARY_DIRat the point whereExternalProject_Add_Step()was called. Home is where the binary dir is, bestie. ๐LOG <bool>โ if set, this causes the output from the custom step to be captured to files in the external project'sLOG_DIRif supplied orSTAMP_DIR.USES_TERMINAL <bool>โ if enabled, this gives the custom step direct access to the terminal if possible.
The command line, comment, working directory and byproducts of every standard and custom step are processed to replace the tokens <SOURCE_DIR>, <SOURCE_SUBDIR>, <BINARY_DIR>, <INSTALL_DIR>, <TMP_DIR>, <DOWNLOAD_DIR> and <DOWNLOADED_FILE> with their corresponding property values defined in the original call to ExternalProject_Add().
Added in version 3.3: token replacement is extended to byproducts. ๐ฆ
Added in version 3.11: the <DOWNLOAD_DIR> substitution token.
๐ง ExternalProject_Add_StepTargets ๐ง
The ExternalProject_Add_StepTargets() function generates targets for the steps listed. The name of each created target will be of the form <name>-<step>:
ExternalProject_Add_StepTargets(<name> <step1> [<step2>...])
Creating a target for a step allows it to be used as a dependency of another target, or to be triggered manually. Having targets for specific steps also allows them to be driven independently of each other by specifying targets on build command lines. For example, you may be submitting to a sub-project based dashboard where you want to drive the configure portion of the build, then submit to the dashboard, followed by the build portion, followed by tests. And bestie, if you invoke a custom target that depends on a step halfway through the step dependency chain, then all the previous steps will also run to ensure everything is up to date. Chain reaction, but make it productive. ๐ซ
Internally, ExternalProject_Add() calls ExternalProject_Add_Step() to create each step. If any STEP_TARGETS were specified, then ExternalProject_Add_StepTargets() will also be called after ExternalProject_Add_Step(). Even if a step is not mentioned in the STEP_TARGETS option, ExternalProject_Add_StepTargets() can still be called later to manually define a target for the step. So like, it's never too late. ๐
The STEP_TARGETS option for ExternalProject_Add() is generally the easiest way to ensure targets are created for specific steps of interest. For custom steps, ExternalProject_Add_StepTargets() must be called explicitly if a target should also be created for that custom step. An alternative to these two options is to populate the EP_STEP_TARGETS directory property. It acts as a default for the step target options and can save having to repeatedly specify the same set of step targets when multiple external projects are being defined. Efficiency slay. โญ
Added in version 3.19: if CMP0114 is set to NEW, step targets are fully responsible for holding the custom commands implementing their steps. The primary target created by ExternalProject_Add depends on the step targets, and the step targets depend on each other. The target-level dependencies match the file-level dependencies used by the custom commands for each step. The targets for steps created with ExternalProject_Add_Step()'s INDEPENDENT option do not depend on the external targets specified by ExternalProject_Add()'s DEPENDS option. The predefined steps mkdir, download, update, and patch are independent. ๐
If CMP0114 is not NEW, the following deprecated behavior is available: ๐
- A deprecated
NO_DEPENDSoption can go right after the<name>and before the first step. If you slapNO_DEPENDSon there, the step target will not depend on the dependencies of the external project (like, it won't depend on any dependencies of the<name>custom target thatExternalProject_Add()made). This is usually safe for the download, update and patch steps, since those don't typically need the deps to be updated and built. But usingNO_DEPENDSfor any of the other pre-defined steps? Yeah, that may break parallel builds ๐ฌ. Only useNO_DEPENDSwhere you're certain the named steps genuinely don't have dependencies. And for custom steps, think about whether the custom commands actually need the dependencies configured, built and installed. - The
INDEPENDENT_STEP_TARGETSoption forExternalProject_Add(), or theEP_INDEPENDENT_STEP_TARGETSdirectory property, tells the function to callExternalProject_Add_StepTargets()internally using theNO_DEPENDSoption for the steps you listed.
ExternalProject_Add_StepDependencies
Added in version 3.2.
The ExternalProject_Add_StepDependencies() function is your go-to for adding dependencies to a step. The deps you add have to be targets CMake already knows about (ordinary executable or library targets, custom targets, or even step targets of another external project โ all valid bestie ๐
):
ExternalProject_Add_StepDependencies(<name> <step> <target1> [<target2>...])
This function is careful and sets both target and file level dependencies, and it makes sure parallel builds won't break. Use it instead of add_dependencies() whenever you're adding a dependency for any of the step targets generated by the ExternalProject module. It's the icon behavior, fr fr ๐
Examples
Okay so the following example shows how to download and build a hypothetical project called FooBar from github:
include(ExternalProject)
ExternalProject_Add(foobar
GIT_REPOSITORY git@github.com:FooCo/FooBar.git
GIT_TAG origin/release/1.2.3
)
For the sake of the example, we also define a second hypothetical external project called SecretSauce, downloaded from a web server. Two URLs are given so it can take advantage of a faster internal network if available, with a fallback to a slower external server. The project is a typical Makefile project with no configure step, so some of the default commands are overridden. The build only needs to build the sauce target:
find_program(MAKE_EXE NAMES gmake nmake make)
ExternalProject_Add(secretsauce
URL http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
https://www.somecompany.com/downloads/sauce-2.7.zip
URL_HASH MD5=d41d8cd98f00b204e9800998ecf8427e
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_EXE} sauce
)
Suppose the build step of secretsauce requires that foobar must already be built. You can enforce that like this:
ExternalProject_Add_StepDependencies(secretsauce build foobar)
Another alternative would be to create a custom target for foobar's build step and make secretsauce depend on that rather than the whole foobar project. That means foobar only needs to be built โ it doesn't need to run its install or test steps before secretsauce can be built. The dependency can also be defined along with the secretsauce project:
ExternalProject_Add_StepTargets(foobar build)
ExternalProject_Add(secretsauce
URL http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
https://www.somecompany.com/downloads/sauce-2.7.zip
URL_HASH MD5=d41d8cd98f00b204e9800998ecf8427e
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_EXE} sauce
DEPENDS foobar-build
)
Instead of calling ExternalProject_Add_StepTargets(), the target could be defined along with the foobar project itself:
ExternalProject_Add(foobar
GIT_REPOSITORY git@github.com:FooCo/FooBar.git
GIT_TAG origin/release/1.2.3
STEP_TARGETS build
)
If lots of external projects should have the same set of step targets, setting a directory property may be more convenient. The build step target could be created automatically by setting the EP_STEP_TARGETS directory property before creating the external projects with ExternalProject_Add():
set_property(DIRECTORY PROPERTY EP_STEP_TARGETS build)
Lastly, suppose secretsauce provides a script called makedoc that can generate its own documentation. Further suppose the script expects the output directory to be provided as the only parameter, and that it should be run from the secretsauce source directory. A custom step and a custom target to trigger the script can be defined like so:
ExternalProject_Add_Step(secretsauce docs
COMMAND <SOURCE_DIR>/makedoc <BINARY_DIR>
WORKING_DIRECTORY <SOURCE_DIR>
COMMENT "Building secretsauce docs"
ALWAYS TRUE
EXCLUDE_FROM_MAIN TRUE
)
ExternalProject_Add_StepTargets(secretsauce docs)
The custom step could then be triggered from the main build like so:
cmake --build . --target secretsauce-docs
FeatureSummary
This module hands you commands for generating a summary of enabled/disabled features. So slay โจ
Load this module in CMake with:
include(FeatureSummary)
Commands provided by this module can be used to generate a summary of enabled and disabled packages and/or features for a build tree, like this gorgeousness:
-- The following features have been enabled:
* Example, usage example
-- The following OPTIONAL packages have been found:
* LibXml2 (required version >= 2.4), XML library, <http://xmlsoft.org>
Enables HTML-import in MyWordProcessor
Enables odt-export in MyWordProcessor
* PNG, image library, <http://www.libpng.org/pub/png/>
Enables saving screenshots
-- The following OPTIONAL packages have not been found:
* Lua, the Lua scripting language, <https://www.lua.org>
Enables macros in MyWordProcessor
* OpenGL, Open Graphics Library
Global Properties
The following global properties are used by this module:
FeatureSummary_PKG_TYPES
Added in version 3.8.
This global property defines a semicolon-separated list of package types used by the FeatureSummary module.
The order in this list is important โ the first package type in the list has the lowest importance, while the last has the highest importance. A package's type can only be changed to a type with higher importance.
The default package types are RUNTIME, OPTIONAL, RECOMMENDED and REQUIRED, with their importance ranked as RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED.
FeatureSummary_REQUIRED_PKG_TYPES
Added in version 3.8.
This global property defines a semicolon-separated list of package types that are considered required.
If one or more packages in these categories are not found, CMake will abort when the feature_summary() command is called with the FATAL_ON_MISSING_REQUIRED_PACKAGES option enabled. No pressure though ๐
The default value for this global property is REQUIRED.
FeatureSummary_DEFAULT_PKG_TYPE
Added in version 3.8.
This global property defines the default package type.
When the feature_summary() command is called, and the user has not explicitly set a type for some package, its type will be set to the value of this property.
This value must be one of the types defined in the FeatureSummary_PKG_TYPES global property.
The default value for this global property is OPTIONAL.
FeatureSummary_<TYPE>_DESCRIPTION
Added in version 3.9.
This global property can be defined for each package <TYPE> to a string that will be used in the output titles of the feature_summary() command. For example:
The following <FeatureSummary_<TYPE>_DESCRIPTION> have been found:
If it's not set, the default string <TYPE> packages is used.
Commands
This module provides the following commands:
feature_summary()set_package_properties()add_feature_info()
Printing Feature Summary
feature_summary
Prints information about enabled or disabled packages and features of a project:
feature_summary(
WHAT (ALL
| PACKAGES_FOUND | PACKAGES_NOT_FOUND
| <TYPE>_PACKAGES_FOUND | <TYPE>_PACKAGES_NOT_FOUND
| ENABLED_FEATURES | DISABLED_FEATURES)
[FILENAME <file>]
[APPEND]
[VAR <variable-name>]
[INCLUDE_QUIET_PACKAGES]
[FATAL_ON_MISSING_REQUIRED_PACKAGES]
[DESCRIPTION <description> | DEFAULT_DESCRIPTION]
[QUIET_ON_EMPTY]
)
This command is literally made for printing info about enabled or disabled packages and features of a project. By default, only the names of the features/packages get printed โ plus their required version when one was specified. Use set_package_properties() to add more useful info, like a homepage URL for the respective package or its purpose in the project. So much more chic ๐
The arguments are:
WHAT โ This is the only mandatory option. It specifies what information will be printed:
ALLโ Print everything. The whole vibe check.ENABLED_FEATURESโ The list of all features which are enabled.DISABLED_FEATURESโ The list of all features which are disabled.PACKAGES_FOUNDโ The list of all packages which have been found.PACKAGES_NOT_FOUNDโ The list of all packages which have not been found. (sad girl hours ๐ญ)
For each package type <TYPE> defined by the FeatureSummary_PKG_TYPES global property, the following information can also be used:
<TYPE>_PACKAGES_FOUNDโ The list of only packages of type<TYPE>which have been found.<TYPE>_PACKAGES_NOT_FOUNDโ the list of only packages of type<TYPE>that did not get found. Just the missing ones, no cap ๐
Changed in version 3.1: theWHAToption is now a multi-value keyword, so you can actually combine these values (everything except theALLvalue) to customize the output however you want. Obsessed. For example:
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
FILENAME <file>โ if you pass this, the info gets printed into this file instead of the terminal ๐ a relative<file>path is interpreted as being relative to the current source directory (i.e.CMAKE_CURRENT_SOURCE_DIR).APPENDโ if you pass this, the output gets appended to the<file>you gave theFILENAMEoption. Otherwise the file just gets overwritten if it already exists ๐ญ (rip your old logs).VAR <variable-name>โ if you pass this, the info gets stored into the specified variable<variable-name>instead of the terminal ๐ซถINCLUDE_QUIET_PACKAGESโ if you pass this, packages that were searched withfind_package(... QUIET)will also show up in the list. By default they get skipped, lowkey ghosted ๐ปFATAL_ON_MISSING_REQUIRED_PACKAGESโ if you pass this, CMake straight-up aborts with a fatal error when a package marked as one of the package types listed in theFeatureSummary_REQUIRED_PKG_TYPESglobal property has not been found ๐ like it's not playing around.DESCRIPTION <description>โ a description or headline that gets printed above the actual content โจ without this option, if you only requested one package type, no title is printed โ unless a custom string is explicitly set using this option, or theDEFAULT_DESCRIPTIONoption is used, which outputs a default title for the requested type.DEFAULT_DESCRIPTIONโ Added in version 3.9. The default description/headline printed above the content, as opposed to the customizableDESCRIPTION <description>๐ธQUIET_ON_EMPTYโ Added in version 3.8. If you pass this, then when only one package type was requested and no packages belonging to that category were found, no output at all gets printed (including theDESCRIPTION), and nothing gets added to theFILENAMEor theVARvariable ๐ silent treatment, deserved.
๐ Package Properties
set_package_properties
Sets package properties:
set_package_properties(
<PackageName>
PROPERTIES
[URL <url>]
[DESCRIPTION <description>]
[TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED)]
[PURPOSE <purpose>]
)
Use this command to configure and provide info about the package named <PackageName>, which can then be displayed using the feature_summary() command ๐ฆ you can call it either directly inside the corresponding Find module or in the project that uses the module, after invoking the find_package() call. The features you can set info for are determined automatically after the find_package() command. Main character energy, honestly.
The arguments are:
<PackageName>โ the name of the package. For example, as specified in thefind_package(<PackageName>)argument.PROPERTIESโ specifies the properties to set:URL <url>โ this should be the homepage of the package, or something similar ๐ ideally this is set already directly in the Find module.DESCRIPTION <description>โ a short description of what that package is, at most one sentence ๐ ideally this is set already directly in the Find module.TYPE <type>โ what type of dependency the using project has on that package.
Default <type> is OPTIONAL. In this case it's a package that can be used by the project when it's available at buildtime, but the project also works without it ๐
The RECOMMENDED package type is similar to OPTIONAL, i.e. the project will build if the package isn't present, but the functionality of the resulting binaries will be severely limited ๐ญ if a REQUIRED package isn't available at buildtime, the project may not even build. This can be combined with the feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES) command option.
Last but not least, a RUNTIME package is a package that's actually not used at all during the build, but which is required for actually running the resulting binaries ๐โโ๏ธ so if such a package is missing, the project can still be built, but it may not work later on. Not me finding out at runtime ๐
If set_package_properties() is called multiple times for the same package with different TYPEs, the TYPE is only changed to higher TYPEs (RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED), and lower TYPEs are ignored ๐ซถ the TYPE property is project-specific, so it can't be set by the Find module โ it must be set in the project.
The accepted types can be changed by setting the FeatureSummary_PKG_TYPES global property โจ
PURPOSE <purpose>โ this describes which features this package enables in the project, i.e. it tells the user what functionality they get in the resulting binaries ๐ ifset_package_properties()is called multiple times for a package, allPURPOSEproperties get appended to a list of purposes of the package in the project. Same as theTYPEproperty, thePURPOSEproperty is also project-specific, so it can't be set by the Find module โ it must be set in the project.
๐ Adding Feature Info
add_feature_info
Adds feature information:
add_feature_info(<name> <condition> <description>)
Use this command to add info about a feature identified with a given <name> โญ
The arguments are:
<name>โ identification name for a feature being added.<condition>โ specifies the conditions that determine whether this feature is enabled or disabled. The<condition>argument can be:- A single condition (such as a variable name).
- Added in version 3.8: a semicolon-separated list of multiple conditions ๐
- Added in version 4.0: a full Condition Syntax as used in an
if(<condition>)clause. See policyCMP0183. This enables using the entire condition syntax (such as grouping conditions with parens and similar) ๐ฅ
<description>โ a text describing the feature. This info can be displayed usingfeature_summary()forENABLED_FEATURESandDISABLED_FEATURESrespectively.
๐ Deprecated Commands
The following legacy and deprecated commands are provided for backward compatibility with previous CMake versions โ they're giving "still here for the plot", ngl:
set_package_info
Deprecated since version 3.8: use theset_package_properties()andadd_feature_info()commands instead ๐
Sets up information about the specified package, which can then be displayed via feature_summary():
set_package_info(<PackageName> <description> [<url> [<purpose>]])
<PackageName>โ name of the package.<description>โ a short description of the package.<url>โ homepage of the package.<purpose>โ the purpose of the package.
This command can be used either directly in the Find module or in the project which uses the FeatureSummary module, after the find_package() call. The features for which info can be set are added automatically by the find_package() command โจ
set_feature_info
Deprecated since version 3.8.
Sets feature info for a package:
set_feature_info(<name> <description> [<url>])
Does the same as:
set_package_info(<name> <description> [<url>])
print_enabled_features
Deprecated since version 3.8.
Prints enabled features:
print_enabled_features()
Does the same as:
feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
print_disabled_features
Deprecated since version 3.8.
Prints disabled features:
print_disabled_features()
Does the same as:
feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
๐ธ Examples
๐ Example: Appending Feature Summary to a File
In the following example, the feature summary output will be appended to a specified file instead of printing ๐
include(FeatureSummary)
feature_summary(WHAT ALL FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
๐ฆ Example: Storing Feature Summary in a Variable
In the following example, the feature summary of enabled features is stored in a specified variable enabledFeaturesText, including the QUIET packages ๐
include(FeatureSummary)
feature_summary(
WHAT ENABLED_FEATURES
INCLUDE_QUIET_PACKAGES
DESCRIPTION "Enabled Features:"
VAR enabledFeaturesText
)
okay bestie, last line of that loop, then we move on:
message(STATUS "${enabledFeaturesText}")
๐ Example: Adding a Custom Package Type
So this next example adds a custom package type and prints only the categories that are not empty. Obsessed with a tidy summary, honestly:
include(FeatureSummary)
set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD)
find_package(FOO)
set_package_properties(FOO PROPERTIES TYPE BUILD)
feature_summary(
WHAT BUILD_PACKAGES_FOUND
DESCRIPTION "Build tools found:"
QUIET_ON_EMPTY
)
feature_summary(
WHAT BUILD_PACKAGES_NOT_FOUND
DESCRIPTION "Build tools not found:"
QUIET_ON_EMPTY
)
๐ธ Example: Setting Package Info
Here's how you set the info for a package. It's giving โgive the summary actual contextโ:
include(FeatureSummary)
find_package(LibXml2)
set_package_properties(
LibXml2
PROPERTIES
DESCRIPTION "XML library"
URL "http://xmlsoft.org"
)
# or
set_package_properties(
LibXml2
PROPERTIES
TYPE RECOMMENDED
PURPOSE "Enables HTML-import in MyWordProcessor"
)
# or
set_package_properties(
LibXml2
PROPERTIES
TYPE OPTIONAL
PURPOSE "Enables odt-export in MyWordProcessor"
)
find_package(DBUS)
set_package_properties(
DBUS
PROPERTIES
TYPE RUNTIME
PURPOSE "Necessary to disable the screensaver during a presentation"
)
โจ Example: Printing Feature Summary
In this one, the module outputs the feature summary at the end of the configuration. And if any required package is not found, processing stops with an error message at the end of the configuration phase. No quiet missing-required erasure, periodt.
cmake_minimum_required(VERSION 3.15)
project(Example)
add_library(example example.c)
include(FeatureSummary)
find_package(CURL)
set_package_properties(CURL PROPERTIES TYPE REQUIRED)
target_link_libraries(example PRIVATE CURL::libcurl)
find_package(LibXml2 QUIET)
set_package_properties(LibXml2 PROPERTIES TYPE RECOMMENDED)
if(LibXml2_FOUND)
target_link_libraries(example PRIVATE LibXml2::LibXml2)
endif()
feature_summary(
WHAT ALL
INCLUDE_QUIET_PACKAGES
DESCRIPTION "Feature summary:"
FATAL_ON_MISSING_REQUIRED_PACKAGES
)
๐ฆ Examples: Setting Feature Info
Example for setting the info for a feature:
include(FeatureSummary)
option(WITH_FOO "Help for foo" ON)
add_feature_info(Foo WITH_FOO "this feature provides very cool stuff")
Example for setting feature info based on a list of conditions:
include(FeatureSummary)
option(WITH_FOO "Help for foo" ON)
option(WITH_BAR "Help for bar" OFF)
add_feature_info(
FooBar
"WITH_FOO;NOT WITH_BAR"
"this feature is enabled when WITH_FOO is ON and WITH_BAR turned OFF"
)
In the next example, feature info is set depending on a full condition syntax. Unlike a semicolon-separated list of conditions, this lets you use the entire condition syntax as the if clause argument:
include(FeatureSummary)
option(WITH_FOO "Help for foo" ON)
option(WITH_BAR "Help for bar" ON)
option(WITH_BAZ "Help for baz" OFF)
add_feature_info(
FooBarBaz
"WITH_FOO AND (WITH_BAR OR WITH_BAZ)"
"this feature is enabled when the entire condition is true"
)
๐ง FetchContent
Added in version 3.11.
This module gives you commands to populate content at configure time or as part of the calling script.
Load this module in CMake with:
include(FetchContent)
Note: The Using Dependencies Guide gives a high-level intro to this whole topic. It gives a broader overview of where the FetchContent module fits into the bigger picture, including its relationship to the find_package() command. The guide is recommended pre-reading before moving on to the details below.
Overview
This module enables populating content at configure time via any method supported by the ExternalProject module. Meanwhile ExternalProject_Add() downloads at build time, but FetchContent makes content available immediately, so the configure step can use the content in commands like add_subdirectory(), include(), or file() operations. It's giving configure-time bestie behavior, not build-time waiting.
Content population details should be defined separately from the command that performs the actual population. This separation ensures all the dependency details are defined before anything might try to use them to populate content. That's particularly important in more complex project hierarchies where dependencies may be shared between multiple projects.
A typical example declares content details for some dependencies and then ensures they're populated with a separate call:
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)
FetchContent_Declare(
myCompanyIcons
URL https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
)
FetchContent_MakeAvailable(googletest myCompanyIcons)
FetchContent_MakeAvailable() ensures the named dependencies have been populated, either by an earlier call or by populating them itself. When it performs the population, it will also add them to the main build, if possible, so the main build can use the populated projects' targets, etc. See the command's documentation for how these steps are performed.
With hierarchical project arrangement, projects at higher levels in the hierarchy are able to override the declared details of content specified anywhere lower in the project hierarchy. The first details declared for a given dependency take precedence, regardless of where in the project hierarchy that occurs. Similarly, the first call that tries to populate a dependency "wins", with subsequent populations reusing the result of the first instead of repeating the population again. See the Examples which demonstrate this scenario.
The FetchContent module also supports defining and populating content in a single call, with no check for whether the content has been populated elsewhere already. This should not be done in projects, but may be appropriate for populating content in CMake script mode. See FetchContent_Populate() for details.
Commands
FetchContent_Declare
FetchContent_Declare(
<name>
<contentOptions>...
[EXCLUDE_FROM_ALL]
[SYSTEM]
[OVERRIDE_FIND_PACKAGE |
FIND_PACKAGE_ARGS args...]
)
The FetchContent_Declare() function records the options that describe how to populate the specified content. If such details have already been recorded earlier in this project (regardless of where in the project hierarchy), this and all later calls for the same content <name> are ignored. This "first to record, wins" approach is what allows hierarchical projects to have parent projects override content details of child projects.
The content <name> can be any string without spaces, but good practice would be to use only letters, numbers, and underscores. The name will be treated case-insensitively, and it should be obvious for the content it represents. It is often the name of the child project, or the value given to its top level project() command (if it is a CMake project). For well-known public projects, the name should generally be the official name of the project. Choosing an unusual name makes it unlikely that other projects needing that same content will use the same name, leading to the content being populated multiple times.
The <contentOptions> can be any of the download, update, or patch options that the ExternalProject_Add() command understands. The configure, build, install, and test steps are explicitly disabled, so options related to those steps are prohibited and will be discarded if given. The SOURCE_SUBDIR option is an exception, see FetchContent_MakeAvailable() for details on how that affects behavior.
Changed in version 3.30: When policy CMP0168 is set to NEW, some output-related and directory-related options are ignored. See the policy documentation for details.
In most cases, <contentOptions> will just be a couple of options defining the download method and method-specific details like a commit tag or archive hash. For example:
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)
FetchContent_Declare(
myCompanyIcons
URL https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
)
FetchContent_Declare(
myCompanyCertificates
SVN_REPOSITORY svn+ssh://svn.mycompany.com/srv/svn/trunk/certs
SVN_REVISION -r12345
)
Where contents are being fetched from a remote location and you do not control that server, it is advisable to use a hash for GIT_TAG rather than a branch or tag name. A commit hash is more secure and helps to confirm that the downloaded contents are what you expected.
Changed in version 3.14: Commands for the download, update, or patch steps can access the terminal. This may be needed for things like password prompts or real-time display of command progress.
Added in version 3.22: the CMAKE_TLS_VERIFY, CMAKE_TLS_CAINFO, CMAKE_NETRC, and CMAKE_NETRC_FILE variables now hand out the defaults for their matching content options โ literally the exact same way they already do it for ExternalProject_Add(). ๐ Before this glow-up, FetchContent straight up ignored those variables. Not seen, not invited. ๐
Added in version 3.24:
๐ FIND_PACKAGE_ARGS
Okay so this one is for those scenarios where FetchContent_MakeAvailable() might first try a call to find_package() to satisfy the dependency for <name>. Bestie, by default that call is just plain find_package(<name>) โ no extras, no frills. But FIND_PACKAGE_ARGS lets you slide in extra arguments that get appended after the <name>. โจ
You can also write FIND_PACKAGE_ARGS with literally nothing after it, and that means find_package() can still be called if FETCHCONTENT_TRY_FIND_PACKAGE_MODE is set to OPT_IN, or isn't set at all. ๐ซถ
โ ๏ธ It would not normally be appropriate to specifyREQUIREDas one of the extra arguments afterFIND_PACKAGE_ARGS. Why? Because that would mean thefind_package()call must succeed โ so none of the other details you specified in theFetchContent_Declare()call would ever get a chance to be used as a fall-back. No plan B. No safety net. ๐ญ
Everything after the FIND_PACKAGE_ARGS keyword gets appended to the find_package() call, so all the other <contentOptions> have to come before the FIND_PACKAGE_ARGS keyword. Order matters, queen. ๐
If the CMAKE_FIND_PACKAGE_TARGETS_GLOBAL variable is set to true at the time FetchContent_Declare() is called, a GLOBAL keyword will be appended to the find_package() arguments โ unless it was already specified. It'll also get appended if FIND_PACKAGE_ARGS wasn't given, but FETCHCONTENT_TRY_FIND_PACKAGE_MODE was set to ALWAYS. ๐
OVERRIDE_FIND_PACKAGE cannot be used when FIND_PACKAGE_ARGS is given. Pick a lane, babe. ๐
Dependency Providers discusses another way that FetchContent_MakeAvailable() calls can get redirected. But like โ FIND_PACKAGE_ARGS is for project control, whereas dependency providers let users override project behavior. Different vibes, different lanes. ๐ฆ
๐ OVERRIDE_FIND_PACKAGE
When a FetchContent_Declare(<name> ...) call includes this option, subsequent calls to find_package(<name> ...) will make sure that FetchContent_MakeAvailable(<name>) has been called first, and then use the config package files chilling in the CMAKE_FIND_PACKAGE_REDIRECTS_DIR directory (which are usually created by FetchContent_MakeAvailable()). โจ
So basically this makes FetchContent_MakeAvailable() override find_package() for that named dependency, letting the former satisfy the package requirements of the latter. It's giving "I got you, bestie." ๐ซถ
FIND_PACKAGE_ARGS cannot be used when OVERRIDE_FIND_PACKAGE is given. Mutual exclusivity, periodt. ๐
If a dependency provider has been set and the project callsfind_package()for the<name>dependency,OVERRIDE_FIND_PACKAGEwill not stop the provider from seeing that call. Dependency providers always get the chance to intercept any direct call tofind_package()โ except if that call contains theBYPASS_PROVIDERoption. ๐
Added in version 3.25:
๐ง SYSTEM
If the SYSTEM argument is provided, the SYSTEM directory property of a subdirectory added by FetchContent_MakeAvailable() will be set to true. That affects the non-imported targets created as part of that command. See the SYSTEM target property documentation for a much more detailed discussion of the effects. ๐
Added in version 3.28:
๐ซ EXCLUDE_FROM_ALL
If the EXCLUDE_FROM_ALL argument is provided, then targets in the subdirectory added by FetchContent_MakeAvailable() will not be included in the ALL target by default โ and they may be excluded from IDE project files too. See the docs for the directory property EXCLUDE_FROM_ALL for a detailed discussion of the effects. ๐ธ
๐ FetchContent_MakeAvailable
Added in version 3.14.
FetchContent_MakeAvailable(<name1> [<name2>...])
This command makes sure that each of the named dependencies are made available to the project by the time it returns. โญ
There must have been a call to FetchContent_Declare() for each dependency, and the first such call controls how that dependency gets made available, as described below. First one wins, no cap. ๐
If FETCHCONTENT_SOURCE_DIR_<uppercaseName> is not set:
- Added in version 3.24: If a dependency provider is set, call the provider's command with
FETCHCONTENT_MAKEAVAILABLE_SERIALas the first argument, followed by the arguments of the first call toFetchContent_Declare()for<name>. IfSOURCE_DIRorBINARY_DIRweren't part of the original declared arguments, they'll be added with their default values. IfFETCHCONTENT_TRY_FIND_PACKAGE_MODEwas set toNEVERwhen the details were declared, anyFIND_PACKAGE_ARGSwill be omitted. TheOVERRIDE_FIND_PACKAGEkeyword is also always omitted. If the provider fulfilled the request,FetchContent_MakeAvailable()considers that dependency handled, skips the remaining steps below, and moves on to the next dependency in the list. ๐โโ๏ธ๐จ - Added in version 3.24: If permitted,
find_package(<name> [<args>...])will be called, where<args>...may be provided by theFIND_PACKAGE_ARGSoption inFetchContent_Declare(). The value of theFETCHCONTENT_TRY_FIND_PACKAGE_MODEvariable at the timeFetchContent_Declare()was called is what determines whetherFetchContent_MakeAvailable()can callfind_package(). And if theCMAKE_FIND_PACKAGE_TARGETS_GLOBALvariable is set to true whenFetchContent_MakeAvailable()is called, it still affects any imported targets created when that in turn callsfind_package()โ even if that variable was false when the corresponding details were declared. Sneaky but factual. ๐ฅ
If the dependency wasn't satisfied by a provider or a find_package() call, FetchContent_MakeAvailable() then uses the following logic to make the dependency available:
- If the dependency has already been populated earlier in this run, set the
<lowercaseName>_POPULATED,<lowercaseName>_SOURCE_DIR, and<lowercaseName>_BINARY_DIRvariables in the same way as a call toFetchContent_GetProperties(), then skip the remaining steps below and move on to the next dependency in the list. Already handled, bestie. ๐ - Populate the dependency using the details recorded by an earlier call to
FetchContent_Declare(). Halt with a fatal error if no such details have been recorded. ๐FETCHCONTENT_SOURCE_DIR_<uppercaseName>can be used to override the declared details and use content provided at the specified location instead. ๐ฆ - Added in version 3.24: make sure the
CMAKE_FIND_PACKAGE_REDIRECTS_DIRdirectory actually contains a<lowercaseName>-config.cmakeand a<lowercaseName>-config-version.cmakefile (or, same energy,<name>Config.cmakeand<name>ConfigVersion.cmake). Heads up: that directory gets cleared at the start of every CMake run, so it's a fresh slate every time. If there's still no config file after the dependency got populated in the previous step, CMake writes a minimal one for you thatincludes any<lowercaseName>-extra.cmakeor<name>Extra.cmakefile with theOPTIONALflag โ so the files can literally be missing and you won't get a warning ๐ . Same deal for the version file: if none exists, a very simple one gets written that setsPACKAGE_VERSION_COMPATIBLEandPACKAGE_VERSION_EXACTto true. This is what makes all futurefind_package()calls for that dependency use the redirected config file, no matter what version requirements they ask for. Real talk though: CMake can't automatically figure out an arbitrary dependency's version, so it cannot setPACKAGE_VERSION. When the dependency gets pulled in viaadd_subdirectory()in the next step, it may choose to overwrite the generated config version file inCMAKE_FIND_PACKAGE_REDIRECTS_DIRwith one that does setPACKAGE_VERSION. The dependency can also write a<lowercaseName>-extra.cmakeor<name>Extra.cmakefile to do custom processing, or to define any variables that their normal (installed) package config file would otherwise usually define โ and ngl, many projects don't do any custom processing or set any variables, so they simply have no need to do this. If it's required, the main project can write these files instead when the dependency project doesn't. That's the whole slay: it lets the main project fill in missing details from older dependencies that haven't โ or can't โ be updated to support this functionality. See Integrating With find_package() for examples ๐ฆ. - If the top directory of the populated content contains a
CMakeLists.txtfile, CMake callsadd_subdirectory()to add it to the main build. And it is not an error for there to be noCMakeLists.txtfile โ that's lowkey the point, because it lets you use the command for dependencies that make downloaded content available at a known location, but which don't need or support being added directly to the build โจ.- Added in version 3.18: the
SOURCE_SUBDIRoption can be given in the declared details to look somewhere below the top directory instead (i.e. the same way thatSOURCE_SUBDIRis used by theExternalProject_Add()command). The path you hand toSOURCE_SUBDIRmust be relative, and it will be treated as relative to the top directory. It can also point to a directory that doesn't contain aCMakeLists.txtfile, or even to a directory that doesn't exist at all ๐. Useful trick: this lets you avoid adding a project that contains aCMakeLists.txtfile in its top directory. - Added in version 3.25: if the
SYSTEMkeyword was included in the call toFetchContent_Declare(), theSYSTEMkeyword will be added to theadd_subdirectory()command. - Added in version 3.28: if the
EXCLUDE_FROM_ALLkeyword was included in the call toFetchContent_Declare(), theEXCLUDE_FROM_ALLkeyword will be added to theadd_subdirectory()command. - Added in version 3.29:
CMAKE_EXPORT_FIND_PACKAGE_NAMEis set to the dependency name before callingadd_subdirectory().
- Added in version 3.18: the
Okay so here's the vibe check projects should live by: aim to declare the details of all dependencies you might use before you call FetchContent_MakeAvailable() for any of them. Why? Because if any of the dependencies are also sub-dependencies of one or more of the others, the main project still controls the details that get used โ since it declares them first, before the dependencies even get a chance ๐ซถ. In the following code samples, assume that the uses_other dependency also uses FetchContent to add the other dependency internally:
# WRONG: Should declare all details first
FetchContent_Declare(uses_other ...)
FetchContent_MakeAvailable(uses_other)
FetchContent_Declare(other ...) # Will be ignored, uses_other beat us to it
FetchContent_MakeAvailable(other) # Would use details declared by uses_other
# CORRECT: All details declared first, so they will take priority
FetchContent_Declare(uses_other ...)
FetchContent_Declare(other ...)
FetchContent_MakeAvailable(uses_other other)
Also note that CMAKE_VERIFY_INTERFACE_HEADER_SETS and CMAKE_VERIFY_PRIVATE_HEADER_SETS are explicitly set to false upon entry to FetchContent_MakeAvailable(), and are restored to their original values before the command returns ๐. Why? Because developers typically only want to verify header sets from the main project, not those from any dependencies โ this local manipulation of the CMAKE_VERIFY_INTERFACE_HEADER_SETS and CMAKE_VERIFY_PRIVATE_HEADER_SETS variables is what gives you that intuitive behavior. Want verification back on for all or some dependencies? Use variables like CMAKE_PROJECT_INCLUDE or CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE. You can also just set the VERIFY_INTERFACE_HEADER_SETS and VERIFY_PRIVATE_HEADER_SETS properties of individual targets. Options galore, icon behavior ๐.
๐ง FetchContent_Populate
So FetchContent_Populate() is a self-contained call that does content population as a totally isolated operation. Fr fr, it is rarely the right command to use โ projects should almost always reach for FetchContent_Declare() and FetchContent_MakeAvailable() instead ๐ญ. The main use case for FetchContent_Populate() is in CMake script mode <#script-processing-mode> as part of implementing some other higher level custom feature.
FetchContent_Populate(
<name>
[QUIET]
[SUBBUILD_DIR <subBuildDir>]
[SOURCE_DIR <srcDir>]
[BINARY_DIR <binDir>]
...
)
At least one option must be specified after <name>, otherwise the call gets interpreted differently (see below) ๐. The supported options for FetchContent_Populate() are the same as those for FetchContent_Declare(), with a few exceptions. These ones do not relate to populating content with FetchContent_Populate() and therefore are not supported:
EXCLUDE_FROM_ALLSYSTEMOVERRIDE_FIND_PACKAGEFIND_PACKAGE_ARGS
The few options shown in the signature above are either specific to FetchContent_Populate(), or their behavior is slightly modified from how ExternalProject_Add() treats them:
QUIET โ you can give the QUIET option to hide the output associated with populating the specified content ๐คซ. But if the population fails, the output will be shown regardless of whether you gave this option or not, so the cause of the failure can actually be diagnosed. Also: the FETCHCONTENT_QUIET variable has no effect on FetchContent_Populate() calls of this form, the ones where the content details are provided directly.
Changed in version 3.30: theQUIEToption and theFETCHCONTENT_QUIETvariable have no effect when policyCMP0168is set toNEW. The output is still quiet by default in that case, but verbosity is controlled by the message logging level (seeCMAKE_MESSAGE_LOG_LEVELand--log-level) ๐ .
SUBBUILD_DIR โ you can provide the SUBBUILD_DIR argument to change the location of the sub-build created to perform the population. The default value is ${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-subbuild, and honestly it would be unusual to need to override this default. If you specify a relative path, it'll be interpreted as relative to CMAKE_CURRENT_BINARY_DIR. And don't confuse this option with the SOURCE_SUBDIR option โ that one only affects the FetchContent_MakeAvailable() command ๐.
Changed in version 3.30:SUBBUILD_DIRis ignored when policyCMP0168is set toNEW, since there is no sub-build in that case.
SOURCE_DIR, BINARY_DIR โ the SOURCE_DIR and BINARY_DIR arguments are supported by ExternalProject_Add(), but FetchContent_Populate() uses different default values. SOURCE_DIR defaults to ${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-src, and BINARY_DIR defaults to ${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-build. If you specify a relative path, it'll be interpreted as relative to CMAKE_CURRENT_BINARY_DIR. Defaults set, paths handled, no cap ๐.
Okay so real talk: anything you pass that isn't one of the explicit options above gets yeeted straight through to ExternalProject_Add() <#command:externalproject_add>, unmodified, so it can set up the download, patch, and update steps. But a few options are explicitly prohibited โ the FetchContent_Populate() command literally disables them:
CONFIGURE_COMMANDBUILD_COMMANDINSTALL_COMMANDTEST_COMMAND
When you use this form, FETCHCONTENT_FULLY_DISCONNECTED and FETCHCONTENT_UPDATES_DISCONNECTED and policy CMP0170 <#policy:CMP0170> are all just... ignored. not them being ghosted, it's just not their moment ๐
When this form of FetchContent_Populate() returns, it's gonna set these variables in the scope of whoever called it:
<lowercaseName>_SOURCE_DIRโ the location where the populated content can be found upon return. this is the one you actually want โจ<lowercaseName>_BINARY_DIRโ a directory that was originally intended for use as a corresponding build directory, but is unlikely to be relevant when you're using this form of the command. it's giving "invited but not needed" ๐ซถ
If you're using FetchContent_Populate() inside CMake script mode <#script-processing-mode>, heads up bestie: the implementation sets up a sub-build, which therefore requires a CMake generator and build tool to be available. If those can't be found by default, then the CMAKE_GENERATOR <#variable:CMAKE_GENERATOR> and potentially the CMAKE_MAKE_PROGRAM <#variable:CMAKE_MAKE_PROGRAM> variables will need to be set appropriately on the command line invoking the script. like, you gotta hand it the tools, it can't just manifest them ๐ญ
Changed in version 3.30: If policyCMP0168<#policy:CMP0168> is set toNEW, no sub-build is used. Within CMake script mode <#script-processing-mode>, that allowsFetchContent_Populate()to be called without any build tool or CMake generator. we love a glow-up ๐
Added in version 3.18: Added support for the DOWNLOAD_NO_EXTRACT option. ๐
The command supports another form, although it should no longer be used:
FetchContent_Populate(<name>)
Changed in version 3.30: This form is deprecated. PolicyCMP0169<#policy:CMP0169> provides backward compatibility for projects that still need to use this form, but projects should be updated to useFetchContent_MakeAvailable()instead. fr fr, migrate. it's for your own good ๐
In this form, the only argument given to FetchContent_Populate() is the <name>. When used this way, the command assumes the content details have been recorded by an earlier call to FetchContent_Declare(). Those details are stored in a global property, so they are unaffected by things like variable or directory scope. iconic behavior, honestly โ therefore, it doesn't matter where in the project the details were previously declared, as long as they have been declared before the call to FetchContent_Populate(). Those saved details are then used to populate the content using a method based on ExternalProject_Add() <#command:externalproject_add> (see policy CMP0168 <#policy:CMP0168> for important behavioral aspects of how that's done).
When this form of FetchContent_Populate() returns, the following variables will be set in the scope of the caller:
<lowercaseName>_POPULATEDโ this will always be set toTRUEby the call. always. no cap โ<lowercaseName>_SOURCE_DIRโ the location where the populated content can be found upon return. ๐<lowercaseName>_BINARY_DIRโ a directory intended for use as a corresponding build directory. ๐๏ธ
The values of those three variables can also be retrieved from anywhere in the project hierarchy using the FetchContent_GetProperties() command. convenient?? yes ma'am ๐ฆ
The implementation ensures that if the content has already been populated in a previous CMake run, that content will be reused rather than repopulating again. For the common case where population involves downloading content, the cost of the download is only paid once. your bandwidth said thank you ๐ But note that it is an error to call FetchContent_Populate(<name>) with the same <name> more than once within a single CMake run. See FetchContent_GetProperties() for how to determine if population of a <name> has already been performed in the current run. do not test it. it will not go well ๐
๐ซ FetchContent_GetProperties
When you're using saved content details, a call to FetchContent_MakeAvailable() or FetchContent_Populate() records information in global properties which can be queried at any time. This information may include the source and binary directories associated with the content, and also whether or not the content population has been processed during the current configure run.
FetchContent_GetProperties(
<name>
[SOURCE_DIR <srcDirVar>]
[BINARY_DIR <binDirVar>]
[POPULATED <doneVar>]
)
The SOURCE_DIR, BINARY_DIR, and POPULATED options can be used to specify which properties should be retrieved. Each option accepts a value which is the name of the variable in which to store that property. so meta, we're naming the variable that holds the answer ๐
Most of the time though, only <name> is given, in which case the call will then set the same variables as a call to FetchContent_MakeAvailable(name) or FetchContent_Populate(name). Note that the SOURCE_DIR and BINARY_DIR values can be empty if the call is fulfilled by a dependency provider <#dependency-providers>. empty string era, we've all been there ๐
This command is rarely needed when you're using FetchContent_MakeAvailable(). It's more commonly used as part of implementing the deprecated pattern with FetchContent_Populate(), which ensures that the relevant variables will always be defined regardless of whether or not the population has been performed elsewhere in the project already:
# WARNING: This pattern is deprecated, don't use it!
#
# Check if population has already been performed
FetchContent_GetProperties(depname)
if(NOT depname_POPULATED)
# Fetch the content using previously declared details
FetchContent_Populate(depname)
# Set custom variables, policies, etc.
# ...
# Bring the populated content into the build
add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
endif()
WARNING: that pattern is deprecated, don't use it! The comment says it, I'm saying it, the manpage is saying it. three sources, one truth ๐
๐ง FetchContent_SetPopulated
Added in version 3.24. โญ
Note: This command should only be called by dependency providers <#dependency-providers>. Calling it in any other context is unsupported and future CMake versions may halt with a fatal error in such cases. like, do not. unsupported means unsupported ๐ญ
FetchContent_SetPopulated(
<name>
[SOURCE_DIR <srcDir>]
[BINARY_DIR <binDir>]
)
If a provider command fulfills a FETCHCONTENT_MAKEAVAILABLE_SERIAL request, it must call this function before returning. mandatory, bestie The SOURCE_DIR and BINARY_DIR arguments can be used to specify the values that FetchContent_GetProperties() should return for its corresponding arguments. Only provide SOURCE_DIR and BINARY_DIR if they have the same meaning as if they had been populated by the built-in FetchContent_MakeAvailable() implementation. same meaning or don't bother ๐ซถ
๐ธ Variables
A number of cache variables can influence the behavior where details from a FetchContent_Declare() call are used to populate content.
Note: All of these variables are intended for the developer to customize behavior. They should not normally be set by the project. project's job is vibes, developer's job is settings โจ
๐ FETCHCONTENT_BASE_DIR
In most cases, the saved details don't specify any options relating to the directories to use for the internal sub-build, final source, and build areas. It's generally best to leave these decisions up to the FetchContent module to handle on the project's behalf. let it cook ๐ The FETCHCONTENT_BASE_DIR cache variable controls the point under which all content population directories are collected, but in most cases, developers would not need to change this. The default location is ${CMAKE_BINARY_DIR}/_deps, but if developers change this value, they should aim to keep the path short and just below the top level of the build tree to avoid running into path length problems on Windows. windows path length said "not today" ๐
๐ฆ FETCHCONTENT_QUIET
The logging output during population can be quite verbose, making the configure stage quite noisy. so much yapping This cache option (ON by default) hides all population output unless an error is encountered. If you're experiencing problems with hung downloads, temporarily switching this option off may help diagnose which content population is causing the issue. ๐
Changed in version 3.30:FETCHCONTENT_QUIETis ignored if policyCMP0168<#policy:CMP0168> is set toNEW. The output is still quiet by default in that case, but verbosity is controlled by the message logging level (seeCMAKE_MESSAGE_LOG_LEVEL<#variable:CMAKE_MESSAGE_LOG_LEVEL> and--log-level<#cmdoption-cmake-log-level>). different knob, same quietness ๐คซ
๐ FETCHCONTENT_FULLY_DISCONNECTED
When this option is enabled, no attempt is made to download or update any content. It's assumed that all content has already been populated in a previous run, or the source directories have been pointed at existing contents the developer has provided manually (using options described further below). When the developer knows that no changes have been made to any content details, turning this option ON can speed up the configure stage. It is OFF by default. โก
Note: The FETCHCONTENT_FULLY_DISCONNECTED variable is not an appropriate way to prevent any network access on the first run in a build directory. Doing so can break projects, lead to misleading error messages, and hide subtle population failures. it will lie to you and you will believe it ๐ญ This variable is specifically intended to only be turned on after the first time CMake has been run. If you want to prevent network access even on the first run, use a dependency provider <#dependency-providers> and populate the dependency from local content instead. that's the actual move ๐
Changed in version 3.30: The constraint that the source directory has already been populated whenFETCHCONTENT_FULLY_DISCONNECTEDis true is now enforced. See policyCMP0170<#policy:CMP0170>. they're checking now. behave. ๐ฅ
FETCHCONTENT_UPDATES_DISCONNECTEDโ okay so this one is like the chill, less severe sibling ofFETCHCONTENT_FULLY_DISCONNECTED. ๐ Instead of straight-up bypassing all the download and update logic,FETCHCONTENT_UPDATES_DISCONNECTEDonly stops the update step from making connections to remote servers when you're using thegitorhgdownload methods. Updates still happen if details about the update step change โ but the update is attempted using only the info already available locally. So switching to a different tag or commit that's already fetched locally will succeed โจ, but switching to an unknown commit hash will fail ๐ญ. The download step is not affected at all, so if content hasn't been downloaded before, it will still be downloaded when this option is enabled. This can speed up the configure step, but not as much asFETCHCONTENT_FULLY_DISCONNECTED. AndFETCHCONTENT_UPDATES_DISCONNECTEDisOFFby default.FETCHCONTENT_TRY_FIND_PACKAGE_MODEโ added in version3.24. ๐
This variable modifies the details that FetchContent_Declare() records for a given dependency. The tea here โ: while it ultimately controls the behavior of FetchContent_MakeAvailable(), it's the variable's value when FetchContent_Declare() is called that gets used. It makes no difference what the variable is set to when FetchContent_MakeAvailable() is called. Since the variable should only be set by the user and not by projects directly, it'll typically have the same value throughout anyway, so this distinction is not usually noticeable. ๐
FETCHCONTENT_TRY_FIND_PACKAGE_MODE ultimately controls whether FetchContent_MakeAvailable() is allowed to call find_package() to satisfy a dependency. The variable can be set to one of these values:
OPT_INโFetchContent_MakeAvailable()will only callfind_package()if theFetchContent_Declare()call included aFIND_PACKAGE_ARGSkeyword. This is also the default behavior ifFETCHCONTENT_TRY_FIND_PACKAGE_MODEis not set. ๐ธALWAYSโfind_package()can be called byFetchContent_MakeAvailable()regardless of whether theFetchContent_Declare()call included aFIND_PACKAGE_ARGSkeyword or not. If noFIND_PACKAGE_ARGSkeyword was given, the behavior will be as thoughFIND_PACKAGE_ARGShad been provided, with no additional arguments after it. ๐ฅNEVERโFetchContent_MakeAvailable()will not callfind_package(). AnyFIND_PACKAGE_ARGSgiven to theFetchContent_Declare()call will be ignored. ๐
As a special case ๐, if the FETCHCONTENT_SOURCE_DIR_<uppercaseName> variable has a non-empty value for a dependency, it's assumed that the user is overriding all other methods of making that dependency available. FETCHCONTENT_TRY_FIND_PACKAGE_MODE will have no effect on that dependency, and FetchContent_MakeAvailable() will not try to call find_package() for it.
In addition to the above, the following variables are also defined for each content name:
FETCHCONTENT_SOURCE_DIR_<uppercaseName>โ if this is set, no download or update steps are performed for the specified content, and the<lowercaseName>_SOURCE_DIRvariable returned to the caller is pointed at this location. ๐ซถ This gives developers a way to have a separate checkout of the content that they can modify freely without interference from the build. The build simply uses that existing source, but it still defines<lowercaseName>_BINARY_DIRto point inside its own build area. Developers are strongly encouraged to use this mechanism rather than editing the sources populated in the default location, because changes to sources in the default location can be lost when content population details are changed by the project. ๐ญ No cap.FETCHCONTENT_UPDATES_DISCONNECTED_<uppercaseName>โ this is the per-content equivalent ofFETCHCONTENT_UPDATES_DISCONNECTED. If the global option or this option isON, then updates for thegitandhgmethods will not contact any remote for the named content. They'll only use information already available locally. Disabling updates for individual content can be useful for content whose details rarely change, while still leaving other frequently changing content with updates enabled. ๐
๐ Examples ๐
๐ Typical Case ๐
This first, fairly straightforward example ensures that some popular testing frameworks are available to the main build. It's giving "classic, iconic, does exactly what it says":
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG 605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
)
# After the following call, the CMake targets defined by googletest and
# Catch2 will be available to the rest of the build
FetchContent_MakeAvailable(googletest Catch2)
๐ฆ Integrating With find_package() ๐ฆ
For the previous example, if the user wanted to try to find googletest and Catch2 via find_package() first before trying to download and build them from source, they could set the FETCHCONTENT_TRY_FIND_PACKAGE_MODE variable to ALWAYS. ๐ But heads up โ this would also affect any other calls to FetchContent_Declare() throughout the project, which might not be acceptable. ๐ฌ The behavior can be enabled for just these two dependencies instead by adding FIND_PACKAGE_ARGS to the declared details and leaving FETCHCONTENT_TRY_FIND_PACKAGE_MODE unset, or set to OPT_IN:
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
FIND_PACKAGE_ARGS NAMES GTest
)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG 605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
FIND_PACKAGE_ARGS
)
# This will try calling find_package() first for both dependencies
FetchContent_MakeAvailable(googletest Catch2)
For Catch2, no additional arguments to find_package() are needed, so no additional arguments are provided after the FIND_PACKAGE_ARGS keyword. For googletest, its package is more commonly called GTest, so arguments are added to support it being found by that name. โจ iykyk
If the user wanted to disable FetchContent_MakeAvailable() from calling find_package() for any dependency โ even if it provided FIND_PACKAGE_ARGS in its declared details โ they could set FETCHCONTENT_TRY_FIND_PACKAGE_MODE to NEVER. ๐ซ
If the project wanted to indicate that these two dependencies should be downloaded and built from source, and that find_package() calls should be redirected to use the built dependencies, the OVERRIDE_FIND_PACKAGE option should be used when declaring the content details:
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
OVERRIDE_FIND_PACKAGE
)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG 605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
OVERRIDE_FIND_PACKAGE
)
# The following will automatically forward through to FetchContent_MakeAvailable()
find_package(googletest)
find_package(Catch2)
CMake provides a FindGTest module which defines some variables that older projects may use instead of linking to the imported targets. To support those cases, we can provide an extra file. ๐ In keeping with the "first to define, wins" philosophy of FetchContent, we only write out that file if something else hasn't already done so:
FetchContent_MakeAvailable(googletest)
if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-extra.cmake AND
NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletestExtra.cmake)
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-extra.cmake
[=[
if("${GTEST_LIBRARIES}" STREQUAL "" AND TARGET GTest::gtest)
set(GTEST_LIBRARIES GTest::gtest)
endif()
if("${GTEST_MAIN_LIBRARIES}" STREQUAL "" AND TARGET GTest::gtest_main)
set(GTEST_MAIN_LIBRARIES GTest::gtest_main)
endif()
if("${GTEST_BOTH_LIBRARIES}" STREQUAL "")
set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
endif()
]=])
endif()
Projects will also likely be using find_package(GTest) rather than find_package(googletest), but it's possible to make use of the CMAKE_FIND_PACKAGE_REDIRECTS_DIR area to pull in the latter as a dependency of the former. This is likely to be sufficient to satisfy a typical find_package(GTest) call. ๐ซถ
FetchContent_MakeAvailable(googletest)
if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake AND
NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfig.cmake)
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake
[=[
include(CMakeFindDependencyMacro)
find_dependency(googletest)
]=])
endif()
if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config-version.cmake AND
NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfigVersion.cmake)
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config-version.cmake
[=[
include(${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-config-version.cmake OPTIONAL)
if(NOT PACKAGE_VERSION_COMPATIBLE)
include(${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletestConfigVersion.cmake OPTIONAL)
endif()
]=])
endif()
๐ฏ Overriding Where To Find CMakeLists.txt
Okay so sometimes the sub-project's CMakeLists.txt file is not chilling at the top level of its source tree โ like, it's hiding in a subfolder somewhere, living its truth. That's where the SOURCE_SUBDIR option comes in: it tells FetchContent exactly where to go find it. ๐
The example below shows how to use that option, and it also sets a variable that's meaningful to the subproject before pulling it into the main build. Heads up: it's set as an INTERNAL cache variable to avoid problems with policy CMP0077 <#policy:CMP0077>. iykyk.
include(FetchContent)
FetchContent_Declare(
protobuf
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
GIT_TAG ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0
SOURCE_SUBDIR cmake
)
set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "")
FetchContent_MakeAvailable(protobuf)
๐ณ Complex Dependency Hierarchies
In more complex project hierarchies, the dependency relationships can get more complicated. Buckle up bestie. ๐ข
Consider a hierarchy where projA is the top level project, and it depends directly on projects projB and projC. Both projB and projC can be built standalone, and they also both depend on another project projD. On top of that, projB additionally depends on projE. This example assumes that all five projects are available on a company git server. The CMakeLists.txt of each project might have sections like the following:
projA
include(FetchContent)
FetchContent_Declare(
projB
GIT_REPOSITORY git@mycompany.com:git/projB.git
GIT_TAG 4a89dc7e24ff212a7b5167bef7ab079d
)
FetchContent_Declare(
projC
GIT_REPOSITORY git@mycompany.com:git/projC.git
GIT_TAG 4ad4016bd1d8d5412d135cf8ceea1bb9
)
FetchContent_Declare(
projD
GIT_REPOSITORY git@mycompany.com:git/projD.git
GIT_TAG origin/integrationBranch
)
FetchContent_Declare(
projE
GIT_REPOSITORY git@mycompany.com:git/projE.git
GIT_TAG v2.3-rc1
)
# Order is important, see notes in the discussion further below
FetchContent_MakeAvailable(projD projB projC)
projB
include(FetchContent)
FetchContent_Declare(
projD
GIT_REPOSITORY git@mycompany.com:git/projD.git
GIT_TAG 20b415f9034bbd2a2e8216e9a5c9e632
)
FetchContent_Declare(
projE
GIT_REPOSITORY git@mycompany.com:git/projE.git
GIT_TAG 68e20f674a48be38d60e129f600faf7d
)
FetchContent_MakeAvailable(projD projE)
projC
include(FetchContent)
FetchContent_Declare(
projD
GIT_REPOSITORY git@mycompany.com:git/projD.git
GIT_TAG 7d9a17ad2c962aa13e2fbb8043fb6b8a
)
FetchContent_MakeAvailable(projD)
A few key points should be noted in the above, bestie โ this is the important part:
projBandprojCdefine different content details forprojD, butprojAalso defines a set of content details forprojD. BecauseprojAwill define them first, the details fromprojBandprojCwill not be used. The override details defined byprojAare not required to match either of those fromprojBorprojC, but it is up to the higher level project to ensure that the details it does define still make sense for the child projects. ๐- In the
projAcall toFetchContent_MakeAvailable(),projDis listed ahead ofprojBandprojC, so it will be populated before eitherprojBorprojC. It isn't required forprojAto do this, but doing so ensures thatprojAfully controls the environment in whichprojDis brought into the build (directory properties are particularly relevant). โจ - While
projAdefines content details forprojE, it does not need to explicitly callFetchContent_MakeAvailable(projE)orFetchContent_Populate(projD)itself. Instead, it leaves that to the childprojB. For higher level projects, it is often enough to just define the override content details and leave the actual population to the child projects. This saves repeating the same thing at each level of the project hierarchy unnecessarily, but it should only be done if directory properties set by dependencies are not expected to influence the population of the shared dependency (projEin this case).
๐ฆ Populating Content Without Adding It To The Build
Projects don't always need to add the populated content to the build. Sometimes the project just wants to make the downloaded content available at a predictable location. ๐บ๏ธ
The next example ensures that a set of standard company toolchain files (and potentially even the toolchain binaries themselves) is available early enough to be used for that same build:
cmake_minimum_required(VERSION 3.14)
include(FetchContent)
FetchContent_Declare(
mycom_toolchains
URL https://intranet.mycompany.com//toolchains_1.3.2.tar.gz
)
FetchContent_MakeAvailable(mycom_toolchains)
project(CrossCompileExample)
The project could be configured to use one of the downloaded toolchains like so:
cmake -DCMAKE_TOOLCHAIN_FILE=_deps/mycom_toolchains-src/toolchain_arm.cmake /path/to/src
When CMake processes the CMakeLists.txt file, it will download and unpack the tarball into _deps/mycompany_toolchains-src relative to the build directory. The CMAKE_TOOLCHAIN_FILE <#variable:CMAKE_TOOLCHAIN_FILE> variable is not used until the project() <#command:project> command is reached, at which point CMake looks for the named toolchain file relative to the build directory. Because the tarball has already been downloaded and unpacked by then, the toolchain file will be in place โ even the very first time that cmake is run in the build directory. ๐
๐ง Populating Content In CMake Script Mode
This last example demonstrates how one might download and unpack a firmware tarball using CMake's script mode <#script-processing-mode>. The call to FetchContent_Populate() specifies all the content details, and the unpacked firmware will be placed in a firmware directory below the current working directory.
getFirmware.cmake
# NOTE: Intended to be run in script mode with cmake -P
include(FetchContent)
FetchContent_Populate(
firmware
URL https://mycompany.com/assets/firmware-1.23-arm.tar.gz
URL_HASH MD5=68247684da89b608d466253762b0ff11
SOURCE_DIR firmware
)
โจ FindPackageHandleStandardArgs โจ
This module provides commands intended for use in Find Modules <#find-modules> implementing find_package(<PackageName>) <#command:find_package> calls.
Load this module in a CMake find module with:
FindFoo.cmake
include(FindPackageHandleStandardArgs)
๐ธ Commands
This module provides the following commands:
find_package_handle_standard_args()find_package_check_version()
๐ find_package_handle_standard_args
Handles the REQUIRED, QUIET and version-related arguments of find_package() <#command:find_package>.
There are two signatures:
find_package_handle_standard_args(
<PackageName>
(DEFAULT_MSG|<custom-failure-message>)
<required-vars>...
)
find_package_handle_standard_args(
<PackageName>
[REQUIRED_VARS <required-vars>...]
[VERSION_VAR <version-var>]
[HANDLE_VERSION_RANGE]
[HANDLE_COMPONENTS]
[CONFIG_MODE]
[NAME_MISMATCHED]
[REASON_FAILURE_MESSAGE <reason-failure-message>]
[FAIL_MESSAGE <custom-failure-message>]
[FOUND_VAR <result-var>] # Deprecated
)
This command sets the <PackageName>_FOUND variable to TRUE if all the variables listed in <required-vars>... contain valid results (e.g., valid filepaths) and any optional constraints are satisfied, and FALSE otherwise. A success or failure message may be displayed based on the results and on whether the REQUIRED and/or QUIET option was given to the find_package() <#command:find_package> call. ๐ซถ
The arguments are:
<PackageName>โ the name of the package. For example, as written in theFind<PackageName>.cmakefind module filename.(DEFAULT_MSG|<custom-failure-message>)โ in the simple signature, this specifies the failure message. UseDEFAULT_MSGto ask for a default message to be computed (recommended). Not valid in the full signature.REQUIRED_VARS <required-vars>...โ specify the variables which are required for this package. These may be named in the generated failure message asking the user to set the missing variable values. Therefore these should typically be cache entries such asFoo_LIBRARYand not output variables likeFoo_LIBRARIES.
Changed in version 3.18: if HANDLE_COMPONENTS is specified, this option can be omitted.
VERSION_VAR <version-var>โ specify the name of a variable that holds the version of the package that has been found. This version will be checked against the (potentially) specified required version given to thefind_package()<#command:find_package> call, including itsEXACToption. The default messages include information about the required version and the version which has been actually found, both if the version is ok or not. ๐ฅHANDLE_VERSION_RANGEโ added in version 3.19. Enable handling of a version range, if one is specified. Without this option, a developer warning will be displayed if a version range is specified.HANDLE_COMPONENTSโ enable handling of package components. In this case, the command will report which components have been found and which are missing, and the<PackageName>_FOUNDvariable will be set toFALSEif any of the required components (i.e. not the ones listed after theOPTIONAL_COMPONENTSoption offind_package()<#command:find_package>) are missing. ๐ญCONFIG_MODEโ specify that the calling find module is a wrapper around a call tofind_package(<PackageName> NO_MODULE). This implies aVERSION_VARvalue of<PackageName>_VERSION. The command will automatically check whether the package configuration file was found.NAME_MISMATCHEDโ added in version 3.17.
Indicate that the <PackageName> does not match the value of the CMAKE_FIND_PACKAGE_NAME variable. Like, this is usually a mistake and CMake will side-eye you with a warning ๐ฌ โ but sometimes it's lowkey intentional, like when you're using the command for components of a bigger package. So it's allowed, just be aware.
REASON_FAILURE_MESSAGE <reason-failure-message>โ Added in version 3.16. ๐ซ Here's where you drop your own custom message explaining why the failure happened, and it gets appended to the default generated message. Main character reason, default-message supporting role ๐FAIL_MESSAGE <custom-failure-message>โ Lets you specify a completely custom failure message instead of the default generated one. Not recommended ๐ ngl, just let the default do its thing.FOUND_VAR <result-var>โ Deprecated since version 3.3: this option should no longer be used, periodt ๐ It specifies either<PackageName>_FOUNDor<PACKAGENAME>_FOUNDas the result variable. It exists only for backward compatibility with older CMake versions and is now ignored. Both result variables are now always set anyway โ with or without this option โ for compatibility. So it's giving "we keep it around but we don't listen to it" energy ๐ซ
Note ๐ โ If<PackageName>doesn't matchCMAKE_FIND_PACKAGE_NAMEfor the calling module, you get a warning that there's a mismatch. Two ways to dodge it: set theFPHSA_NAME_MISMATCHEDvariable (if you're using the old signature), or use theNAME_MISMATCHEDargument (new signature). And so you don't force callers to require newer CMake versions just to use your module: for the new signature, if theNAME_MISMATCHEDargument isn't passed, the variable's value gets used if it's defined. But using both at the same time? That's an error, bestie ๐ญ pick a lane.
find_package_check_version โจ
Added in version 3.19.
This one checks if a given version is valid against the version-related arguments of find_package() ๐ฆ
find_package_check_version(
<version>
<result-var>
[HANDLE_VERSION_RANGE]
[RESULT_MESSAGE_VARIABLE <message-var>]
)
Okay so the arguments, one by one ๐
<version>โ the version string you want checked. That's it, that's the whole vibe.<result-var>โ the name of the result variable that'll hold a boolean value giving the result of the check.TRUEfound,FALSEnot, yk ๐HANDLE_VERSION_RANGEโ turns on handling of a version range, if one is specified. Without this option, you get a developer warning if a version range is specified. So like, if ranges are in play and you didn't opt in, expect to be called out ๐RESULT_MESSAGE_VARIABLE <message-var>โ specify a variable to get back a message describing the result of the check. Cute little receipt of what happened ๐งพ
Examples ๐
Examples: Full Signature
Example for using a full signature of find_package_handle_standard_args():
FindLibArchive.cmake
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
LibArchive
REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
VERSION_VAR LibArchive_VERSION
)
In this case, the LibArchive package counts as found if both LibArchive_LIBRARY and LibArchive_INCLUDE_DIR are valid. Also, the version of LibArchive gets checked using the version contained in LibArchive_VERSION. And since no FAIL_MESSAGE is given, the default messages get printed. Slay, defaults ๐
Another example for the full signature of find_package_handle_standard_args():
FindAutomoc4.cmake
find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Automoc4 CONFIG_MODE)
So here, a FindAutomoc4.cmake module wraps a call to find_package(Automoc4 NO_MODULE) and adds an extra search directory for automoc4. Then the call to find_package_handle_standard_args() produces a proper success/failure message. Like, it handles the messaging so you don't have to ๐
Example: Simple Signature
Example for using a simple signature of find_package_handle_standard_args():
FindLibXml2.cmake
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
LibXml2
DEFAULT_MSG
LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR
)
In this example, the LibXml2 package is considered found if both LIBXML2_LIBRARY and LIBXML2_INCLUDE_DIR variables are valid. Then LibXml2_FOUND also gets set to TRUE. If it's not found and REQUIRED was used, it fails with a message(FATAL_ERROR), regardless of whether QUIET was used or not ๐ค no quiet-option immunity here. If it is found, success gets reported, including the content of the first required variable specified in <required-vars>..... And on repeated CMake runs, the same message won't be printed again โ no spam, we love that for us โจ
Example: Checking Version
Example for the find_package_check_version() usage:
FindFoo.cmake
include(FindPackageHandleStandardArgs)
find_package_check_version(
1.2.3
result
HANDLE_VERSION_RANGE
RESULT_MESSAGE_VARIABLE reason
)
if(result)
message(STATUS "${reason}")
else()
# Logic when version check is not successful.
message(WARNING "${reason}")
endif()
See Also ๐
- Find Modules for details how to write a find module. iykyk ๐
FindPackageMessage ๐
This module provides a command for printing find result messages, and it's intended for use in Find Modules implementing find_package(<PackageName>) calls. Basically: "hey bestie, we found this thing, here's where it is" ๐ฃ
Load this module in a CMake find module with:
FindFoo.cmake
include(FindPackageMessage)
Commands ๐
This module provides the following command:
find_package_message
Prints a message once for each unique find result, to inform the user which package was found and where:
find_package_message(<PackageName> <message> <details>)
<PackageName>โ the name of the package (for example, as used in theFind<PackageName>.cmakemodule filename).<message>โ the message string to display.<details>โ a unique identifier for tracking message display. The<message>is printed only once per distinct<details>value. If the<details>string changes in a subsequent configuration phase, the message will be displayed again. So it's a little memory-holder for "did I already say this?" ๐ง โจ
If find_package() was called with the QUIET option, the <message> is not printed. Respect the quiet, periodt ๐คซ
Examples ๐
Printing a result message in a custom find module:
FindFoo.cmake
find_library(Foo_LIBRARY foo)
find_path(Foo_INCLUDE_DIR foo.h)
include(FindPackageMessage)
if(Foo_LIBRARY AND Foo_INCLUDE_DIR)
find_package_message(
Foo
"Found Foo: ${Foo_LIBRARY}"
"[${Foo_LIBRARY}][${Foo_INCLUDE_DIR}]"
)
else()
message(STATUS "Could NOT find Foo")
endif()
When writing standard find modules, use the FindPackageHandleStandardArgs module and its find_package_handle_standard_args() command, which automatically prints the find result message based on whether the package was found. Like, why hand-roll it when the icon already does it ๐
FindFoo.cmake
# ...
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Foo
REQUIRED_VARS Foo_LIBRARY Foo_INCLUDE_DIR
)
FortranCInterface ๐ฆ
This module provides variables and commands to detect Fortran/C Interface. Yes, Fortran and C, together, in one project โ iconic crossover episode ๐
Load this module in a CMake project with:
include(FortranCInterface)
This module automatically detects the API by which C and Fortran languages interact. It just figures it out for you and honestly? obsessed ๐ฅ
Variables ๐ธ
Result Variables
Including this module defines the following variables that indicate if the mangling is found:
FortranCInterface_GLOBAL_FOUNDโ boolean indicating whether global subroutines and functions are available. โ /โFortranCInterface_MODULE_FOUNDโ boolean indicating whether module subroutines and functions (declared byMODULE PROCEDURE) are available. That's the fancy module-scoped ones ๐
Input Variables
This module also provides the following variables to specify the detected mangling, though a typical use case doesn't need to reference them at all โ you can just use the Commands below and vibe โจ
FortranCInterface_GLOBAL_PREFIXโ prefix for a global symbol without an underscore.FortranCInterface_GLOBAL_SUFFIXโ suffix for a global symbol without an underscore.FortranCInterface_GLOBAL_CASEโ the case for a global symbol without an underscore, eitherUPPERorLOWER.FortranCInterface_GLOBAL__PREFIXโ prefix for a global symbol with an underscore. (Yes, that's two underscores in the name โ not a typo, bestie ๐ญ)FortranCInterface_GLOBAL__SUFFIXโ suffix for a global symbol with an underscore.FortranCInterface_GLOBAL__CASEโ the case for a global symbol with an underscore, eitherUPPERorLOWER.FortranCInterface_MODULE_PREFIXโ prefix for a module symbol without an underscore.FortranCInterface_MODULE_MIDDLEโ middle of a module symbol without an underscore that appears between the name of the module and the name of the symbol. The literal middle child ๐ฅบFortranCInterface_MODULE_SUFFIXโ suffix for a module symbol without an underscore.FortranCInterface_MODULE_CASEโ the case for a module symbol without an underscore, eitherUPPERorLOWER.FortranCInterface_MODULE_ORDERโ Added in version 4.1. Order of components for module symbols without an underscore:MODULE_THEN_SYMBOLโ the module name appears before the symbol name, i.e.,<PREFIX><module><MIDDLE><symbol><SUFFIX>.SYMBOL_THEN_MODULEโ the module name appears after the symbol name, i.e.,<PREFIX><symbol><MIDDLE><module><SUFFIX>.
FortranCInterface_MODULE__PREFIXโ prefix for a module symbol with an underscore.FortranCInterface_MODULE__MIDDLEโ middle of a module symbol with an underscore that appears between the name of the module and the name of the symbol.FortranCInterface_MODULE__SUFFIXโ suffix for a module symbol with an underscore.FortranCInterface_MODULE__CASEโ the case for a module symbol with an underscore, eitherUPPERorLOWER.FortranCInterface_MODULE__ORDERโ Added in version 4.1. Order of components for module symbols with an underscore:MODULE_THEN_SYMBOLโ the module name shows up before the symbol name, like<PREFIX><module><MIDDLE><symbol><SUFFIX>. ๐SYMBOL_THEN_MODULEโ opposite behavior bestie: module name comes after the symbol, i.e.<PREFIX><symbol><MIDDLE><module><SUFFIX>. ๐ฆ
โจ Variables For Additional Manglings โจ
This module already knows about a bunch of possible GLOBAL and MODULE manglings for lots of Fortran compilers, but it also hands you an interface so you can add your own. ๐ซถ Set the following variables before including this module to add extra manglings:
FortranCInterface_GLOBAL_SYMBOLS
FortranCInterface_MODULE_SYMBOLS
...before including this module, to specify manglings of the symbols MySub, My_Sub, MyModule:MySub, and My_Module:My_Sub. ๐ธ
๐ Commands ๐
This module provides the following commands:
FortranCInterface_HEADER
Generates a C header file stuffed with macros that mangle symbol names ๐:
FortranCInterface_HEADER(
<file>
[MACRO_NAMESPACE <macro-ns>]
[SYMBOL_NAMESPACE <ns>]
[SYMBOLS [<module>:]<function> ...]
)
This command generates a <file> with definitions of these macros:
#define FortranCInterface_GLOBAL (name,NAME) ...
#define FortranCInterface_GLOBAL_(name,NAME) ...
#define FortranCInterface_MODULE (mod,name, MOD,NAME) ...
#define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...
These macros mangle four categories of Fortran symbols, respectively:
- Global symbols without
'_':call mysub() - Global symbols with
'_':call my_sub() - Module symbols without
'_':use mymod; call mysub() - Module symbols with
'_':use mymod; call my_sub()
If the mangling for some category isn't known, its macro is just left undefined (she's ghosting you ๐ป). And heads up: all macros require raw names in both lower case and upper case, no exceptions.
The options are:
MACRO_NAMESPACEโ replaces the defaultFortranCInterface_prefix with whatever namespace<macro-ns>you hand it. ๐SYMBOL_NAMESPACEโ prefixes all the preprocessor definitions generated by theSYMBOLSoption with a given namespace<ns>. โจSYMBOLSโ lists the symbols to mangle automatically with C preprocessor definitions:
<function> ==> #define <ns><function> ...
<module>:<function> ==> #define <ns><module>_<function> ...
If the mangling for some symbol isn't known, then no preprocessor definition gets created, and a warning is displayed. ๐
FortranCInterface_VERIFY
Verifies that the Fortran and C/C++ compilers actually work together, no cap ๐ง:
FortranCInterface_VERIFY([CXX] [QUIET])
This command tests whether a simple test executable using Fortran and C (and C++ when the CXX option is given) compiles and links successfully. The result lands in the cache entry FortranCInterface_VERIFIED_C (or FortranCInterface_VERIFIED_CXX if CXX is given) as a boolean. If the check fails and QUIET is not given, the command terminates with a fatal error message describing the problem. ๐ The whole point of this check is to stop a build early for incompatible compiler combinations. The test is built in the Release configuration.
๐ Examples ๐
Examples: Basic Usage
The following example creates a FC.h header that defines mangling macros FC_GLOBAL(), FC_GLOBAL_(), FC_MODULE(), and FC_MODULE_():
include(FortranCInterface)
FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
The next example creates a FCMangle.h header that defines those same FC_*() mangling macros as the previous example, plus the preprocessor symbols FC_mysub and FC_mymod_my_sub. Slay. ๐
include(FortranCInterface)
FortranCInterface_HEADER(
FCMangle.h
MACRO_NAMESPACE "FC_"
SYMBOL_NAMESPACE "FC_"
SYMBOLS mysub mymod:my_sub
)
Example: Additional Manglings
The following example shows how to specify manglings of the symbols MySub, My_Sub, MyModule:MySub, and My_Module:My_Sub. The code below tells this module to try the given GLOBAL and MODULE manglings. (The carets point at raw symbol names for clarity in this example, but they are not needed. ๐ซถ)
set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_)
# ^^^^^ ^^^^^^ ^^^^^
set(FortranCInterface_MODULE_SYMBOLS
__mymodule_MOD_mysub __my_module_MOD_my_sub)
# ^^^^^^^^ ^^^^^ ^^^^^^^^^ ^^^^^^
include(FortranCInterface)
# ...
๐ GenerateExportHeader ๐
This module provides commands for generating a header file containing preprocessor macro definitions to control C/C++ symbol visibility. ๐
Load this module in a CMake project with:
include(GenerateExportHeader)
Added in version 3.12: Support for C projects. Previous versions supported C++ projects only. โจ
When developing C or C++ projects, especially for cross-platform use, symbol visibility determines which functions, classes, global variables, templates, and other symbols are made visible to users of the library. It's giving gatekeeper energy fr fr.
For example, on Windows, symbols must be explicitly marked with __declspec(dllexport) when building a shared library, and __declspec(dllimport) when using it. Other platforms may use attributes like __attribute__((visibility("default"))).
This module simplifies the creation and usage of preprocessor macros to manage these requirements, avoiding repetitive and error-prone #ifdef blocks in source code. ๐ญ (not the #ifdef spaghetti)
Some symbol visibility can also be controlled with compiler options. In CMake, target properties such as <LANG>_VISIBILITY_PRESET and VISIBILITY_INLINES_HIDDEN enable compiler visibility flags, where appropriate. See also the related convenience variables CMAKE_<LANG>_VISIBILITY_PRESET and CMAKE_VISIBILITY_INLINES_HIDDEN to enable it for all targets in the current scope. These are commonly used in combination with this module to further simplify C/C++ code, removing the need for some of the preprocessor macros in the source code. ๐ง
โญ Commands โญ
This module provides the following commands:
๐ธ Generating Export Header ๐ธ
generate_export_header
Generates a header file suitable for inclusion in source code, containing preprocessor export macros for controlling the visibility of symbols ๐:
generate_export_header(
<target>
[BASE_NAME <base-name>]
[EXPORT_FILE_NAME <export-file-name>]
[EXPORT_MACRO_NAME <export-macro-name>]
[NO_EXPORT_MACRO_NAME <no-export-macro-name>]
[DEPRECATED_MACRO_NAME <deprecated-macro-name>]
[DEFINE_NO_DEPRECATED]
[NO_DEPRECATED_MACRO_NAME <no-deprecated-macro-name>]
[STATIC_DEFINE <static-define>]
[PREFIX_NAME <prefix>]
[CUSTOM_CONTENT_FROM_VARIABLE <variable>]
[INCLUDE_GUARD_NAME <include-guard-name>]
)
By default, this command generates a header file named <target-name-lowercase>_export.h in the current binary directory (CMAKE_CURRENT_BINARY_DIR). This header defines a set of preprocessor macros used to mark API symbols as exported, hidden, or deprecated across different platforms and build types (e.g., static or shared builds), and is intended to be installed along with the library's public headers, because it affects public API declarations. ๐
<MACRO>_EXPORT: Marks symbols for export or import, making them visible as part of the public API when building or consuming a shared library. ๐ฅ<MACRO>_NO_EXPORT: Marks symbols that should not be exported. If the<LANG>_VISIBILITY_PRESETtarget property is set tohidden, using this macro in source code is typically redundant.<MACRO>_DEPRECATED: Marks symbols as deprecated. When such symbols are used, the compiler emits a warning at compile-time. ๐<MACRO>_DEPRECATED_EXPORT: Combines export/import and deprecation markers for a symbol that is both part of the public API and deprecated. ๐<MACRO>_DEPRECATED_NO_EXPORT: Marks a deprecated symbol that should not be exported (internal and deprecated).<MACRO>_NO_DEPRECATED: A macro that can be used in source code to conditionally exclude deprecated code parts from the build via preprocessor logic. ๐ฆ
The <MACRO> part is derived by default from the uppercase name of the target or the explicitly provided <base-name>. All macro names can be customized using the optional arguments. ๐
The arguments are:
<target>โ name of a target for which the export header will be generated. Supported target types:STATIClibrary (in this case, export-related macros are defined without values) ๐ธSHAREDlibraryMODULElibrary- Added in version 3.1:
OBJECTlibrary โญ
BASE_NAME <base-name>โ if specified, it overrides the default file name and macro names.EXPORT_FILE_NAME <export-file-name>โ if specified, it overrides the full path and the name of the generated export header file (<base-name-lowercase>_export.h) to<export-file-name>. If given as a relative path, it will be interpreted relative to the current binary directory (CMAKE_CURRENT_BINARY_DIR). ๐ซถEXPORT_MACRO_NAME <export-macro-name>โ if specified, it overrides the default macro name for the export directive.NO_EXPORT_MACRO_NAME <no-export-macro-name>โ if specified, the<no-export-macro-name>will be used for the macro name that designates the attribute for items that shouldn't be exported. ๐DEPRECATED_MACRO_NAME <deprecated-macro-name>โ if specified, the following names will be used:<deprecated-macro-name>(macro for marking deprecated symbols)
<deprecated-macro-name>_EXPORTโ okay so this one's the macro for deprecated symbols that do get export markers ๐<deprecated-macro-name>_NO_EXPORTโ and this is the macro for deprecated symbols with the no-export markers ๐
โฆand you use those instead of the default names, which come in the format <MACRO>_DEPRECATED{,_EXPORT,_NO_EXPORT}. iykyk โจ
DEFINE_NO_DEPRECATED
If you pass this, it defines a macro named <MACRO>_NO_DEPRECATED. That's literally it, bestie โ a whole little flag macro appears ๐
NO_DEPRECATED_MACRO_NAME <no-deprecated-macro-name>
Only really does anything when you pair it with the DEFINE_NO_DEPRECATED option. If you specify it, then a macro named <no-deprecated-macro-name> gets used instead of the default <MACRO>_NO_DEPRECATED. So you get to name your own little guy ๐ฆ
STATIC_DEFINE <static-define>
If specified, the <static-define> macro name is used instead of the default <MACRO>_STATIC_DEFINE. What does this macro even do? It controls the symbol export behavior in the generated header for static libraries โ main character of the static world ๐
It's typically used when you're building both shared and static variants of a library from the same sources, using a single generated export header. And when this macro is defined for the static library, the export-related macros expand to nothing. Which matters a LOT on Windows, because symbol decoration is only required for shared libraries there, not static ones. no cap ๐ฅ
PREFIX_NAME <prefix>
If specified, that extra <prefix> gets prepended to all the generated macro names. Prepend arc, slay ๐
CUSTOM_CONTENT_FROM_VARIABLE <variable>
Added in version 3.7.
If specified, the content from the <variable> value is appended to the generated header file content after the preprocessor macro definitions. So yes, it goes at the bottom, after the macros โ respect the order ๐ซถ
INCLUDE_GUARD_NAME <include-guard-name>
Added in version 3.11.
If specified, <include-guard-name> is used as the preprocessor macro name to guard against multiple inclusions of the generated header, instead of the default name <export-macro-name>_H. Protect that header from being included twice, periodt โจ
<base-name-lowercase>_export.h
#ifndef <include-guard-name>
#define <include-guard-name>
// ...
#endif /* <include-guard-name> */
๐ Deprecated Command ๐
add_compiler_export_flags
Deprecated since version 3.0: Set the target propertiesCXX_VISIBILITY_PRESET(<LANG>_VISIBILITY_PRESET) andVISIBILITY_INLINES_HIDDENinstead.
Okay so here's the whole thing, bestie: this adds the C++ compiler options -fvisibility=hidden (and -fvisibility-inlines-hidden, if supported) to hide all symbols by default โ either to the CMAKE_CXX_FLAGS variable (CMAKE_<LANG>_FLAGS) or to a variable you specify. Like:
add_compiler_export_flags([<output_variable>])
And on Windows this command is a straight-up no-op, because Windows doesn't need extra compiler flags for exporting support. Not its problem ๐
<output-variable> : Optional variable name that gets populated with a string of space-separated C++ compile options required to enable visibility support for the compiler/architecture in use. And if you do specify this argument, the CMAKE_CXX_FLAGS variable (CMAKE_<LANG>_FLAGS) will not be modified. Nobody touches it, iconic ๐
๐ Examples ๐
Example: Generating Export Header
The following example demonstrates how to use this module to generate an export header in the current binary directory (example_export.h) and use it in a C++ library named example to control symbols visibility. The generated header defines the preprocessor macros EXAMPLE_EXPORT, EXAMPLE_NO_EXPORT, EXAMPLE_DEPRECATED, EXAMPLE_DEPRECATED_EXPORT, and EXAMPLE_DEPRECATED_NO_EXPORT, and it's installed along with the library's other public headers. Obsessed with the tidiness honestly ๐
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(GenerateExportHeaderExample)
# Set default visibility of all symbols to hidden
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
add_library(example)
include(GenerateExportHeader)
generate_export_header(example)
target_sources(
example
PRIVATE example.cxx
PUBLIC
FILE_SET HEADERS
FILES example.h
FILE_SET generated_headers
TYPE HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/example_export.h
)
install(
TARGETS example
FILE_SET HEADERS
FILE_SET generated_headers
)
And in the ABI header files:
example.h
#include "example_export.h"
// This class is part of the public API and is exported
class EXAMPLE_EXPORT SomeClass
{
public:
SomeClass();
void doSomething();
// This method is deprecated
EXAMPLE_DEPRECATED void legacyMethod();
};
// This function is exported and deprecated
EXAMPLE_DEPRECATED_EXPORT void legacyPublicFunction();
// This function is deprecated but not exported
EXAMPLE_DEPRECATED void legacyInternalFunction();
example.cxx
#include <iostream>
#include "example.h"
SomeClass::SomeClass() = default;
void SomeClass::doSomething()
{
std::cout << "SomeClass::doSomething() called" << std::endl;
}
void SomeClass::legacyMethod()
{
std::cout << "SomeClass::legacyMethod() is deprecated" << std::endl;
}
void legacyPublicFunction()
{
std::cout << "legacyPublicFunction() is deprecated" << std::endl;
}
void internalLegacyFunction()
{
std::cout << "legacyInternalFunction() is deprecated" << std::endl;
}
Examples: Customizing Generated Header
The BASE_NAME argument can be used to override the generated file name and the names used for the macros. The following will generate a file named other_name_export.h containing export-related macros such as OTHER_NAME_EXPORT, OTHER_NAME_NO_EXPORT, OTHER_NAME_DEPRECATED, etc. Glow-up for your header ๐ธ
add_library(example example.cxx)
include(GenerateExportHeader)
generate_export_header(example BASE_NAME "other_name")
And the BASE_NAME may be overridden by specifying other command options. For example, the following creates a macro OTHER_NAME_EXPORT instead of EXAMPLE_EXPORT, but the other macros and the generated header file name stay at their default values. Selective rebranding, we love to see it ๐
add_library(example example.cxx)
include(GenerateExportHeader)
generate_export_header(example EXPORT_MACRO_NAME "OTHER_NAME_EXPORT")
The following example creates the KDE_DEPRECATED macro instead of the default EXAMPLE_DEPRECATED:
add_library(example example.cxx)
include(GenerateExportHeader)
generate_export_header(example DEPRECATED_MACRO_NAME "KDE_DEPRECATED")
The DEFINE_NO_DEPRECATED option can be used to define a macro which can be used to remove deprecated code from preprocessor output. Bye-bye legacy code, you will not be missed ๐ฆ
option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library")
if(EXCLUDE_DEPRECATED)
set(NO_BUILD_DEPRECATED DEFINE_NO_DEPRECATED)
endif()
include(GenerateExportHeader)
generate_export_header(example ${NO_BUILD_DEPRECATED})
example.h
class EXAMPLE_EXPORT SomeClass
{
public:
#ifndef EXAMPLE_NO_DEPRECATED
EXAMPLE_DEPRECATED void legacyMethod();
#endif
};
example.cxx
#ifndef EXAMPLE_NO_DEPRECATED
void SomeClass::legacyMethod() { }
#endif
The PREFIX_NAME argument can be used to prepend all generated macro names with some prefix. For example, the following will generate macros such as VTK_SOMELIB_EXPORT, etc. Prefix era ๐ฅ
include(GenerateExportHeader)
generate_export_header(somelib PREFIX_NAME "VTK_")
Appending additional content to the generated header can be done with the CUSTOM_CONTENT_FROM_VARIABLE argument:
include(GenerateExportHeader)
set(content [[#include "project_api.h"]])
generate_export_header(example CUSTOM_CONTENT_FROM_VARIABLE content)
Example: Building Shared and Static Library
In the following example, both a shared and a static library are built from the same sources, and the <MACRO>_STATIC_DEFINE macro compile definition is defined to make sure the same generated export header works for both. One header, two libraries, main character energy ๐
add_library(example_shared SHARED example.cxx)
add_library(example_static STATIC example.cxx)
include(GenerateExportHeader)
generate_export_header(example_shared BASE_NAME "example")
# Define macro to disable export attributes for static build
target_compile_definitions(example_static PRIVATE EXAMPLE_STATIC_DEFINE)
Example: Upgrading Deprecated Command
In earlier versions of CMake, the add_compiler_export_flags() command was used to add symbol visibility compile options. Look at this historical artifact ๐ญ
CMakeLists.txt
add_library(example example.cxx)
include(GenerateExportHeader)
add_compiler_export_flags(flags)
string(REPLACE " " ";" flags "${flags}")
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS "${flags}")
generate_export_header(example)
In new code, the following target properties are used to achieve the same functionality. Glow-up complete โจ
CMakeLists.txt
add_library(example example.cxx)
include(GenerateExportHeader)
set_target_properties(
example
PROPERTIES
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN TRUE
)
generate_export_header(example)
๐ See Also ๐
- The
DEFINE_SYMBOLtarget property, for customizing the preprocessor macro name used by the generated header. This macro determines whether the library header is being included during the library's own compilation or when it's used by another project (e.g., after installation). Context is everything, bestie ๐ซถ - The
ENABLE_EXPORTStarget property. - The
WINDOWS_EXPORT_ALL_SYMBOLStarget property.
๐ง GNUInstallDirs ๐ง
This module defines the installation directory variables according to the GNU Coding Standards (https://www.gnu.org/prep/standards/html_node/Directory-Variables.html) and provides a command to compute installation-related absolute paths. Very "know where everything goes" of it ๐
Load this module in a CMake project with:
include(GNUInstallDirs)
Result Variables
Inclusion of this module defines the following variables:
CMAKE_INSTALL_<dir>โ bestie, this is the destination for files of a given type. You can pass this value to theDESTINATIONoptions ofinstall()commands for the corresponding file type. It should be a path relative to the installation prefix so it can be converted into an absolute path in a relocatable way. But โ there are some special cases, documented below. ๐
So like, absolute paths are allowed, but they're not recommended, because they do NOT work with the cmake --install command's --prefix option, or with the cpack installer generators. And there's genuinely no need to make paths absolute by prepending CMAKE_INSTALL_PREFIX โ that prefix is already used by default if the DESTINATION is a relative path. Save yourself the trouble, iykyk. ๐
CMAKE_INSTALL_FULL_<dir>โ the absolute path generated from the correspondingCMAKE_INSTALL_<dir>value. If the value isn't already an absolute path, an absolute path gets constructed โ typically by prepending the value of theCMAKE_INSTALL_PREFIXvariable, except in the special cases documented below. โจ
These variables shouldn't be used in install() commands, because they don't work with the cmake --install command's --prefix option, or with the cpack installer generators. Periodt.
where <dir> is one of these icons ๐:
BINDIRโ user executables (bin)SBINDIRโ system admin executables (sbin)LIBEXECDIRโ program executables (libexec)SYSCONFDIRโ read-only single-machine data (etc)
Changed in version 4.1: if the CMAKE_INSTALL_PREFIX falls into the special cases, the default paths are the absolute path variants as described there. See policy CMP0192. ๐ซถ
SHAREDSTATEDIRโ modifiable architecture-independent data (com)LOCALSTATEDIRโ modifiable single-machine data (var)
Changed in version 4.1: if the CMAKE_INSTALL_PREFIX falls into the special cases, the default paths are the absolute path variants as described there. See policy CMP0192. ๐ซถ
RUNSTATEDIRโ run-time variable data (LOCALSTATEDIR/run)
Added in version 3.9.
Changed in version 4.1: if the CMAKE_INSTALL_PREFIX falls into the special cases, the default paths are the absolute path variants as described there. See policy CMP0192. ๐ซถ
LIBDIRโ object code libraries (liborlib64)
On Linux, when you're not cross-compiling, the default is the distro's arch-specific library directory, like lib or lib64. On Debian, this may be lib/<multiarch-tuple> when CMAKE_INSTALL_PREFIX is /usr. When cross-compiling, the default is lib. ๐ธ
Note: when an alternative installation prefix is specified with the--prefixoption at install time, the special case with the multi-architecture tuple is evaluated based on the configuration-timeCMAKE_INSTALL_PREFIX, not on the alternative prefix value. Don't get it twisted! ๐ญ
INCLUDEDIRโ C header files (include)OLDINCLUDEDIRโ C header files for non-gcc (/usr/include)DATAROOTDIRโ read-only architecture-independent data root (share)DATADIRโ read-only architecture-independent data (DATAROOTDIR)
DATADIR and DATAROOTDIR are treated separately so that DATADIR can be customized for project-specific data files, while DATAROOTDIR stays unchanged for the standard architecture-independent locations INFODIR, LOCALEDIR, MANDIR, and DOCDIR. The way that's such a clean design tho. ๐ง
INFODIRโ info documentation (DATAROOTDIR/info)LOCALEDIRโ locale-dependent data (DATAROOTDIR/locale)MANDIRโ man documentation (DATAROOTDIR/man)DOCDIRโ documentation root (DATAROOTDIR/doc/PROJECT_NAME)
If the includer doesn't define a value, the above-shown default gets used, and the value shows up in the cache for the user to edit. Highkey convenient. ๐
If a default value for CMAKE_INSTALL_<dir> is used and CMAKE_INSTALL_PREFIX gets changed, the new default value gets calculated off the new CMAKE_INSTALL_PREFIX value. Using --prefix in cmake --install will not alter these values. ๐คทโโ๏ธ
๐ Special Cases ๐
Added in version 3.4.
These particular values of CMAKE_INSTALL_PREFIX are special, bestie โ pay attention:
/
For <dir> other than SYSCONFDIR, LOCALSTATEDIR and RUNSTATEDIR, the value of CMAKE_INSTALL_<dir> is prefixed with usr/ if it isn't user-specified as an absolute path. For example, the INCLUDEDIR value include becomes usr/include. This is required by the GNU Coding Standards (https://www.gnu.org/prep/standards/html_node/Directory-Variables.html), which state:
When building the complete GNU system, the prefix will be empty and/usrwill be a symbolic link to/.
Changed in version 4.1: the CMAKE_INSTALL_<dir> variables are cached with the usr/ prefix. See policy CMP0193. โจ
/usr
For <dir> equal to SYSCONFDIR, LOCALSTATEDIR or RUNSTATEDIR, the CMAKE_INSTALL_FULL_<dir> is computed by prepending just / to the value of CMAKE_INSTALL_<dir> if it isn't already an absolute path. For example, the SYSCONFDIR value etc becomes /etc. This is required by the GNU Coding Standards (https://www.gnu.org/prep/standards/html_node/Directory-Variables.html). ๐ฆ
Changed in version 4.1: the default values of CMAKE_INSTALL_<dir> for <dir> equal to SYSCONFDIR, LOCALSTATEDIR and RUNSTATEDIR are the absolute paths /etc, /var and /var/run respectively. See policy CMP0192.
/opt/...
For <dir> equal to SYSCONFDIR, LOCALSTATEDIR or RUNSTATEDIR, the CMAKE_INSTALL_FULL_<dir> is computed by appending the prefix to the value of CMAKE_INSTALL_<dir> if it isn't already an absolute path. For example, the SYSCONFDIR value etc becomes /etc/opt/.... This is defined by the Filesystem Hierarchy Standard (https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html). ๐
This behavior does not apply to paths under /opt/homebrew/.... (sorry, Homebrew girlies ๐)
Changed in version 4.1: the default values of CMAKE_INSTALL_<dir> for <dir> equal to SYSCONFDIR, LOCALSTATEDIR and RUNSTATEDIR are the absolute paths /etc/opt/..., /var/opt/... and /var/run/opt/... respectively. See policy CMP0192.
Note: when an alternative installation prefix is specified with the--prefixoption at install time, these special cases are evaluated based on the configuration-timeCMAKE_INSTALL_PREFIX, not on the alternative prefix value. Literally the same energy as before, just saying it again for the people in the back. ๐
๐ Commands ๐
This module provides the following command:
GNUInstallDirs_get_absolute_install_dir
Added in version 3.7.
Computes an absolute installation path from a given relative path:
GNUInstallDirs_get_absolute_install_dir(<result-var> <input-var> <dir>)
This command takes the value from the variable <input-var> and computes its absolute path according to the GNU standard installation directories. If the input path is relative, it gets prepended with CMAKE_INSTALL_PREFIX and may be adjusted for the special cases described above. โจ
The arguments are:
<result-var>โ name of the variable in which to store the computed absolute path.<input-var>โ name of the variable containing the path that will be used to compute its associated absolute installation path.
Changed in version 4.1: this variable is no longer altered. See policy CMP0193. In previous CMake versions, this command modified the <input-var> variable value based on the special cases. โ ๏ธ
<dir>โ Added in version 3.20.
The directory type name, e.g. SYSCONFDIR, LOCALSTATEDIR, RUNSTATEDIR, etc. This argument determines whether special cases apply when computing the absolute path.
Changed in version 3.20: before the <dir> argument was introduced, the directory type could be specified by setting the dir variable prior to calling this command. As of CMake 3.20, if the <dir> argument is provided explicitly, the dir variable is ignored. ๐
While this command is used internally by this module to compute the CMAKE_INSTALL_FULL_<dir> variables, it's also exposed publicly so users can create additional custom installation path variables and compute absolute paths where necessary, using the same logic. Main character energy for a helper command, honestly. ๐
๐ See Also ๐
- The
install()command.
๐ GoogleTest ๐
Added in version 3.9.
This module provides commands to help you use the Google Test infrastructure. ๐งช
Load this module in a CMake project with:
include(GoogleTest)
Two mechanisms for adding tests are provided. gtest_add_tests() has been around for some time, originally via find_package(GTest). gtest_discover_tests() was introduced in CMake 3.10. โญ
The (older) gtest_add_tests() scans source files to identify tests. This is usually effective, with some caveats, including in cross-compiling environments, and it makes setting additional properties on tests more convenient. However, its handling of parameterized tests is less comprehensive, and it requires re-running CMake to detect changes to the list of tests. ๐ฎโ๐จ
The (newer) gtest_discover_tests() discovers tests by asking the compiled test executable to enumerate its tests. This is more robust and provides better handling of parameterized tests, and it does not require CMake to be re-run when tests change. However, it may not work in a cross-compiling environment, and setting test properties is less convenient. Trade-offs, bestie, trade-offs. โ๏ธ
More details can be found in the documentation of the respective functions. ๐
Okay so both of these commands are literally designed to replace your old-school add_test() call โ they register tests, and they create a separate CTest test for each individual Google Test test case. Ngl, that's sometimes less efficient, because common set-up and tear-down logic can't be shared by multiple test cases executing in the same instance. But it hands you way more fine-grained pass/fail info to CTest, which is usually considered the more beneficial trade. By default the CTest test name is the same as the Google Test name (i.e. suite.testcase) โ see also TEST_PREFIX and TEST_SUFFIX. ๐ซถ
โจ gtest_add_tests โจ
Automatically add tests with CTest by scanning source code for Google Test macros:
gtest_add_tests(TARGET target
[SOURCES src1...]
[EXTRA_ARGS args...]
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
[SKIP_DEPENDENCY]
[TEST_LIST outVar]
)
gtest_add_tests tries to identify tests by scanning source files. It's generally effective, sure, but bestie be warned: it uses only a basic regular expression match, which can absolutely be defeated by atypical test declarations, and it's unable to fully "split" parameterized tests. ๐ญ Additionally, it requires that CMake be re-run to discover any newly added, removed or renamed tests (by default that means CMake is re-run when any test source file is changed, but see SKIP_DEPENDENCY). The upside though? It declares tests at CMake time, which somewhat simplifies setting additional properties on tests, and it always works in a cross-compiling environment. ๐
The options are:
TARGETtarget โ Specifies the Google Test executable, which must be a known CMake executable target. CMake will substitute the location of the built executable when running the test.SOURCESsrc1... โ When provided, only the listed files will be scanned for test cases. If this option is not given, theSOURCESproperty of the specified target will be used to obtain the list of sources.EXTRA_ARGSargs... โ Any extra arguments to pass on the command line to each test case.- Changed in version 3.31: Empty values in args... are preserved, see
CMP0178.
- Changed in version 3.31: Empty values in args... are preserved, see
WORKING_DIRECTORYdir โ Specifies the directory in which to run the discovered test cases. If this option is not provided, the current binary directory is used.TEST_PREFIXprefix โ Specifies a prefix to be prepended to the name of each discovered test case. This can be useful when the same source files are being used in multiple calls togtest_add_test()but with differentEXTRA_ARGS.TEST_SUFFIXsuffix โ Similar toTEST_PREFIXexcept the suffix is appended to the name of every discovered test case. BothTEST_PREFIXandTEST_SUFFIXmay be specified.SKIP_DEPENDENCYโ Normally, the function creates a dependency which will cause CMake to be re-run if any of the sources being scanned are changed. That's to ensure the list of discovered tests is updated. If this behavior is not desired (as may be the case while you're actually writing the test cases), this option can be used to prevent the dependency from being added.TEST_LISToutVar โ The variable named by outVar will be populated in the calling scope with the list of discovered test cases. This lets the caller do things like manipulate test properties of the discovered tests. ๐
Changed in version 3.31: Empty values in theTEST_LAUNCHERandCROSSCOMPILING_EMULATORtarget properties are preserved, see policyCMP0178.
Usage example, bestie, straight from the source:
include(GoogleTest)
add_executable(FooTest FooUnitTest.cxx)
gtest_add_tests(TARGET FooTest
TEST_SUFFIX .noArgs
TEST_LIST noArgsTests
)
gtest_add_tests(TARGET FooTest
EXTRA_ARGS --someArg someValue
TEST_SUFFIX .withArgs
TEST_LIST withArgsTests
)
set_tests_properties(${noArgsTests} PROPERTIES TIMEOUT 10)
set_tests_properties(${withArgsTests} PROPERTIES TIMEOUT 20)
For backward compatibility, the following form is also supported:
gtest_add_tests(exe args files...)
exeโ The path to the test executable or the name of a CMake target.argsโ A semicolon-separated list of extra arguments to be passed to executable. The entire list must be passed as a single argument. Enclose it in quotes, or pass""for no arguments. (Yes,"". Not vibes. Actual empty quotes. ๐)files...โ A list of source files to search for tests and test fixtures. Alternatively, useAUTOto specify that exe is the name of a CMake executable target whose sources should be scanned.
include(GoogleTest)
set(FooTestArgs --foo 1 --bar 2)
add_executable(FooTest FooUnitTest.cxx)
gtest_add_tests(FooTest "${FooTestArgs}" AUTO)
๐ gtest_discover_tests ๐
Automatically add tests with CTest by querying the compiled test executable for available tests:
gtest_discover_tests(target
[EXTRA_ARGS args...]
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
[TEST_FILTER expr]
[NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
[PROPERTIES name1 value1...]
[TEST_LIST var]
[DISCOVERY_TIMEOUT seconds]
[XML_OUTPUT_DIR dir]
[DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
[DISCOVERY_EXTRA_ARGS args...]
)
Added in version 3.10.
gtest_discover_tests() sets up a post-build or pre-test command on the test executable that generates the list of tests by parsing the output from running the test executable with the --gtest_list_tests argument. Compared to the source-parsing approach of gtest_add_tests(), this guarantees you get the full list of tests, including instantiations of parameterized tests. ๐
Since test discovery happens at build or test time, you don't have to re-run CMake when the list of tests changes โ iconic, honestly. However (and this is the catch, bestie), it requires that CROSSCOMPILING_EMULATOR is properly set in order to function in a cross-compiling environment.
Also, setting properties on tests is somewhat less convenient, since the tests are not available at CMake time. Additional test properties may be assigned to the set of tests as a whole using the PROPERTIES option. If you need more fine-grained test control, custom content may be provided through an external CTest script using the TEST_INCLUDE_FILES directory property. The set of discovered tests is made accessible to such a script via the <target>_TESTS variable (see the TEST_LIST option below for further discussion and limitations). ๐ฆ
The options are:
targetโ Specifies the Google Test executable, which must be a known CMake executable target. CMake will substitute the location of the built executable when running the test.EXTRA_ARGSargs... โ Any extra arguments to pass on the command line to each test case.- Changed in version 3.31: Empty values in args... are preserved, see
CMP0178.
- Changed in version 3.31: Empty values in args... are preserved, see
WORKING_DIRECTORYdir โ Specifies the directory in which to run the discovered test cases. If this option is not provided, the current binary directory is used.TEST_PREFIXprefix โ Specifies a prefix to be prepended to the name of each discovered test case. This can be useful when the same test executable is being used in multiple calls togtest_discover_tests()but with differentEXTRA_ARGS.TEST_SUFFIXsuffix โ Similar toTEST_PREFIXexcept the suffix is appended to the name of every discovered test case. BothTEST_PREFIXandTEST_SUFFIXmay be specified.TEST_FILTERexpr โ Added in version 3.22. Filter expression to pass as a--gtest_filterargument during test discovery. Note that the expression is a wildcard-based format that matches against the original test names as used by gtest. For type- or value-parameterized tests, these names may be different to the potentially pretty-printed test names thatctestuses. ๐งNO_PRETTY_TYPESโ By default, the type index of type-parameterized tests is replaced by the actual type name in the CTest test name. If this behavior is undesirable (e.g. because the type names are unwieldy), this option will suppress it.NO_PRETTY_VALUESโ By default, the value index of value-parameterized tests is replaced by the actual value in the CTest test name. If this behavior is undesirable (e.g. because the value strings are unwieldy), this option will suppress it.PROPERTIESname1 value1... โ Specifies additional properties to be set on all tests discovered by this invocation ofgtest_discover_tests().TEST_LISTvar โ so instead of dumping the test list into the default<target>_TESTS, you get it in var. iconic when you're reusing the same test executable across multiplegtest_discover_tests()calls ngl. heads up tho: this variable is only available in CTest. and bestie, listen โ due to a limitation of CMake's parsing rules, any test with a square bracket in its name gets omitted from the list stored in this variable ๐ญ those tests are still defined and executed by ctest as normal, so like, no crisis, just a lil gap.DISCOVERY_TIMEOUTnum โ โจ added in version 3.10.3 โจ this is how long (in seconds) CMake waits for the test to enumerate its available tests. if the test takes longer than that, discovery (and your whole build ๐ซ ) fails. most test executables enumerate super fast, but under some exceptional circumstances a test may need a longer timeout. the default is5. see also theTIMEOUToption ofexecute_process().
Note, bestie: in CMake versions3.10.1and3.10.2, this option was calledTIMEOUT. that clashed with theTIMEOUTtest property, which is one of the common properties that would be set with thePROPERTIESkeyword โ usually leading to legal but unintended behavior ๐ so the keyword got changed toDISCOVERY_TIMEOUTin CMake3.10.3to fix it. the ambiguous behavior of theTIMEOUTkeyword in3.10.1and3.10.2has not been preserved. periodt.
XML_OUTPUT_DIRdir โ added in version 3.18. if specified, the parameter gets passed along with--gtest_output=xml:to the test executable. the actual file name is the same as the test target, including prefix and suffix. use this instead ofEXTRA_ARGS --gtest_output=xmlto avoid race conditions writing the XML result output when you're doing parallel test execution ๐ฅ like, trust, it's giving safer.DISCOVERY_MODEโ added in version 3.18. gives you greater control over whengtest_discover_tests()performs test discovery. by default,POST_BUILDsets up a post-build command to do discovery at build time. but in certain scenarios โ like cross-compiling โ thisPOST_BUILDbehavior is not desirable.PRE_TEST, by contrast, delays test discovery until just prior to test execution. that way discovery happens in the target environment, where the test has a better chance at finding appropriate runtime dependencies ๐
DISCOVERY_MODE defaults to the value of the CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE variable if it's not passed when calling gtest_discover_tests(). so you get a mechanism for globally selecting a preferred test discovery behavior without having to modify each call site. obsessed actually.
DISCOVERY_EXTRA_ARGSargs... โ added in version 3.31. any extra arguments to pass on the command line for the discovery command. slay.
Added in version 3.29: the TEST_LAUNCHER target property is honored during test discovery and test execution ๐
Changed in version 3.31: empty values in the TEST_LAUNCHER and CROSSCOMPILING_EMULATOR target properties are preserved, see policy CMP0178.
๐ง InstallRequiredSystemLibraries ๐ง
this module searches for compiler-provided system runtime libraries and adds installation rules for them. lowkey a lifesaver on Windows fr fr.
load it in a CMake project with:
include(InstallRequiredSystemLibraries)
some optional variables may be set prior to including this module to adjust behavior:
CMAKE_INSTALL_SYSTEM_RUNTIME_LIBSโ specify additional runtime libraries that may not be detected. after inclusion, any detected libraries will be appended to this. ๐ธCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIPโ set toTRUEto skip calling theinstall(PROGRAMS)command, which lets the includer specify its own install rule, using the value ofCMAKE_INSTALL_SYSTEM_RUNTIME_LIBSto get the list of libraries. you're the main character of your own install rules, i respect it.CMAKE_INSTALL_DEBUG_LIBRARIESโ set toTRUEto install the debug runtime libraries when available with MSVC tools.CMAKE_INSTALL_DEBUG_LIBRARIES_ONLYโ set toTRUEto install only the debug runtime libraries with MSVC tools, even if the release runtime libraries are also available. debug girlies rise ๐CMAKE_INSTALL_UCRT_LIBRARIESโ added in version 3.6. set toTRUEto install the Windows Universal CRT libraries for app-local deployment (e.g. to Windows XP). this is meaningful only with MSVC from Visual Studio 2015 or higher.
Added in version 3.9: you may set a CMAKE_WINDOWS_KITS_10_DIR environment variable to an absolute path to tell CMake to look for Windows 10 SDKs in a custom location. the specified directory is expected to contain Redist/ucrt/DLLs/* directories ๐ฆ
CMAKE_INSTALL_MFC_LIBRARIESโ set toTRUEto install the MSVC MFC runtime libraries.CMAKE_INSTALL_OPENMP_LIBRARIESโ set toTRUEto install the MSVC OpenMP runtime libraries.CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATIONโ specify theinstall(PROGRAMS)commandDESTINATIONoption. if not specified, the default isbinon Windows andlibelsewhere.CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGSโ set toTRUEto disable warnings about required library files that don't exist. (for example, Visual Studio Express editions may not provide the redistributable files ๐)CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENTโ added in version 3.3. specify theinstall(PROGRAMS)commandCOMPONENToption. if not specified, no such option will be used.
Added in version 3.10: support for installing Intel compiler runtimes. we love to see it โจ
๐ ProcessorCount ๐
this module provides a command to determine the number of processors/cores. literally the "how many friends can come to the party" module.
load this module in CMake with:
include(ProcessorCount)
Commands
this module provides the following command:
ProcessorCount โ determines the number of logical CPU cores available on the machine:
ProcessorCount(<variable>)
this command sets a variable named <variable> to the number of logical CPU cores available on the machine, if the information can be determined. if successful, the variable is guaranteed to be set to a positive integer (>=1). if the processor count can't be determined, it's set to 0 ๐
currently, this functionality is implemented for AIX, Cygwin, FreeBSD, Haiku, HPUX, Linux, macOS, QNX, Sun and Windows. around the world, bestie ๐
this command provides an approximation of the number of compute cores available on the current machine, making it useful for parallel building and testing. it's meant to help utilize as much of the machine as seems reasonable, though users should consider other workloads running on the machine before using its full capacity for parallel tasks. like, don't hog the whole group chat bandwidth, yk? ๐ซถ
Changed in version 3.15: on Linux, returns the container CPU count instead of the host CPU count.
Note: this module relies on system-dependent commands to determine the number of processors, which may not always provide accurate information in certain environments. a more generally accurate logical CPU count can also be obtained with cmake_host_system_information():
cmake_host_system_information(RESULT n QUERY NUMBER_OF_LOGICAL_CORES)
Examples
in the following example this module is used in a ctest -S dashboard script to determine the number of cores to use for a parallel CTest Build Step:
include(ProcessorCount)
ProcessorCount(n)
if(NOT n EQUAL 0)
set(CTEST_BUILD_FLAGS -j${n})
set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${n})
endif()
ate, no notes ๐
๐ SelectLibraryConfigurations ๐
this module provides a command to automatically set library variables when a package is available with multiple Build Configurations. it's intended for use in Find Modules implementing find_package(<PackageName>) calls. highkey niche but so useful.
load this module in a CMake find module with:
FindFoo.cmake
include(SelectLibraryConfigurations)
supported build configurations are Release and Debug, since these are the most common ones in such packages ๐ธ
Note: this module has been available since early versions of CMake, back when the<PackageName>_LIBRARIESresult variable was used for linking found packages. when writing standard find modules, Imported Targets should be preferred. in addition to or as an alternative to this module, imported targets provide finer control over linking through theIMPORTED_CONFIGURATIONSproperty. glow-up behavior, honestly โจ
Commands
this module provides the following command:
select_library_configurations โ sets and adjusts library variables based on debug and release build configurations:
select_library_configurations(<basename>)
this command is a helper for setting the <basename>_LIBRARY and <basename>_LIBRARIES result variables when a library might be provided with multiple build configurations.
the argument is:
<basename>โ the base name of the library, used as a prefix for variable names. this is the name of the package as used in theFind<PackageName>.cmakemodule filename, or the component name, when the find module provides them. ๐
prior to calling this command, the following cache variables should be set in the find module (for example, by the find_library() command):
<basename>_LIBRARY_RELEASEโ a cache variable holding the full path to the Release build of the library ๐ if it's not set already, or nothing turns up, this command sets it to<basename>_LIBRARY_RELEASE-NOTFOUND(sad girl hours).<basename>_LIBRARY_DEBUGโ same vibe but for the Debug build ๐ it stores the full path, and if it's unset or unfound it becomes<basename>_LIBRARY_DEBUG-NOTFOUND.
Then, bestie, the command sets these local result variables:
<basename>_LIBRARYโ a result variable that gets the value of your<basename>_LIBRARY_RELEASEif that was found; otherwise it takes<basename>_LIBRARY_DEBUGif that was found. Both found? Release wins, no debate, release takes precedence ๐ neither found? it's set to<basename>_LIBRARY-NOTFOUND.
Okay so this next bit is important โ if the CMake Generator (cmake-generators(7)) your build is using supports build configurations, then this variable becomes a list of the found libraries, each one prepended with the optimized or debug keyword that says which library should get linked for that given configuration. Those keywords are the exact ones target_link_libraries() understands. But if no build configuration has been set, or your generator doesn't do build configurations at all, then the value won't contain those keywords. Simple as that โจ
<basename>_LIBRARIESโ a result variable set to the same value as<basename>_LIBRARY. Literally twins ๐ซถ
Note: you should call theselect_library_configurations()command before handling the standard find module arguments withfind_package_handle_standard_args(), so that the<PackageName>_FOUNDresult variable actually ends up correctly set based on<basename>_LIBRARYor the other related variables. Order matters, periodt ๐
Examples
Setting library variables based on the build configuration inside a find module file:
FindFoo.cmake
# Find release and debug build of the library
find_library(Foo_LIBRARY_RELEASE ...)
find_library(Foo_LIBRARY_DEBUG ...)
# Set Foo_LIBRARY and Foo_LIBRARIES result variables
include(SelectLibraryConfigurations)
select_library_configurations(Foo)
# Set Foo_FOUND variable and print result message.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Foo
REQUIRED_VARS Foo_LIBRARY ...
)
And when your find module provides components with multiple build configurations:
FindFoo.cmake
include(SelectLibraryConfigurations)
foreach(component IN LISTS Foo_FIND_COMPONENTS)
# ...
select_library_configurations(Foo_${component})
# ...
endforeach()
A project can then use this find module like this:
CMakeLists.txt
find_package(Foo)
target_link_libraries(project_target PRIVATE ${Foo_LIBRARIES})
# ...
๐ง TestForANSIForScope
This module checks whether the CXX compiler restricts the scope of variables declared in a for-init-statement to the loop body ๐
Load this module in a CMake project with:
include(TestForANSIForScope)
So back in early C++ (pre-C++98), variables declared in for(<init-statement> ...) could stay accessible outside the loop after its body finished (for() { <body> }). Messy, I know ๐ญ
This module defines the following cache variable:
CMAKE_NO_ANSI_FOR_SCOPEโ a cache variable containing the result of the check. It'll be0if the for-init-statement has restricted scope (C++ 98 and newer), and1if it doesn't (ANSI C++).
Note: as of the C++ 98 standard, variables declared in a for-init-statement are restricted to the loop body, which makes this whole behavior obsolete. History lesson over ๐
Examples
Including this module will check the for() loop scope behavior and define the CMAKE_NO_ANSI_FOR_SCOPE cache variable:
CMakeLists.txt
include(TestForANSIForScope)
file(
CONFIGURE
OUTPUT config.h
CONTENT "#cmakedefine CMAKE_NO_ANSI_FOR_SCOPE"
)
which can be then used in a C++ program:
example.cxx
#include "config.h"
#ifdef CMAKE_NO_ANSI_FOR_SCOPE
# define for if(false) {} else for
#endif
See Also
- The
CMakeBackwardCompatibilityCXXmodule.
๐ TestForANSIStreamHeaders
This module checks whether the CXX compiler supports standard library headers without the .h extension (like <iostream>), which is honestly such a flex โจ
Load this module in a CMake project with:
include(TestForANSIStreamHeaders)
Early versions of C++ (pre-C++98) didn't support including standard headers without extensions. Rough times ๐
This module defines the following cache variable:
CMAKE_NO_ANSI_STREAM_HEADERSโ a cache variable containing the result of the check. Set to0if the standard headers can be included without the.hextension (C++ 98 and newer), and1if.his required (ANSI C++).
Note: the C++ standard headers without extensions got formally introduced in the C++ 98 standard, making this issue obsolete. Girl, it's vintage ๐
Examples
Including this module will check how the C++ standard headers can be included and define the CMAKE_NO_ANSI_STREAM_HEADERS cache variable:
CMakeLists.txt
include(TestForANSIStreamHeaders)
file(
CONFIGURE
OUTPUT config.h
CONTENT "#cmakedefine CMAKE_NO_ANSI_STREAM_HEADERS"
)
A C++ program can then include the available header conditionally:
example.cxx
#include "config.h"
#ifdef CMAKE_NO_ANSI_STREAM_HEADERS
# include <iostream.h>
#else
# include <iostream>
#endif
int main() { ... }
See Also
- The
CMakeBackwardCompatibilityCXXmodule.
๐ฆ TestForSSTREAM
This module checks whether the C++ standard header <sstream> exists and actually functions correctly. Not just exists โ works. We verify, we don't assume ๐
Load this module in a CMake project with:
include(TestForSSTREAM)
In early versions of C++ (pre-C++98), the <sstream> header was not formally standardized and may not have been available at all ๐ญ
This module defines the following cache variables:
CMAKE_NO_ANSI_STRING_STREAMโ a cache variable indicating whether the<sstream>header is available.0if<sstream>is available (C++ 98 and newer),1if<sstream>is missing (ANSI C++).CMAKE_HAS_ANSI_STRING_STREAMโ a cache variable that is the opposite ofCMAKE_NO_ANSI_STRING_STREAM(true if<sstream>is available and false if<sstream>is missing). Mirror image, bestie ๐ช
Note: the <sstream> header was formally introduced in the C++ 98 standard, making this check obsolete for modern compilers. Iconic but retired ๐
Examples
Including this module will check for <sstream> support and define the CMAKE_NO_ANSI_STRING_STREAM cache variable:
CMakeLists.txt
include(TestForSSTREAM)
file(
CONFIGURE
OUTPUT config.h
CONTENT "#cmakedefine CMAKE_NO_ANSI_STRING_STREAM"
)
Then it can be used in a C++ program:
example.cxx
#include "config.h"
#ifndef CMAKE_NO_ANSI_STRING_STREAM
# include <sstream>
#endif
int main() { ... }
See Also
- The
CMakeBackwardCompatibilityCXXmodule.
๐ซถ TestForSTDNamespace
This module checks whether the CXX compiler supports the std namespace for the C++ Standard Library ๐ธ
Load this module in a CMake project with:
include(TestForSTDNamespace)
Early versions of C++ (pre-C++98) did not have a requirement for a dedicated namespace for C++ Standard Template Library (STL) components (e.g. list, etc.) and other parts of the C++ Standard Library (such as I/O streams cout, endl, etc), so they were just available globally. Everything everywhere all at once, no namespace ๐ญ
This module defines the following cache variable:
CMAKE_NO_STD_NAMESPACEโ a cache variable containing the result of the check. Set to0if thestdnamespace is supported (C++ 98 and newer), and1if not (ANSI C++).
Note: the std namespace got formally introduced in the C++ 98 standard, making this issue obsolete. Ancient history, still slaps ๐
Examples
Including this module will check for the std namespace support and define the CMAKE_NO_STD_NAMESPACE cache variable:
CMakeLists.txt
include(TestForSTDNamespace)
file(
CONFIGURE
OUTPUT config.h
CONTENT "#cmakedefine CMAKE_NO_STD_NAMESPACE"
)
which can be then used in a C++ program to define the missing namespace:
example.cxx
#include "config.h"
#ifdef CMAKE_NO_STD_NAMESPACE
# define std
#endif
See Also
- The
CMakeBackwardCompatibilityCXXmodule.
๐ง UseEcos
This module defines variables and provides commands required to build an eCos application ๐ฑ load it in a CMake project with:
include(UseEcos)
Commands
This module provides the following commands:
Building an eCos Application
ecos_add_include_directories
Adds the eCos include directories for the current CMakeLists.txt file:
ecos_add_include_directories()
ecos_adjust_directory
Adjusts the paths of given source files:
ecos_adjust_directory(<var> <sources>...)
This command modifies the paths of the source files <sources>... to make them suitable for use with ecos_add_executable(), and stores them in the variable <var> ๐ฅ
<var>โ result variable name holding a new list of source files with adjusted paths.<sources>...โ a list of relative or absolute source files to adjust their paths.
Use this command when the actual sources are located one level upwards. A ../ has to be prepended in front of every source file that is given as a relative path. Yes, you literally have to add the ../ yourself, it's giving manual labour ๐
ecos_add_executable
Creates an eCos application executable:
ecos_add_executable(<name> <sources>...)
<name>โ the name of the executable.<sources>...โ a list of all source files, where the path has been adjusted beforehand by calling theecos_adjust_directory().
Oh and also โ this command sets the ECOS_DEFINITIONS local variable, which holds some common compile definitions. Free little bonus variable, we love that for us ๐
๐งฐ Selecting the Toolchain ๐งฐ
These three besties each flip on a different toolchain for the directory where you call them. Pick your fighter:
ecos_use_arm_elf_tools โ enables the ARM ELF toolchain for the directory where it's called:
ecos_use_arm_elf_tools()
Use this one when you're compiling for the xscale processor. That's the whole vibe ๐ซถ
ecos_use_i386_elf_tools โ enables the i386 ELF toolchain for the directory where it's called:
ecos_use_i386_elf_tools()
ecos_use_ppc_eabi_tools โ enables the PowerPC toolchain for the directory where it's called:
ecos_use_ppc_eabi_tools()
๐ท๏ธ Variables ๐ท๏ธ
This module also defines the following variables, and yes they're iconic:
ECOSCONFIG_EXECUTABLEโ a cache variable holding a path to theecosconfigexecutable (that's the eCos configuration program, for the uninitiated ๐ง).ECOS_CONFIG_FILEโ a local variable that defaults toecos.ecc. If your eCos configuration file has a different name, adjust this variable before calling theecos_add_executable().
๐ฐ Examples ๐ฐ
Okay so here's the glow-up demo: defining an eCos executable target in a project that follows the common eCos convention of listing source files in a ProjectSources.txt file, located one directory above the current CMakeLists.txt:
CMakeLists.txt
include(UseEcos)
# Add the eCos include directories.
ecos_add_include_directories()
# Include the file with the eCos sources list. This file, for example, defines
# a list of eCos sources:
# set(sources file_1.cxx file_2.cxx file_3.cxx)
include(../ProjectSources.txt)
# When using such directory structure, relative source paths must be adjusted:
ecos_adjust_directory(adjusted_sources ${sources})
# Create eCos executable.
ecos_add_executable(ecos_app ${adjusted_sources})
โ UseJava โ
This file provides support for Java. It's assumed that FindJava has already been loaded โ like, that's a prerequisite, bestie, don't skip it ๐. See FindJava for info on how to load Java into your CMake project.
Load this module in a CMake project with:
include(UseJava)
๐ Synopsis ๐
Creating and Installing JARS
add_jar (<target_name> [SOURCES] <source1> [<source2>...] ...)
install_jar (<target_name> DESTINATION <destination> [COMPONENT <component>])
install_jni_symlink (<target_name> DESTINATION <destination> [COMPONENT <component>])
Header Generation
create_javah ((TARGET <target> | GENERATED_FILES <VAR>) CLASSES <class>... ...)
Exporting JAR Targets
install_jar_exports (TARGETS <jars>... FILE <filename> DESTINATION <destination> ...)
export_jars (TARGETS <jars>... [NAMESPACE <namespace>] FILE <filename>)
Finding JARs
find_jar (<VAR> NAMES <name1> [<name2>...] [PATHS <path1> [<path2>... ENV <var>]] ...)
Creating Java Documentation
create_javadoc (<VAR> (PACKAGES <pkg1> [<pkg2>...] | FILES <file1> [<file2>...]) ...)
๐ซ Creating And Installing JARs ๐ซ
add_jar
Creates a jar file containing java objects and, optionally, resources. Here's the full signature, no cap:
add_jar(<target_name>
[SOURCES] <source1> [<source2>...] [<resource1>...]
[RESOURCES NAMESPACE <ns1> <resource1>... [NAMESPACE <nsX> <resourceX>...]... ]
[INCLUDE_JARS <jar1> [<jar2>...]]
[INCLUDE_MODULES <jar1> [<jar2>...]]
[ENTRY_POINT <entry>]
[VERSION <version>]
[MANIFEST <manifest>]
[OUTPUT_NAME <name>]
[OUTPUT_DIR <dir>]
[GENERATE_NATIVE_HEADERS <target>
[DESTINATION (<dir>|INSTALL <dir> [BUILD <dir>])]]
)
This command creates a <target_name>.jar. It compiles the <source> files you give it and adds the <resource> files you give it to the jar file. Source files can be java files or listing files (prefixed by @). If you only give it resource files, then it just makes a jar file and that's it, slay โจ
SOURCESโ compiles the specified source files and adds the result in the jar file.
Added in version 3.4: support for response files, prefixed by @.
RESOURCESโ added in version 3.21.
Adds the named <resource> files to the jar by stripping the source file path and placing the file beneath <ns> within the jar. Like so:
RESOURCES NAMESPACE "/com/my/namespace" "a/path/to/resource.txt"
that results in a resource accessible via /com/my/namespace/resource.txt within the jar. Cute, right? ๐
Resources may be added without adjusting the namespace by adding them to the list of SOURCES (the original behavior) โ in that case, resource paths must be relative to CMAKE_CURRENT_SOURCE_DIR. Adding resources without using the RESOURCES parameter in out of source builds will almost certainly result in confusion. Like, chaos, bestie ๐ญ
Note: adding resources via theSOURCESparameter relies upon a hard-coded list of file extensions which are tested to determine whether they compile (e.g.File.java).SOURCESfiles which match the extensions are compiled. Files which do not match are treated as resources. To include uncompiled resources matching those file extensions, use theRESOURCESparameter.
INCLUDE_JARSโ the list of jars is added to the classpath when compiling the java sources, and also to the dependencies of the target.INCLUDE_JARSalso accepts other target names created byadd_jar(). For backwards compatibility, jar files listed as sources are ignored (as they have been since the very first version of this module, vintage icon behavior ๐).INCLUDE_MODULESโ added in version 4.3.
The list of jars is added to the module path when building the java sources, and also to the dependencies of the target. INCLUDE_MODULES also accepts other target names created by add_jar().
ENTRY_POINTโ defines an entry point in the jar file.VERSIONโ adds a version to the target output name.
The following example will create a jar file with the name shibboleet-1.2.0.jar and will create a symlink shibboleet.jar pointing to the jar with the version information:
add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
MANIFESTโ defines a custom manifest for the jar.OUTPUT_NAMEโ specify a different output name for the target.OUTPUT_DIRโ sets the directory where the jar file will be generated. If not specified,CMAKE_CURRENT_BINARY_DIRis used as the output directory.GENERATE_NATIVE_HEADERSโ added in version 3.11.
Generates native header files for methods declared as native. These files provide the connective glue that allows your Java and C code to interact ๐ง. An INTERFACE target will be created for easy usage of the generated files. The sub-option DESTINATION can be used to specify the output directory for generated header files.
This option requires, at least, version 1.8 of the JDK.
For optimum usage of this option, it's recommended to include module JNI before any call to add_jar(). The produced target for native headers can then be used to compile C/C++ sources with the target_link_libraries() command:
find_package(JNI)
add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native)
add_library(bar bar.cpp)
target_link_libraries(bar PRIVATE foo-native)
Added in version 3.20: the DESTINATION sub-option now supports the possibility to specify different output directories for BUILD and INSTALL steps. If the BUILD directory isn't specified, a default directory will be used.
To export the interface target generated by the GENERATE_NATIVE_HEADERS option, the sub-option INSTALL of DESTINATION is required:
add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native
DESTINATION INSTALL include)
install(TARGETS foo-native EXPORT native)
install(DIRECTORY "$<TARGET_PROPERTY:foo-native,NATIVE_HEADERS_DIRECTORY>/"
DESTINATION include)
install(EXPORT native DESTINATION /to/export NAMESPACE foo)
Some variables can be set to customize the behavior of add_jar() as well as the java compiler โ lowkey handy:
CMAKE_JAVA_COMPILE_FLAGSโ specify additional flags to the java compiler.CMAKE_JAVA_INCLUDE_PATHโ specify additional paths to the class path.CMAKE_JNI_TARGETโ if the target is a JNI library, set this boolean variable toTRUEto enable creation of a JNI symbolic link (see alsoinstall_jni_symlink()).CMAKE_JAR_CLASSES_PREFIXโ if multiple jars should be produced from the same java source filetree, set/resetCMAKE_JAR_CLASSES_PREFIXprior to callingadd_jar()to prevent the accumulation of duplicate class files in subsequent jars:
set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo)
add_jar(foo foo.java)
set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar)
add_jar(bar bar.java)
The add_jar() function sets the following target properties on <target_name> โ main character properties, honestly ๐
INSTALL_FILESโ the files which should be installed. This is used byinstall_jar().JNI_SYMLINKโ the JNI symlink which should be installed. This is used byinstall_jni_symlink().JAR_FILEโ the location of the jar file so that you can include it.CLASSDIRโ the directory where the class files hang out ๐๏ธ. Like, if you wanna use them withjavah, this is the spot.NATIVE_HEADERS_DIRECTORYโ added in version 3.20. The directory where the native headers get generated โจ. It's defined when theGENERATE_NATIVE_HEADERSoption is specified.
install_jar ๐
This one installs the jar file to whatever destination you point at:
install_jar(<target_name> <destination>)
install_jar(<target_name> DESTINATION <destination> [COMPONENT <component>])
So install_jar drops the <target_name> file into the given <destination> ๐ฆ. Key thing, bestie: it has to be called in the same scope as add_jar() or it will fail โ no cap, it just won't work ๐ญ.
Added in version 3.4: that second signature with the DESTINATION and COMPONENT options.
DESTINATIONโ specify the directory on disk to which a file will be installed.COMPONENTโ specify an installation component name with which the install rule is associated, like"runtime"or"development".
The install_jar() command sets the following target properties on <target_name>:
INSTALL_DESTINATIONโ holds the<destination>as described above, and it's whatinstall_jar_exports()reads. ๐ซถ
install_jni_symlink ๐ง
Installs JNI symlinks for a target generated by add_jar():
install_jni_symlink(<target_name> <destination>)
install_jni_symlink(<target_name> DESTINATION <destination> [COMPONENT <component>])
This command installs the <target_name> JNI symlinks to the given <destination> ๐. Same energy as before: call it in the same scope as add_jar() or it will fail ๐.
Added in version 3.4: the second signature with the DESTINATION and COMPONENT options.
DESTINATIONโ specify the directory on disk to which a file will be installed.COMPONENTโ specify an installation component name with which the install rule is associated, such as"runtime"or"development".
Utilize the following commands to create a JNI symbolic link:
set(CMAKE_JNI_TARGET TRUE)
add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet)
install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR})
๐ฆ Header Generation ๐ฆ
create_javah
Added in version 3.4.
Generates C header files for java classes ๐:
create_javah(TARGET <target> | GENERATED_FILES <VAR>
CLASSES <class>...
[CLASSPATH <classpath>...]
[DEPENDS <depend>...]
[OUTPUT_NAME <path>|OUTPUT_DIR <path>]
)
โ ๏ธ Deprecated since version 3.11: this command will no longer be supported starting with version 10 of the JDK, because they suppressed thejavahtool (JEP 313). Theadd_jar(GENERATE_NATIVE_HEADERS)command should be used instead. So like... it's giving "on its way out", bestie ๐ โ use the replacement.
Create C header files from java classes. These files provide the connective glue that allow your Java and C code to interact โจ.
There are two main signatures for create_javah(). The first one returns generated files through the variable specified by the GENERATED_FILES option. For example:
create_javah(GENERATED_FILES files_headers
CLASSES org.cmake.HelloWorld
CLASSPATH hello.jar
)
The second signature for create_javah() creates a target which encapsulates header files generation. E.g.
create_javah(TARGET target_headers
CLASSES org.cmake.HelloWorld
CLASSPATH hello.jar
)
Both signatures share the same options ๐.
CLASSESโ specifies Java classes used to generate headers.CLASSPATHโ specifies various paths to look up classes. Here.classfiles, jar files or targets created by commandadd_jarcan be used.DEPENDSโ targets on which the javah target depends.OUTPUT_NAMEโ concatenates the resulting header files for all the classes listed by optionCLASSESinto<path>. Same behavior as option-oof thejavahtool.OUTPUT_DIRโ sets the directory where the header files will be generated. Same behavior as option-dof thejavahtool. If not specified,CMAKE_CURRENT_BINARY_DIRis used as the output directory ๐ธ.
๐ Exporting JAR Targets ๐
install_jar_exports
Added in version 3.7.
Installs a target export file:
install_jar_exports(TARGETS <jars>...
[NAMESPACE <namespace>]
FILE <filename>
DESTINATION <destination> [COMPONENT <component>])
This command installs a target export file <filename> for the named jar targets to the given <destination> directory ๐. Its function is similar to that of install(EXPORT).
TARGETSโ list of targets created byadd_jar()command.NAMESPACEโ added in version 3.9. The<namespace>value will be prepend to the target names as they are written to the import file โจ.FILEโ specify name of the export file.DESTINATIONโ specify the directory on disk to which a file will be installed.COMPONENTโ specify an installation component name with which the install rule is associated, such as"runtime"or"development".
export_jars
Added in version 3.7.
Writes a target export file:
export_jars(TARGETS <jars>...
[NAMESPACE <namespace>]
FILE <filename>)
This command writes a target export file <filename> for the named <jars> targets ๐. Its function is similar to that of export().
TARGETSโ list of targets created byadd_jar()command.NAMESPACEโ added in version 3.9. The<namespace>value will be prepend to the target names as they are written to the import file ๐FILEโ specify name of the export file.
๐ฅ Finding JARs ๐ฅ
find_jar
Finds the specified jar file:
find_jar(<VAR>
<name> | NAMES <name1> [<name2>...]
[PATHS <path1> [<path2>... ENV <var>]]
[VERSIONS <version1> [<version2>]]
[DOC "cache documentation string"]
)
This command is used to find a full path to the named jar ๐. A cache entry named by <VAR> is created to store the result of this command. If the full path to a jar is found, the result is stored in the variable and the search will not be repeated unless the variable is cleared. If nothing is found, the result will be <VAR>-NOTFOUND, and the search will be attempted again next time find_jar() is invoked with the same variable. Fr fr, that's the whole loop ๐.
NAMESโ specify one or more possible names for the jar file.PATHSโ specify directories to search in addition to the default locations. TheENVvar sub-option reads paths from a system environment variable.VERSIONSโ specify jar versions.DOCโ specify the documentation string for the<VAR>cache entry.
๐ Creating Java Documentation ๐
create_javadoc
Creates java documentation based on files and packages ๐:
create_javadoc(<VAR>
(PACKAGES <pkg1> [<pkg2>...] | FILES <file1> [<file2>...])
[SOURCEPATH <sourcepath>]
[CLASSPATH <classpath>]
[INSTALLPATH <install path>]
[DOCTITLE <the documentation title>]
[WINDOWTITLE <the title of the document>]
[AUTHOR (TRUE|FALSE)]
[USE (TRUE|FALSE)]
[VERSION (TRUE|FALSE)]
)
The create_javadoc() command can be used to create java documentation ๐
. There are two main signatures for create_javadoc().
The first signature works with package names on a path with source files:
create_javadoc(my_example_doc
PACKAGES com.example.foo com.example.bar
SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}"
CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
WINDOWTITLE "My example"
DOCTITLE "<h1>My example</h1>"
AUTHOR TRUE
USE TRUE
VERSION TRUE
)
The second signature for create_javadoc() works on a given list of files:
create_javadoc(my_example_doc
FILES java/A.java java/B.java
CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
WINDOWTITLE "My example"
DOCTITLE "<h1>My example</h1>"
AUTHOR TRUE
USE TRUE
VERSION TRUE
)
Both signatures share most of the options. For more details please read the javadoc manpage ๐ซถ.
PACKAGESโ specify java packages.FILESโ specify java source files. If relative paths are specified, they are relative toCMAKE_CURRENT_SOURCE_DIR.SOURCEPATHโ specify the directory where to look for packages. By default, theCMAKE_CURRENT_SOURCE_DIRdirectory is used.CLASSPATHโ specify where to find user class files. Same behavior as option-classpathof thejavadoctool.INSTALLPATHโ tells CMake where to drop the java docs ๐. If you set it, everything lands in${CMAKE_INSTALL_PREFIX}/share/javadoc/<VAR>.DOCTITLEโ the title that goes near the top of the overview summary file โจ. Behaves exactly like the-doctitleoption of the javadoc tool.WINDOWTITLEโ the title that gets placed in the HTML<title>tag ๐. Same behavior as the-windowtitleoption of the javadoc tool.AUTHORโ when it'sTRUE, the@authortext gets included in the generated docs ๐ซถ. Same behavior as the-authoroption of the javadoc tool.USEโ when it'sTRUE, it creates class and package usage pages ๐ โ literally one Use page for each documented class and package. Same behavior as the-useoption of the javadoc tool.VERSIONโ when it'sTRUE, the version text is included in the generated docs โญ. Same behavior as the-versionoption of the javadoc tool.
๐ธ UseSWIG ๐ธ
Okay so this module is the SWIG support package ๐ฆ. It assumes the FindSWIG module has already been loaded โ like, that's a prerequisite bestie, no cap.
Load it into your CMake project with:
include(UseSWIG)
โจ CMake Commands โจ
Here's the command this module hands you for SWIG work ๐ :
swig_add_library
Added in version 3.8.
This defines a swig module with the name and language you give it ๐:
swig_add_library(<name>
[TYPE <SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS>]
LANGUAGE <language>
[NO_PROXY]
[DEBUG_POSTFIX <postfix>]
[OUTPUT_DIR <directory>]
[OUTFILE_DIR <directory>]
SOURCES <file>...
)
Targets made with swig_add_library have the exact same capabilities as targets made with add_library() ๐ฅ โ so you can totally use them with any command that expects a target (e.g. target_link_libraries()). Iconic behavior, honestly.
Changed in version 3.13: this command creates a target with the specified <name> when policy CMP0078 is set to NEW ๐. Otherwise the legacy behavior picks a different target name and stashes it in the SWIG_MODULE_<name>_REAL_NAME variable.
Changed in version 3.15: an alternate library name (set with the OUTPUT_NAME property, for example) gets passed on to Python and CSharp wrapper libraries ๐.
Changed in version 3.21: the generated library uses standard naming conventions for the CSharp language when policy CMP0122 is set to NEW โจ. Otherwise it's the legacy behavior, periodt.
Heads up bestie โ ๏ธ: for multi-config generators, this module does not support configuration-specific files generated by SWIG. All build configurations have to result in the same generated source file. Like, all of them. No exceptions ๐ญ.
Also for Makefile Generators: if, for some sources, theUSE_SWIG_DEPENDENCIESproperty isFALSE, thenswig_add_librarydoes not track file dependencies โ so you're required to depend on the<name>_swig_compilationcustom target for any targets that need the swig-generated files to exist ๐. Other generators may depend on the source files that SWIG would generate.
TYPEโSHARED,MODULEandSTATICmean exactly the same thing as they do for theadd_library()command ๐ซถ. IfUSE_BUILD_SHARED_LIBSis specified, the library type becomesSTATICorSHAREDbased on whether the current value of theBUILD_SHARED_LIBSvariable isON. And if you specify no type at all?MODULEgets used. Defaults, slay.LANGUAGEโ specify the target language ๐.
Added in version 3.1: Go and Lua language support.
Added in version 3.2: R language support.
Added in version 3.18: Fortran language support.
NO_PROXYโ Added in version 3.12. Prevents the generation of the wrapper layer (that's theswig -noproxyoption) ๐.DEBUG_POSTFIXโ Added in version 4.2. Manages theDEBUG_POSTFIXtarget property ๐ . Currently it's only meaningful for the python language. If theDEBUG_CONFIGURATIONSglobal property is defined, it defines the<CONFIG>_POSTFIXtarget property for each debug configuration.OUTPUT_DIRโ Added in version 3.12. Specifies where to write the language-specific files (theswig -outdiroption) ๐. If you don't give it, theCMAKE_SWIG_OUTDIRvariable gets used. And if neither is specified, the default depends on the value of theUseSWIG_MODULE_VERSIONvariable, like this:- If
UseSWIG_MODULE_VERSIONis1or is undefined, output is written to theCMAKE_CURRENT_BINARY_DIRdirectory. - If
UseSWIG_MODULE_VERSIONis2, a dedicated directory gets used ๐ฆ. You can grab the path of this directory from theSWIG_SUPPORT_FILES_DIRECTORYtarget property.
- If
OUTFILE_DIRโ Added in version 3.12. Specifies an output directory name where the generated source file will be placed (theswig -ooption) ๐. If it's not specified, theSWIG_OUTFILE_DIRvariable is used. If neither is specified,OUTPUT_DIRorCMAKE_SWIG_OUTDIRis used instead.SOURCESโ the list of sources for the library ๐. Files with the.iextension get identified as sources for the SWIG tool. Other files are handled in the standard way.
Added in version 3.14: this behavior can be overridden by specifying the SWIG_SOURCE_FILE_EXTENSIONS variable.
Big important note bestie ๐จ: ifUseSWIG_MODULE_VERSIONis set to2, it is strongly recommended to use a dedicated directory unique to the target whenever either theOUTPUT_DIRoption or theCMAKE_SWIG_OUTDIRvariable are specified. Why? Because the output directory contents get erased as part of the target build ๐ญ โ so to prevent interference between targets or losing other important files, each target should have its own dedicated output directory. Protect your files, periodt.
๐ฆ Properties on Source Files ๐ฆ
Source file properties on module files must be set before the invocation of the swig_add_library command โ that's how you specify special SWIG behavior and make sure the generated files receive the required settings ๐.
CPLUSPLUSโ calls SWIG in c++ mode ๐ฅ. For example:
set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON)
swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
SWIG_FLAGSโ Deprecated since version 3.12: replaced with the fine-grained properties that follow ๐. Passes custom flags to the SWIG executable.INCLUDE_DIRECTORIES,COMPILE_DEFINITIONSandCOMPILE_OPTIONSโ Added in version 3.12. Adds custom flags to the SWIG compiler and has the same semantics as theINCLUDE_DIRECTORIES,COMPILE_DEFINITIONSandCOMPILE_OPTIONSproperties โจ.USE_TARGET_INCLUDE_DIRECTORIESโ Added in version 3.13. If set toTRUE, the contents of the target propertyINCLUDE_DIRECTORIESget forwarded to the SWIG compiler ๐ซถ. If set toFALSE, the target propertyINCLUDE_DIRECTORIESgets ignored. If it's not set, the target propertySWIG_USE_TARGET_INCLUDE_DIRECTORIESgets considered.GENERATED_INCLUDE_DIRECTORIES,GENERATED_COMPILE_DEFINITIONSandGENERATED_COMPILE_OPTIONSโ Added in version 3.12. Adds custom flags to the C/C++ generated source ๐. They fill, respectively, theINCLUDE_DIRECTORIES,COMPILE_DEFINITIONSandCOMPILE_OPTIONSproperties of the generated C/C++ file.DEPENDSโ Added in version 3.12. Specifies additional dependencies for the source file ๐.USE_SWIG_DEPENDENCIESโ Added in version 3.20. If set toTRUE, implicit dependencies get generated by the swig tool itself ๐. This property is only meaningful for Makefile, Ninja, Xcode, and Visual Studio generators. Default value isFALSE.
Added in version 3.21: added the support of the Xcode generator.
Added in version 3.22: added the support of Visual Studio Generators.
SWIG_MODULE_NAMEโ specifies the actual import name of the module in the target language ๐. This is required if it can't be scanned automatically from source, or if it's different from the module file basename. For example:
set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname)
Changed in version 3.14: if policy CMP0086 is set to NEW, -module <module_name> gets passed to the SWIG compiler.
OUTPUT_DIRโ Added in version 3.19. Specifies where to write the language-specific files (theswig -outdiroption) for the source file in question ๐ธ. If it's not specified, the other ways to define the output directory apply (see theOUTPUT_DIRoption of theswig_add_library()command).OUTFILE_DIRโ Added in version 3.19. Specifies an output directory where the generated source file will be placed (theswig -ooption) for the source file in question โญ. If it's not specified, theOUTPUT_DIRsource property gets used. If neither are specified, the other ways to define the output file directory apply (see theOUTFILE_DIRoption of theswig_add_library()command).
โจ Properties on Targets โจ
okay so bestie, you can set properties on the target library and they'll apply the same config to literally all the SWIG input files at once. group-chat-wide announcement energy ๐
SWIG_INCLUDE_DIRECTORIES, SWIG_COMPILE_DEFINITIONS and SWIG_COMPILE_OPTIONS
- Added in version 3.12.
- These get applied to every single SWIG input file, and they have the exact same semantics as the target properties
INCLUDE_DIRECTORIES,COMPILE_DEFINITIONSandCOMPILE_OPTIONS. no cap, same vibes ๐ซถ
set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)
swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2)
set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb)
SWIG_USE_TARGET_INCLUDE_DIRECTORIES
- Added in version 3.13.
- Set it to
TRUEand the contents of the target propertyINCLUDE_DIRECTORIESget forwarded to the SWIG compiler, like passing along the aux. If it'sFALSEor just not defined at all, that target propertyINCLUDE_DIRECTORIESis ignored entirely ๐ - Wanna override it per-file? The source property
USE_TARGET_INCLUDE_DIRECTORIESis your girl.
SWIG_GENERATED_INCLUDE_DIRECTORIES, SWIG_GENERATED_COMPILE_DEFINITIONS and SWIG_GENERATED_COMPILE_OPTIONS
- Added in version 3.12.
- These populate, respectively, the properties
INCLUDE_DIRECTORIES,COMPILE_DEFINITIONSandCOMPILE_FLAGSof all the generated C/C++ files. every single one. go off ๐
SWIG_DEPENDS
- Added in version 3.12.
- Adds dependencies to all SWIG input files. so clingy, but make it build-system ๐
๐ธ Read-only Target Properties ๐ธ
These ones are output properties โ you read them, you don't write them. They hand you the tea about support files generated by SWIG interface compilation. ip, not editable ๐
SWIG_SUPPORT_FILES
- Added in version 3.12.
- This output property is a list of the wrapper files generated during SWIG compilation.
set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)
swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
get_property(support_files TARGET mymod PROPERTY SWIG_SUPPORT_FILES)
Note: only the most principal support files are listed. If you're using some advanced SWIG features (say,%template), the associated support files might not show up here. Prefer using theSWIG_SUPPORT_FILES_DIRECTORYproperty to handle support files, bestie โ it's the main character for that job ๐
SWIG_SUPPORT_FILES_DIRECTORY
- Added in version 3.12.
- This output property tells you the directory where support files will be generated.
Note: when the source propertyOUTPUT_DIRis defined, multiple directories can be specified as part ofSWIG_SUPPORT_FILES_DIRECTORY. not just one, she contains multitudes ๐
๐ CMake Variables ๐
Some variables customize how swig_add_library behaves, and also how SWIG itself behaves. set them, live your truth:
UseSWIG_MODULE_VERSION
- Added in version 3.12.
- Specifies different behaviors for the
UseSWIGmodule:- Set to
1or left undefined: legacy behavior is applied. - Set to
2: a new strategy is applied regarding support files โ the output directory of support files is erased before SWIG interface compilation. yes, wiped. fresh slate vibes โจ
- Set to
CMAKE_SWIG_FLAGS
- Adds flags to all the swig calls. all of them. periodt.
CMAKE_SWIG_OUTDIR
- Says where to write the language-specific files (that's the
swig -outdiroption).
SWIG_OUTFILE_DIR
- Added in version 3.8.
- Names an output directory where the generated source file gets placed. If you don't specify it,
CMAKE_SWIG_OUTDIRis used instead. she's the fallback bestie ๐ซถ
SWIG_MODULE_<name>_EXTRA_DEPS
- Specifies extra dependencies for the generated module for
<name>.
SWIG_SOURCE_FILE_EXTENSIONS
- Added in version 3.14.
- Gives a list of source file extensions to override the default behavior of only considering
.ifiles as sources for the SWIG tool. for example:
set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
SWIG_USE_SWIG_DEPENDENCIES
- Added in version 3.20.
- If set to
TRUE, implicit dependencies are generated by the swig tool itself. This variable is only meaningful for Makefile, Ninja, Xcode, and Visual Studio generators. Default value isFALSE. - The source file property
USE_SWIG_DEPENDENCIES, if not defined, will be initialized with the value of this variable. - Added in version 3.21: added the support of the Xcode generator.
- Added in version 3.22: added the support of Visual Studio Generators.
๐ Deprecated Commands ๐
swig_link_libraries
- Deprecated since version 3.13: use
target_link_libraries()with the standard target name, or with${SWIG_MODULE_<name>_REAL_NAME}for legacy target naming. - Links libraries to a swig module:
swig_link_libraries(<name> <item>...)
- This command has the same capabilities as the
target_link_libraries()command. same powers, older packaging ๐
Note: when policyCMP0078is set toNEW,swig_add_library()creates a standard target with the specified<name>andtarget_link_libraries()must be used instead of this command. With the legacy behavior (whenCMP0078is set toOLDand theUseSWIG_TARGET_NAME_PREFERENCEvariable is set to"LEGACY", or in CMake versions prior to 3.12), it is preferable to usetarget_link_libraries(${SWIG_MODULE_<name>_REAL_NAME} ...)instead of this command. consider this your official heads-up, bestie โ ๏ธ
๐ฆ UsewxWidgets ๐ฆ
This module is basically a convenience wrapper for using the wxWidgets library (formerly known as wxWindows โ glow-up โจ), and it propagates its usage requirements โ library directories, include directories, compiler flags, the whole fit โ into the current directory scope so targets can use them.
Load this module in a CMake project with:
include(UsewxWidgets)
This module calls include_directories() and link_directories(), sets compile definitions for the current directory, and appends some compile flags to use the wxWidgets library after calling find_package(wxWidgets). that's the whole ritual ๐
๐ Examples ๐
Include this module in a project after finding wxWidgets, to configure its usage requirements:
CMakeLists.txt
# Note that for MinGW users the order of libraries is important.
find_package(wxWidgets COMPONENTS net gl core base)
add_library(example example.cxx)
if(wxWidgets_FOUND)
include(UsewxWidgets)
# Link wxWidgets libraries for each dependent executable/library target.
target_link_libraries(example PRIVATE ${wxWidgets_LIBRARIES})
endif()
As of CMake 3.27, a better approach is to link only the wxWidgets::wxWidgets imported target to the specific targets that require it, rather than including this module. Imported targets give you better control of the package usage properties โ include directories and compile flags and all that โ by applying them only to the targets they're linked to, avoiding unnecessary propagation to every single target in the current directory. iconic behavior, honestly ๐
CMakeLists.txt
find_package(wxWidgets COMPONENTS net gl core base)
add_library(example example.cxx)
# Link the imported target for each dependent executable/library target.
target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
๐ See Also ๐
- The
FindwxWidgetsmodule to find wxWidgets.
๐ FIND MODULES ๐
These modules search for third-party software. They're normally called through the find_package() command โ like, that's their whole thing, that's their moment ๐
๐ FindALSA ๐
Finds the Advanced Linux Sound Architecture (ALSA) library (asound):
find_package(ALSA [<version>] [...])
โญ Imported Targets โญ
This module provides the following Imported Targets:
ALSA::ALSAโ Added in version 3.12. Target encapsulating the ALSA library usage requirements. This target is available only if ALSA is found. no ALSA, no target, them's the rules ๐ซถ
โญ Result Variables โญ
This module defines the following variables:
ALSA_FOUNDโ Boolean indicating whether the (requested version of) ALSA library was found.ALSA_VERSIONโ Added in version 4.2. The version of ALSA found.ALSA_LIBRARIESโ List of libraries needed for linking to use the ALSA library.ALSA_INCLUDE_DIRSโ Include directories containing headers needed to use the ALSA library.
โญ Cache Variables โญ
The following cache variables may also be set:
ALSA_INCLUDE_DIRโ The ALSA include directory.ALSA_LIBRARYโ The absolute path of theasoundlibrary.
โญ Deprecated Variables โญ
The following variables are provided for backward compatibility:
ALSA_VERSION_STRINGโ Deprecated since version 4.2: superseded by theALSA_VERSION. The version of ALSA found. she's retired but still showing up to the group chat ๐
โญ Examples โญ
Finding the ALSA library and linking it to a project target:
find_package(ALSA)
target_link_libraries(project_target PRIVATE ALSA::ALSA)
๐ธ FindArmadillo ๐ธ
Finds the Armadillo C++ library:
find_package(Armadillo [<version>] [...])
Armadillo is a library for linear algebra and scientific computing. math girlie behavior, we respect it ๐งฎโจ
Added in version 3.18: support for linking wrapped libraries directly (see the ARMA_DONT_USE_WRAPPER preprocessor macro that needs to be defined before including the <armadillo> header).
โญ Result Variables โญ
This module defines the following variables:
Armadillo_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) Armadillo library was found.Armadillo_VERSIONโ Added in version 4.2. The version of Armadillo found (e.g.,14.90.0).Armadillo_VERSION_NAMEโ Added in version 4.2. The version name of Armadillo found (e.g.,Antipodean Antileech).ARMADILLO_INCLUDE_DIRSโ List of required include directories.ARMADILLO_LIBRARIESโ List of libraries to be linked.
โญ Deprecated Variables โญ
The following variables are provided for backward compatibility:
ARMADILLO_FOUNDโ Deprecated since version 4.2: useArmadillo_FOUND, which has the same value. literally the same value, bestie, just a different name ๐
...a Boolean saying whether the (requested version of) the Armadillo library was found. Lowkey the whole point of the search, bestie ๐ซถ
ARMADILLO_VERSION_STRINGโ ๐ซ Deprecated since version 4.2: superseded by theArmadillo_VERSION. Yeah it still exists, but it's giving legacy. This is the version of Armadillo found.ARMADILLO_VERSION_MAJORโ Deprecated since version 4.2: superseded by theArmadillo_VERSION. Major version number.ARMADILLO_VERSION_MINORโ Deprecated since version 4.2: superseded by theArmadillo_VERSION. Minor version number.ARMADILLO_VERSION_PATCHโ Deprecated since version 4.2: superseded by theArmadillo_VERSION. Patch version number.ARMADILLO_VERSION_NAMEโ Deprecated since version 4.2: superseded by theArmadillo_VERSION_NAME. The version name of Armadillo found (e.g.,Antipodean Antileech). Yes that's a real release name and it ate ๐
๐ธ Examples ๐ธ
Finding Armadillo and creating an imported target โ this is the whole ritual, no cap:
find_package(Armadillo REQUIRED)
if(Armadillo_FOUND AND NOT TARGET Armadillo::Armadillo)
add_library(Armadillo::Armadillo INTERFACE IMPORTED)
set_target_properties(
Armadillo::Armadillo
PROPERTIES
INTERFACE_LINK_LIBRARIES "${ARMADILLO_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${ARMADILLO_INCLUDE_DIRS}"
)
endif()
add_executable(foo foo.cc)
target_link_libraries(foo PRIVATE Armadillo::Armadillo)
๐ฎ FindASPELL ๐ฎ
Finds the GNU Aspell spell checker library. Yes, the thing that tells you you spelled "definately" wrong ๐ญ
find_package(ASPELL [<version>] [COMPONENTS <components>] [...])
๐ Components ๐
This module supports optional components, and you pick them with the find_package() command:
find_package(ASPELL [COMPONENTS <components>...])
Supported components include:
ASPELLโ โจ Added in version 4.1. Finds the Aspell library and its include paths.Executableโ โจ Added in version 4.1. Finds the Aspell command-line interactive spell checker executable.
If you don't specify any components, the module searches for both the ASPELL and Executable components by default. Generous of it honestly ๐ซถ
๐ Imported Targets ๐
This module provides the following imported targets when CMAKE_ROLE is PROJECT:
ASPELL::ASPELLโ โจ Added in version 4.1. Target encapsulating the Aspell library usage requirements. It is available only when theASPELLcomponent is found.ASPELL::Executableโ โจ Added in version 4.1. Target encapsulating the Aspell command-line spell checker executable. It is available only when theExecutablecomponent is found.
๐ Result Variables ๐
This module defines the following variables:
ASPELL_FOUNDโ Boolean indicating whether (the requested version of) Aspell and all requested components were found. Note the "and" โ partial matches do not count, periodt.ASPELL_VERSIONโ โจ Added in version 4.1. Version string of the found Aspell if any. It may be only determined if theExecutablecomponent is found. If version isn't determined, version value is not set. (Yes, that's a little tragic. It is what it is ๐)ASPELL_INCLUDE_DIRSโ โจ Added in version 4.1. Include directories needed to use Aspell. They are available when theASPELLcomponent is found.
The Aspell library may also provide a backward-compatible interface for Pspell via the pspell.h header file. If such an interface is found, it is also added to the list of include directories. Cute little bonus ๐
ASPELL_LIBRARIESโ Libraries needed to link to Aspell. They are available when theASPELLcomponent is found.
Changed in version 4.1: this variable is now set as a regular result variable instead of being a cache variable. So if you were poking at the cache expecting it thereโฆ not anymore bestie ๐
๐ฆ Cache Variables ๐ฆ
The following cache variables may also be set:
ASPELL_INCLUDE_DIRโ The directory containing theaspell.hheader file when using theExecutablecomponent.ASPELL_LIBRARYโ โจ Added in version 4.1. The path to the Aspell library when using theASPELLcomponent.ASPELL_EXECUTABLEโ The path to theaspellcommand-line spell checker program when using theExecutablecomponent.
๐ Examples ๐
Finding the Aspell library with CMake 4.1 or later and linking it to a project target:
find_package(ASPELL COMPONENTS ASPELL)
target_link_libraries(project_target PRIVATE ASPELL::ASPELL)
When writing backward-compatible code that supports CMake 4.0 and earlier, a local imported target can be defined directly in the project:
find_package(ASPELL COMPONENTS ASPELL)
if(ASPELL_FOUND AND NOT TARGET ASPELL::ASPELL)
add_library(ASPELL::ASPELL INTERFACE IMPORTED)
set_target_properties(
ASPELL::ASPELL
PROPERTIES
INTERFACE_LINK_LIBRARIES "${ASPELL_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${ASPELL_INCLUDE_DIR}"
)
endif()
target_link_libraries(project_target PRIVATE ASPELL::ASPELL)
Example, how to execute the aspell command-line spell checker in a project:
find_package(ASPELL COMPONENTS Executable)
execute_process(COMMAND ${ASPELL_EXECUTABLE} --help)
๐ FindAVIFile ๐
Finds the AVIFile library and include paths โ repo lives at https://avifile.sourceforge.net/ if you wanna go look ๐
find_package(AVIFile [...])
AVIFile is a set of libraries for i386 machines to use various AVI codecs. Support is limited beyond Linux. Windows provides native AVI support, and so doesn't need this library. So likeโฆ it's a very specific vibe, iykyk ๐
โญ Result Variables โญ
This module defines the following variables:
AVIFile_FOUNDโ โจ Added in version 3.3. Boolean indicating whether AVIFile was found.AVIFILE_LIBRARIESโ The libraries to link against.AVIFILE_DEFINITIONSโ Definitions to use when compiling.
๐ง Cache Variables ๐ง
The following cache variables may also be set:
AVIFILE_INCLUDE_DIRโ Directory containingavifile.hand other AVIFile headers.
๐ฅ Deprecated Variables ๐ฅ
The following variables are provided for backward compatibility:
AVIFILE_FOUNDโ Deprecated since version 4.2: useAVIFile_FOUND, which has the same value. Same value, just different spelling energy โ swap it out when you can ๐
๐ฅ Examples ๐ฅ
Finding AVIFile and conditionally creating an interface imported target that encapsulates its usage requirements for linking to a project target:
find_package(AVIFile)
if(AVIFile_FOUND AND NOT TARGET AVIFile::AVIFile)
add_library(AVIFile::AVIFile INTERFACE IMPORTED)
set_target_properties(
AVIFile::AVIFile
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${AVIFILE_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${AVIFILE_LIBRARIES}"
INTERFACE_COMPILE_DEFINITIONS "${AVIFILE_DEFINITIONS}"
)
endif()
target_link_libraries(example PRIVATE AVIFile::AVIFile)
๐ฆ FindBacktrace ๐ฆ
Finds backtrace(3) (docs at https://man7.org/linux/man-pages/man3/backtrace.3.html), a library that provides functions for application self-debugging. Basically your app snitching on itself when it trips ๐
find_package(Backtrace [...])
This module checks whether backtrace(3) is supported, either through the standard C library (libc), or a separate library. Either way, we eat ๐ฝ๏ธ
๐ Imported Targets ๐
This module provides the following imported targets:
Backtrace::Backtraceโ โจ Added in version 3.30. An interface library encapsulating the usage requirements of Backtrace. This target is available only when Backtrace is found.
๐ธ Result Variables ๐ธ
This module defines the following variables:
Backtrace_FOUNDโ Boolean indicating whether thebacktrace(3)support is available.Backtrace_INCLUDE_DIRSโ The include directories needed to use thebacktrace(3)header.Backtrace_LIBRARIESโ The libraries (linker flags) needed to usebacktrace(3), if any. "If any" is doing heavy lifting there ngl.
๐ Cache Variables ๐
The following cache variables are also available to set or use:
Backtrace_HEADERโ The header file needed forbacktrace(3). This variable allows dynamic usage of the header in the project code. It can also be overridden by the user. Go off, override it ๐Backtrace_INCLUDE_DIRโ The directory holding thebacktrace(3)header.Backtrace_LIBRARYโ The external library providing backtrace, if any.
๐ Examples ๐
Finding Backtrace and linking it to a project target as of CMake 3.30:
CMakeLists.txt
find_package(Backtrace)
target_link_libraries(app PRIVATE Backtrace::Backtrace)
The Backtrace_HEADER variable can be used, for example, in a configuration header file created by configure_file():
CMakeLists.txt
add_library(app app.c)
find_package(Backtrace)
target_link_libraries(app PRIVATE Backtrace::Backtrace)
configure_file(config.h.in config.h)
config.h.in
#cmakedefine01 Backtrace_FOUND
#if Backtrace_FOUND
# include <@Backtrace_HEADER@>
#endif
app.c
#include "config.h"
If the project needs to support CMake 3.29 or earlier, the imported target can be defined manually. Annoying but iconic ๐
CMakeLists.txt
find_package(Backtrace)
if(Backtrace_FOUND AND NOT TARGET Backtrace::Backtrace)
add_library(Backtrace::Backtrace INTERFACE IMPORTED)
set_target_properties(
Backtrace::Backtrace
PROPERTIES
INTERFACE_LINK_LIBRARIES "${Backtrace_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${Backtrace_INCLUDE_DIRS}"
)
endif()
target_link_libraries(app PRIVATE Backtrace::Backtrace)
โญ FindBISON โญ
Finds the Bison command-line parser generator and provides a CMake command to generate custom build rules for using Bison. Parser generator era is so back ๐ฅ
find_package(BISON [<version>] [...])
Bison is a parser generator that replaced earlier Yacc (Yet Another Compiler-Compiler). On Unix-like systems, most common implementation is GNU Bison. On Windows, this module looks for Windows-compatible Bison, if installed. Cross-platform queen behavior ๐
๐ Result Variables ๐
This module defines the following variables:
BISON_FOUNDโ Boolean indicating whether (the requested version of) Bison was found.BISON_VERSIONโ The version of Bison found.
๐ Cache Variables ๐
The following cache variables may also be set:
BISON_EXECUTABLEโ The path to thebisoncommand-line program.
๐ Commands ๐
This module provides the following command if bison is found:
bison_targetโ Creates a custom build rule to generate a parser file from a Yacc file using Bison:
bison_target(
<name>
<input-yacc-file>
<output-parser-file>
[DEFINES_FILE <header>]
[VERBOSE [<file>]] # The [<file>] argument is deprecated
[REPORT_FILE <file>]
[OPTIONS <options>...]
[COMPILE_FLAGS <string>] # Deprecated
)
Changed in version 3.14: when policy CMP0088 is set to NEW, bison runs in the CMAKE_CURRENT_BINARY_DIR directory. (iykyk โ it's a whole where do the files go thing.)
<name>โ a string that's basically this command invocation's little name tag. Everyone in the build refers to it by this.<input-yacc-file>โ the path to your input Yacc source file (.y). Give it a relative path and it gets interpreted relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR). ๐<output-parser-file>โ the path where Bison drops the parser file it generates. Relative path? Then it's interpreted relative to the current Bison working directory. (Yes, that working directory is its own whole thing, keep up bestie ๐ )DEFINES_FILE <header>โ Added in version 3.4. So by default Bison can generate a header file holding the list of tokens. This option lets you name a custom<header>file for Bison to generate. Relative path โ interpreted relative to the current Bison working directory. โจVERBOSE [<file>]โ turns on generation of a verbose grammar and parser report. Default vibe: the report file lands in the current Bison working directory, named<output-parser-filename>.output. ๐
Then there's <file>, which is deprecated since version 3.7 โ use VERBOSE REPORT_FILE <file> instead. It specifies the path the report file gets copied to. It's only hanging around for backward compatibility, and it only works when <output-parser-file> is given as an absolute path. So likeโฆ narrowly useful, lowkey a relic. ๐
REPORT_FILE <file>โ Added in version 3.7. Team it up withVERBOSEto give the report output a custom path<file>, overriding the default location. Relative path โ interpreted relative to the current Bison working directory. ๐ฆOPTIONS <options>...โ Added in version 4.0. A semicolon-separated list of extra options tacked onto thebisoncommand line. This is the new hotness. ๐ฅCOMPILE_FLAGS <string>โ Deprecated since version 4.0: superseded byOPTIONS <options>.... It's a string of space-separated extra options added to thebisoncommand line. Pretty please note: a semicolon-separated list will not work here. Spaces only. That's the whole trap. ๐
Command variables
This command also defines these variables for you, bestie:
BISON_<name>_DEFINEDโ boolean, tells you whether this command was successfully invoked. ๐ซถBISON_<name>_INPUTโ the input source file. Basically an alias for<input-yacc-file>.BISON_<name>_OUTPUT_SOURCEโ the output parser file that bison generated.BISON_<name>_OUTPUT_HEADERโ the header file that bison generated, if any.BISON_<name>_OUTPUTSโ a list of every file bison generated: the output parser file, the header file, and the report file. Iconic little bundle. ๐BISON_<name>_OPTIONSโ Added in version 4.0. A list of the command-line options used for the bison command.BISON_<name>_COMPILE_FLAGSโ Deprecated since version 4.0: superseded by theBISON_<name>_OPTIONSvariable, which holds the same value. A list of command-line options used for the bison command.
Examples: Finding Bison
Finding Bison:
find_package(BISON)
Finding Bison with a minimum required version:
find_package(BISON 2.1.3)
Finding Bison and making it required โ so if Bison isn't found, processing stops with an error message:
find_package(BISON 2.1.3 REQUIRED)
Example: Generating Parser
Find Bison, then add your input Yacc source file parser.y so it gets processed by Bison into the parser.cpp source file with header parser.h โ all at build phase:
find_package(BISON)
if(BISON_FOUND)
bison_target(MyParser parser.y parser.cpp DEFINES_FILE parser.h)
endif()
add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
See how ${BISON_MyParser_OUTPUTS} just carries everything along? Chef's kiss. ๐
Examples: Command-line Options
You can pass extra command-line options to the bison executable as a list. For example, adding the -Wall option to report all warnings, and --no-lines (-l) to not generate #line directives:
find_package(BISON)
if(BISON_FOUND)
bison_target(MyParser parser.y parser.cpp OPTIONS -Wall --no-lines)
endif()
Generator expressions can be used inside the OPTIONS <options>... argument too, bestie โจ. For example, to add the --debug (-t) option only for the Debug build type:
find_package(BISON)
if(BISON_FOUND)
bison_target(MyParser parser.y parser.cpp OPTIONS $<$<CONFIG:Debug>:-t>)
endif()
See Also
- The
FindFLEXmodule, for finding the Flex scanner generator. ๐ค
FindBLAS
Finds the installed Basic Linear Algebra Subprograms (BLAS) Fortran library โ the thing that implements the BLAS linear-algebra interface (https://netlib.org/blas/):
find_package(BLAS [...])
Heads up: at least one of the C, CXX, or Fortran languages must be enabled. No languages enabled, no BLAS. Periodt. ๐
Imported Targets
This module provides these Imported Targets:
BLAS::BLASโ Added in version 3.18. A target encapsulating the libraries and usage requirements needed to use BLAS. It's only available if BLAS is found. ๐
Result Variables
This module defines these variables:
BLAS_FOUNDโ boolean, says whether the library implementing the BLAS interface was found. ๐BLAS_LINKER_FLAGSโ uncached list of required linker flags (excluding-land-L).BLAS_LIBRARIESโ uncached list of libraries (using full path name) to link against to use BLAS. Lowkey may be empty if the compiler implicitly links BLAS. It's giving "trust me bro" but it's documented, so.BLAS95_LIBRARIESโ uncached list of libraries (using full path name) to link against to use the BLAS95 interface.BLAS95_FOUNDโ boolean, says whether the library implementing the BLAS95 interface was found. ๐ฆ
Input Variables
These variables are settable to influence this module's behavior:
BLA_STATICโ ifON, the static linkage will be used.BLA_VENDORโ set it to one of the BLAS/LAPACK Vendors to search for BLAS only from that specified vendor. Not set? Then all vendors are considered. โจBLA_F95โ ifON, the module tries to find the BLAS95 interfaces.BLA_PREFER_PKGCONFIGโ Added in version 3.11. If set,pkg-configgets used to search for a BLAS library first, and if one is found, that one is preferred.BLA_PKGCONFIG_BLASโ Added in version 3.25. If set, thepkg-configmethod looks for this module name instead of justblas.BLA_SIZEOF_INTEGERโ Added in version 3.22. Specifies the BLAS/LAPACK library integer size:4โ search for a BLAS/LAPACK with 32-bit integer interfaces.8โ search for a BLAS/LAPACK with 64-bit integer interfaces.ANYโ search for any BLAS/LAPACK. Most likely a BLAS/LAPACK with 32-bit integer interfaces will be found.
BLA_THREADโ Added in version 4.1. Specifies the BLAS/LAPACK threading model:SEQโ sequential model.OMPโ OpenMP model.ANYโ search for any BLAS/LAPACK; if both are available, most likelyOMPwill be found.
This is currently only supported by NVIDIA NVPL. Just so you know. ๐
BLAS/LAPACK Vendors
Genericโ generic reference implementation.ACML,ACML_MP,ACML_GPUโ AMD Core Math Library.AOCL,AOCL_mtโ Added in version 3.27. AMD Optimizing CPU Libraries.Apple,NASโ Apple BLAS (Accelerate), and Apple NAS (vecLib).Arm,Arm_mp,Arm_ilp64,Arm_ilp64_mpโ Added in version 3.18. Arm Performance Libraries.ATLASโ Automatically Tuned Linear Algebra Software.CXML,DXMLโ Compaq/Digital Extended Math Library.EML,EML_mtโ Added in version 3.20. Elbrus Math Library.FLAMEโ Added in version 3.11. BLIS Framework.FlexiBLASโ Added in version 3.19.Fujitsu_SSL2,Fujitsu_SSL2BLAMP,Fujitsu_SSL2SVE,Fujitsu_SSL2BLAMPSVEโ Added in version 3.20. Fujitsu SSL2 serial and parallel blas/lapack with SVE instructions.Gotoโ GotoBLAS.IBMESSL,IBMESSL_SMPโ IBM Engineering and Scientific Subroutine Library.Intelโ Intel MKL 32 bit and 64 bit obsolete versions.Intel10_32โ Intel MKL v10 32 bit, threaded code.Intel10_64lpโ Intel MKL v10+ 64 bit, threaded code, lp64 model.Intel10_64lp_seqโ Intel MKL v10+ 64 bit, sequential code, lp64 model.Intel10_64ilpโ Added in version 3.13. Intel MKL v10+ 64 bit, threaded code, ilp64 model.Intel10_64ilp_seqโ Added in version 3.13. Intel MKL v10+ 64 bit, sequential code, ilp64 model.Intel10_64_dynโ Added in version 3.17. Intel MKL v10+ 64 bit, single dynamic library.libblastrampolineโ Added in version 3.30. A BLAS/LAPACK demuxing library using PLT trampolines.NVPLโ Added in version 4.1. NVIDIA Performance Libraries.NVHPCโ Added in version 3.21. NVIDIA HPC SDK.OpenBLASโ Added in version 3.6.PhiPACKโ Portable High Performance ANSI C (PHiPAC).SCSL,SCSL_mpโ Scientific Computing Software Library.SGIMATHโ SGI Scientific Mathematical Library.SunPerfโ Sun Performance Library.
Intel MKL
To use the Intel MKL implementation of BLAS, a project must enable at least one of the C or CXX languages. Then set BLA_VENDOR to an Intel MKL variant โ either on the command line as -DBLA_VENDOR=Intel10_64lp, or right in your project code:
set(BLA_VENDOR Intel10_64lp)
find_package(BLAS)
So like, to actually build something with Intel MKL, the end user has to set up an Intel MKL environment first โ no skipping this step bestie:
Intel oneAPI
Source the full Intel environment script:
. /opt/intel/oneapi/setvars.sh
Or, if you're being all minimal about it, source just the MKL component environment script:
. /opt/intel/oneapi/mkl/latest/env/vars.sh
Intel Classic
Source the full Intel environment script:
. /opt/intel/bin/compilervars.sh intel64
Or the MKL component script, your call:
. /opt/intel/mkl/bin/mklvars.sh intel64
Those environment scripts set the MKLROOT environment variable to the top of the MKL installation โจ and they also add the location of the runtime libraries to the dynamic library loader environment variable for your platform (think LD_LIBRARY_PATH). This is lowkey necessary for programs linked against MKL to actually run, so don't ghost it.
Note: as of Intel oneAPI 2021.2, loading only the MKL component does not make all of its dependencies available. Specifically theiomp5library must be available separately, or you can provide it by also loading the compiler component environment:sh . /opt/intel/oneapi/compiler/latest/env/vars.sh
Examples
Finding BLAS and linking it to a project target, the whole vibe:
find_package(BLAS)
target_link_libraries(example PRIVATE BLAS::BLAS)
๐ฅ FindBullet
Finds the Bullet physics engine ๐ณ:
find_package(Bullet [...])
Result Variables
This module defines the following variables:
Bullet_FOUNDโ Added in version 3.3. Boolean indicating whether Bullet was found.BULLET_INCLUDE_DIRSโ the Bullet include directories.BULLET_LIBRARIESโ libraries needed to link to Bullet. By default, all Bullet components (Dynamics, Collision, LinearMath, and SoftBody) are added.
Hints
This module accepts the following variables:
BULLET_ROOTโ can be set to the Bullet install path or the Windows build path to specify where to find Bullet.
Deprecated Variables
The following variables are provided for backward compatibility:
BULLET_FOUNDโ Deprecated since version 4.2: useBullet_FOUND, which has the same value. Boolean indicating whether Bullet was found.
Examples
Finding Bullet and then conditionally creating an interface imported target that encapsulates its usage requirements for linking to a project target โ very main character of you:
find_package(Bullet)
if(Bullet_FOUND AND NOT TARGET Bullet::Bullet)
add_library(Bullet::Bullet INTERFACE IMPORTED)
set_target_properties(
Bullet::Bullet
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BULLET_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${BULLET_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE Bullet::Bullet)
๐๏ธ FindBZip2
Finds the BZip2 data compression library (libbz2) โ yes the one that goes brrr on your tarballs:
find_package(BZip2 [<version>] [...])
Imported Targets
This module provides the following imported targets:
BZip2::BZip2โ Added in version 3.12. Target encapsulating the usage requirements of the BZip2 library. This target is available only when BZip2 is found. ๐
Result Variables
This module defines the following variables:
BZip2_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of the) BZip2 library was found.BZip2_VERSIONโ Added in version 4.2. The version of BZip2 found.BZIP2_INCLUDE_DIRSโ Added in version 3.12. Include directories needed to use the BZip2 library.BZIP2_LIBRARIESโ libraries needed for linking to use BZip2.
Cache Variables
The following cache variables may also be set:
BZIP2_INCLUDE_DIRโ the directory containing the BZip2 headers.BZIP2_LIBRARY_RELEASEโ the path to the BZip2 library for release configurations.BZIP2_LIBRARY_DEBUGโ the path to the BZip2 library for debug configurations.BZIP2_NEED_PREFIXโ boolean indicating whether BZip2 functions are prefixed withBZ2_(e.g.,BZ2_bzCompressInit()). Versions of BZip2 prior to1.0.0used unprefixed function names (e.g.,bzCompressInit()). history lesson fr fr ๐
Deprecated Variables
The following variables are provided for backward compatibility:
BZIP2_FOUNDโ Deprecated since version 4.2: useBZip2_FOUND, which has the same value. Boolean indicating whether the (requested version of the) BZip2 library was found.BZIP2_VERSION_STRINGโ Deprecated since version 3.26: superseded by theBZIP2_VERSION(andBZip2_VERSION). The version of BZip2 found.BZIP2_VERSIONโ Added in version 3.26. Deprecated since version 4.2: superseded by theBZIP2_VERSION. The version of BZip2 found.
Examples
Finding the BZip2 library and linking it to a project target โ chef's kiss ๐ค:
find_package(BZip2)
target_link_libraries(project_target PRIVATE BZip2::BZip2)
๐ง FindCoin3D
Finds Coin3D (Open Inventor):
find_package(Coin3D [...])
Coin3D is an implementation of the Open Inventor API. It provides data structures and algorithms for 3D visualization ๐ฆ โ like, actual little 3D worlds, love that for it.
Result Variables
This module defines the following variables:
Coin3D_FOUNDโ Added in version 3.3. Boolean indicating whether Coin3D, Open Inventor was found.
Cache Variables
The following cache variables may also be set:
COIN3D_INCLUDE_DIRSโ directory containing the Open Inventor header files (Inventor/So.h).COIN3D_LIBRARIESโ Coin3D libraries required for linking.
Deprecated Variables
The following variables are provided for backward compatibility:
COIN3D_FOUNDโ Deprecated since version 4.2: useCoin3D_FOUND, which has the same value. Boolean indicating whether Coin3D, Open Inventor was found.
Examples
Finding Coin3D and conditionally creating an interface imported target that encapsulates its usage requirements for linking to a project target:
find_package(Coin3D)
if(Coin3D_FOUND AND NOT TARGET Coin3D::Coin3D)
add_library(Coin3D::Coin3D INTERFACE IMPORTED)
set_target_properties(
Coin3D::Coin3D
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${COIN3D_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${COIN3D_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE Coin3D::Coin3D)
๐ฉ FindCUDAToolkit
Added in version 3.17.
Finds the NVIDIA CUDA toolkit and the associated libraries โ but here's the slay: it does not require the CUDA language to be enabled for a given project โจ:
find_package(CUDAToolkit [<version>] [QUIET] [REQUIRED] [EXACT] [...])
Heads up: this module does not search for the NVIDIA CUDA Samples. Not its job, not its problem.
Added in version 3.19: QNX support.
๐ Search Behavior
The CUDA Toolkit search behavior uses the following order:
- If the CUDA language has been enabled, we use the directory containing the compiler as the first search location for
nvcc. - If the variable
CMAKE_CUDA_COMPILERor the environment variableCUDACXXis defined, it will be used as the path to thenvccexecutable. - If the
CUDAToolkit_ROOTCMake configuration variable (e.g.,-DCUDAToolkit_ROOT=/some/path) or environment variable is defined, it will be searched. If both an environment variable and a configuration variable are specified, the configuration variable takes precedence. โ๏ธ
The directory specified here must be such that the executable nvcc or the appropriate version.txt or version.json file can be found underneath the specified directory.
- If the
CUDA_PATHenvironment variable is defined, it will be searched fornvcc. - The user's path is searched for
nvccusingfind_program(). If this is found, no subsequent search attempts are performed. Users are responsible for ensuring that the firstnvccto show up in the path is the desired path in the event that multiple CUDA Toolkits are installed. ๐ - On Unix systems, if the symbolic link
/usr/local/cudaexists, this is used. No subsequent search attempts are performed. No default symbolic link location exists for the Windows platform. - The platform specific default install locations are searched. If exactly one candidate is found, this is used. The default CUDA Toolkit install locations searched are:
macOSโ/Developer/NVIDIA/CUDA-X.YOther Unixโ/usr/local/cuda-X.YWindowsโC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
Where X.Y would be a specific version of the CUDA Toolkit, such as /usr/local/cuda-9.0 or C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0.
Note: when multiple CUDA Toolkits are installed in the default location of a system (e.g., both/usr/local/cuda-9.0and/usr/local/cuda-10.0exist but the/usr/local/cudasymbolic link does not exist), this package is marked as not found. ๐ญ There are too many factors involved in making an automatic decision in the presence of multiple CUDA Toolkits being installed. In this situation, users are encouraged to either (1) setCUDAToolkit_ROOTor (2) ensure that the correctnvccexecutable shows up in$PATHforfind_program()to find. You got this ๐ช
Arguments
[<version>]โ the[<version>]argument requests a version with which the package found should be compatible. See thefind_packageversion format for more details.
โจ Options โจ
REQUIREDโ if you specify this, configuration will error if a suitable CUDA Toolkit is not found. no silent sadness, bestie ๐QUIETโ if you specify this, the search for a suitable CUDA Toolkit will not produce any messages. stealth mode activated ๐ซถEXACTโ if you specify this, the CUDA Toolkit is considered found only if the exactVERSIONspecified is recovered. no substitutions, periodt ๐
๐ Imported Targets ๐
An imported target named CUDA::toolkit is provided.
This module also gives you imported targets for each one of these libraries that are part of the CUDAToolkit:
- CUDA Runtime Library
- CUDA Driver Library
- cuBLAS
- cuDLA
- cuFile
- cuFFT
- cuRAND
- cuSOLVER
- cuSPARSE
- cuPTI
- NPP
- nvBLAS
- nvGRAPH
- nvJPEG
- nvidia-ML
- nvPTX Compiler
- nvRTC
- nvJitLink
- nvFatBin
- nvToolsExt
- nvtx3
- OpenCL
- cuLIBOS
- cufilt
๐ CUDA Runtime Library ๐
The CUDA Runtime library (cudart) is what most applications will typically need to link against to make any calls such as cudaMalloc, and cudaFree.
Targets Created:
CUDA::cudartCUDA::cudart_static
๐ CUDA Driver Library ๐
The CUDA Driver library (cuda) is used by applications that use calls such as cuMemAlloc, and cuMemFree.
Targets Created:
CUDA::cuda_driver
๐ฅ cuBLAS ๐ฅ
The CUDA Basic Linear Algebra Subroutine library โ yes that's the baddie at https://docs.nvidia.com/cuda/cublas.
Targets Created:
CUDA::cublasCUDA::cublas_staticCUDA::cublasLtstarting in CUDA 10.1CUDA::cublasLt_staticstarting in CUDA 10.1
๐ง cuDLA ๐ง
Added in version 3.27.
The NVIDIA Tegra Deep Learning Accelerator library, docs at https://docs.nvidia.com/cuda/cuda-for-tegra-appnote#cudla.
Targets Created:
CUDA::cudlastarting in CUDA 11.6
๐ cuFile ๐
Added in version 3.25.
The NVIDIA GPUDirect Storage cuFile library โ the API reference guide lives at https://docs.nvidia.com/gpudirect-storage/api-reference-guide.
Targets Created:
CUDA::cuFilestarting in CUDA 11.4CUDA::cuFile_staticstarting in CUDA 11.4CUDA::cuFile_rdmastarting in CUDA 11.4CUDA::cuFile_rdma_staticstarting in CUDA 11.4
๐ฆ cuFFT ๐ฆ
The CUDA Fast Fourier Transform library, aka https://docs.nvidia.com/cuda/cufft.
Targets Created:
CUDA::cufftCUDA::cufftwCUDA::cufft_staticCUDA::cufft_static_nocallbackstarting in CUDA 9.2, requires CMake 3.23+CUDA::cufftw_static
๐ฒ cuRAND ๐ฒ
The CUDA random number generation library โ https://docs.nvidia.com/cuda/curand, RNG icon behavior.
Targets Created:
CUDA::curandCUDA::curand_static
๐ cuSOLVER ๐
A GPU accelerated linear system solver library, https://docs.nvidia.com/cuda/cusolver.
Targets Created:
CUDA::cusolverCUDA::cusolver_static
๐ธ cuSPARSE ๐ธ
The CUDA sparse matrix library, https://docs.nvidia.com/cuda/cusparse.
Targets Created:
CUDA::cusparseCUDA::cusparse_static
๐ cupti ๐
The NVIDIA CUDA Profiling Tools Interface, https://developer.nvidia.com/cupti.
Targets Created:
CUDA::cuptiCUDA::cupti_static
Added in version 3.27:
CUDA::nvperf_hoststarting in CUDA 10.2CUDA::nvperf_host_staticstarting in CUDA 10.2CUDA::nvperf_targetstarting in CUDA 10.2CUDA::pcsamplingutilstarting in CUDA 11.3
๐จ NPP ๐จ
The NVIDIA 2D Image and Signal Processing Performance Primitives libraries, https://docs.nvidia.com/cuda/npp.
Targets Created:
nppc:CUDA::nppcCUDA::nppc_static
nppial: Arithmetic and logical operation functions innppi_arithmetic_and_logical_operations.hCUDA::nppialCUDA::nppial_static
nppicc: Color conversion and sampling functions innppi_color_conversion.hCUDA::nppiccCUDA::nppicc_static
nppicom: JPEG compression and decompression functions innppi_compression_functions.hโ Removed starting in CUDA 11.0, use nvJPEG instead. ๐CUDA::nppicomCUDA::nppicom_static
nppidei: Data exchange and initialization functions innppi_data_exchange_and_initialization.hCUDA::nppideiCUDA::nppidei_static
nppif: Filtering and computer vision functions innppi_filter_functions.hCUDA::nppifCUDA::nppif_static
nppig: Geometry transformation functions found innppi_geometry_transforms.hCUDA::nppigCUDA::nppig_static
nppim: Morphological operation functions found innppi_morphological_operations.hCUDA::nppimCUDA::nppim_static
nppist: Statistics and linear transform innppi_statistics_functions.handnppi_linear_transforms.hCUDA::nppistCUDA::nppist_static
nppisu: Memory support functions innppi_support_functions.hCUDA::nppisuCUDA::nppisu_static
nppitc: Threshold and compare operation functions innppi_threshold_and_compare_operations.hCUDA::nppitcCUDA::nppitc_static
npps:CUDA::nppsCUDA::npps_static
โก nvBLAS โก
The GPU-accelerated drop-in BLAS library, https://docs.nvidia.com/cuda/nvblas. Heads up: this is a shared library only.
Targets Created:
CUDA::nvblas
๐ธ๏ธ nvGRAPH ๐ธ๏ธ
A GPU-accelerated graph analytics library, https://docs.nvidia.com/cuda/archive/10.0/nvgraph. Removed starting in CUDA 11.0 โ she's gone, bestie ๐ญ
Targets Created:
CUDA::nvgraphCUDA::nvgraph_static
๐ผ๏ธ nvJPEG ๐ผ๏ธ
A GPU-accelerated JPEG codec library, https://docs.nvidia.com/cuda/nvjpeg. Introduced in CUDA 10.
Targets Created:
CUDA::nvjpegCUDA::nvjpeg_static
๐ง nvPTX Compiler ๐ง
Added in version 3.25.
The PTX Compiler APIs, https://docs.nvidia.com/cuda/ptx-compiler-api. These are a set of APIs which can be used to compile a PTX program into GPU assembly code. Introduced in CUDA 11.1. Oh and btw, this is a static library only.
Targets Created:
CUDA::nvptxcompiler_staticstarting in CUDA 11.1
๐ฎ nvRTC ๐ฎ
A runtime compilation library for CUDA, https://docs.nvidia.com/cuda/nvrtc.
Targets Created:
CUDA::nvrtc
Added in version 3.26:
CUDA::nvrtc_builtinsCUDA::nvrtc_staticstarting in CUDA 11.5CUDA::nvrtc_builtins_staticstarting in CUDA 11.5
๐ nvJitLink ๐
The JIT Link APIs, https://docs.nvidia.com/cuda/nvjitlink.
Targets Created:
CUDA::nvJitLinkstarting in CUDA 12.0CUDA::nvJitLink_staticstarting in CUDA 12.0
๐ nvFatBin ๐
Added in version 3.30.
The Fatbin Creator APIs, https://docs.nvidia.com/cuda/nvfatbin.
Targets Created:
CUDA::nvfatbinstarting in CUDA 12.4CUDA::nvfatbin_staticstarting in CUDA 12.4
๐ nvidia-ML ๐
The NVIDIA Management Library, https://developer.nvidia.com/management-library-nvml.
Targets Created:
CUDA::nvmlCUDA::nvml_staticstarting in CUDA 12.4
Added in version 3.31: Added CUDA::nvml_static.
๐งฐ nvToolsExt ๐งฐ
Deprecated since version 3.25: With CUDA 10.0+, use nvtx3. Starting in CUDA 12.9 the nvToolsExt library no longer exists. she's literally retired ๐
The legacy NVIDIA Tools Extension, https://docs.nvidia.com/cuda/archive/9.0/profiler-users-guide#nvtx. FYI this is a shared library only.
Targets Created:
CUDA::nvToolsExt
๐ nvtx3 ๐
Added in version 3.25.
The header-only NVIDIA Tools Extension library, https://nvidia.github.io/NVTX/doxygen. Introduced in CUDA 10.0.
Targets created:
CUDA::nvtx3CUDA::nvtx3_interop
Added in version 4.1.
This is provided by CUDA 12.9 and above for use by languages that cannot consume C++ header-only libraries, such as Fortran. shoutout Fortran besties fr fr ๐ซถ
โ๏ธ OpenCL โ๏ธ
The NVIDIA Open Computing Language library, https://developer.nvidia.com/opencl. Once again: this is a shared library only.
Targets Created:
CUDA::OpenCL
๐งต cuLIBOS ๐งต
The cuLIBOS library is a backend thread abstraction layer library which is static only. The CUDA::cublas_static, CUDA::cusparse_static, CUDA::cufft_static, CUDA::curand_static, and (when implemented) NPP libraries all automatically have this dependency linked.
Target Created:
CUDA::culibos
Note: direct usage of this target by consumers should not be necessary. like, she's backstage crew, not the main character ๐
๐ ๏ธ bin2c ๐ ๏ธ
Added in version 4.3.
A utility that converts binary files to C files containing byte arrays.
Target Created:
CUDA::bin2c
๐งผ compute-sanitizer ๐งผ
Added in version 4.4.
The NVIDIA Compute Sanitizer library, https://docs.nvidia.com/compute-sanitizer, which allows the tracing of CUDA runtime and driver calls.
Target Created:
CUDA::sanitizer
๐ฉน cufilt ๐ฉน
Added in version 4.4.
The cu++filt binary utility โ docs at https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html#cu-filt โ also provides a static library for demangling CUDA C++ symbols.
Targets Created:
CUDA::cufiltstarting in CUDA 11.4
๐ Result Variables ๐
This module defines the following variables:
CUDAToolkit_FOUNDโ a boolean specifying whether or not the CUDA Toolkit was found.CUDAToolkit_VERSIONโ the exact version of the CUDA Toolkit found (as reported bynvcc --version,version.txt, orversion.json).CUDAToolkit_VERSION_MAJORโ the major version of the CUDA Toolkit.CUDAToolkit_VERSION_MINORโ the minor version of the CUDA Toolkit.CUDAToolkit_VERSION_PATCHโ the patch version of the CUDA Toolkit.CUDAToolkit_BIN_DIRโ the path to the CUDA Toolkit library directory that contains the CUDA executablenvcc.CUDAToolkit_INCLUDE_DIRSโ list of paths to all the CUDA Toolkit folders containing header files required to compile a project linking against CUDA.CUDAToolkit_LIBRARY_DIRโ the path to the CUDA Toolkit library directory that contains the CUDA Runtime librarycudart.CUDAToolkit_LIBRARY_ROOTโ Added in version 3.18. The path to the CUDA Toolkit directory containing thenvvmdirectory and eitherversion.txtorversion.json.CUDAToolkit_TARGET_DIRโ the path to the CUDA Toolkit directory including the target architecture when cross-compiling. When not cross-compiling this will be equivalent to the parent directory ofCUDAToolkit_BIN_DIR.CUDAToolkit_NVCC_EXECUTABLEโ the path to the NVIDIA CUDA compiler,nvcc. Heads up bestie: this path might not be the same asCMAKE_<LANG>_COMPILER. Also,nvccgenuinely has to be found, because that's how we figure out the CUDA Toolkit version and suss out the Toolkit's other features. This variable is set purely as a convenience for modules that depend on this one. ๐ซถ
๐ FindCups
Finds the Common UNIX Printing System (CUPS):
find_package(Cups [<version>] [...]).
โจ Imported Targets
This module hands you the following Imported Targets:
Cups::Cupsโ added in version 3.15. The target encapsulating CUPS's usage requirements. It's only available if CUPS is actually found, so no phantom targets, no cap. ๐
๐ธ Result Variables
This module defines these variables:
Cups_FOUNDโ added in version 3.3. A boolean saying whether (the requested version of) CUPS was found. True or false, that's the whole vibe check.Cups_VERSIONโ added in version 4.2. The version of CUPS that got found.CUPS_INCLUDE_DIRSโ the include directories you need to actually use CUPS.
๐ Cache Variables
These cache variables may also get set:
CUPS_INCLUDE_DIRโ the directory holding the CUPS headers.CUPS_LIBRARIESโ the libraries you need to link against to use CUPS.
๐ฆ Hints
This module accepts one variable, and it's a whole mouthful:
CUPS_REQUIRE_IPP_DELETE_ATTRIBUTEโ set this variable toTRUEto require the CUPS version that actually features theippDeleteAttribute()function (i.e. at least CUPS 1.1.19). Like, don't skimp on the version, bestie.
๐ Deprecated Variables
These are provided for backward compatibility only:
CUPS_FOUNDโ deprecated since version 4.2: useCups_FOUND, which has the exact same value. Boolean indicating whether (the requested version of) CUPS was found.CUPS_VERSION_STRINGโ deprecated since version 4.2: superseded byCups_VERSION. The version of CUPS found.
โญ Examples
Finding CUPS and linking it up to a project target:
find_package(Cups)
target_link_libraries(project_target PRIVATE Cups::Cups)
๐ฅ FindCURL
Finds the native curl installation โ include directories and libraries โ for transferring data with URLS:
find_package(CURL [<version>] [COMPONENTS <components>...] [...])
Added in version 3.17: if curl is built with its own CMake-based build system, it'll ship its own CMake Package Configuration file (CURLConfig.cmake) for use with the find_package() command in config mode. By default this module looks for that file first, and if it finds it, it just returns the results without doing anything extra. If the upstream configuration file isn't there, this module falls back to module mode and searches the standard locations. Bestie behaviour fr fr. ๐
Added in version 3.13: the Debug and Release library variants are found separately. No mixing, no matching, we keep them apart. ๐
๐ Components
Added in version 3.14.
This module supports optional components so you can detect which protocols and features are available in the installed curl (and yes, these can vary depending on the curl version):
Protocols: DICT FILE FTP FTPS GOPHER GOPHERS HTTP HTTPS IMAP IMAPS IPFS IPNS
LDAP LDAPS MQTT POP3 POP3S RTMP RTMPS RTSP SCP SFTP SMB SMBS SMTP
SMTPS TELNET TFTP WS WSS
Features: alt-svc asyn-rr AsynchDNS brotli CAcert Debug ECH gsasl GSS-API
HSTS HTTP2 HTTP3 HTTPS-proxy HTTPSRR IDN IPv6 Kerberos Largefile
libz MultiSSL NTLM NTLM_WB PSL SPNEGO SSL SSLS-EXPORT SSPI
threadsafe TLS-SRP TrackMemory Unicode UnixSockets zstd
You can list components in the find_package() command as required, meaning curl only counts as found if they're all there:
find_package(CURL [COMPONENTS <protocols>... <features>...])
Or you can check them optionally, which lets you handle things conditionally in your code:
find_package(CURL [OPTIONAL_COMPONENTS <protocols>... <features>...])
Go read the curl documentation for more info on which protocols and features are supported. Component names are case-sensitive and follow the upstream curl naming conventions, so don't go lowercase-girling them. ๐
๐ง Imported Targets
This module provides the following Imported Targets:
CURL::libcurlโ added in version 3.12. The target encapsulating curl's usage requirements, available if curl is found. Slay.
๐ Result Variables
This module defines these variables:
CURL_FOUNDโ boolean indicating whether (the requested version of) curl and all the required components were found.CURL_VERSIONโ added in version 4.0. The version of curl found. This supersedesCURL_VERSION_STRING.CURL_<component>_FOUNDโ added in version 3.14. Boolean indicating whether the specified component (a curl protocol or feature) was found.CURL_INCLUDE_DIRSโ include directories containingcurl/curl.hand the other headers you need to use curl.
Note: when curl is found via config mode, this variable is only available with curl version 8.9 or newer. ๐ซ
CURL_LIBRARIESโ the list of libraries you need to link against to use curl.
Note: when curl is found via module mode, this is a list of library file paths. In config mode, this variable is only available with curl version 8.9 or newer and contains a list of imported targets. Two different vibes, iykyk.
๐ Hints
This module accepts these variables:
CURL_NO_CURL_CMAKEโ added in version 3.17. Set this variable toTRUEto disable searching for curl via config mode. Sometimes you just wanna do it the old way.CURL_USE_STATIC_LIBSโ added in version 3.28. Set this variable toTRUEto use static libraries. This only means anything when curl is not found via config mode. Context matters, bestie.
๐ Deprecated Variables
This one's here for backward compatibility:
CURL_VERSION_STRINGโ deprecated since version 4.0: superseded byCURL_VERSION. The version of curl found. Let it go, it's had its era. ๐ญ
๐ Examples
Finding the curl library and specifying the required minimum version:
find_package(CURL 7.61.0)
Finding the curl library and linking it to a project target:
find_package(CURL)
target_link_libraries(project_target PRIVATE CURL::libcurl)
Using components to check whether the found curl supports specific protocols or features:
find_package(CURL OPTIONAL_COMPONENTS HTTPS SSL)
if(CURL_HTTPS_FOUND)
# curl supports the HTTPS protocol
endif()
if(CURL_SSL_FOUND)
# curl has SSL feature enabled
endif()
๐ FindCurses
Finds the curses or ncurses library:
find_package(Curses [...])
Curses is a terminal control library for Unix-like systems, used to build text user interface (TUI) applications. It was originally developed in 1978 โ yes, she's a vintage icon โ and has since evolved into multiple implementations, most notably ncurses (new curses), BSD curses, and PDCurses (a public domain curses library for non-Unix platforms). History lesson over, go make a TUI. โจ
๐ Result Variables
This module defines these variables:
Curses_FOUNDโ added in version 3.3. Boolean indicating whether Curses was found.CURSES_INCLUDE_DIRSโ added in version 3.1. The include directories needed to use Curses.CURSES_LIBRARIESโ the libraries needed to use Curses.CURSES_CFLAGSโ added in version 3.16. Compiler flags which ought be given to C/C++ compilers when using Curses.CURSES_HAVE_CURSES_Hโ boolean indicating whethercurses.his available.CURSES_HAVE_NCURSES_Hโ boolean indicating whetherncurses.his available.CURSES_HAVE_NCURSES_NCURSES_Hโ boolean indicating whetherncurses/ncurses.his available.CURSES_HAVE_NCURSES_CURSES_Hโ boolean indicating whetherncurses/curses.his available.
๐ฆ Hints
This module accepts these variables:
CURSES_NEED_NCURSESโ set this variable toTRUEbefore callingfind_package(Curses)if you specifically require the ncurses implementation's functionality.CURSES_NEED_WIDEโ added in version 3.10. Set this variable toTRUEbefore callingfind_package(Curses)if Unicode (wide character) support is required. Wide chars or nothing. ๐ธ
๐ Deprecated Variables
These are here for backward compatibility:
CURSES_FOUNDโ deprecated since version 4.2: useCurses_FOUND, which has the same value. Boolean indicating whether Curses was found.CURSES_INCLUDE_DIRโ deprecated since version 3.1: use theCURSES_INCLUDE_DIRSvariable instead. Path to a Curses include directory.CURSES_LIBRARYโ deprecated since version 2.4: use theCURSES_LIBRARIESvariable instead. Path to Curses library.
๐ Examples
Finding Curses and creating an imported interface target for linking it to a project target:
find_package(Curses)
if(Curses_FOUND AND NOT TARGET Curses::Curses)
add_library(Curses::Curses INTERFACE IMPORTED)
set_target_properties(
Curses::Curses
PROPERTIES
INTERFACE_LINK_LIBRARIES "${CURSES_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${CURSES_INCLUDE_DIRS}"
)
endif()
add_executable(app app.c)
target_link_libraries(app PRIVATE Curses::Curses)
When ncurses is specifically required:
set(CURSES_NEED_NCURSES TRUE)
find_package(Curses)
๐ฏ FindCVS
Finds the Concurrent Versions System (CVS):
find_package(CVS [...])
โญ Result Variables
This module defines this variable:
CVS_FOUNDโ boolean indicating whether thecvscommand-line client was found.
๐ Cache Variables
This cache variable may also be set:
CVS_EXECUTABLEโ path to thecvscommand-line client.
๐ Examples
Finding CVS and executing it in a process:
find_package(CVS)
if(CVS_FOUND)
execute_process(COMMAND ${CVS_EXECUTABLE} --help)
endif()
๐ง FindCxxTest
Finds CxxTest (https://github.com/CxxTest/cxxtest), a C++ unit testing framework suite, and hooks you up with a helper command to create test runners and integrate them with CTest:
find_package(CxxTest [...])
๐ฅ Result Variables
This module defines these variables:
CxxTest_FOUNDโ added in version 4.2. Boolean indicating whether the CxxTest framework was found.CXXTEST_INCLUDE_DIRSโ include directories containing the headers needed to use CxxTest.CXXTEST_TESTGEN_EXECUTABLEโ the path to the found CxxTest test generator script (Perl- or Python-based), selected based on the found interpreter or the user-specified preference. She picks the one that fits, periodt. ๐CXXTEST_TESTGEN_INTERPRETERโ the path to whichever interpreter (Perl or Python) got found, the one used to run the test generator script when it's actually needed โ like, say, on platforms where script shebang lines are simply not supported ๐ญ
๐๏ธ Cache Variables
Bestie, these live in the cache, and yes you can set them too:
CXXTEST_PYTHON_TESTGEN_EXECUTABLEโ the path to the Python-based CxxTest test generator script.CXXTEST_PERL_TESTGEN_EXECUTABLEโ the path to the Perl-based CxxTest test generator script.
โ ๏ธ Real talk: the Perl-based test generator script was removed in CxxTest version 4.0, in favor of the Python-based script. So don't be shocked when it ghosts you.
๐ก Hints
This module accepts the following variables before you call find_package(CxxTest):
CXXTEST_TESTGEN_ARGSโ set this to a semicolon-separated list of command-line options you wanna pass to the CxxTest code generator. If you don't set it, the default value is--error-printer. slay โจ
๐ ๏ธ Commands
This module hands you the following command if CxxTest is found:
cxxtest_add_testโ creates a CxxTest runner and adds it to the CTest testing suite:
cxxtest_add_test(<test-name> <gen-source-file> <input-files-to-testgen>...)
Parameters, one by one, no skipping:
<test-name>โ the name of the test executable target that gets created and registered as a test in the CTest suite.<gen-source-file>โ the name of the source file that the CxxTest code generator will generate. This must be a relative path, and it's interpreted relative to the current binary directory (CMAKE_CURRENT_BINARY_DIR).<input-files-to-testgen>...โ a list of header files containing test suite classes derived from the C++ classCxxTest::TestSuite, which get included in the test runner. These must be given as absolute paths โ like, actual full paths, no shortcuts ๐ซถ
๐ป Deprecated Variables
These are here purely for backward compatibility, iykyk:
CXXTEST_FOUNDโ deprecated since version 4.2: useCxxTest_FOUND, which has the same value. Boolean indicating whether the CxxTest framework was found.CXXTEST_USE_PYTHONโ deprecated since version 2.8.3: in earlier versions of CMake, this hint variable was used to force the Python-based test generator over the Perl one, no matter which scripting language was installed. Now it's only considered when both Perl and Python interpreters are found. A boolean hint variable that, when set to true, prefers the Python code generator over the Perl one if both interpreters are found. Only relevant when you're using CxxTest version 3.
๐ธ Examples
This example shows how CxxTest can be used in CMake with this module. If CxxTest is found:
- An additional interface imported target is created manually in the project to encapsulate the CxxTest usage requirements, and it's linked to the specified tests. Such a target is useful, for example, when you're dealing with multiple tests.
- The test generator gets invoked to create
foo_test.ccin the current binary directory from the input headerfoo_test.hlocated in the current source directory. - An executable named
unit_test_foois built and registered as a test in CTest. periodt ๐
CMakeLists.txt
find_package(CxxTest)
# Create interface imported target:
if(CxxTest_FOUND AND NOT TARGET CxxTest::CxxTest)
add_library(CxxTest::CxxTest INTERFACE IMPORTED)
set_target_properties(
CxxTest::CxxTest
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CXXTEST_INCLUDE_DIRS}"
)
endif()
# Add test:
if(CxxTest_FOUND)
enable_testing()
cxxtest_add_test(
unit_test_foo
foo_test.cc
${CMAKE_CURRENT_SOURCE_DIR}/foo_test.h
)
target_link_libraries(
unit_test_foo
PRIVATE
CxxTest::CxxTest
# Link any project targets as needed, if test depends on them:
foo
)
endif()
foo_test.h
#include <cxxtest/TestSuite.h>
class MyTestSuite : public CxxTest::TestSuite
{
public:
void testAddition(void)
{
TS_ASSERT(1 + 1 > 1);
TS_ASSERT_EQUALS(1 + 1, 2);
}
};
๐ง FindCygwin
Finds Cygwin โ that POSIX-compatible environment that runs natively on Microsoft Windows:
find_package(Cygwin [...])
๐ Note: this module is primarily intended for use in other Find Modules to help locate programs when using thefind_*()commands, likefind_program(). In most cases, just using those commands directly is enough. Only reach for this module if a specific program is known to be installed via Cygwin and is usable from Windows.
๐ Result Variables
This module defines the following variables:
Cygwin_FOUNDโ added in version 4.2. Boolean indicating whether Cygwin was found. ๐CYGWIN_INSTALL_PATHโ the path to the Cygwin root installation directory.
โจ Examples
Finding the Cygwin installation and using its path inside a custom find module:
FindFoo.cmake
find_package(Cygwin)
find_program(Foo_EXECUTABLE NAMES foo PATHS ${CYGWIN_INSTALL_PATH}/bin)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo REQUIRED_VARS Foo_EXECUTABLE)
๐ See Also
- The
FindMsysmodule, to find the MSYS path in a similar way.
๐ฉป FindDCMTK
Finds the DICOM ToolKit (DCMTK) libraries and applications:
find_package(DCMTK [...])
DCMTK is a set of libraries and applications implementing large parts of the DICOM Standard โ that's Digital Imaging and Communications in Medicine, for the uninitiated ๐ฉบ
Added in version 3.5: this module is now able to find a version of DCMTK that does or does not export a DCMTKConfig.cmake file.
DCMTK, since its version 3.6.1_20140617, supports and installs a package configuration file (DCMTKConfig.cmake) so it can be used with the find_package() command in config mode.
This module now runs a two-step process:
- Step 1: attempts to find a DCMTK version that provides a
DCMTKConfig.cmakefile, and if found, returns the results without any further action. - Step 2: if step 1 failed, the module falls back to module mode (it searches standard locations) and sets the
DCMTK_*result variables.
Until every client updates to the more recent DCMTK, build systems are gonna need to support different versions of DCMTK. That's just the vibe rn ๐ญ
On any given system, the following combinations of DCMTK versions could be considered for the DCMTK installed on the system (for example, via a system package manager), or locally (for example, a custom installation, or through the FetchContent module):
- Case A โ System DCMTK: N/A; Local DCMTK:
[ ] DCMTKConfig; Supported? YES - Case B โ System DCMTK: N/A; Local DCMTK:
[X] DCMTKConfig; Supported? YES - Case C โ System DCMTK:
[ ] DCMTKConfig; Local DCMTK: N/A; Supported? YES - Case D โ System DCMTK:
[X] DCMTKConfig; Local DCMTK: N/A; Supported? YES - Case E โ System DCMTK:
[ ] DCMTKConfig; Local DCMTK:[ ] DCMTKConfig; Supported? YES (*) - Case F โ System DCMTK:
[X] DCMTKConfig; Local DCMTK:[ ] DCMTKConfig; Supported? NO - Case G โ System DCMTK:
[ ] DCMTKConfig; Local DCMTK:[X] DCMTKConfig; Supported? YES - Case H โ System DCMTK:
[X] DCMTKConfig; Local DCMTK:[X] DCMTKConfig; Supported? YES
Legend, so you can read the above:
(*)โ see the Troubleshooting section.N/Aโ DCMTK is not available.[ ] DCMTKConfigโ DCMTK does NOT export aDCMTKConfig.cmakefile.[X] DCMTKConfigโ DCMTK does export aDCMTKConfig.cmakefile.
๐ Result Variables
This module defines the following variables:
DCMTK_FOUNDโ Boolean indicating whether DCMTK was found.DCMTK_INCLUDE_DIRSโ include directories containing the headers you need to use DCMTK.DCMTK_LIBRARIESโ the libraries you need to link against to use DCMTK.
๐ก Hints
This module accepts the following variables:
DCMTK_DIRโ (optional) source directory for DCMTK.
๐ Troubleshooting
What do you do if the project finds a different version of DCMTK? ๐ณ
Remove the DCMTK entry from the CMake cache, per the find_package() documentation, and re-run configuration. To find DCMTK on a custom location, use variables like CMAKE_PREFIX_PATH, or DCMTK_DIR.
๐ Examples
Example: Finding DCMTK
Finding DCMTK with this module โ that's it, that's the whole thing:
find_package(DCMTK)
๐ Example: Finding DCMTK Without This Module
okay so picture this: you wanna be all independent and explicitly use the DCMTKConfig.cmake package configuration file โ which, ngl, is recommended when possible โ and find DCMTK in config mode without using this module. the move is literally just handing find_package() the NO_MODULE option:
find_package(DCMTK NO_MODULE)
๐ Example: Creating Imported Target
in the next lil scenario, DCMTK gets searched with this module, and then an imported target is conditionally created to give you DCMTK usage requirements that you can painlessly link to your project targets. the vibe: if DCMTK is found in config mode, the DCMTK::DCMTK imported target will already be available through the found config files instead, so you don't gotta do anything:
find_package(DCMTK)
# Upstream DCMTKConfig.cmake already provides DCMTK::DCMTK imported target
if(DCMTK_FOUND AND NOT TARGET DCMTK::DCMTK)
add_library(DCMTK::DCMTK INTERFACE IMPORTED)
set_target_properties(
DCMTK:DCMTK
PROPERTIES
INTERFACE_LINK_LIBRARIES "${DCMTK_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${DCMTK_INCLUDE_DIRS}"
)
endif()
target_link_libraries(example PRIVATE DCMTK::DCMTK)
๐ฆ FindDevIL ๐ฆ
finds the Developer's Image Library, DevIL (over at https://openil.sourceforge.net/), bestie:
find_package(DevIL [<version>] [...])
โจ Added in version 4.2: support for the<version>argument in thefind_package()call. and yes, the version can also be specified as a range. iconic.
so the DevIL package is internally a whole squad of libraries, all distributed as part of the same release:
- The core Image Library (IL) โ this one is always required when you're working with DevIL, because it provides the main image loading and manipulation functionality. it's the main character, fr.
- The Image Library Utilities (ILU) โ depends on IL and provides image filters and effects. only required if your application actually uses this extended functionality.
- The Image Library Utility Toolkit (ILUT) โ depends on both IL and ILU, and on top of that provides an interface to OpenGL. only needed if the application uses DevIL together with OpenGL.
๐ Imported Targets
this module provides the following Imported Targets:
DevIL::ILโ Added in version 3.21. target encapsulating the core Image Library (IL) usage requirements, available if the DevIL package is found.DevIL::ILUโ Added in version 3.21. target encapsulating the Image Library Utilities (ILU) usage requirements, available if the DevIL package is found. this target also links toDevIL::ILfor convenience, since ILU depends on the core IL library.DevIL::ILUTโ Added in version 3.21. target encapsulating the Image Library Utility Toolkit (ILUT) usage requirements, available if the DevIL package and its ILUT library are found. this target also links toDevIL::ILU, and transitively toDevIL::IL, since ILUT depends on both. the way that dependency chain just works ๐
๐ธ Result Variables
this module defines the following variables:
DevIL_FOUNDโ Added in version 3.8. boolean indicating whether the (requested version of the) DevIL package was found, including the IL and ILU libraries.DevIL_VERSIONโ Added in version 4.2. the version of the DevIL found.DevIL_ILUT_FOUNDโ Added in version 3.21. boolean indicating whether the ILUT library was found. on most systems, ILUT is found when both IL and ILU are available.
๐ง Cache Variables
the following cache variables may also be set:
IL_INCLUDE_DIRโ the directory containing theil.h,ilu.handilut.hheader files.IL_LIBRARIESโ the full path to the core Image Library (IL).ILU_LIBRARIESโ the full path to the ILU library.ILUT_LIBRARIESโ the full path to the ILUT library.
โญ Examples
finding the DevIL package and linking against the core Image Library (IL) โ chef's kiss simple:
find_package(DevIL)
target_link_libraries(app PRIVATE DevIL::IL)
linking against the Image Library Utilities (ILU):
find_package(DevIL)
target_link_libraries(app PRIVATE DevIL::ILU)
linking against the Image Library Utility Toolkit (ILUT):
find_package(DevIL)
target_link_libraries(app PRIVATE DevIL::ILUT)
๐ฅ FindDoxygen ๐ฅ
finds Doxygen (over at https://www.doxygen.nl) โ that's the source code documentation generator, if you didn't know โ along with some optional supporting tools, and it hands you a command for integrating Doxygen-based documentation into your CMake projects. obsessed:
find_package(Doxygen [<version>] [COMPONENTS <components>...] [...])
๐ Components
additional Doxygen supporting tools can be specified as components with the find_package() command:
find_package(Doxygen [COMPONENTS <components>...])
supported components include:
doxygenโ Added in version 3.9. finds thedoxygenexecutable. this component is always automatically implied, even if you don't request it. it's the default bestie.dotโ Added in version 3.9. finds the Graphviz (https://graphviz.org)dotutility, used for rendering graphs and diagrams as part of the documentation.mscgenโ Added in version 3.9. finds the Message Chart Generator (https://www.mcternan.me.uk/mscgen/) utility used by Doxygen's\mscand\mscfilecommands.diaโ Added in version 3.9. finds the Dia (https://wiki.gnome.org/Apps/Dia) diagram editor used by Doxygen's\diafilecommand.
๐ Imported Targets
this module provides the following Imported Targets, each of which is defined if the corresponding component was requested and its associated executable was found:
Doxygen::doxygenโ Added in version 3.9. imported executable target encapsulating thedoxygenexecutable usage requirements, available if Doxygen is found.Doxygen::dotโ Added in version 3.9. imported executable target encapsulating thedotexecutable usage requirements, available if the abovedotcomponent is found.Doxygen::mscgenโ Added in version 3.9. imported executable target encapsulating themscgenexecutable usage requirements, available if the abovemscgencomponent is found.Doxygen::diaโ Added in version 3.9. imported executable target encapsulating thediaexecutable usage requirements, available if the abovediacomponent is found.
these targets can be used in commands such as add_custom_command() and are preferred over the older, now-deprecated variables like DOXYGEN_EXECUTABLE. like, please don't be using the deprecated ones, i'm begging ๐
๐ Result Variables
this module defines the following variables:
Doxygen_FOUNDโ Added in version 3.3. boolean indicating whether the (requested version of the)doxygenexecutable and all requested required components were found.Doxygen_VERSIONโ Added in version 4.2. the version of Doxygen found (as reported bydoxygen --version).
๐ Commands
this module provides the following command:
โจ doxygen_add_docs โจ
Added in version 3.9. adds a custom target for generating documentation with Doxygen during the build phase:
doxygen_add_docs(
<target-name>
[<files-or-dirs>...]
[ALL]
[USE_STAMP_FILE]
[WORKING_DIRECTORY <dir>]
[COMMENT <comment>]
[CONFIG_FILE <file>]
)
by default, this convenience command also generates a configuration file named Doxyfile.<target-name> in the current binary directory at CMake configuration phase. it provides sensible defaults, so most projects literally only need to specify input files or directories. additional behavior and configuration can be customized using the variables described in the following sections.
the arguments are:
<target-name>โ the name of the target to be created for generating documentation with Doxygen.<files-or-dirs>...โ one or more paths (files or directories) that serve as input sources for documentation. these are passed to theINPUTDoxygen configuration tag in the generatedDoxyfile.<target-name>. files listed here are also added asSOURCESargument of the underlyingadd_custom_target()command, so they appear in the IDE project's source list. when using theUSE_STAMP_FILEoption, only files (not directories, symlinks, or wildcards) are allowed, and each must exist when this command is called. no cap.ALLโ Added in version 3.12. adds the created documentation target to the default build target so that it runs automatically as part of the build phase.USE_STAMP_FILEโ Added in version 3.16. enables use of a stamp file to avoid regenerating documentation unless source files have changed. stamp file named<target-name>.stampis created in the current binary directory by an underlying custom command. with this option present, all entries in<files-or-dirs>must be existing files (i.e. no directories, symlinks or wildcards) when this command is called โ an error is raised if any listed path is invalid. without this option, CMake will re-run Doxygen every time the<target-name>target is built, regardless of whether any input source file listed in<files-or-dirs>has changed. so yeah, it's giving "rebuild the whole thing bestie" energy ๐WORKING_DIRECTORY <dir>โ by default, the Doxygen working directory is the current source directory (CMAKE_CURRENT_SOURCE_DIR). this aligns with using relative input paths. use this option to change and override the directory where Doxygen is being run โ the absolute path<dir>will then be used as the base point for relative paths. also note that Doxygen's default behavior is to strip the working directory from relative paths in the generated documentation. see theSTRIP_FROM_PATHconfig tag in the Doxygen manual (https://www.doxygen.nl/manual/config.html) for more details.COMMENT <comment>โ bestie if you pass this, the<comment>string gets handed straight to theadd_custom_target()<#command:add_custom_target> command that builds the custom target under the hood. Translation: it shows up in the build system output whenever that target builds. cute little label for your build logs ๐CONFIG_FILE <file>โ Added in version 3.27. โจ
If you set this, the file you give (with a full path, no shortcuts) is used as the Doxygen configuration file instead of the default Doxyfile.<target-name>. slay, custom config era ๐
โจ Variables for customizing Doxygen configuration โจ
So doxygen_add_docs() generates a Doxygen configuration file full of config tags. Like, for example:
Doxygen.<target-name>
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = DoxygenExample
PROJECT_NUMBER = 1.2.3
PROJECT_BRIEF = "Example project using Doxygen"
PROJECT_LOGO =
OUTPUT_DIRECTORY = /home/user/doxygen-example/build
GENERATE_HTML = YES
GENERATE_MAN = NO
# ...
In CMake you can tweak these tags by setting input variables shaped like DOXYGEN_<tag>, where <tag> is one of the configuration tags listed in the Doxygen manual <https://www.doxygen.nl/manual/config.html>. iykyk ๐ง
For example, to change the GENERATE_HTML and GENERATE_MAN configuration tags, you set these variables before calling doxygen_add_docs():
CMakeLists.txt
find_package(Doxygen)
if(Doxygen_FOUND)
set(DOXYGEN_GENERATE_HTML NO)
set(DOXYGEN_GENERATE_MAN YES)
doxygen_add_docs(project_docs ${PROJECT_SOURCE_DIR})
endif()
๐ธ Default configuration ๐ธ
By default, doxygen_add_docs() overrides a bunch of Doxygen's settings so they fit typical CMake projects better. Each of the following variables is explicitly set unless it was already defined before you called doxygen_add_docs() โ with a few exceptions noted below, because of course there are exceptions ๐ญ
DOXYGEN_HAVE_DOTโ set toYESif thedotcomponent was requested and found,NOotherwise. Any existing value ofDOXYGEN_HAVE_DOTis ignored (the module said "not you" ๐).DOXYGEN_DOT_MULTI_TARGETSโ set toYESby this module (heads up: this needs adotversion newer than 1.8.10). This option only matters ifDOXYGEN_HAVE_DOTis also set toYES.DOXYGEN_GENERATE_LATEXโ set toNOby this module. no latex for u ๐DOXYGEN_WARN_FORMATโ for Visual Studio based generators, this gets set to the form the Visual Studio IDE recognizes:$file($line) : $text. For all other generators, Doxygen's default value is left alone, untouched, not overridden.DOXYGEN_PROJECT_NAMEโ filled in with the name of the current project (i.e.PROJECT_NAME<#variable:PROJECT_NAME>). ๐DOXYGEN_PROJECT_NUMBERโ filled in with the version of the current project (i.e.PROJECT_VERSION<#variable:PROJECT_VERSION>).DOXYGEN_PROJECT_BRIEFโ filled in with the description of the current project (i.e.PROJECT_DESCRIPTION<#variable:PROJECT_DESCRIPTION>).DOXYGEN_INPUTโ this one gets automatically filled with the list of files and directories you passed todoxygen_add_docs(). For consistent behavior with other built-in commands likeadd_executable()<#command:add_executable>,add_library()<#command:add_library>, andadd_custom_target()<#command:add_custom_target>, projects should not set this variable manually. If a project does set a variable namedDOXYGEN_INPUT, it gets ignored and a warning gets issued. don't do it, you'll get called out fr frDOXYGEN_RECURSIVEโ set toYESby this module.DOXYGEN_EXCLUDE_PATTERNSโ if the<files-or-dirs>argument ofdoxygen_add_docs()contains directories, this variable specifies the patterns used to exclude files from them. These patterns are added by default so CMake-specific files and directories stay out of the input. If your project sets this variable, those contents get merged with these additional patterns rather than replacing them โ so no, you can't yeet them:
*/.git/*
*/.svn/*
*/.hg/*
*/CMakeFiles/*
*/_CPack_Packages/*
DartConfiguration.tcl
CMakeLists.txt
CMakeCache.txt
DOXYGEN_OUTPUT_DIRECTORYโ set toCMAKE_CURRENT_BINARY_DIR<#variable:CMAKE_CURRENT_BINARY_DIR> by this module. If the project supplies its own value for this and it's a relative path, it gets interpreted relative to the current binary directory (CMAKE_CURRENT_BINARY_DIR<#variable:CMAKE_CURRENT_BINARY_DIR>). This is necessary because Doxygen will normally be run from a directory within the source tree, so relative source paths work as expected. If that directory doesn't exist, it gets recursively created before Doxygen runs. โจ it builds itself โจ
๐ฆ Lists ๐ฆ
So a number of Doxygen config tags accept lists of values, and Doxygen wants them separated by whitespace โ meanwhile in CMake a list is a string with items separated by semicolons <#cmake-language-lists>. different love languages, basically ๐ญ
doxygen_add_docs() specifically checks for the following Doxygen config tags and, if set, converts their associated CMake DOXYGEN_<tag> variable values into Doxygen-formatted lists:
ABBREVIATE_BRIEFALIASESCITE_BIB_FILESDIAFILE_DIRSDOTFILE_DIRSDOT_FONTPATHENABLED_SECTIONSEXAMPLE_PATHEXAMPLE_PATTERNSEXCLUDEEXCLUDE_PATTERNSEXCLUDE_SYMBOLSEXPAND_AS_DEFINEDEXTENSION_MAPPINGEXTRA_PACKAGESEXTRA_SEARCH_MAPPINGSFILE_PATTERNSFILTER_PATTERNSFILTER_SOURCE_PATTERNSHTML_EXTRA_FILESHTML_EXTRA_STYLESHEETIGNORE_PREFIXIMAGE_PATHINCLUDE_FILE_PATTERNSINCLUDE_PATHINPUTLATEX_EXTRA_FILESLATEX_EXTRA_STYLESHEETMATHJAX_EXTENSIONSMSCFILE_DIRSPLANTUML_INCLUDE_PATHPREDEFINEDQHP_CUST_FILTER_ATTRSQHP_SECT_FILTER_ATTRSSTRIP_FROM_INC_PATHSTRIP_FROM_PATHTAGFILESTCL_SUBST
For example, to customize the Doxygen file patterns, you just set a normal semicolon-separated list <#cmake-language-lists> in CMake:
CMakeLists.txt
find_package(Doxygen)
if(Doxygen_FOUND)
set(DOXYGEN_FILE_PATTERNS *.c *.cxx *.h *.hxx)
doxygen_add_docs(example_docs ${CMAKE_CURRENT_SOURCE_DIR} ALL)
endif()
Which produces a Doxygen list of patterns separated by spaces in the generated configuration file:
Doxyfile.<target-name>
# ...
FILE_PATTERNS = *.c *.cxx *.h *.hxx
look at that conversion happen. chef's kiss ๐ฅ
๐ Automatic quoting ๐
If a Doxygen single-value tag contains spaces, its value has to be surrounded by double quotes ("..."). doxygen_add_docs() automatically quotes the values of the following Doxygen tags when it generates the Doxyfile, if they contain at least one space:
CHM_FILEDIA_PATHDOCBOOK_OUTPUTDOCSET_FEEDNAMEDOCSET_PUBLISHER_NAMEDOT_FONTNAMEDOT_PATHEXTERNAL_SEARCH_IDFILE_VERSION_FILTERGENERATE_TAGFILEHHC_LOCATIONHTML_FOOTERHTML_HEADERHTML_OUTPUTHTML_STYLESHEETINPUT_FILTERLATEX_FOOTERLATEX_HEADERLATEX_OUTPUTLAYOUT_FILEMAN_OUTPUTMAN_SUBDIRMATHJAX_CODEFILEMSCGEN_PATHOUTPUT_DIRECTORYPERL_PATHPLANTUML_JAR_PATHPROJECT_BRIEFPROJECT_LOGOPROJECT_NAMEQCH_FILEQHG_LOCATIONQHP_CUST_FILTER_NAMEQHP_VIRTUAL_FOLDERRTF_EXTENSIONS_FILERTF_OUTPUTRTF_STYLESHEET_FILESEARCHDATA_FILEUSE_MDFILE_AS_MAINPAGEWARN_FORMATWARN_LOGFILEXML_OUTPUTDOXYGEN_VERBATIM_VARSโ Added in version 3.11. โญ
This is a CMake input variable used by doxygen_add_docs() to specify a list of Doxygen input variables (including their leading DOXYGEN_ prefix) whose values should be passed to the generated Doxyfile configuration without automatic quoting.
When you use this variable, your project is then responsible for making sure those variables' values actually make sense when dropped directly into the generated Doxyfile configuration. For list variables, items are still separated by spaces in the output, but no quoting is applied to the individual items. that's on you now bestie ๐ซถ
For certain Doxygen tags, such as ALIASES, the automatic quoting done by doxygen_add_docs() may interfere with correct syntax (e.g., embedded quotes). so yeah, that's literally why this variable exists ๐
So like, <#bracket-argument> bracket syntax is literally your bestie here โ it makes dealing with embedded quotes so much less of a nightmare. For example, this next bit will quote DOXYGEN_PROJECT_BRIEF but skip each item in the DOXYGEN_ALIASES list:
CMakeLists.txt
find_package(Doxygen)
if(Doxygen_FOUND)
set(DOXYGEN_PROJECT_BRIEF "String with spaces")
set(
DOXYGEN_ALIASES
[[somealias="@some_command param"]]
"anotherAlias=@foobar"
)
set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES)
add_doxygen_docs(project_docs ${PROJECT_SOURCE_DIR})
endif()
And the resultant Doxyfile config comes out looking like this:
Doxyfile.project_docs
PROJECT_BRIEF = "String with spaces"
ALIASES = somealias="@some_command param" anotherAlias=@foobar
Deprecated Variables ๐
Okay so for compatibility with previous versions of CMake, these variables are also defined โ but bestie, they're deprecated and you should genuinely not be using them anymore:
DOXYGEN_FOUNDโ Deprecated since version 4.2: useDoxygen_FOUNDinstead.
Boolean indicating whether the (requested version of) doxygen executable and all requested required components were found. It has a boolean value of YES or NO.
DOXYGEN_EXECUTABLEโ Deprecated since version 3.9: use theDoxygen::doxygenimported target instead of referring to thedoxygenexecutable directly.
Cache variable containing the path to the doxygen command.
DOXYGEN_DOT_FOUNDโ Deprecated since version 3.9: useDoxygen_dot_FOUND.
Boolean result variable indicating whether dot executable was found.
DOXYGEN_DOT_EXECUTABLEโ Deprecated since version 3.9: use theDoxygen::dotimported target instead of referring to thedotexecutable directly.
Cache variable containing the path to the dot command-line executable.
DOXYGEN_DOT_PATHโ Deprecated since version 3.9.
Result variable containing the path to the directory where the dot executable is located as reported in DOXYGEN_DOT_EXECUTABLE. The path may have forward slashes even on Windows and is not suitable for direct substitution into a Doxyfile.in template. If you actually need this value, get the IMPORTED_LOCATION <#prop_tgt:IMPORTED_LOCATION> property of the Doxygen::dot target and use get_filename_component() <#command:get_filename_component> to extract the directory part of that path. Also consider using file(TO_NATIVE_PATH) <#to-native-path> to prepare the path for a Doxygen configuration file. ๐
DOXYGEN_SKIP_DOTโ Deprecated since version 3.9.
This hint variable has no effect when specifying components in find_package(Doxygen COMPONENTS ...). In backward-compatibility mode (i.e. without specifying components) it prevents this find module from searching for Graphviz's dot utility.
DOXYGEN_VERSIONโ Deprecated since version 4.2: superseded byDoxygen_VERSION.
The version of Doxygen found.
Examples โจ
Examples: Finding Doxygen ๐
Finding Doxygen, that's it, that's the vibe:
find_package(Doxygen)
Or โ finding Doxygen and specifying a minimum required version:
find_package(Doxygen 1.9)
Or โ finding Doxygen and making it required (if it's not found, processing stops with an error message, no chill):
find_package(Doxygen REQUIRED)
Or โ finding Doxygen as required, with dot tool as a required component and mscgen and dia tools as optional components:
find_package(Doxygen REQUIRED COMPONENTS dot OPTIONAL_COMPONENTS mscgen dia)
Example: Using Doxygen in CMake ๐
This one's a whole demo of how to find Doxygen and create documentation from source files at build phase. Once the project is built, the generated documentation files will be located in the html directory inside the project binary directory. Iconic.
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(
DoxygenExample
DESCRIPTION "Example project using Doxygen"
VERSION 1.2.3
)
add_executable(example example.c)
find_package(Doxygen)
if(Doxygen_FOUND)
doxygen_add_docs(project_docs example.c ALL USE_STAMP_FILE)
endif()
example.c
/**
* @file example.c
* @brief A simple example to demonstrate Doxygen.
*/
#include <stdio.h>
/**
* @brief Calculates the sum of two integers.
*
* @param a First integer.
* @param b Second integer.
* @return Sum of a and b.
*
* @par Example
* @code
* int result = sum(3, 4);
* printf("%d\n", result); // Outputs: 7
* @endcode
*/
int sum(int a, int b) { return a + b; }
/**
* @brief Main function.
*
* @return 0 on success.
*/
int main(void)
{
int result = sum(5, 7);
printf("Result: %d\n", result);
return 0;
}
Example: Configuring Doxygen With Variables ๐
In the following example, Doxygen configuration is customized using CMake variables. The configuration sets file patterns when using a directory as the source input (CMAKE_CURRENT_SOURCE_DIR <#variable:CMAKE_CURRENT_SOURCE_DIR>), enables a theme toggle for switching between light and dark modes, suppresses Doxygen's standard output during the build phase, specifies a Markdown file as the main page, and disables warnings about undocumented code:
find_package(Doxygen)
if(Doxygen_FOUND)
set(DOXYGEN_FILE_PATTERNS *.c *.cxx *.md)
set(DOXYGEN_HTML_COLORSTYLE "TOGGLE")
set(DOXYGEN_QUIET YES)
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(DOXYGEN_WARN_IF_UNDOCUMENTED NO)
doxygen_add_docs(example_docs ${CMAKE_CURRENT_SOURCE_DIR} ALL)
endif()
Example: Custom Configuration File ๐ธ
Here a custom Doxyfile configuration file is created in the current binary directory (CMAKE_CURRENT_BINARY_DIR <#variable:CMAKE_CURRENT_BINARY_DIR>) before calling doxygen_add_docs(). That way you can customize project-specific config tags however you need:
CMakeLists.txt
find_package(Doxygen)
if(Doxygen_FOUND)
configure_file(Doxyfile.in Doxyfile)
doxygen_add_docs(
example_docs
foo.c bar.c
ALL
USE_STAMP_FILE
COMMENT "Generating project documentation with custom Doxyfile"
CONFIG_FILE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
)
endif()
Doxyfile.in
PROJECT_NAME = "Customized project name"
OUTPUT_DIRECTORY = "@CMAKE_CURRENT_BINARY_DIR@"
# ...
FindEnvModules ๐ง
Added in version 3.15.
Finds an Environment Modules implementation and provides commands for use in CMake scripts:
find_package(EnvModules [...])
The Environment Modules system is a command-line tool that manages Unix-like shell environments by dynamically modifying environment variables. It's commonly used in High-Performance Computing (HPC) environments to support multiple software versions or configurations. Very much the main character of HPC setups, honestly.
This module is compatible with the two most common implementations:
- Lua-based Lmod
- TCL-based Environment Modules
This module is primarily intended for setting up compiler and library environments within a CTest Script <#ctest-script> (ctest -S). It may also be used in a CMake Script <#script-processing-mode> (cmake -P).
Note: the loaded environment will not persist beyond the end of the calling process. Do not use this module in CMake project code (such as CMakeLists.txt) to load compiler environments โ the environment changes won't be available during the build phase, and then you'll be sad ๐ญ. In such a case, load the desired environment before invoking CMake or the generated build system. Periodt.
Result Variables ๐
This module defines the following variables:
EnvModules_FOUNDโ Boolean indicating whether a compatible Environment Modules framework was found.
Cache Variables ๐๏ธ
The following cache variables may also be set:
EnvModules_COMMANDโ the path to a low levelmodulecommand to use.
Hints ๐ก
This module accepts the following variables before calling the find_package(EnvModules):
ENV{MODULESHOME}โ this environment variable is usually set by the Environment Modules implementation, and can be used as a hint to locate themodulecommand to execute.
Commands ๐ซถ
This module provides the following commands for interacting with the Environment Modules system, if found:
env_module
Executes an arbitrary module command:
env_module(<command> <args>...)
env_module(
COMMAND <command> <args>...
[OUTPUT_VARIABLE <out-var>]
[RESULT_VARIABLE <ret-var>]
)
The options are:
COMMAND <command> <args>...โ the module sub-command and arguments to execute, as if passed directly to themodulecommand in the shell environment.OUTPUT_VARIABLE <out-var>โ stores the standard output of the executed module command in the specified variable.RESULT_VARIABLE <ret-var>โ stores the return code of the executed module command in the specified variable.
env_module_swap
Swaps one module for another:
env_module_swap(
<out-mod>
<in-mod>
[OUTPUT_VARIABLE <out-var>]
[RESULT_VARIABLE <ret-var>]
)
This is functionally equivalent to the module swap <out-mod> <in-mod> shell command.
The options are:
OUTPUT_VARIABLE <out-var>โ stores the standard output of the executed module command in the specified variable.RESULT_VARIABLE <ret-var>โ stores the return code of the executed module command in the specified variable.
env_module_list
Retrieves the list of currently loaded modules:
env_module_list(<out-var>)
This is functionally equivalent to the module list shell command. The result is stored in <out-var> as a properly formatted CMake semicolon-separated list <#cmake-language-lists> variable. Slay. ๐ฅ
env_module_avail โ bestie, this one just asks what's out there. It retrieves the list of available modules:
env_module_avail([<mod-prefix>] <out-var>)
It's functionally equivalent to running the module avail <mod-prefix> shell command, just โจcivilizedโจ. The result lands in <out-var> as a properly formatted CMake semicolon-separated list variable (you know the one, #cmake-language-lists ๐ซถ).
๐ธ Examples ๐ธ
Okay so picture this: a CTest script setting up a whole Cray Programming Environment, and our module is the main character. Once the Environment Modules system is found, env_module() is used to load the necessary compiler, MPI and scientific libraries to set up the build environment. The CRAYPE_LINK_TYPE environment variable gets set to dynamic to specify dynamic linking โ this tells the Cray Linux Environment compiler driver to link against dynamic libraries at runtime instead of linking static libraries at compile time, so the compiler produces dynamically linked executable files. ๐
example-script.cmake
set(CTEST_BUILD_NAME "CrayLinux-CrayPE-Cray-dynamic")
set(CTEST_BUILD_CONFIGURATION Release)
set(CTEST_BUILD_FLAGS "-k -j8")
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
# ...
find_package(EnvModules REQUIRED)
# Clear all currently loaded Environment Modules to start with a clean state
env_module(purge)
# Load the base module-handling system to use other modules
env_module(load modules)
# Load Cray Programming Environment (Cray PE) support, which manages
# platform-specific optimizations and architecture selection
env_module(load craype)
# Load the Cray programming environment
env_module(load PrgEnv-cray)
# Load settings targeting the Intel Knights Landing (KNL) CPU architecture
env_module(load craype-knl)
# Load the Cray MPI (Message Passing Interface) library, needed for
# distributed computing
env_module(load cray-mpich)
# Load Cray's scientific library package, which includes optimized math
# libraries (like BLAS, LAPACK)
env_module(load cray-libsci)
set(ENV{CRAYPE_LINK_TYPE} dynamic)
# ...
๐ฆ FindEXPAT ๐ฆ
Finds the native Expat headers and library, no cap:
find_package(EXPAT [<version>] [...])
Expat is a stream-oriented XML parser library written in C. That's it, that's the whole vibe. ๐
๐ Imported Targets ๐
This module provides the following Imported Targets (#imported-targets):
EXPAT::EXPATโ Added in version 3.10. Target encapsulating the Expat library (expat) usage requirements. It's only available if Expat is actually found, so don't come for it if it's not there.
โจ Result Variables โจ
This module defines the following variables:
EXPAT_FOUNDโ Boolean indicating whether (the requested version of) Expat was found.EXPAT_VERSIONโ Added in version 4.2. The version of Expat found. Obsessed with her.EXPAT_INCLUDE_DIRSโ Include directories containingexpat.hand related headers needed to use Expat.EXPAT_LIBRARIESโ Libraries you need to link against to use Expat.
๐ Hints ๐
This module accepts the following variables:
EXPAT_USE_STATIC_LIBSโ Added in version 3.28. Set it toTRUEto use static libraries. Also: Added in version 3.31: Implemented on non-Windows platforms. ๐ซถ
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility only, iykyk:
EXPAT_VERSION_STRINGโ Deprecated since version 4.2: Superseded by theEXPAT_VERSION. The version of Expat found.
๐ Examples ๐
Finding the Expat library and linking it to a project target โ literal perfection:
find_package(EXPAT)
target_link_libraries(project_target PRIVATE EXPAT::EXPAT)
๐ง FindFLEX ๐ง
Finds the Fast Lexical Analyzer (Flex) command-line generator and its library, and hands you CMake commands to create custom build rules for using Flex:
find_package(FLEX [<version>] [...])
Flex generates lexical analyzers, also known as scanners or lexers. It also includes a runtime library (fl) that supplies support functions for the generated scanners โ input handling, buffer management, and error reporting. She does it all ๐
.
โญ Result Variables โญ
This module defines the following variables:
FLEX_FOUNDโ Boolean indicating whether (the requested version of) Flex was found.FLEX_VERSIONโ The version of Flex found.FLEX_INCLUDE_DIRSโ The include directories containing headers for using the Flex library.FLEX_LIBRARIESโ The libraries needed to link against to use the Flex library.
๐ Cache Variables ๐
The following cache variables may also be set:
FLEX_EXECUTABLEโ The path to theflexexecutable.
๐ Commands ๐
This module provides the following commands if flex is found:
๐ฅ Generating Scanners ๐ฅ
flex_target
Creates a custom build rule to generate a scanner file from a lex file using Flex:
flex_target(
<name>
<input-lex-file>
<output-scanner-file>
[DEFINES_FILE <header>]
[OPTIONS <options>...]
[COMPILE_FLAGS <string>] # Deprecated
)
Changed in version 3.17: When policy CMP0098 (#policy:CMP0098) is set to NEW, flex runs in the CMAKE_CURRENT_BINARY_DIR (#variable:CMAKE_CURRENT_BINARY_DIR) directory. Periodt.
<name>โ String used as an identifier for this command invocation.<input-lex-file>โ The path to an input Flex source file (.l). If given as a relative path, it will be interpreted relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR, #variable:CMAKE_CURRENT_SOURCE_DIR).<output-scanner-file>โ The path of the output file to be generated by Flex. If given as a relative path, it will be interpreted relative to the current Flex working directory.DEFINES_FILE <header>โ Added in version 3.5. If Flex is configured to output a header file, this option may be used to specify its name. If given as a relative path, it will be interpreted relative to the current Flex working directory.OPTIONS <options>...โ Added in version 4.0. A semicolon-separated list (#cmake-language-lists) of extra options added to theflexcommand line.COMPILE_FLAGS <string>โ Deprecated since version 4.0: Superseded byOPTIONS <options>.... A string of space-separated extra options added to theflexcommand line. A semicolon-separated list (#cmake-language-lists) will not work โ not me warning you twice ๐.
Command variables
This command also defines the following variables:
FLEX_<name>_DEFINEDโ Boolean indicating whether this command was successfully invoked.FLEX_<name>_INPUTโ The Flex source file, an alias for<input-lex-file>.FLEX_<name>_OUTPUT_HEADERโ Added in version 3.5. The header file generated byflex, if any.FLEX_<name>_OUTPUTSโ A list of files generated byflex, including the output scanner file, and the header file.FLEX_<name>_OPTIONSโ Added in version 4.0. A list of command-line options used for theflexcommand.
๐ Adding Dependency Between Scanner and Parser ๐
add_flex_bison_dependency
Adds the required dependency between a scanner and a parser:
add_flex_bison_dependency(<flex-name> <bison-name>)
Flex scanners often rely on token definitions generated by Bison, meaning the code produced by Flex depends on the header file created by Bison. So this command wires up the required dependency between a scanner and a parser, where <flex-name> and <bison-name> are the first parameters of respectively flex_target(<name> ...) and bison_target(<name> ...) (#command:bison_target) commands. Matching besties fr fr ๐ซถ.
๐ธ Examples ๐ธ
Examples: Finding Flex
Finding Flex, the classic:
find_package(FLEX)
Finding Flex and specifying its minimum required version:
find_package(FLEX 2.5.13)
Finding Flex and making it required (if Flex is not found, processing stops with an error message โ no soft launches here):
find_package(FLEX 2.5.13 REQUIRED)
Example: Generating Scanner
Finding Flex and generating a scanner source file in the current binary directory from the lex source file in the current source directory:
find_package(FLEX)
if(FLEX_FOUND)
flex_target(MyScanner lexer.l lexer.cpp)
endif()
add_executable(foo foo.cc ${FLEX_MyScanner_OUTPUTS})
Example: Command-line Options
Adding additional command-line options to the flex executable can be passed as a list. For example, adding the --warn option to report warnings, and the --noline (-L) to not generate #line directives:
find_package(FLEX)
if(FLEX_FOUND)
flex_target(MyScanner lexer.l lexer.cpp OPTIONS --warn --noline)
endif()
Generator expressions (#manual:cmake-generator-expressions(7)) can be used in the OPTIONS <options>... argument. For example, to add the --debug (-d) option only for the Debug build type:
find_package(FLEX)
if(FLEX_FOUND)
flex_target(MyScanner lexer.l lexer.cpp OPTIONS $<$<CONFIG:Debug>:--debug>)
endif()
Example: Using Flex Library
Finding Flex and creating an interface imported target (#imported-targets) that encapsulates its library usage requirements for linking to a project target:
find_package(FLEX)
if(FLEX_FOUND AND NOT TARGET FLEX::fl)
add_library(FLEX::fl INTERFACE IMPORTED)
set_target_properties(
FLEX::fl
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FLEX_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${FLEX_LIBRARIES}"
)
endif()
if(FLEX_FOUND)
flex_target(MyScanner lexer.l lexer.cpp)
endif()
add_executable(Foo foo.cc ${FLEX_MyScanner_OUTPUTS})
target_link_libraries(Foo PRIVATE FLEX::fl)
Example: Using Flex and Bison
The following example demonstrates how to use Flex and Bison (#module:FindBISON) in CMake โ the iconic duo, honestly:
find_package(BISON)
find_package(FLEX)
if(BISON_FOUND AND FLEX_FOUND)
bison_target(MyParser parser.y parser.cpp)
flex_target(MyScanner lexer.l lexer.cpp)
add_flex_bison_dependency(MyScanner MyParser)
endif()
add_executable(Foo foo.cc ${BISON_MyParser_OUTPUTS} ${FLEX_MyScanner_OUTPUTS})
# ...
See Also
- The FindBISON module to find that Bison parser generator bestie ๐โจ
๐จ FindFLTK ๐จ
Finds the Fast Light Toolkit (FLTK), a cross-platform toolkit for GUI development, iykyk:
find_package(FLTK [...])
Okay so FLTK uses a CMake-based build system and ships a package configuration file so projects can find it โ slay ๐
. As of its 1.4.0 version it also provides Imported Targets <#imported-targets> that encapsulate usage requirements. For example, fltk::fltk, which can be linked to project targets where FLTK is needed. This module takes that into account and first attempts to find FLTK in config mode. If the configuration file is not available, it falls back to module mode and searches standard locations. Also see the official FLTK documentation for more info on how to use FLTK with CMake ๐ซถ
Added in version 3.11: Debug and release (optimized) library variants are found separately and use per-configuration <#build-configurations> variables. So organized of them โจ
๐ Result Variables
This module defines the following variables:
FLTK_FOUNDโ Boolean indicating whether FLTK was found ๐FLTK_LIBRARIESโ Libraries needed to link against to use FLTK.FLTK_WRAP_UIโ Boolean indicating whether thefluidexecutable is found. This variable is available only if FLTK is found in module mode, and can be used, for example, to conditionally invoke thefltk_wrap_ui()<#command:fltk_wrap_ui> command if it is needed and available ๐ธ
๐๏ธ Cache Variables
The following cache variables are also available to set or use:
FLTK_FLUID_EXECUTABLEโ The path to thefluidbinary tool.FLTK_INCLUDE_DIRโ The include directory containing header files needed to use FLTK.FLTK_BASE_LIBRARY_RELEASEโ Added in version 3.11. The path to the release (optimized) FLTK base library.FLTK_BASE_LIBRARY_DEBUGโ Added in version 3.11. The path to the debug FLTK base library.FLTK_GL_LIBRARY_RELEASEโ Added in version 3.11. The path to the release (optimized) FLTK GL library.FLTK_GL_LIBRARY_DEBUGโ Added in version 3.11. The path to the debug FLTK GL library.FLTK_FORMS_LIBRARY_RELEASEโ Added in version 3.11. The path to the release (optimized) FLTK Forms library.FLTK_FORMS_LIBRARY_DEBUGโ Added in version 3.11. The path to the debug FLTK Forms library.FLTK_IMAGES_LIBRARY_RELEASEโ Added in version 3.11. The path to the release (optimized) FLTK Images protobuf library.FLTK_IMAGES_LIBRARY_DEBUGโ Added in version 3.11. The path to the debug FLTK Images library.
๐๏ธ Input Variables
By default, this module searches for all FLTK libraries and its fluid executable. The following variables can be set before calling find_package(FLTK) to indicate which elements are optional for a successful configuration:
FLTK_SKIP_FLUIDโ Set to boolean true to mark thefluidexecutable as optional.FLTK_SKIP_FORMSโ Set to boolean true to mark the FLTK Forms library as optional; it will therefore not be included in theFLTK_LIBRARIESresult variable.FLTK_SKIP_IMAGESโ Set to boolean true to mark the FLTK Image library as optional; it will therefore not be included in theFLTK_LIBRARIESresult variable.FLTK_SKIP_OPENGLโ Set to boolean true to mark the FLTK OpenGL library as optional; it will therefore not be included in theFLTK_LIBRARIESresult variable.
โจ Examples โจ
Finding FLTK and conditionally creating a fltk::fltk imported interface target, if it is not provided by the upstream FLTK package. The imported target can then be linked to a project target:
find_package(FLTK)
if(FLTK_FOUND AND NOT TARGET fltk::fltk)
add_library(fltk::fltk INTERFACE IMPORTED)
set_target_properties(
fltk::fltk
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FLTK_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${FLTK_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE fltk::fltk)
๐ฆ FindFLTK2 ๐ฆ
Note: This module is specifically for FLTK version 2.x. The 2.0 series was originally a development branch intended as the next major version of FLTK. However, it never reached stable release status, and active development has shifted back to the FLTK 1.x branch ๐ญ. For finding FLTK, including stable and modern versions, use the FindFLTK <#module:FindFLTK> module instead, bestie โ trust ๐
Finds the Fast Light Toolkit (FLTK) version 2.x, a cross-platform toolkit for GUI development:
find_package(FLTK2 [...])
๐ Result Variables
This module defines the following variables:
FLTK2_FOUNDโ Boolean indicating whether FLTK 2.x was found โFLTK2_LIBRARIESโ Libraries needed to link against to use FLTK 2.x.FLTK2_WRAP_UIโ Boolean indicating whether thefluid2executable is found. This variable can be used, for example, to conditionally invoke thefltk_wrap_ui()<#command:fltk_wrap_ui> command if it is needed and available ๐
๐๏ธ Cache Variables
The following cache variables may also be set:
FLTK2_FLUID_EXECUTABLEโ The path to thefluid2binary tool.FLTK2_INCLUDE_DIRโ The directory containing header files needed to use FLTK 2.x.FLTK2_BASE_LIBRARYโ The path to the FLTK 2.x library (fltk2).FLTK2_GL_LIBRARYโ The path to the FLTK 2.x OpenGL compatibility library (fltk2_gl).FLTK2_IMAGES_LIBRARYโ The path to the FLTK 2.x Images library (fltk2_images).
โจ Examples โจ
Finding FLTK version 2:
find_package(FLTK2)
See Also
- The
FindFLTK<#module:FindFLTK> module to find FLTK in a version-agnostic way ๐ซถ
๐ค FindFontconfig ๐ค
Added in version 3.14.
Finds Fontconfig, a library for font configuration and customization โ literally the glow-up your fonts deserve โจ:
find_package(Fontconfig [<version>] [...])
๐ Imported Targets
This module provides the following Imported Targets <#imported-targets>:
Fontconfig::Fontconfigโ Target encapsulating the Fontconfig usage requirements, available if Fontconfig is found ๐
๐ Result Variables
This module defines the following variables:
Fontconfig_FOUNDโ Boolean indicating whether (the requested version of) Fontconfig was found.Fontconfig_VERSIONโ The version of Fontconfig found.Fontconfig_LIBRARIESโ The libraries to link against to use Fontconfig.Fontconfig_INCLUDE_DIRSโ The include directories containing headers needed to use Fontconfig.Fontconfig_COMPILE_OPTIONSโ Compiler options needed to use Fontconfig. These should be passed totarget_compile_options()<#command:target_compile_options> when not using theFontconfig::Fontconfigimported target ๐
โจ Examples โจ
Finding Fontconfig and linking it to a project target:
find_package(Fontconfig)
target_link_libraries(project_target PRIVATE Fontconfig::Fontconfig)
๐๏ธ FindFreetype ๐๏ธ
Finds the FreeType font renderer library โ fonts but make it iconic ๐:
find_package(Freetype [<version>] [...])
Added in version 3.7: Debug and Release (optimized) library variants are found separately. Organized queen behavior ๐
๐ Imported Targets
This module provides the following Imported Targets <#imported-targets>:
Freetype::Freetypeโ Added in version 3.10. Target encapsulating the Freetype library usage requirements, available if Freetype is found โจ
๐ Result Variables
This module defines the following variables:
Freetype_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) Freetype was found.Freetype_VERSIONโ Added in version 4.2. The version of Freetype found.FREETYPE_INCLUDE_DIRSโ Include directories containing headers needed to use Freetype. This is the concatenation of theFREETYPE_INCLUDE_DIR_ft2buildandFREETYPE_INCLUDE_DIR_freetype2variables.FREETYPE_LIBRARIESโ Libraries needed to link against for using Freetype.
Added in version 3.7: Debug and Release library variants are found separately ๐ซถ
๐๏ธ Cache Variables
The following cache variables may also be set:
FREETYPE_INCLUDE_DIR_ft2buildโ The directory containing the main Freetype API configuration header.FREETYPE_INCLUDE_DIR_freetype2โ The directory containing Freetype public headers.
๐ก Hints
This module accepts the following variables:
FREETYPE_DIRโ The user may set this environment variable to the root directory of a Freetype installation to find Freetype in non-standard locations ๐
๐ซ Deprecated Variables
The following variables are provided for backward compatibility:
FREETYPE_FOUNDโ Deprecated since version 4.2: UseFreetype_FOUND, which has the same value. Boolean indicating whether (the requested version of) Freetype was found.FREETYPE_VERSION_STRINGโ Deprecated since version 4.2: Superseded by theFreetype_VERSION. The version of Freetype found.
โจ Examples โจ
Finding Freetype and linking it to a project target:
find_package(Freetype)
target_link_libraries(project_target PRIVATE Freetype::Freetype)
๐ FindGettext ๐
Finds the GNU gettext tools and provides commands for producing multi-lingual messages โ i18n bestie, we love to see it ๐ฃ๏ธโจ:
find_package(Gettext [<version>] [...])
GNU gettext is a system for internationalization (i18n) and localization (l10n), consisting of command-line tools and a runtime library (libintl). This module finds the gettext tools (such as msgmerge and msgfmt), while the runtime library can be found using the separate FindIntl <#module:FindIntl> module, which abstracts libintl handling across various implementations ๐ซถ
Common file types used with gettext:
- POT files โ Portable Object Template (
.pot) files used as the source template for translations ๐ - PO files โ Portable Object (
.po) files containing human-readable translations ๐๏ธ - MO files โ Machine Object (
.mo) files compiled from.pofiles for runtime use โ๏ธ
๐ Result Variables
This module defines the following variables:
Gettext_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) gettext was found.Gettext_VERSIONโ Added in version 4.2. The version of gettext found.
๐๏ธ Cache Variables
The following cache variables may also be set:
GETTEXT_MSGMERGE_EXECUTABLEโ The full path to themsgmergetool for merging message catalog and template.GETTEXT_MSGFMT_EXECUTABLEโ the full path to themsgfmttool, aka the li'l icon that compiles a message catalog into binary format. ๐
๐ ๏ธ Commands ๐ ๏ธ
If gettext gets found, this module hands you the following commands so you can do gettext stuff right inside CMake:
gettext_process_po_files
Creates a build rule that processes one or more .po translation files into binary .mo files for a specified translatable language locale:
gettext_process_po_files(
<language>
[ALL]
[INSTALL_DESTINATION <destdir>]
PO_FILES <po-files>...
)
This command defines a custom target that compiles the given <po-files> into .mo files for the specified <language>. On first invocation it also creates a global custom target named pofiles, and every later invocation just adds to it. That target is your bestie for building all the translation files together, or for referencing from other CMake commands. ๐ซถ
You should invoke this command separately for each language locale, so each locale gets its own appropriate .mo files.
The arguments are:
- <language> โ the target translatable language locale of the PO files.
This string is typically formatted as a locale identifier (e.g., de_DE for German as used in Germany, or de_AT for German as used in Austria, etc.). The part before the underscore specifies the language, and the part after specifies the country or regional variant. In some cases, a shorter form using only the language code (e.g., de) may also be used. no cap, that's literally how it works ๐
ALLโ this option adds the generated target to the default CMake build target, so translations get built by default. iconic default behaviour tbh โจINSTALL_DESTINATION<destdir> โ specifies the installation directory for the generated.mofiles at the install phase. If specified, files are installed to:<destdir>/<language>/LC_MESSAGES/*.mo. If not specified, files are not installed. (yes, the "not installed" part is a real vibe check โ if you skip it, nothing gets installed ๐ซ )PO_FILES<po-files>... โ a list of one or more.potranslation files to be compiled into.mofiles at build phase for the specified <language>. Relative paths will be interpreted relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR). ๐
gettext_process_pot_file
Creates a build rule that processes a gettext Portable Object Template (.pot) file and associated .po files into compiled gettext Machine Object (.mo) files:
gettext_process_pot_file(
<pot-file>
[ALL]
[INSTALL_DESTINATION <destdir>]
LANGUAGES <languages>...
)
This command defines a custom target named potfiles that compiles the given <pot-file> and language-specific .po files into binary .mo files for each specified language. The corresponding <language>.po files must exist in the current binary directory (CMAKE_CURRENT_BINARY_DIR) before this command is invoked. so like, put them there first, bestie, or it's giving nothing ๐ฅ
The arguments are:
- <pot-file> โ the path to the gettext Portable Object Template file (
.pot) serving as the source for translations. If given as a relative path, it will be interpreted relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR). ALLโ adds the generated target to the default CMake build target so that the files are built by default. โญINSTALL_DESTINATION<destdir> โ specifies the installation directory for the generated.mofiles at the install phase. If specified, files are installed to:<destdir>/<language>/LC_MESSAGES/<pot-base-filename>.mo. If not specified, files are not installed.LANGUAGES<languages>... โ a list of one or more translatable language locales (e.g.,en_US,fr,de_DE,zh_CN, etc.). ๐ฆ
gettext_create_translations
Creates a build rule that processes a given .pot template file and associated .po translation files into compiled Machine Object (.mo) files:
gettext_create_translations(<pot-file> [ALL] <po-files>...)
This command defines a custom target named translations that compiles the specified <pot-file> and <po-files> into binary .mo files. It also automatically adds an install rule for the generated .mo files, installing them into the default share/locale/<language>/LC_MESSAGES/<pot-base-filename>.mo path during the install phase. automatic install rule = lowkey main character energy ๐
The arguments are:
- <pot-file> โ the path to the gettext Portable Object Template file (
.pot) serving as the source for translations. If given as a relative path, it will be interpreted relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR). ALLโ adds the generated target to the default CMake build target so that translations are created by default during the build.- <po-files>... โ a list of one or more translation source files in
.poformat, whose filenames must follow the format<language>.po. Relative paths will be interpreted relative to the current source directory (CMAKE_CURRENT_SOURCE_DIR). ๐
Note: for better control over build and installation behavior, use gettext_process_po_files() instead. like, this one is the cute shortcut; that one is the one with options ๐
๐ซ Deprecated Variables ๐ซ
The following variables are provided for backward compatibility:
GETTEXT_FOUNDโ deprecated since version 4.2: useGettext_FOUND, which has the same value.
Boolean indicating whether (the requested version of) gettext was found.
GETTEXT_VERSION_STRINGโ deprecated since version 4.2: superseded by theGettext_VERSION.
The version of gettext found.
Both of these are giving "still here for the old heads" โ deprecated, not deleted, but pls use the new names. ๐
๐ธ Examples ๐ธ
Examples: Finding gettext
Finding the GNU gettext tools:
find_package(Gettext)
Or, finding gettext and specifying a minimum required version:
find_package(Gettext 0.21)
Or, finding gettext and making it required (if not found, processing stops with an error message):
find_package(Gettext REQUIRED)
Example: Working With gettext in CMake
When starting with gettext, .pot file is considered to be created manually. For example, using a xgettext tool on the provided main.cxx source code file:
main.cxx
#include <iostream>
#include <libintl.h>
#include <locale.h>
int main()
{
// Set locale from environment
setlocale(LC_ALL, "");
// Bind the text domain
const char* dir = std::getenv("TEXTDOMAINDIR");
if (!dir) {
dir = "/usr/local/share/locale";
}
bindtextdomain("MyApp", dir);
textdomain("MyApp");
std::cout << gettext("Hello, World") << std::endl;
return 0;
}
The xgettext tool extracts all strings from gettext() calls in provided source code and creates translatable strings:
$ xgettext -o MyApp.pot main.cxx
Translatable files can be initialized by the project manually using msginit tool:
$ mkdir -p locale/de_DE
$ msginit -l de_DE.UTF8 -o locale/de_DE/MyApp.po -i MyApp.pot --no-translator
which creates a human-readable file that can be translated into a desired language (adjust as needed):
locale/de_DE/MyApp.po
msgid ""
msgstr ""
"Language: de\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Hello, World"
msgstr "Hallo, Welt"
In CMake, the gettext_process_po_files() command provided by this module automatically creates the needed .mo files that application loads at runtime depending on the system environment variables such as LANG. In the following example, also the GNUInstallDirs module is used to provide the CMAKE_INSTALL_LOCALEDIR variable:
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(GettextExample)
include(GNUInstallDirs)
find_package(Gettext)
if(Gettext_FOUND)
foreach(language IN ITEMS de_DE)
gettext_process_po_files(
${language}
ALL
PO_FILES locale/${language}/MyApp.po
INSTALL_DESTINATION ${CMAKE_INSTALL_LOCALEDIR}
)
endforeach()
endif()
add_executable(example main.cxx)
# Find and link Intl library to use gettext() from libintl.h
find_package(Intl)
target_link_libraries(example PRIVATE Intl::Intl)
install(TARGETS example)
$ cmake -B build
$ cmake --build build
$ DESTDIR=$(pwd)/stage cmake --install build
To utilize the translations, the de_DE locale needs to be enabled on the system (see locale -a). And then the localized output can be run:
$ LANG=de_DE.UTF-8 TEXTDOMAINDIR=./stage/usr/local/share/locale \
./stage/usr/local/bin/example
Example: Processing POT File
The gettext_process_pot_file() command processes .po translation files located in the current binary directory into .mo files:
CMakeLists.txt
find_package(Gettext)
if(Gettext_FOUND)
set(languages de_DE fr zh_CN)
foreach(language IN LISTS languages)
configure_file(locale/${language}.po ${language}.po COPYONLY)
endforeach()
gettext_process_pot_file(
MyApp.pot
ALL
INSTALL_DESTINATION ${CMAKE_INSTALL_LOCALEDIR}
LANGUAGES ${languages}
)
endif()
Example: Creating Translations
Using a simplified gettext_create_translations() command to create .mo files:
CMakeLists.txt
find_package(Gettext)
if(Gettext_FOUND)
gettext_create_translations(
MyApp.pot
ALL
locale/de_DE.po
locale/fr.po
locale/zh_CN.po
)
endif()
๐ See Also ๐
- The
FindIntlmodule to find the Gettext runtime library (libintl). ๐ง
๐ FindGIF ๐
Finds the Graphics Interchange Format (GIF) library (giflib):
find_package(GIF [<version>] [...])
๐ Imported Targets โ yes bestie, there are targets
GIF::GIFโ added in version 3.14 โจ โ the target that wraps up all the usage requirements of the GIF library. It's there for you whenever the library gets found, no cap.
๐ธ Result Variables โ the receipts this module hands you
GIF_FOUNDโ boolean, tells you whether the (requested version of the) GIF library was found ๐GIF_VERSIONโ version string of the GIF library it found (like, for example,5.1.4). โ ๏ธ lowkey important: for GIF library versions prior to4.1.6, the version string gets set only to3or4, because those old versions didn't put version info in their headers. So don't come for the module, it's doing its best ๐ญGIF_INCLUDE_DIRSโ include directories you need to actually use the GIF libraryGIF_LIBRARIESโ the libraries you need to link to the GIF library
๐ฆ Cache Variables โ these might get set too
GIF_INCLUDE_DIRโ the directory holdinggif_lib.hand the other GIF library headersGIF_LIBRARYโ path to the GIF library itself
๐ง Hints โ little nudges you can give it
GIF_DIRโ an environment variable you can set to help locate a GIF library that's installed in a custom location ๐ซถ. It should point at the installation destination that was used when configuring, building, and installing the GIF library:./configure --prefix=$GIF_DIR
โญ Examples โ finding GIF and linking it to a project target:
find_package(GIF)
target_link_libraries(project_target PRIVATE GIF::GIF)
FindGit
Finds the Git distributed version control system, aka the thing you literally cannot live without:
find_package(Git [<version>] [...])
๐ Imported Targets โ provided when CMAKE_ROLE is PROJECT
Git::Gitโ added in version 3.14 โจ โ the target that encapsulates the Git command-line client executable. Bestie you can use this in generator expressions, and in commands likeadd_custom_target()andadd_custom_command(). It's only available if Git is found, obviously ๐
๐ธ Result Variables
Git_FOUNDโ added in version 3.3 โ boolean, tells you whether (the requested version of) Git was foundGit_VERSIONโ added in version 4.2 โ the version of Git that was found
๐ฆ Cache Variables
GIT_EXECUTABLEโ path to thegitcommand-line client executable
๐ Deprecated Variables โ kept around for backward compatibility, bless
GIT_FOUNDโ deprecated since version 4.2: useGit_FOUND, which has the same value. Boolean indicating whether (the requested version of) Git was found.GIT_VERSION_STRINGโ deprecated since version 4.2: useGit_VERSION, which has the same value. The version of Git found.
โญ Examples โ finding Git and grabbing the latest commit from the project repo:
find_package(Git)
if(Git_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} --no-pager log -n 1 HEAD "--pretty=format:%h %s"
OUTPUT_VARIABLE output
RESULT_VARIABLE result
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(result EQUAL 0)
message(STATUS "Last Git commit: ${output}")
endif()
endif()
FindGLEW
Finds the OpenGL Extension Wrangler Library (GLEW) ๐:
find_package(GLEW [<version>] [...])
GLEW is a cross-platform C/C++ library that helps you manage OpenGL extensions โ it gives you efficient run-time mechanisms to query and load OpenGL functionality beyond the core specification. It's giving "I know a guy" but for GPU features, fr fr.
- Added in version 3.7: Debug and Release library variants are found separately now โจ
- Added in version 3.15: if GLEW is built with its CMake-based build system, it ships a CMake package configuration file (
GLEWConfig.cmake). This module takes that into account and first attempts to find GLEW in config mode. If that config file isn't available, it falls back to module mode and searches standard locations. Iconic fallback behaviour tbh ๐ซถ
๐ Imported Targets
GLEW::GLEWโ added in version 3.1 โ the main imported target encapsulating GLEW's usage requirements, available if GLEW is found. It maps the usage requirements of eitherGLEW::gleworGLEW::glew_s, depending on which one is available.GLEW::glewโ added in version 3.15 โ target encapsulating the usage requirements for a shared GLEW library. Available if GLEW is found and static libraries aren't requested via theGLEW_USE_STATIC_LIBShint variable (see below ๐).GLEW::glew_sโ added in version 3.15 โ target encapsulating the usage requirements for a static GLEW library. Available if GLEW is found and theGLEW_USE_STATIC_LIBShint variable is set to boolean true.
๐ธ Result Variables
GLEW_FOUNDโ boolean, whether (the requested version of) GLEW was foundGLEW_VERSIONโ added in version 3.15 โ the version of GLEW foundGLEW_VERSION_MAJORโ added in version 3.15 โ the major version of GLEW foundGLEW_VERSION_MINORโ added in version 3.15 โ the minor version of GLEW foundGLEW_VERSION_MICROโ added in version 3.15 โ the micro version of GLEW foundGLEW_INCLUDE_DIRSโ include directories needed to use the GLEW libraryGLEW_LIBRARIESโ libraries needed to link against to use GLEW (shared or static, depending on configuration)GLEW_SHARED_LIBRARIESโ added in version 3.15 โ libraries needed to link against to use the shared GLEW libraryGLEW_STATIC_LIBRARIESโ added in version 3.15 โ libraries needed to link against to use the static GLEW library
๐ง Hints โ set these before calling find_package(GLEW) to influence this module's behavior
GLEW_USE_STATIC_LIBSโ added in version 3.15 โ set to boolean true to find the static GLEW library and create theGLEW::glew_simported target for static linkageGLEW_VERBOSEโ added in version 3.15 โ set to boolean true to output a detailed log of what this module is doing. Perfect for debugging, we love a verbose queen ๐ฅ
โญ Examples โ finding GLEW and linking it to a project target:
find_package(GLEW)
target_link_libraries(project_target PRIVATE GLEW::GLEW)
Using the static GLEW library, if it's found:
set(GLEW_USE_STATIC_LIBS TRUE)
find_package(GLEW)
target_link_libraries(project_target PRIVATE GLEW::GLEW)
FindGLUT
Finds the OpenGL Utility Toolkit (GLUT) library โ it gives you a simple API for creating windows, handling input, and managing events in OpenGL apps ๐ช:
find_package(GLUT [...])
๐ Imported Targets
GLUT::GLUTโ added in version 3.1 โ the target encapsulating GLUT's usage requirements, available if GLUT is found โจ
๐ธ Result Variables
GLUT_FOUNDโ boolean, whether GLUT was foundGLUT_INCLUDE_DIRSโ added in version 3.23 โ include directories needed to use GLUT. Starting with CMake3.23, this variable is meant to be used in target usage requirements instead of the cache variableGLUT_INCLUDE_DIR, which is meant for finding GLUT. iykyk ๐GLUT_LIBRARIESโ list of libraries you need to link against to use GLUT
๐ฆ Cache Variables โ this module may set these depending on platform. You can optionally set them yourself to help it find the correct files, but they should not be used as result variables, bestie ๐
GLUT_INCLUDE_DIRโ the full path to the directory containingGL/glut.h(without theGL/)GLUT_glut_LIBRARYโ the full path to the glut libraryGLUT_Xi_LIBRARYโ the full path to the dependent Xi (X Input Device Extension) library on some systemsGLUT_Xmu_LIBRARYโ the full path to the dependent Xmu (X Miscellaneous Utilities) library on some systems
โญ Examples โ finding GLUT and linking it to a project target:
find_package(GLUT)
target_link_libraries(project_target PRIVATE GLUT::GLUT)
FindGnuplot
Finds the Gnuplot command-line graphing utility, the one for generating two- and three-dimensional plots (gnuplot) ๐:
find_package(Gnuplot [<version>] [...])
๐ธ Result Variables
Gnuplot_FOUNDโ added in version 3.3 โ boolean, whether (the requested version of) Gnuplot was foundGnuplot_VERSIONโ added in version 4.2 โ the version of Gnuplot found
Note: version detection is available only for Gnuplot 4 and later. Earlier versions didn't provide version output at all, so don't @ the module about it ๐ญ
๐ฆ Cache Variables
GNUPLOT_EXECUTABLEโ absolute path to thegnuplotexecutable
๐ Deprecated Variables โ for backward compatibility only
GNUPLOT_FOUNDโ deprecated since version 4.2: useGnuplot_FOUND, which has the same value. Boolean indicating whether (the requested version of) Gnuplot was found.GNUPLOT_VERSION_STRINGโ deprecated since version 4.2: superseded by theGnuplot_VERSION. The version of Gnuplot found.
โญ Examples โ finding Gnuplot and running it in a process:
find_package(Gnuplot)
if(Gnuplot_FOUND)
execute_process(COMMAND ${GNUPLOT_EXECUTABLE} --help)
endif()
FindGnuTLS
Finds the GNU Transport Layer Security library (GnuTLS) ๐:
find_package(GnuTLS [<version>] [...])
So here's the tea: the GnuTLS package includes the main libraries (libgnutls and libdane), plus the optional gnutls-openssl compatibility extra library. They're all distributed as part of the same release ๐. This module checks for the presence of the main libgnutls library and gives you usage requirements for integrating GnuTLS into your CMake projects. Secure comms, slay.
๐ฏ Imported Targets ๐ฏ
Okay so this module hands you these imported target besties:
GnuTLS::GnuTLSโ Added in version 3.16. This is the target that wraps up all of GnuTLS's usage requirements in one cute little package. It's available whenever GnuTLS is found, so like, if it's there, she's there. ๐
๐ Result Variables ๐
The module sets these for you:
GnuTLS_FOUNDโ Added in version 3.3. A boolean, bestie โ it just tells you whether (the requested version of) GnuTLS was found. Yes or no. That's the whole vibe check. โจGnuTLS_VERSIONโ Added in version 4.2. The version of GnuTLS that was found. Slay, now you know what you're working with.GNUTLS_INCLUDE_DIRSโ The include directories you need to actually use GnuTLS. ๐ซถGNUTLS_LIBRARIESโ The libraries you gotta link against to use GnuTLS.GNUTLS_DEFINITIONSโ Compiler options that are required for using GnuTLS. Don't skip these, fr fr.
๐๏ธ Cache Variables ๐๏ธ
These cache variables may also get set:
GNUTLS_INCLUDE_DIRโ The directory that's holding thegnutls/gnutls.hheader file. Like, that's where the header lives. ๐GNUTLS_LIBRARYโ The path to the GnuTLS library itself.
๐ Deprecated Variables ๐
These ones are still hanging around for backward compatibility, like that one friend who refuses to leave the group chat:
GNUTLS_FOUNDโ Deprecated since version 4.2: useGnuTLS_FOUNDinstead, it literally has the same value. A boolean indicating whether (the requested version of) GnuTLS was found.GNUTLS_VERSION_STRINGโ Deprecated since version 3.16: use theGnuTLS_VERSION, which has the same value. Same energy, newer name.GNUTLS_VERSIONโ Added in version 3.16. Deprecated since version 4.2: use theGnuTLS_VERSION, which has the same value. (Yes, it's spelled differently from the new one by exactly one underscore and that's the whole drama. ๐)
๐ Examples ๐
Finding GnuTLS and linking it to a project target โ the whole thing, look:
find_package(GnuTLS)
target_link_libraries(project_target PRIVATE GnuTLS::GnuTLS)
That's it. That's the post. ๐
๐ฌ FindGSL ๐ฌ
Added in version 3.2.
This one finds the native GNU Scientific Library (GSL) includes and libraries:
find_package(GSL [<version>] [...])
So like, what even is GSL? The GNU Scientific Library (GSL) is a numerical library for C and C++ programmers, and it's free software under the GNU General Public License. Very much giving "math but make it open source." ๐
๐ฏ Imported Targets ๐ฏ
This module provides these imported targets:
GSL::gslโ The target that encapsulates the main GSL library and all of its usage requirements. Only available if GSL is found, no cap.GSL::gslcblasโ This target encapsulates the usage requirements of the CBLAS support library that GSL uses. Available if GSL is found. Lowkey important detail: it's also linked into theGSL::gsltarget, but it's provided separately for granularity. So you can grab it on its own if that's your vibe. ๐
๐ Result Variables ๐
The module defines these:
GSL_FOUNDโ A boolean telling you whether (the requested version of) GSL was found on the local system. Iconic yes/no moment.GSL_VERSIONโ The version of the GSL installation that got discovered. ๐GSL_INCLUDE_DIRSโ The directory containing GSL header files.GSL_LIBRARIESโ The GSL libraries. The actual goods.
๐๏ธ Cache Variables ๐๏ธ
Depending on the platform and the type of GSL installation it finds, this module may set the following variables. And plot twist โ you can optionally set these yourself to help the module find the correct files. Teamwork! ๐ซถ
GSL_CBLAS_LIBRARYโ Location of the GSL CBLAS library.GSL_CBLAS_LIBRARY_DEBUGโ Location of the debug GSL CBLAS library (if any exists โ if not, no biggie).GSL_CONFIG_EXECUTABLEโ Location of thegsl-configscript (if any).GSL_LIBRARYโ Location of the GSL library.GSL_LIBRARY_DEBUGโ Location of the debug GSL library (if any).
๐ก Hints ๐ก
This module accepts this variable:
GSL_ROOT_DIRโ Set this bad boy to a directory that contains a GSL installation.
So here's the tea: if you don't set this variable, the module will use pkg-config and default paths to find GSL. But if you do provide it, the module expects to find libraries at ${GSL_ROOT_DIR}/lib and the GSL headers at ${GSL_ROOT_DIR}/include/gsl. Very specific. Very demure.
The library directory may optionally provide Release and Debug folders. If those are available, the libraries named gsld, gslblasd or cblasd get recognized as debug libraries. ๐ And on Unix-like systems, this module will also use gsl-config (if found) to aid in the discovery of GSL. Extra help, why not.
๐ Examples ๐
Finding GSL and linking it to a project target:
find_package(GSL)
target_link_libraries(project_target PRIVATE GSL::gsl)
Periodt. โจ
๐งช FindGTest ๐งช
Finds GoogleTest, aka the Google C++ testing and mocking framework:
find_package(GTest [...])
And btw? The GoogleTest framework also includes GoogleMock, which is the library for writing and using C++ mock classes. On some systems, GoogleMock may be distributed as a separate package, so like, keep an eye out. ๐
When both debug and release (optimized) variants of the GoogleTest and GoogleMock libraries are available, this module picks whichever variants match your current Build Configuration. It just knows. ๐
Added in version 3.20: If GoogleTest is built and installed using its CMake-based build system, it provides a package configuration file (GTestConfig.cmake) that can be used with find_package() in Config mode. By default, this module now searches for that configuration file and, if it finds it, returns the results without any further action โ like, she's done, no notes. If the upstream configuration file is not found, this module falls back to Module mode and searches standard locations instead. Backup plan always. ๐ซถ
๐ฏ Imported Targets ๐ฏ
This module provides these imported targets:
GTest::gtestโ Added in version 3.20. Target encapsulating the usage requirements of the GoogleTestgtestlibrary, available if GoogleTest is found. Thegtestlibrary provides the core GoogleTest testing framework functionality. The main character of testing, honestly. ๐GTest::gtest_mainโ Added in version 3.20. Target encapsulating the usage requirements of the GoogleTestgtest_mainlibrary, available if GoogleTest is found. Thegtest_mainlibrary provides amain()function, so your tests can be run without you manually defining one. Huge time-save.
Only link toGTest::gtest_mainif GoogleTest should supply themain()function for the executable. If the project is supplying its ownmain()implementation, link only toGTest::gtest. Do not do both, bestie, that's chaos. ๐ญ
GTest::gmockโ Added in version 3.23. Target encapsulating the usage requirements of the GoogleMockgmocklibrary, available if GoogleTest and its Mock library are found. Thegmocklibrary provides facilities for writing and using mock classes in C++. Mocks are the moment. ๐GTest::gmock_mainโ Added in version 3.23. Target encapsulating the usage requirements of the GoogleMockgmock_mainlibrary, available if GoogleTest andgmock_mainare found. Thegmock_mainlibrary provides amain()function, so GoogleMock tests can run without you defining one manually.
Only link toGTest::gmock_mainif GoogleTest should supply themain()function for the executable. If the project is supplying its ownmain()implementation, link only toGTest::gmock. Same rule as before, fr fr.
๐ Result Variables ๐
The module defines this:
GTest_FOUNDโ Added in version 3.3. A boolean indicating whether GoogleTest was found. That's it, that's the variable. Simple. Elegant. โจ
๐ก Hints ๐ก
This module accepts these variables before you call find_package(GTest):
GTEST_ROOTโ The root directory of the GoogleTest installation (may also be set as an environment variable, cute). Heads up though: this variable is used only when GoogleTest is found in Module mode. Config mode doesn't care about it. ๐GTEST_MSVC_SEARCHโ When you're compiling with MSVC, this variable controls which GoogleTest build variant gets searched for, based on the runtime library linkage model. Also only used when GoogleTest is found in Module mode. It accepts one of these values:MDโ (Default) Searches for shared library variants of GoogleTest that are built to link against the dynamic C runtime. These libraries are typically compiled with the MSVC runtime flags/MDor/MDd(for Release or Debug, respectively).MTโ Searches for static library variants of GoogleTest that are built to link against the static C runtime. These libraries are typically compiled with the MSVC runtime flags/MTor/MTd.
๐ Deprecated Items ๐
Deprecated Variables
The following variables are provided for backward compatibility:
GTEST_INCLUDE_DIRSโ Deprecated since version 4.1: use theGTest::gtestimported target instead, which exposes the required include directories through itsINTERFACE_INCLUDE_DIRECTORIEStarget property. She's got it handled.
This result variable provides include directories containing headers needed to use GoogleTest. And word of warning: this variable is only guaranteed to be available when GoogleTest is found in Module mode. So don't go relying on it in Config mode. ๐ญ
GTEST_LIBRARIESโ Deprecated since version 4.1: use theGTest::gtestimported target instead.
Result variable providing libraries needed to link against to use the GoogleTest gtest library. โ ๏ธ Note that projects are also responsible for linking with an appropriate thread library in addition to the libraries specified by this variable. So that's two jobs, not one.
GTEST_MAIN_LIBRARIESโ Deprecated since version 4.1: use theGTest::gtest_mainimported target instead.
Result variable providing libraries needed to link against to use the GoogleTest gtest_main library.
GTEST_BOTH_LIBRARIESโ Deprecated since version 4.1: use theGTest::gtestandGTest::gtest_mainimported targets instead.
Result variable providing both gtest and gtest_main libraries combined. Two for one, but like, deprecated two for one.
GTEST_FOUNDโ Deprecated since version 4.2: useGTest_FOUND, which has the same value.
Boolean indicating whether GoogleTest was found. (Notice the ALL CAPS spelling, that's the old one. The new one's got the nicer casing. ๐ )
Deprecated Imported Targets
For backward compatibility, this module also provides the following imported targets (available since CMake 3.5):
GTest::GTestโ Deprecated since version 3.20: use theGTest::gtestimported target instead.
Imported target linking the GTest::gtest library.
GTest::Mainโ Deprecated since version 3.20: use theGTest::gtest_mainimported target instead.
Imported target linking the GTest::gtest_main library.
๐ Examples ๐
๐ Examples: Finding GoogleTest ๐
Finding GoogleTest:
find_package(GoogleTest)
Or, finding GoogleTest and making it required (if it's not found, processing stops with an error message):
find_package(GoogleTest REQUIRED)
โจ Examples: Using Imported Targets โจ
So in this next one, the GTest::gtest imported target gets linked to a project target, and that's literally how you unlock the core GoogleTest testing framework bestie:
find_package(GTest REQUIRED)
target_link_libraries(foo PRIVATE GTest::gtest)
And in this next example, the GTest::gtest_main imported target is also linked to the executable, and a test gets registered. The GTest::gtest_main library hands you a main() function so you do NOT have to write one yourself, no cap ๐ซถ. The GTest::gtest library is still linked because your test code directly uses stuff that GTest::gtest provides, and the good-practice vibe is to link directly to the libraries you use directly. Periodt.
enable_testing()
find_package(GTest REQUIRED)
add_executable(foo foo.cc)
target_link_libraries(foo PRIVATE GTest::gtest GTest::gtest_main)
add_test(NAME AllTestsInFoo COMMAND foo)
๐ฅ Deeper Integration With CTest ๐ฅ
This module is commonly used together with the GoogleTest module, which is the one serving up the gtest_discover_tests() and gtest_add_tests() commands โ those are the girlies that help you integrate all the GoogleTest infrastructure with CTest:
find_package(GTest)
target_link_libraries(example PRIVATE GTest::gtest GTest::gtest_main)
include(GoogleTest)
gtest_discover_tests(example)
# ...
Changed in version 3.9: previous CMake versions defined the gtest_add_tests() command in this module. So if you're on old CMake, that's where she lived ๐
๐ธ FindGTK ๐ธ
Note: this module works only on Unix-like systems and was intended for the early GTK branch of 1.x, which is no longer maintained. So likeโฆ use the latest supported GTK version and the FindPkgConfig module to find GTK in CMake instead of this module, mwah ๐. For example:
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14)
target_link_libraries(example PRIVATE PkgConfig::GTK)
Finds GTK, glib and GTKGLArea:
find_package(GTK [...])
GTK is a multi-platform toolkit for creating graphical user interfaces. She's iconic, she's classic ๐
๐ Result Variables ๐
This module defines the following variables:
GTK_FOUNDโ boolean telling you whether GTK was found.GTK_GL_FOUNDโ boolean telling you whether GTK's GL features were found.GTK_INCLUDE_DIRโ the include directories holding the headers you need to use GTK.GTK_LIBRARIESโ the libraries you need to link against for using GTK.
๐ Examples ๐
Finding GTK 1.x and creating an interface imported target that wraps up all her usage requirements so you can link her to a project target:
find_package(GTK)
if(GTK_FOUND)
add_library(GTK::GTK INTERFACE IMPORTED)
set_target_properties(
GTK::GTK
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GTK_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${GTK_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE GTK::GTK)
๐ฆ See Also ๐ฆ
- The
FindGTK2module, for finding GTK version 2.
๐ FindGTK2 ๐
Note: this module is intended specifically for GTK version 2.x, which is obsolete and no longer maintained โ she's giving vintage, but like, in the unsupported way ๐ญ. Use the latest supported GTK version and the FindPkgConfig module to find GTK in CMake instead of this module. For example:
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14)
target_link_libraries(example PRIVATE PkgConfig::GTK)
Finds the GTK widget libraries plus several of her other optional components:
find_package(GTK2 [<version>] [COMPONENTS <components>...] [...])
GTK is a multi-platform toolkit for creating graphical user interfaces. Same queen, older era โจ
๐ Components ๐
This module supports optional components, and you can specify them with the find_package() command:
find_package(GTK2 [COMPONENTS <components>...])
Supported components include:
atkatkmmcairocairommgdk_pixbufgdkgdkmmgiogiommgladeglademmglibglibmmgmodulegobjectgthreadgtkgtkmmpangopangocairopangoft2pangommpangoxftsigc- Added in version 3.16.7:
harfbuzz
If you don't specify any components, the module by default searches for the gtk component. Default queen behavior ๐
๐ Imported Targets ๐
This module provides the following imported targets (subject to component selection, bestie):
GTK2::<component>โ target encapsulating the specified GTK component's usage requirements, available if GTK and this component are found. The<component>should be written in the same case as listed above. So like, useGTK2::gtkfor thegtkcomponent, orGTK2::gdk_pixbuffor thegdk_pixbufcomponent, etc.GTK2::sigc++โ Added in version 3.5. Target encapsulating the usage requirements to enable c++11 on its dependents when using sigc++ 2.5.1 or higher. This target is automatically applied to dependent targets as needed โ she does it herself, main character energy ๐ซ
๐ Result Variables ๐
This module defines the following variables:
GTK2_FOUNDโ boolean indicating whether (the requested version of) GTK 2 and all the specified components were found.GTK2_VERSIONโ the version of GTK found (x.y.z).GTK2_MAJOR_VERSIONโ the major version of GTK found.GTK2_MINOR_VERSIONโ the minor version of GTK found.GTK2_PATCH_VERSIONโ the patch version of GTK found.GTK2_INCLUDE_DIRSโ include directories containing headers needed to use GTK.GTK2_LIBRARIESโ libraries needed to link against to use GTK.GTK2_TARGETSโ Added in version 3.5. A list of all defined imported targets.GTK2_DEFINITIONSโ additional compiler flags needed to use GTK.
๐ง Input Variables ๐ง
This module accepts the following optional variables before you call find_package(GTK2):
GTK2_DEBUGโ boolean variable that enables verbose debugging output from this module. Turn it on when you need the tea โGTK2_ADDITIONAL_SUFFIXESโ a list of additional path suffixes to search for include files.GTK2_USE_IMPORTED_TARGETSโ Added in version 3.5. When this variable is set to boolean true, theGTK2_LIBRARIESvariable will contain a list of imported targets instead of library paths.
โญ Examples โญ
๐ Examples: Finding GTK version 2 ๐
Call find_package() once. Here are some examples to pick from, babe:
Require GTK 2.6 or later:
find_package(GTK2 2.6 REQUIRED COMPONENTS gtk)
Require GTK 2.10 or later and its Glade component:
find_package(GTK2 2.10 REQUIRED COMPONENTS gtk glade)
Search for GTK/GTKMM 2.8 or later:
find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
Finding GTK 2 and linking it to a project target:
find_package(GTK2)
add_executable(mygui mygui.cc)
target_link_libraries(mygui PRIVATE GTK2::gtk)
๐ Examples: Finding GTK version 3 or later ๐
Finding GTK 3 with FindPkgConfig instead of this module:
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED IMPORTED_TARGET gtk+-3.0>=3.14)
target_link_libraries(example PRIVATE PkgConfig::GTK3)
Or, similarly, to find GTK 4:
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK4 REQUIRED IMPORTED_TARGET gtk4>=4.14)
target_link_libraries(example PRIVATE PkgConfig::GTK4)
๐ FindHDF5 ๐
Finds Hierarchical Data Format (HDF5), which is a library for reading and writing self-describing array data:
find_package(HDF5 [<version>] [COMPONENTS <components>...] [...])
Okay so here's the lore ๐ซถ: if the HDF5 library is built using its CMake-based build system, then as of HDF5 version 1.8.15 she provides her own CMake Package Configuration file (hdf5-config.cmake) for use with the find_package() command in config mode. By default, this module searches for that file and, if it finds it, returns the results based on the found configuration. She said "I'll handle it myself" ๐
If the upstream configuration file is not found, this module falls back to module mode and invokes the HDF5 wrapper compiler that's typically installed with the HDF5 library. Depending on the configuration, this wrapper compiler is named either h5cc (serial) or h5pcc (parallel). If found, the wrapper gets queried with the -show argument to determine the compiler and linker flags required for building an HDF5 client application. Both serial and parallel versions of the HDF5 wrapper are considered. The first directory containing either is used. If both versions are found in the same directory, the serial version is preferred by default. To change this behavior, set the variable HDF5_PREFER_PARALLEL to TRUE โ you're the one in charge, bestie ๐
On top of finding the include directories and libraries needed to compile an HDF5 application, this module also attempts to find additional tools provided by the HDF5 distribution, which can be useful for regression testing or development workflows. Little bonus gifts ๐
๐ Components ๐
This module supports optional components, which you can specify with the find_package() command:
find_package(HDF5 [COMPONENTS <components>...])
Supported components include:
Cโ finds the HDF5 C library (C bindings).CXXโ finds the HDF5 C++ library (C++ bindings).Fortranโ finds the HDF5 Fortran library (Fortran bindings).HLโ this component can be used in combination with other components to find the high-level (HL) HDF5 library variants for C, CXX, and/or Fortran, which provide high-level functions.
If no components are specified, then this module will by default search for the C component. Default slay ๐
๐ฅ Imported Targets ๐ฅ
This module provides the following imported targets:
HDF5::HDF5โ Added in version 3.19. Target encapsulating the usage requirements for all found HDF5 binding libraries (HDF5_LIBRARIES), available if HDF5 and all required components are found.hdf5::hdf5โ Added in version 3.19. Target encapsulating the usage requirements for the HDF5 C library, available if the HDF5 library and itsCcomponent are found.hdf5::hdf5_cppโ Added in version 3.19. Target encapsulating the usage requirements for the HDF5 C and C++ libraries, available if the HDF5 library, and itsCandCXXcomponents are found.hdf5::hdf5_fortranโ Added in version 3.19.hdf5::hdf5_fortranโ honestly the whole point of this one is wrapping up the usage requirements for the HDF5 Fortran library, and it only shows up if the HDF5 library and its Fortran component are both found. ๐ซถhdf5::hdf5_hlโ added in version 3.19, bestie โจ. It's the target that encapsulates the usage requirements for the HDF5 high-level C library, and it's available when the HDF5 library plus its C and HL components are found.hdf5::hdf5_hl_cppโ added in version 3.19 too. High-level C++ library. It encapsulates the usage requirements for the HDF5 high-level C and high-level C++ libraries, and it's available if the HDF5 library and itsC,CXX, andHLcomponents are all found. ๐hdf5::hdf5_hl_fortranโ added in version 3.19. This one encapsulates the usage requirements for the HDF5 high-level Fortran library, available if the HDF5 library and its Fortran and HL components are found.hdf5::h5diffโ added in version 3.19. It's an imported executable target encapsulating the usage requirements for theh5diffexecutable, available ifh5diffis found. literally so convenient ๐
Result Variables
This module defines these variables, no cap:
HDF5_FOUNDโ boolean that tells you whether (the requested version of) HDF5 was found. ๐ฏHDF5_VERSIONโ added in version 3.3. The version of the HDF5 library that was found.HDF5_INCLUDE_DIRSโ the include directories holding the header files you need to actually use HDF5.HDF5_DEFINITIONSโ the compiler definitions required for using HDF5.HDF5_LIBRARIESโ the libraries of all the requested bindings that you need to link against to use HDF5.HDF5_HL_LIBRARIESโ the libraries required for the HDF5 high-level API for all bindings, but only if theHLcomponent is enabled.HDF5_IS_PARALLELโ boolean indicating whether the HDF5 library has parallel IO support. ๐๏ธ
For each enabled language binding component you get a matching HDF5_<LANG>_LIBRARIES variable, and possibly HDF5_<LANG>_DEFINITIONS, defined for you. And if the HL component is enabled, then you also get HDF5_<LANG>_HL_LIBRARIES variables. Obsessed with the consistency tbh ๐
HDF5_C_DEFINITIONSโ required compiler definitions for HDF5 C bindings.HDF5_CXX_DEFINITIONSโ required compiler definitions for HDF5 C++ bindings.HDF5_Fortran_DEFINITIONSโ required compiler definitions for HDF5 Fortran bindings.HDF5_C_INCLUDE_DIRSโ required include directories for HDF5 C bindings.HDF5_CXX_INCLUDE_DIRSโ required include directories for HDF5 C++ bindings.HDF5_Fortran_INCLUDE_DIRSโ required include directories for HDF5 Fortran bindings.HDF5_C_LIBRARIESโ required libraries for the HDF5 C bindings.HDF5_CXX_LIBRARIESโ required libraries for the HDF5 C++ bindings.HDF5_Fortran_LIBRARIESโ required libraries for the HDF5 Fortran bindings.HDF5_C_HL_LIBRARIESโ required libraries for the high-level C bindings, if theHLcomponent is enabled.HDF5_CXX_HL_LIBRARIESโ required libraries for the high-level C++ bindings, if theHLcomponent is enabled.HDF5_Fortran_HL_LIBRARIESโ required libraries for the high-level Fortran bindings, if theHLcomponent is enabled. ๐
Cache Variables
These cache variables may also get set, keep an eye out ๐:
HDF5_C_COMPILER_EXECUTABLEโ the path to the HDF5 C wrapper compiler.HDF5_CXX_COMPILER_EXECUTABLEโ the path to the HDF5 C++ wrapper compiler.HDF5_Fortran_COMPILER_EXECUTABLEโ the path to the HDF5 Fortran wrapper compiler.HDF5_C_COMPILER_EXECUTABLE_NO_INTERROGATEโ added in version 3.6. The path to the primary C compiler which is also the HDF5 wrapper. Heads up: this variable is used only in module mode. ๐งHDF5_CXX_COMPILER_EXECUTABLE_NO_INTERROGATEโ added in version 3.6. The path to the primary C++ compiler which is also the HDF5 wrapper. Again, used only in module mode.HDF5_Fortran_COMPILER_EXECUTABLE_NO_INTERROGATEโ added in version 3.6. The path to the primary Fortran compiler which is also the HDF5 wrapper. Module mode only, iykyk.HDF5_DIFF_EXECUTABLEโ the path to the HDF5 dataset comparison tool (h5diff).
Hints
Okay so these variables can be set before you call find_package(HDF5), and they guide the search for the HDF5 library. Little cheat codes โจ
HDF5_PREFER_PARALLELโ added in version 3.4. Set this to boolean true to prefer parallel HDF5 (by default, serial is preferred, jsyk). This variable is used only in module mode.HDF5_FIND_DEBUGโ added in version 3.9. Set it to boolean true and this module gives you extra debugging output. Lifesaver when things get messy ๐ญHDF5_NO_FIND_PACKAGE_CONFIG_FILEโ added in version 3.8. Set this to boolean true to skip finding and using the CMake package configuration file (hdf5-config.cmake).HDF5_USE_STATIC_LIBRARIESโ set this to a boolean value to decide whether or not to prefer a static link over a dynamic link for HDF5 and all of its dependencies.
Added in version 3.10: support for HDF5_USE_STATIC_LIBRARIES on Windows. ๐ช
Examples
Examples: Finding HDF5
Finding HDF5, the classic:
find_package(HDF5)
Specifying a minimum required version of HDF5 to find:
find_package(HDF5 1.8.15)
Finding HDF5 and making it required โ and if HDF5 isn't found, processing stops with an error message. dramatic but fair ๐
find_package(HDF5 1.8.15 REQUIRED)
Searching for static HDF5 libraries:
set(HDF5_USE_STATIC_LIBRARIES TRUE)
find_package(HDF5)
Specifying components to find high-level C and C++ functions:
find_package(HDF5 COMPONENTS C CXX HL)
Examples: Using HDF5
Finding HDF5 and linking it to a project target. slay ๐
find_package(HDF5)
target_link_libraries(project_target PRIVATE HDF5::HDF5)
Using Fortran HDF5 and HDF5-HL functions:
find_package(HDF5 COMPONENTS Fortran HL)
target_link_libraries(project_target PRIVATE HDF5::HDF5)
FindHg
Finds the Mercurial command-line client executable (hg) and โ this is the cute part โ provides a command for extracting information from a Mercurial working copy:
find_package(Hg [<version>] [...])
Result Variables
This module defines these variables:
Hg_FOUNDโ added in version 3.3. Boolean indicating whether the (requested version of) Mercurial client was found. ๐ฆHg_VERSIONโ added in version 4.2. The version of Mercurial that was found.
Cache Variables
The following cache variables may also be set:
HG_EXECUTABLEโ absolute path to the Mercurial command-line client (hg).
Commands
This module provides the following command when the Mercurial client (hg) is found:
Hg_WC_INFOโ added in version 3.1. Extracts information of a Mercurial working copy:
Hg_WC_INFO(<dir> <var-prefix>)
This command defines the following variables if running the Mercurial client on the working copy located at the given location <dir> succeeds; otherwise a SEND_ERROR message is generated. so like, no silent failures here ๐ค
<var-prefix>_WC_CHANGESETโ current changeset.<var-prefix>_WC_REVISIONโ current revision.
Deprecated Variables
These variables are provided for backward compatibility only:
HG_FOUNDโ deprecated since version 4.2: useHg_FOUND, which has the same value. Boolean indicating whether the (requested version of) Mercurial client was found.HG_VERSION_STRINGโ deprecated since version 4.2: useHg_VERSION, which has the same value. The version of Mercurial found. ๐
Examples
Finding the Mercurial client and retrieving information about the current project's working copy:
find_package(Hg)
if(Hg_FOUND)
Hg_WC_INFO(${PROJECT_SOURCE_DIR} Project)
message("Current revision is ${Project_WC_REVISION}")
message("Current changeset is ${Project_WC_CHANGESET}")
endif()
FindHSPELL
Finds the Hebrew spell-checker and morphology engine (Hspell):
find_package(HSPELL [<version>] [...])
Result Variables
This module defines these variables:
HSPELL_FOUNDโ boolean indicating whether (the requested version of) Hspell was found. ๐HSPELL_VERSIONโ added in version 4.2. The version of Hspell found (x.y).HSPELL_VERSION_MAJORโ the major version of Hspell found.HSPELL_VERSION_MINORโ the minor version of Hspell found.
Cache Variables
The following cache variables may also be set:
HSPELL_INCLUDE_DIRโ the Hspell include directory.HSPELL_LIBRARIESโ the libraries needed to use Hspell.
Deprecated Variables
Provided for backward compatibility:
HSPELL_VERSION_STRINGโ deprecated since version 4.2: useHSPELL_VERSION, which has the same value. The version of Hspell found (x.y).
Examples
Finding Hspell:
find_package(HSPELL)
FindHTMLHelp
Finds the Microsoft HTML Help Compiler and its API, which is part of the HTML Help Workshop:
find_package(HTMLHelp [...])
Note, bestie: HTML Help Workshop is in maintenance mode only and is considered deprecated. For modern documentation, consider alternatives such as Microsoft Help Viewer for producing .mshc files or web-based documentation tools. ๐
Result Variables
This module defines the following variable:
HTMLHelp_FOUNDโ added in version 4.2. Boolean indicating whether HTML Help was found.
Cache Variables
The following cache variables may also be set:
HTML_HELP_COMPILERโ full path to the HTML Help Compiler (hhc.exe), used to compile.chmfiles.HTML_HELP_INCLUDE_PATHโ directory containinghtmlhelp.h, required for applications integrating the HTML Help API.HTML_HELP_LIBRARYโ full path to thehtmlhelp.liblibrary, required for linking applications that use the HTML Help API.
Examples
Finding the HTML Help Compiler:
find_package(HTMLHelp)
message(STATUS "HTML Help Compiler found at: ${HTML_HELP_COMPILER}")
FindIce
Added in version 3.1. ๐
Finds the Internet Communication Engine (Ice) programs, libraries and datafiles:
find_package(Ice [<version>] COMPONENTS <components>... [...])
Ice is an open-source remote procedure call (RPC) framework developed by ZeroC, and it provides SDKs for various languages so you can develop network applications. main character framework energy ngl ๐
Added in version 3.4: imported targets for components plus many new *_EXECUTABLE variables. ๐
Added in version 3.7: Debug and Release library variants get found separately bestie, two different vibes, two different results, no mixing ๐
Added in version 3.10: Ice 3.7 support is in the building ๐ โ and that includes the new components, the new programs, and the Nuget package. Slay.
๐ Components ๐
Ice isn't just one thing, it's a whole little ecosystem of libraries and programs (executables). This find module supports components, which you can specify using the find_package() command, so you can pick exactly which Ice libraries your CMake project gets to use. And heads up: executables that come with the Ice installation are always searched automatically, no matter which components you asked for. They just show up. Main character energy fr fr ๐
Which components even exist? Depends on the Ice version you've got, bestie. But to successfully find Ice, you gotta specify at least one component:
find_package(Ice COMPONENTS <components>...)
Supported components include:
FreezeGlacier2IceIceBoxIceDBIceDiscoveryIceGridIceLocatorDiscoveryIcePatchIceSSLIceStormIceUtilIceXMLSlice
Ice 3.7 and later also include these C++11-specific components โจ
Glacier2++11Ice++11IceBox++11IceDiscovery++11IceGrid++11IceLocatorDiscovery++11IceSSL++11IceStorm++11
๐ Imported Targets ๐
This module provides the following Imported Targets:
Ice::<component>โ Added in version 3.4. This is the target that encapsulates all the usage requirements for the specified Ice component (library), and it's available if that component was found. Write<component>in the same case as it's listed above, okay? Like, useIce::Glacier2for the Ice Glacier2 library, orIce::Ice++11for the Ice++11 library, etc. Case matters, don't play with me ๐
๐ Result Variables ๐
This module defines these variables, and yes, there are a lot of them:
Ice_FOUNDโ Boolean that tells you whether the (requested version of the) main programs, libraries and all requested components for using Ice were found. Basically the vibe check โIce_VERSIONโ the version of the Ice release that got found.Ice_INCLUDE_DIRSโ the include directories holding the headers you need to use Ice.Ice_LIBRARIESโ the component libraries you need to link against to use Ice.Ice_SLICE_DIRSโ the data directories containing interface definitions (*.icefiles) for Slice (Specification Language for Ice).
Ice component libraries are stored in these bad boys:
Ice_<COMPONENT>_FOUNDโ Boolean, was the specified Ice component found or not. Write<COMPONENT>in uppercase.Ice_<COMPONENT>_LIBRARIESโ the libraries provided by the specified Ice component. Again,<COMPONENT>goes in uppercase.
Slice programs are stored in:
Ice_SLICE2CONFLUENCE_EXECUTABLEโ Added in version 3.14. The path to theslice2confluenceexecutable.Ice_SLICE2CPP_EXECUTABLEโ the path to theslice2cppexecutable.Ice_SLICE2CS_EXECUTABLEโ the path to theslice2csexecutable.Ice_SLICE2FREEZEJ_EXECUTABLEโ the path to theslice2freezejexecutable.Ice_SLICE2FREEZE_EXECUTABLEโ the path to theslice2freezeexecutable.Ice_SLICE2HTML_EXECUTABLEโ the path to theslice2htmlexecutable.Ice_SLICE2JAVA_EXECUTABLEโ the path to theslice2javaexecutable.Ice_SLICE2JS_EXECUTABLEโ Added in version 3.4. The path to theslice2jsexecutable.Ice_SLICE2MATLAB_EXECUTABLEโ Added in version 3.14. The path to theslice2matlabexecutable.Ice_SLICE2OBJC_EXECUTABLEโ Added in version 3.10. The path to theslice2objcexecutable.Ice_SLICE2PHP_EXECUTABLEโ the path to theslice2phpexecutable.Ice_SLICE2PY_EXECUTABLEโ the path to theslice2pyexecutable.Ice_SLICE2RB_EXECUTABLEโ the path to theslice2rbexecutable.
Ice programs are stored in:
Ice_GLACIER2ROUTER_EXECUTABLEโ Added in version 3.4. The path to theglacier2routerexecutable.Ice_ICEBOX_EXECUTABLEโ Added in version 3.4. The path to theiceboxexecutable.Ice_ICEBOX++11_EXECUTABLEโ Added in version 3.10. The path to theicebox++11executable.Ice_ICEBOXADMIN_EXECUTABLEโ Added in version 3.4. The path to theiceboxadminexecutable.Ice_ICEBOXD_EXECUTABLEโ Added in version 3.4. The path to theiceboxdexecutable.Ice_ICEBOXNET_EXECUTABLEโ Added in version 3.4. The path to theiceboxnetexecutable.Ice_ICEBRIDGE_EXECUTABLEโ Added in version 3.10. The path to theicebridgeexecutable.Ice_ICEGRIDADMIN_EXECUTABLEโ Added in version 3.4. The path to theicegridadminexecutable.Ice_ICEGRIDDB_EXECUTABLEโ Added in version 3.10. The path to theicegriddbexecutable.Ice_ICEGRIDNODE_EXECUTABLEโ Added in version 3.4. The path to theicegridnodeexecutable.Ice_ICEGRIDNODED_EXECUTABLEโ Added in version 3.4. The path to theicegridnodedexecutable.Ice_ICEGRIDREGISTRY_EXECUTABLEโ Added in version 3.4. The path to theicegridregistryexecutable.Ice_ICEGRIDREGISTRYD_EXECUTABLEโ Added in version 3.4. The path to theicegridregistrydexecutable.Ice_ICEPATCH2CALC_EXECUTABLEโ the path to theicepatch2calcexecutable.Ice_ICEPATCH2CLIENT_EXECUTABLEโ Added in version 3.4. The path to theicepatch2clientexecutable.Ice_ICEPATCH2SERVER_EXECUTABLEโ Added in version 3.4. The path to theicepatch2serverexecutable.Ice_ICESERVICEINSTALL_EXECUTABLEโ Added in version 3.4. The path to theiceserviceinstallexecutable.Ice_ICESTORMADMIN_EXECUTABLEโ Added in version 3.4. The path to theicestormadminexecutable.Ice_ICESTORMDB_EXECUTABLEโ Added in version 3.10. The path to theicestormdbexecutable.Ice_ICESTORMMIGRATE_EXECUTABLEโ Added in version 3.4. The path to theicestormmigrateexecutable.
Ice database programs are stored in the following variables โ and quick context bestie: on Windows these come with the Ice installation; on other platforms you usually get them through the standard Berkeley DB packages ๐ซถ
Ice_DB_ARCHIVE_EXECUTABLEโ Added in version 3.4. The path to thedb_archiveexecutable.Ice_DB_CHECKPOINT_EXECUTABLEโ Added in version 3.4. The path to thedb_checkpointexecutable.Ice_DB_DEADLOCK_EXECUTABLEโ Added in version 3.4. The path to thedb_deadlockexecutable.Ice_DB_DUMP_EXECUTABLEโ Added in version 3.4. The path to thedb_dumpexecutable.Ice_DB_HOTBACKUP_EXECUTABLEโ Added in version 3.4. The path to thedb_hotbackupexecutable.Ice_DB_LOAD_EXECUTABLEโ Added in version 3.4. The path to thedb_loadexecutable.Ice_DB_LOG_VERIFY_EXECUTABLEโ Added in version 3.4. The path to thedb_log_verifyexecutable.Ice_DB_PRINTLOG_EXECUTABLEโ Added in version 3.4. The path to thedb_printlogexecutable.Ice_DB_RECOVER_EXECUTABLEโ Added in version 3.4. The path to thedb_recoverexecutable.Ice_DB_STAT_EXECUTABLEโ Added in version 3.4. The path to thedb_statexecutable.Ice_DB_TUNER_EXECUTABLEโ Added in version 3.4. The path to thedb_tunerexecutable.Ice_DB_UPGRADE_EXECUTABLEโ Added in version 3.4. The path to thedb_upgradeexecutable.Ice_DB_VERIFY_EXECUTABLEโ Added in version 3.4. The path to thedb_verifyexecutable.Ice_DUMPDB_EXECUTABLEโ Added in version 3.4. The path to thedumpdbexecutable.Ice_TRANSFORMDB_EXECUTABLEโ Added in version 3.4. The path to thetransformdbexecutable.
๐ฆ Cache Variables ๐ฆ
These cache variables can also be set manually, iykyk:
Ice_<PROGRAM>_EXECUTABLEโ the path to the specified<PROGRAM>executable. Here<PROGRAM>is the uppercase name of the Ice program as listed in the result variables of executables up above ๐Ice_INCLUDE_DIRโ the directory containing the Ice headers.Ice_SLICE_DIRโ the data directory containing interface definitions for Slice.Ice_<COMPONENT>_LIBRARYโ the path to the library for the specified component.<COMPONENT>goes in uppercase, periodt.
๐ธ Hints ๐ธ
This module accepts the following variables:
Ice_HOMEโ set this CMake variable to the root of the Ice installation and it'll go search for Ice in your custom little location ๐
Note: On Windows, Ice 3.7.0 and later hand out libraries via the NuGet package manager. The appropriate NuGet packages get searched for usingCMAKE_PREFIX_PATH, or alternatively you can setIce_HOMEto the location of a specific NuGet package to restrict the search. Choose your fighter ๐
ICE_HOMEโ an environment variable (uppercased, notice the case difference bestie) that can also be set to the root of the Ice installation. But theIce_HOMECMake variable takes precedence, so it wins the crown ๐Ice_DEBUGโ set this to boolean true and you get debug output from this module. Very demure, very helpful ๐
Note: In most cases, none of the above variables need to be set โ unless you've got multiple Ice versions installed and you need one specific one. On Windows, the most recent version is typically found using the registry. On Unix-like systems, programs, headers and libraries are usually found in standard locations, althoughIce_SLICE_DIRSmight not be detected automatically (commonly known locations are searched, so don't panic). All the other variables default based on the value ofIce_HOME, if it's set. You can also setIce_HOMEwhile selectively overriding specific locations for individual components. This might be required, for example, in newer versions of Visual Studio if the heuristics aren't sufficient to identify the correct programs and libraries for that specific Visual Studio version. So like, the defaults do their best but sometimes you gotta step in ๐ซก
โญ Examples โญ
Finding the Ice core library and linking it to a project target:
find_package(Ice COMPONENTS Ice)
target_link_libraries(project_target PRIVATE Ice::Ice)
Finding the Ice core library and the IceSSL library, and linking both of them to a project target:
find_package(Ice COMPONENTS Ice IceSSL)
target_link_libraries(project_target PRIVATE Ice::Ice Ice::IceSSL)
Finding the Ice core library as a required component and the Ice Freeze library as an optional one:
find_package(Ice COMPONENTS Ice OPTIONAL_COMPONENTS Freeze)
FindIconv
Added in version 3.11.
Okay so this one goes hunting for the iconv() POSIX.1 functions on your system:
find_package(Iconv [<version>] [...] )
Bestie, plot twist: those iconv functions might already live in the standard C library, or they might show up externally as a whole extra library. Either way, we find them ๐
Imported Targets
Iconv::Iconvโ the target that bundles up all the iconv usage requirements. Heads up: it only exists if iconv was actually found, no cap.
Result Variables
Iconv_FOUNDโ a boolean saying whether (the requested version of) iconv support was found. Slay or sad, nothing in between.Iconv_VERSIONโ Added in version 3.21. The version of iconv we found, inx.yform.
Note: some libiconv implementations justโฆ don't embed the version in their header files ๐ญ In that case the Iconv_VERSION* variables come back empty. Not a bug, just how it is.
Iconv_VERSION_MAJORโ Added in version 3.21. The major version of iconv.Iconv_VERSION_MINORโ Added in version 3.21. The minor version of iconv.Iconv_INCLUDE_DIRSโ the include directories that hold the iconv headers.Iconv_LIBRARIESโ the iconv libraries you'll be linking against.
Cache Variables
These cuties may also get set:
Iconv_IS_BUILT_INโ a boolean telling you whether iconv support is coming from the C standard library or not. And like, even if the C library does provideiconv(), an external libiconv implementation hanging around might make this come out false. Vibe check accordingly ๐ซถIconv_INCLUDE_DIRโ the directory holding the iconv headers.Iconv_LIBRARYโ the iconv library (in the case that it's not implicitly given in the C library).
Note: on POSIX platforms iconv might be part of the C library, and then the cache variablesIconv_INCLUDE_DIRandIconv_LIBRARYmight just be empty. No drama.
Examples
Finding iconv and linking it to a project target โ literally the whole plot:
find_package(Iconv)
target_link_libraries(project_target PRIVATE Iconv::Iconv)
FindIcotool
Finds icotool, the command-line program for converting and creating Win32 icon and cursor files:
find_package(Icotool [<version>] [...] )
Result Variables
Icotool_FOUNDโ Added in version 3.3. Boolean telling you whether (the requested version of) icotool was found.Icotool_VERSIONโ Added in version 4.2. The version of icotool we found.
Cache Variables
ICOTOOL_EXECUTABLEโ the full path to the icotool tool.
Deprecated Variables
These ones are still here purely for backward compatibility, bestie โ they're giving legacy energy:
ICOTOOL_FOUNDโ Deprecated since version 4.2: useIcotool_FOUND, which has the same value.ICOTOOL_VERSION_STRINGโ Deprecated since version 4.2: useIcotool_VERSION, which has the same value. It's the version of icotool found.
Examples
Finding icotool and running it in a process to make a .ico icon out of the source img.png image sitting in the current source directory โ chef's kiss ๐
find_package(Icotool)
if(Icotool_FOUND)
execute_process(
COMMAND
${ICOTOOL_EXECUTABLE} -c -o ${CMAKE_CURRENT_BINARY_DIR}/img.ico img.png
)
endif()
FindICU
Added in version 3.7.
Finds the International Components for Unicode (ICU) libraries and programs:
find_package(ICU [<version>] COMPONENTS <components>... [...] )
Added in version 3.11: support for static libraries on Windows. We love to see it.
Components
This module supports components, and you specify them like this:
find_package(ICU COMPONENTS <components>...)
Here's the full roster of supported components, no gatekeeping:
dataโ finds the ICU Data library. On Windows this library component is nameddt; otherwise any of these component names may be used, and the appropriate platform-specific library name gets selected automatically. Iconic.i18nโ finds the ICU Internationalization library. On Windows this library component is namedin; otherwise any of these component names may be used, and the appropriate platform-specific library name gets selected automatically.ioโ finds the ICU Stream and I/O (Unicode stdio) library.leโ finds the deprecated ICU Layout Engine library, which got removed as of ICU version 58. Rip, she's gone ๐lxโ finds the ICU Layout Extensions Engine library, used for paragraph layout.testโ finds the ICU test suits.tuโ finds the ICU Tool Utility library.ucโ finds the base ICU Common and Data libraries. Every other ICU library requires this one, so honestly you should include it when you're working with ICU components. Main character library fr.
At least one component should be specified for this module to successfully find ICU. Zero components = zero success, iykyk.
Imported Targets
ICU::<component>โ the target encapsulating the usage requirements for the specified ICU component, available only if that component is found. Write<component>in lowercase, exactly like the list above. So like, useICU::i18nfor the Internationalization library. ๐
Result Variables
ICU_FOUNDโ boolean saying whether the (requested version of) main ICU programs and libraries were found.ICU_VERSIONโ the version of the ICU release found.ICU_INCLUDE_DIRSโ the include directories holding the ICU headers.ICU_LIBRARIESโ component libraries to be linked.
The ICU programs get defined in these variables, bestie, brace yourself, there's a lot of them:
ICU_GENCNVAL_EXECUTABLEโ the path to thegencnvalexecutable.ICU_ICUINFO_EXECUTABLEโ the path to theicuinfoexecutable.ICU_GENBRK_EXECUTABLEโ the path to thegenbrkexecutable.ICU_ICU-CONFIG_EXECUTABLEโ the path to theicu-configexecutable.ICU_GENRB_EXECUTABLEโ the path to thegenrbexecutable.ICU_GENDICT_EXECUTABLEโ the path to thegendictexecutable.ICU_DERB_EXECUTABLEโ the path to thederbexecutable.ICU_PKGDATA_EXECUTABLEโ the path to thepkgdataexecutable.ICU_UCONV_EXECUTABLEโ the path to theuconvexecutable.ICU_GENCFU_EXECUTABLEโ the path to thegencfuexecutable.ICU_MAKECONV_EXECUTABLEโ the path to themakeconvexecutable.ICU_GENNORM2_EXECUTABLEโ the path to thegennorm2executable.ICU_GENCCODE_EXECUTABLEโ the path to thegenccodeexecutable.ICU_GENSPREP_EXECUTABLEโ the path to thegensprepexecutable.ICU_ICUPKG_EXECUTABLEโ the path to theicupkgexecutable.ICU_GENCMN_EXECUTABLEโ the path to thegencmnexecutable.
ICU component libraries live in these variables:
ICU_<COMPONENT>_FOUNDโ boolean telling you whether the ICU component was found. Write<COMPONENT>in uppercase. โจICU_<COMPONENT>_LIBRARIESโ libraries for the component. Again,<COMPONENT>in uppercase.
And the ICU datafiles:
ICU_MAKEFILE_INCโ the path to theMakefile.incfile.ICU_PKGDATA_INCโ the path to thepkgdata.incfile.
Cache Variables
These may also get set:
ICU_<PROGRAM>_EXECUTABLEโ the path to the executable<PROGRAM>; write<PROGRAM>in uppercase. These correspond to the ICU program result variables listed above, so it's the same cast of characters, different variable.ICU_INCLUDE_DIRโ the directory containing the ICU headers.ICU_<COMPONENT>_LIBRARYโ the library for the ICU component.<COMPONENT>uppercase, as always ๐
Hints
This module reads hints about search results from:
ICU_ROOTโ the root of the ICU installation. The environment variableICU_ROOTmay also be used; theICU_ROOTvariable takes precedence. Queen behaviour.
Note: in most cases, you won't need to set any of the above variables at all โ unless you've got multiple versions of ICU floating around and you specifically need one of them. Then it's hint time.
Examples
Finding ICU components and linking them to a project target:
find_package(ICU COMPONENTS i18n io uc)
target_link_libraries(project_target PRIVATE ICU::i18n ICU::io ICU::uc)
FindImageMagick
Finds ImageMagick, the software suite for displaying, converting, and manipulating raster images:
find_package(ImageMagick [<version>] [COMPONENTS <components>...] [...] )
Added in version 3.9: support for ImageMagick 7. Obsessed.
Components
This module supports components and searches for a set of ImageMagick tools. Typical components are the names of ImageMagick executables, but it's not limited to these โ future versions of ImageMagick may provide extra components that aren't listed here:
animatecomparecompositeconjureconvertdisplayidentifyimportmogrifymontagestream
There are also components for these ImageMagick APIs:
Magick++โ finds the ImageMagick C++ API.MagickWandโ finds the ImageMagick MagickWand C API.MagickCoreโ finds the ImageMagick MagickCore low-level C API.
Components can be specified using the find_package() command:
find_package(ImageMagick [COMPONENTS <components>...])
If you specify no components at all, the module only searches for the ImageMagick executable directory. That's it, that's the whole search. ๐ฆ
Imported Targets
ImageMagick::Magick++โ Added in version 3.26. Target encapsulating the ImageMagick C++ API usage requirements, available if ImageMagick C++ is found.ImageMagick::MagickWandโ Added in version 3.26. Target encapsulating the ImageMagick MagickWand C API usage requirements, available if MagickWand is found.ImageMagick::MagickCoreโ Added in version 3.26. Target encapsulating the ImageMagick MagickCore low-level C API usage requirements, available if MagickCore is found.
Result Variables
This module defines the following variables:
ImageMagick_FOUNDโ boolean, bestie: was (the requested version of) ImageMagick found, along with all its requested components? yes or no ๐ImageMagick_VERSIONโ added in version 4.2. the version of ImageMagick that got found, in the form<major>.<minor>.<patch>-<addendum>(so like6.9.12-98, where98is the addendum release number โจ)
ngl, version detection is only available for ImageMagick 6 and later ๐ซถ
ImageMagick_INCLUDE_DIRSโ all the include directories you need to actually use ImageMagick ๐ImageMagick_LIBRARIESโ the libraries you need to link against to use ImageMagick ๐ImageMagick_COMPILE_OPTIONSโ added in version 3.26. compile options of all the libraries โจImageMagick_<component>_FOUNDโ boolean, was the ImageMagick<component>found ๐ImageMagick_<component>_EXECUTABLEโ the full path to the<component>executable ๐ImageMagick_<component>_INCLUDE_DIRSโ include directories holding the headers you need to use that ImageMagick<component>๐ImageMagick_<component>_COMPILE_OPTIONSโ added in version 3.26. compile options of the ImageMagick<component>โจImageMagick_<component>_LIBRARIESโ added in version 3.31. the libraries you need to link against to use the ImageMagick<component>๐
Cache Variables
these cache variables may also be set:
ImageMagick_EXECUTABLE_DIRโ the full path to the directory that contains the ImageMagick executables ๐
Deprecated Variables
so these are here purely for backward compatibility vibes (they still work, they're just old):
ImageMagick_VERSION_STRINGโ deprecated since version 4.2: useImageMagick_VERSION, which has the same value. the version of ImageMagick found ๐
Examples
finding ImageMagick with its Magick++ component and linking it to a project target โ slay:
find_package(ImageMagick COMPONENTS Magick++)
target_link_libraries(example PRIVATE ImageMagick::Magick++)
FindIntl
Added in version 3.2.
finds internationalization support โ like, the message translation functions such as gettext() ๐โจ
find_package(Intl [<version>] [...])
these functions originally come from the GNU libintl library, which is part of the GNU gettext utilities, but lowkey they may also be provided by the standard C library ๐ซถ
Imported Targets
this module gives you the following Imported Targets:
Intl::Intlโ added in version 3.20. the target encapsulating the Intl usage requirements, available if Intl is found ๐
Result Variables
this module defines these variables, bestie:
Intl_FOUNDโ boolean, was (the requested version of) Intl found ๐Intl_VERSIONโ added in version 3.21. the version of the found Intl implementation or library, in the formatx.y.zโจ
heads up: some Intl implementations don't embed the version in their header files. in that case the variables Intl_VERSION* will be empty ๐ญ
Intl_VERSION_MAJORโ added in version 3.21. the major version of Intl foundIntl_VERSION_MINORโ added in version 3.21. the minor version of Intl foundIntl_VERSION_PATCHโ added in version 3.21. the patch version of Intl foundIntl_INCLUDE_DIRSโ include directories containing the headers you need to use Intl ๐Intl_LIBRARIESโ the libraries you need to link against to use Intl ๐
Cache Variables
these cache variables may also be set:
Intl_IS_BUILT_INโ added in version 3.20. boolean saying whether the found Intl functionality is provided by the standard C library instead of a separate libintl library ๐งIntl_INCLUDE_DIRโ the directory containing thelibintl.hheader file ๐Intl_LIBRARYโ the path to the Intl library (if any)
ok so on some platforms โ like Linux with GNU libc โ the gettext functions are just there in the C standard library and libintl isn't required at all. in that caseIntl_LIBRARYandIntl_INCLUDE_DIRwill be empty. no cap ๐
Examples
finding the Intl support and linking the imported target for use in a project:
find_package(Intl)
target_link_libraries(app PRIVATE Intl::Intl)
See Also
- The
FindGettextmodule to find and use the GNU gettext tools (msgmerge,msgfmt, etc.) ๐ ๏ธ
FindJasper
finds the JasPer Image Coding Toolkit โ yes, the one for handling image data in a whole variety of formats, such as the JPEG-2000 ๐ผ๏ธโจ
find_package(Jasper [<version>] [...])
Imported Targets
this module provides the following Imported Targets:
Jasper::Jasperโ added in version 3.22. the target encapsulating the JasPer library usage requirements, available only if the library is found ๐
Result Variables
this module defines these variables:
Jasper_FOUNDโ added in version 3.3. boolean, was (the requested version of) JasPer found ๐Jasper_VERSIONโ added in version 4.2. the version of JasPer found โจJASPER_INCLUDE_DIRSโ added in version 3.22. the include directories you need to use the JasPer library ๐JASPER_LIBRARIESโ the libraries you need to use JasPer ๐
Cache Variables
these cache variables may also be set:
JASPER_INCLUDE_DIRโ the directory containingjasper/jasper.hand the other headers you need to use the JasPer library ๐JASPER_LIBRARY_RELEASEโ the path to the release (optimized) variant of the JasPer library ๐JASPER_LIBRARY_DEBUGโ the path to the debug variant of the JasPer library ๐
Deprecated Variables
backward-compatibility besties, still kicking around:
JASPER_FOUNDโ deprecated since version 4.2: useJasper_FOUND, which has the same value. boolean, was (the requested version of) JasPer found ๐JASPER_VERSION_STRINGโ deprecated since version 4.2: superseded by theJasper_VERSION. the version of JasPer found
Examples
finding the JasPer library and linking it to a project target:
find_package(Jasper)
target_link_libraries(project_target PRIVATE Jasper::Jasper)
FindJava
finds your Java installation and figures out its runtime tools and development components โ๐ฅ
find_package(Java [<version>] [COMPONENTS <components>...] [...])
Added in version 3.10: support for Java 9+ version parsing ๐
Components
this module supports optional components, which you can specify with the find_package() command:
find_package(Java [COMPONENTS <components>...])
the supported components include:
Runtimeโ finds the Java Runtime Environment used to execute Java byte-compiled applications ๐Developmentโ finds the development tools (java,javac,javah,jar, andjavadoc). specifying this component also implies theRuntimecomponent ๐ ๏ธIdlJโ added in version 3.4. finds the Interface Description Language (IDL) to Java compiler ๐ธJarSignerโ added in version 3.4. finds the signer and verifier tool for Java Archive (JAR) files โ๏ธ
if you specify no components at all, the module searches for the Runtime component by default. periodt ๐
Result Variables
this module defines these variables:
Java_FOUNDโ added in version 3.3. boolean, was (the requested version of) Java found with all the specified components ๐Java_<component>_FOUNDโ boolean, was the<component>found ๐Java_VERSIONโ the version of Java found. this gets set to:<major>[.<minor>[.<patch>[.<tweak>]]]โจJava_VERSION_MAJORโ the major version of Java foundJava_VERSION_MINORโ the minor version of Java foundJava_VERSION_PATCHโ the patch version of Java foundJava_VERSION_TWEAKโ the tweak version of Java found (that's the part after the underscore character_)Java_VERSION_STRINGโ the version of Java found, e.g.,1.6.0_12
ok important:Java_VERSIONandJava_VERSION_STRINGare not guaranteed to be identical. for example, some Java versions may returnJava_VERSION_STRING = 1.8.0_17andJava_VERSION = 1.8.0.17. another example is the Java OEM, withJava_VERSION_STRING = 1.8.0-oemandJava_VERSION = 1.8.0. it's giving chaos but it's fine ๐ญ
Cache Variables
these cache variables may also be set:
Java_JAVA_EXECUTABLEโ the full path to the Java runtime ๐Java_JAVAC_EXECUTABLEโ the full path to the Java compiler ๐ ๏ธJava_JAVAH_EXECUTABLEโ the full path to the Java header generatorJava_JAVADOC_EXECUTABLEโ the full path to the Java documentation generator ๐Java_IDLJ_EXECUTABLEโ added in version 3.4. the full path to the Java idl compilerJava_JAR_EXECUTABLEโ the full path to the Java archiver ๐๏ธJava_JARSIGNER_EXECUTABLEโ added in version 3.4. the full path to the Java jar signer โ๏ธ
Hints
this module accepts the following variables:
JAVA_HOMEโ you can set this variable yourself to explicitly specify the installation directory of Java ๐
Examples
finding Java:
find_package(Java)
finding Java with at least the specified minimum version:
find_package(Java 1.8)
finding Java and making it required (so if Java isn't found, processing stops with an error message โ dramatic but fair ๐):
find_package(Java 1.8 REQUIRED)
specifying exactly which Java components you need to find:
find_package(Java COMPONENTS Development JarSigner)
See Also
- The
FindJNImodule to find Java Native Interface (JNI) ๐ - The
UseJavamodule to use Java in CMake โ
FindJNI
finds the Java Native Interface (JNI) include directories and libraries โ๐
find_package(JNI [<version>] [COMPONENTS <components>...] [...])
JNI is what lets Java code running in a Java Virtual Machine (JVM) or Dalvik Virtual Machine (DVM) on Android call โ and be called by โ native applications and libraries written in other languages such as C and C++ ๐งโจ
this module finds whether Java is installed and determines where the include files and libraries are. it also determines what the name of the library is ๐
Added in version 3.24: imported targets, components, and Android NDK support ๐
When you're using Android NDK, the corresponding package version gets reported and you can request a specific release. At Android API level 31 and above, the extra NativeHelper component can be requested too โจ NativeHelper is also exposed as an implicit dependency of the JVM component (only if that doesn't cause a conflict, bestie, we're not about that drama) which gives you uniform access to JVM functions.
Components
This module supports optional components, and you specify them with the find_package() command:
find_package(JNI [COMPONENTS <components>...])
Supported components include:
AWTโ Added in version 3.24. Finds the Java Abstract Window Toolkit (AWT). ๐JVMโ Added in version 3.24. Finds the Java Virtual Machine (JVM).NativeHelperโ Added in version 3.24. Finds the NativeHelper library on Android (libnativehelper.so), which exposes JVM functions such asJNI_CreateJavaVM().
If you don't specify any components, the module defaults are:
- When targeting Android with API level 31 and above: the module looks for the
NativeHelpercomponent. For other Android API levels, components are by default not set. - When targeting other systems: the module looks for
AWTandJVMcomponents. ๐ซถ
Imported Targets
This module provides the following Imported Targets:
JNI::JNIโ Added in version 3.24. The main target encapsulating all JNI usage requirements, available ifjni.his found.JNI::AWTโ Added in version 3.24. Target encapsulating the Java AWT Native Interface (JAWT) library usage requirements, available if theAWTcomponent is found.JNI::JVMโ Added in version 3.24. Target encapsulating the Java Virtual Machine (JVM) library usage requirements, available if componentJVMis found.JNI::NativeHelperโ Added in version 3.24. Target encapsulating the NativeHelper library usage requirements, available when targeting Android API level 31 and above, and the library is found. ๐
Result Variables
This module defines the following variables:
JNI_FOUNDโ Boolean indicating whether (the requested version of) JNI was found.JNI_<component>_FOUNDโ Added in version 3.24. Boolean indicating whether the<component>was found.JNI_VERSIONโ Full Android NDK package version (including suffixes such as-beta3and-rc1) or undefined otherwise.JNI_VERSION_MAJORโ Added in version 3.24. Android NDK major version or undefined otherwise.JNI_VERSION_MINORโ Added in version 3.24. Android NDK minor version or undefined otherwise.JNI_VERSION_PATCHโ Added in version 3.24. Android NDK patch version or undefined otherwise.JNI_INCLUDE_DIRSโ The include directories needed to use the JNI.JNI_LIBRARIESโ The libraries (JAWT and JVM) needed to link against to use JNI.
Cache Variables
The following cache variables are also available to set or use:
JAVA_INCLUDE_PATHโ The directory containing thejni.hheader.JAVA_INCLUDE_PATH2โ The directory containing machine-dependent headersjni_md.handjniport.h. This variable is defined only ifjni.hdepends on one of these headers. In contrast, Android NDKjni.hcan be typically used standalone. ๐JAVA_AWT_INCLUDE_PATHโ The directory containing thejawt.hheader.JAVA_AWT_LIBRARYโ The path to the Java AWT Native Interface (JAWT) library.JAVA_JVM_LIBRARYโ The path to the Java Virtual Machine (JVM) library.
Hints
This module accepts the following variables:
JAVA_HOMEโ The caller can set this variable to specify the installation directory of Java explicitly.
Examples
Finding JNI and linking it to a project target, iconic behaviour honestly:
find_package(JNI)
target_link_libraries(project_target PRIVATE JNI::JNI)
Finding JNI with the AWT component specified and linking them to a project target:
find_package(JNI COMPONENTS AWT)
target_link_libraries(project_target PRIVATE JNI::JNI JNI::AWT)
A more common way to use Java and JNI in CMake is to use a dedicated UseJava module, and yes bestie that's the move:
find_package(Java)
find_package(JNI)
include(UseJava)
See Also
- The
FindJavamodule to find Java runtime tools and development components. ๐ฆ - The
UseJavamodule to use Java in CMake.
FindJPEG
Finds the Joint Photographic Experts Group (JPEG) library (libjpeg), photogenic queen that she is ๐ธ:
find_package(JPEG [<version>] [...])
Changed in version 3.12: Debug and Release JPEG library variants are now found separately. Slay.
Imported Targets
This module provides the following Imported Targets:
JPEG::JPEGโ Added in version 3.12. Target encapsulating the JPEG library usage requirements. It is available only when JPEG is found.
Result Variables
This module defines the following variables:
JPEG_FOUNDโ Boolean indicating whether the (requested version of) JPEG library was found.JPEG_VERSIONโ Added in version 3.12. The version of JPEG library found.JPEG_INCLUDE_DIRSโ Include directories containing headers needed to use JPEG.JPEG_LIBRARIESโ Libraries needed to link to JPEG.
Cache Variables
The following cache variables may also be set:
JPEG_INCLUDE_DIRโ Directory containing the<jpeglib.h>and related header files.JPEG_LIBRARY_RELEASEโ Added in version 3.12. Path to the release (optimized) variant of the JPEG library. โจJPEG_LIBRARY_DEBUGโ Added in version 3.12. Path to the debug variant of the JPEG library. ๐
Deprecated Variables
The following variables are provided for backward compatibility:
JPEG_LIBRARYโ Deprecated since version 3.12: This variable has been superseded by theJPEG_LIBRARY_RELEASEandJPEG_LIBRARY_DEBUGvariables. Path to the JPEG library.
She's giving legacy energy โ still here, but lowkey past her prime ๐
Examples
Finding the JPEG library and linking it to a project target:
find_package(JPEG)
target_link_libraries(project_target PRIVATE JPEG::JPEG)
FindKDE3
Note: This module is specifically intended for KDE version 3, which is obsolete and no longer maintained. For modern application development using KDE technologies with CMake, use a newer version of KDE, and refer to the KDE documentation (https://develop.kde.org/docs/getting-started/building/cmake-build/). Like bestie this is straight-up ancient history, do not build new stuff with it, okay? ๐ญ
Finds KDE 3 include directories, libraries, and KDE-specific preprocessor tools:
find_package(KDE3 [...])
This module provides usage requirements for building KDE 3 software and defines several helper commands to simplify working with KDE 3 in CMake.
Result Variables
This module defines the following variables:
KDE3_FOUNDโ Boolean indicating whether KDE 3 was found.KDE3_DEFINITIONSโ Compiler definitions required for compiling KDE 3 software.KDE3_INCLUDE_DIRSโ The KDE and the Qt include directories, for use with thetarget_include_directories()command.KDE3_LIB_DIRโ The directory containing the installed KDE 3 libraries, for use with thetarget_link_directories()command.QT_AND_KDECORE_LIBSโ A list containing both the Qt and thekdecorelibrary, typically used together when linking KDE 3. ๐ซถ
Cache Variables
The following cache variables may also be set:
KDE3_INCLUDE_DIRโ The directory containing KDE 3 header files.KDE3_DCOPIDL_EXECUTABLEโ The path to thedcopidlexecutable.KDE3_DCOPIDL2CPP_EXECUTABLEโ The path to thedcopidl2cppexecutable.KDE3_KCFGC_EXECUTABLEโ The path to thekconfig_compilerexecutable.
Hints
This module accepts the following variables:
KDE3_BUILD_TESTSโ Provided as a user adjustable option. Set this variable to boolean true to build KDE 3 testcases.
Commands
This module provides the following commands to work with KDE 3 in CMake:
kde3_automocโ Enables automatic processing withmocfor the given source files:
kde3_automoc(<sources>...)
Call this command to enable automatic moc file handling. For example, if a source file (e.g., foo.cpp) contains include "foo.moc", a moc file for the corresponding header (foo.h) will be generated automatically. To skip processing for a specific source file, set the SKIP_AUTOMOC source file property. ๐ง
kde3_add_moc_filesโ Processes header files withmoc:
kde3_add_moc_files(<variable> <headers>...)
If not using kde3_automoc(), this command can be used to generate moc files for one or more <headers> files. The generated files are named <filename>.moc.cpp and the resulting list of these generated source files is stored in the variable named <variable> for use in project targets.
kde3_add_dcop_skelsโ Generates KIDL and DCOP skeletons:
kde3_add_dcop_skels(<variable> <dcop-headers>...)
This command generates .kidl and DCOP skeleton source files from the given DCOP header files. The resulting list of generated source files is stored in the variable named <variable> for use in project targets. ๐ฅ
kde3_add_dcop_stubsโ Generates DCOP stubs:
kde3_add_dcop_stubs(<variable> <headers>...)
Use this command to generate DCOP stubs from one or more given header files. The resulting list of generated source files is stored in the variable named <variable> for use in project targets.
kde3_add_ui_filesโ Adds Qt designer UI files:
kde3_add_ui_files(<variable> <ui-files>...)
This command creates the implementation files from the given Qt designer .ui files. The resulting list of generated files is stored in the variable named <variable> for use in project targets. ๐
kde3_add_kcfg_filesโ Adds KDE kconfig compiler files:
kde3_add_kcfg_files(<variable> <kcfgc-files>...)
Use this command to add KDE kconfig compiler files (.kcfgc) to the application/library. The resulting list of generated source files is stored in the variable named <variable> for use in project targets.
kde3_install_libtool_fileโ Creates and installs a libtool file:
kde3_install_libtool_file(<target>)
This one creates and installs a basic libtool file for the target <target>. That's it, that's the whole vibe โจ
kde3_add_executableโ adds a KDE executable:
kde3_add_executable(<name> <sources>...)
bestie this is functionally identical to the built-in add_executable() command. It was originally intended to support extra features in future versions of this module โ so like, it's the same thing in a cuter outfit ๐
kde3_add_kpartโ creates a KDE plugin:
kde3_add_kpart(<name> [WITH_PREFIX] <sources>...)
This command creates a KDE plugin (KPart, kioslave, etc.) from one or more source files <sources>. It also creates and installs an appropriate libtool .la file, because it's an overachiever ๐
If the WITH_PREFIX option is given, the resulting plugin name will be prefixed with lib. Otherwise, no prefix is added. Pick your fighter ๐ซถ
kde3_add_kdeinit_executableโ creates a KDE application as a module loadable via kdeinit:
kde3_add_kdeinit_executable(<name> <sources>...)
This command creates a library named kdeinit_<name> from one or more source files <sources>. It also builds a small executable linked against this library. Two for the price of one, we love a bundle deal ๐ญ๐
Examples โจ
Finding KDE 3, king of the one-liners:
find_package(KDE3)
FindKDE4
Note: This module is specifically intended for KDE version 4, which is obsolete and no longer maintained. Ngl, this is vintage. For modern application development using KDE technologies with CMake, use a newer version of KDE, and refer to the KDE documentation at https://develop.kde.org/docs/getting-started/building/cmake-build/ ๐ฆ
Finds the KDE 4 installation:
find_package(KDE4 [...])
This module is a wrapper around the following upstream KDE 4 modules, so it's giving "middle manager of modules" energy ๐
FindKDE4Internal.cmakeโ upstream internal module, which finds the KDE 4 include directories, libraries, and KDE-specific preprocessor tools. It provides usage requirements for building KDE 4 software and defines several helper commands to simplify working with KDE 4 in CMake.KDE4Macros.cmakeโ upstream utility module that defines all additional KDE4-specific commands to use KDE 4 in CMake. For example:kde4_automoc(),kde4_add_executable(),kde4_add_library(),kde4_add_ui_files(),kde4_add_ui3_files(),kde4_add_kcfg_files(),kde4_add_kdeinit_executable(), etc.
Upstream KDE 4 modules are installed by the KDE 4 distribution package in $KDEDIRS/share/apps/cmake/modules/. This path is automatically appended to the CMAKE_MODULE_PATH variable when calling find_package(KDE4), so any additional KDE 4 modules can be included in the project with include(). For example ๐:
KDE4Defaults.cmakeโ upstream internal module that sets some CMake options which are useful, but not required for building KDE 4 software. If these settings should be used, include this module after finding KDE 4:
find_package(KDE4)
include(KDE4Defaults)
For usage details, refer to the upstream KDE 4 documentation. For example, at the top of the FindKDE4Internal module a complete documentation is available for all variables and commands these modules provide. Iconic, honestly ๐
Result Variables ๐ธ
This module defines the following variables:
KDE4_FOUNDโ Boolean indicating whether KDE 4 was found. This variable is set by the upstreamFindKDE4Internalmodule. (So like, not this module's fault if it's weird, iykyk ๐)
Hints ๐ก
This module accepts the following variables before calling the find_package(KDE4):
ENV{KDEDIRS}โ environment variable containing the path to the KDE 4 installation.
KDE 4 is searched in the following directories in the given order โ respect the queue bestie ๐ง:
CMAKE_INSTALL_PREFIXvariableKDEDIRSenvironment variable/opt/kde4path
Examples โจ
Example: Basic Usage
Finding KDE 4 as required and using it in CMake:
find_package(KDE4 REQUIRED)
set(sources main.cpp mywidget.cpp mypart.cpp)
# The kde4_*() commands are provided by the KDE4Macros module, which is
# included automatically by FindKDE4, if KDE4 is found:
kde4_automoc(${sources})
kde4_add_executable(example ${sources})
target_include_directories(example PRIVATE ${KDE4_INCLUDES})
target_link_libraries(example PRIVATE ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS})
install(TARGETS example DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES kfoo.desktop DESTINATION ${XDG_APPS_DIR})
Example: Full Featured Example
In the following example this module is used to find KDE 4 installation. Buckle up, this one's a whole journey ๐ข
project(kfoo)
find_package(KDE4 REQUIRED)
# Append path from where to include local project modules if any:
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include_directories(${KDE4_INCLUDE_DIRS})
add_definitions(${KDE4_DEFINITIONS})
set(sources main.cpp myappl.cpp view.cpp)
# If Qt designer UI files version 3 or 4 are available add them to the
# sources variable:
kde4_add_ui_files(sources maindialog.ui logindialog.ui)
kde4_add_ui3_files(sources printerdlg.ui previewdlg.ui)
# If there are files for the kconfig_compiler add them this way:
kde4_add_kcfg_files(sources settings.kcfg)
# When everything is listed, probably automoc is wanted:
kde4_automoc(${sources})
# Finally, specify what to build:
kde4_add_executable(kfoo ${sources})
The kde4_add_executable() command is a slightly extended version of the CMake command add_executable(). Additionally, it does some more RPATH handling and supports the KDE4_ENABLE_FINAL variable. The first argument is the name of the executable followed by a list of source files. If a library needs to be created instead of an executable, the kde4_add_library() can be used. It is an extended version of the add_library() command. It adds support for the KDE4_ENABLE_FINAL variable and under Windows it adds the -DMAKE_KFOO_LIB to the compile flags ๐ช
find_package(KDE4 REQUIRED)
# ...
kde4_add_library(kfoo ${sources})
# Optionally, set the library version number if needed:
set_target_properties(kfoo PROPERTIES VERSION 5.0.0 SOVERSION 5)
KDE is very modular, so if a KPart, a control center module, or an ioslave needs to be created, here's how to do it:
find_package(KDE4 REQUIRED)
# ...
kde4_add_plugin(kfoo ${sources})
Now, the application/library/plugin probably needs to link to some libraries. For this use the standard target_link_libraries() command. For every KDE library there are variables available in the form of KDE4_FOO_LIBS. Use them to get also all depending libraries โ no cap, this is the good stuff ๐ฅ
target_link_libraries(kfoo ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS})
Example: The kdeinit Executable
In the following example, the so called kdeinit executable is created. The kde4_add_kdeinit_executable() command creates both an executable with the given name and a library with the given name prefixed with kdeinit_. The target_link_libraries() command adds all required libraries to the kdeinit_kbar library, and then links the kbar against the kdeinit_kbar:
find_package(KDE4 REQUIRED)
# ...
kde4_add_kdeinit_executable(kbar ${kbarSources})
target_link_libraries(kdeinit_kbar ${KDE4_KIO_LIBS})
target_link_libraries(kbar kdeinit_kbar)
install(TARGETS kbar DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS kdeinit_kbar DESTINATION ${CMAKE_INSTALL_LIBDIR})
Example: Removing Compile Definitions
Sometimes, a default compile definition passed to the compiler needs to be removed. The remove_definitions() command can be used. For example, by default, the KDE4 build system sets the -DQT_NO_STL flag. If the project code uses some of the Qt STL compatibility layer, this flag should be removed ๐
find_package(KDE4 REQUIRED)
add_definitions(${KDE4_DEFINITIONS})
# ...
remove_definitions(-DQT_NO_STL)
FindLAPACK
Finds the installed Linear Algebra PACKage (LAPACK) Fortran library that implements the LAPACK linear-algebra interface at https://netlib.org/lapack/ โ math girlies rise ๐งฎ๐
find_package(LAPACK [...])
At least one of the C, CXX, or Fortran languages must be enabled. Like, pick one, bestie, it's not optional ๐ญ
Imported Targets ๐
This module provides the following Imported Targets:
LAPACK::LAPACKโ added in version 3.18. Target encapsulating the LAPACK usage requirements, available only if LAPACK is found. (So if it's not found, it just โจdoesn't existโจ โ checkLAPACK_FOUNDfirst, fr fr.)
Result Variables ๐
This module defines the following variables:
LAPACK_FOUNDโ Boolean indicating whether the library implementing the LAPACK interface was found.LAPACK_LINKER_FLAGSโ uncached list of required linker flags (excluding-land-L).LAPACK_LIBRARIESโ uncached list of libraries (using full path name) to link against to use LAPACK.LAPACK95_LIBRARIESโ uncached list of libraries (using full path name) to link against to use LAPACK95.LAPACK95_FOUNDโ Boolean indicating whether the library implementing the LAPACK95 interface was found.
Input Variables ๐
The following variables may be set to influence this module's behavior:
BLA_STATICโ ifON, the static linkage will be used.BLA_VENDORโ set to one of the BLAS/LAPACK Vendors to search for BLAS only from the specified vendor. If not set, all vendors are considered. (Free-for-all mode ๐)BLA_F95โ ifON, the module tries to find the BLAS95/LAPACK95 interfaces.BLA_PREFER_PKGCONFIGโ added in version 3.20. If set,pkg-configwill be used to search for a LAPACK library first and if one is found that is preferred. pkg-config girlies stay winning ๐ซถBLA_PKGCONFIG_LAPACKโ added in version 3.25. If set, thepkg-configmethod will look for this module name instead of justlapack.BLA_SIZEOF_INTEGERโ added in version 3.22. Specify the BLAS/LAPACK library integer size:4โ search for a BLAS/LAPACK with 32-bit integer interfaces.8โ search for a BLAS/LAPACK with 64-bit integer interfaces.ANYโ search for any BLAS/LAPACK. Most likely, a BLAS/LAPACK with 32-bit integer interfaces will be found.
BLA_THREADโ added in version 4.1. Specify the BLAS/LAPACK threading model:SEQโ sequential model.OMPโ OpenMP model.ANYโ search for any BLAS/LAPACK, if both are available most likelyOMPwill be found.
Ok so tiny footnote first: this one's only supported by NVIDIA NVPL right now. That's it, that's the whole note. ๐
๐ธ Intel MKL
So if you wanna use the Intel MKL flavor of LAPACK, your project has to turn on at least one of the C or CXX languages first โ no languages, no MKL, that's the rule.
Then you set BLA_VENDOR to one of the Intel MKL variants, either straight from the command line like -DBLA_VENDOR=Intel10_64lp, or right in your project code:
set(BLA_VENDOR Intel10_64lp)
find_package(LAPACK)
And bestie, listen โ to actually build something with Intel MKL, the end user has to set up an Intel MKL environment first. That's on them, not on you. ๐ซถ If you want the whole rundown, go peek at the FindBLAS module section, specifically the bit about Intel MKL.
โจ Examples
Finding LAPACK and hooking it up to a project target, iconic:
find_package(LAPACK)
target_link_libraries(project_target PRIVATE LAPACK::LAPACK)
๐ FindLATEX
Finds the LaTeX compiler plus all the LaTeX-adjacent software like BibTeX:
find_package(LATEX [...])
If you don't know what LaTeX is (the way I'd have to explain it: it's not "latex" like the glove material, ok ๐ญ) โ it's a typesetting system for making technical and scientific documentation. Very academia, very "my thesis is 200 pages," we love her.
๐ Components
Added in version 3.2.
You can optionally list components with the standard CMake syntax:
find_package(LATEX [COMPONENTS <component>...])
Here's the full roster of supported components:
PDFLATEXโ finds the PdfLaTeX compiler.XELATEXโ finds the XeLaTeX compiler.LUALATEXโ finds the LuaLaTeX compiler.BIBTEXโ finds the BibTeX compiler.BIBERโ finds the Biber compiler.MAKEINDEXโ finds the MakeIndex compiler.XINDYโ finds the xindy compiler.DVIPSโ finds the DVI-to-PostScript (DVIPS) converter.DVIPDFโ finds the DVIPDF converter.PS2PDFโ finds the PS2PDF converter.PDFTOPSโ finds the PDF-to-PostScript converter.LATEX2HTMLโ finds the converter for converting LaTeX documents to HTML.HTLATEXโ finds the htlatex compiler.
๐ฆ Result Variables
This module sets these variables for you, no cap:
LATEX_FOUNDโ boolean, tells you whether the LaTeX compiler and all of its required components were found.LATEX_<component>_FOUNDโ boolean, tells you whether that specific LaTeX <component> was found.
๐ธ Cache Variables
These cache variables might also get set:
LATEX_COMPILERโ the path to the LaTeX compiler.PDFLATEX_COMPILERโ the path to the PdfLaTeX compiler.XELATEX_COMPILERโ Added in version 3.2. The path to the XeLaTeX compiler.LUALATEX_COMPILERโ Added in version 3.2. The path to the LuaLaTeX compiler.BIBTEX_COMPILERโ the path to the BibTeX compiler.BIBER_COMPILERโ Added in version 3.2. The path to the Biber compiler.MAKEINDEX_COMPILERโ the path to the MakeIndex compiler.XINDY_COMPILERโ Added in version 3.2. The path to the xindy compiler.DVIPS_CONVERTERโ the path to the DVIPS converter.DVIPDF_CONVERTERโ the path to the DVIPDF converter.PS2PDF_CONVERTERโ the path to the PS2PDF converter.PDFTOPS_CONVERTERโ Added in version 3.2. The path to the pdftops converter.LATEX2HTML_CONVERTERโ the path to the LaTeX2Html converter.HTLATEX_COMPILERโ Added in version 3.2. The path to the htlatex compiler.
๐ Examples
Finding LaTeX in a project, easy:
find_package(LATEX)
Finding the LaTeX compiler and telling CMake which extra LaTeX components have to be there before LaTeX counts as found:
find_package(LATEX COMPONENTS PDFLATEX)
if(LATEX_FOUND)
execute_process(COMMAND ${LATEX_COMPILER} ...)
execute_process(COMMAND ${PDFLATEX_COMPILER} ...)
endif()
Or go off and name multiple components at once:
find_package(LATEX COMPONENTS BIBTEX PS2PDF)
if(LATEXT_FOUND)
# ...
endif()
Heads up bestie: that last check is spelled LATEXT_FOUND in the original โ yes, with the extra T. Not me, not a typo I introduced, it's literally what the docs say. Copy it exactly and don't come for me. ๐
โญ FindLibArchive
Finds the libarchive library and its include directories:
find_package(LibArchive [<version>] [...])
Libarchive is a multi-format archive and compression library โ little legend handles All The Formats for you. ๐ฅ
๐ Imported Targets
This module gives you these Imported Targets:
LibArchive::LibArchiveโ Added in version 3.17. A target that bundles up libarchive's usage requirements. Only available if libarchive is found, obviously.
๐ Result Variables
This module defines these:
LibArchive_FOUNDโ boolean, says whether (the version you asked for of) libarchive was found.LibArchive_VERSIONโ a 3-component version string (major.minor.patch) of the libarchive that was found.- Added in version 3.6: support for a new libarchive version string format. Starting from libarchive version 3.2, a different preprocessor macro is used in the header to define the version. In CMake 3.5 and earlier, this variable only gets set for libarchive versions 3.1 and earlier. In CMake 3.6 and newer, it gets set for all libarchive versions. Glow-up behavior, honestly. โจ
LibArchive_INCLUDE_DIRSโ the include search path for using libarchive.LibArchive_LIBRARIESโ the libraries to link against for libarchive.
๐ซถ Examples
Finding libarchive and linking it to a project target:
find_package(LibArchive)
target_link_libraries(project_target PRIVATE LibArchive::LibArchive)
๐ง FindLibinput
Added in version 3.14.
Finds the libinput library โ the one that handles input devices in Wayland compositors and also provides a generic X.Org input driver:
find_package(Libinput [<version>] [...])
๐ Imported Targets
This module provides these Imported Targets:
Libinput::Libinputโ the target encapsulating the libinput library usage requirements, available only if the library is found.
๐ Result Variables
This module defines these variables:
Libinput_FOUNDโ boolean, says whether the (requested version of the) libinput library was found.Libinput_VERSIONโ the version of libinput that was found.Libinput_LIBRARIESโ the libraries to link against to use libinput.Libinput_INCLUDE_DIRSโ the include directories holding the headers you need to use libinput.Libinput_COMPILE_OPTIONSโ the compile options you need to use libinput. You can pass these to thetarget_compile_options()command when you're not using theLibinput::Libinputimported target.
๐ Examples
Finding libinput and linking it to a project target:
find_package(Libinput)
target_link_libraries(project_target PRIVATE Libinput::Libinput)
๐ฆ FindLibLZMA
Finds liblzma โ the data compression library that implements LZMA (the Lempel-Ziv-Markov chain algorithm, yes that's a mouthful, no I will not be pronouncing it ๐ญ):
find_package(LibLZMA [<version>] [...])
โญ Imported Targets
This module provides this Imported Target:
LibLZMA::LibLZMAโ Added in version 3.14. The target encapsulating liblzma's usage requirements, available only if liblzma is found.
๐ธ Result Variables
This module defines these:
LibLZMA_FOUNDโ Added in version 3.3. Boolean, says whether (the requested version of) liblzma was found.LibLZMA_VERSIONโ Added in version 4.2. The version of liblzma that was found (given as a string, like for example5.0.3).LIBLZMA_INCLUDE_DIRSโ the include directories holding the headers you need to use liblzma.LIBLZMA_LIBRARIESโ the libraries you need to link against to use liblzma.
๐ Cache Variables
These cache variables might also get set:
LIBLZMA_HAS_AUTO_DECODERโ boolean sanity check result, says whether thelzma_auto_decoder()function (that's the automatic decoder functionality) is found in liblzma. Required.LIBLZMA_HAS_EASY_ENCODERโ boolean sanity check result, says whether thelzma_easy_encoder()function (the basic encoder API) is found in liblzma. Required.LIBLZMA_HAS_LZMA_PRESETโ boolean sanity check result, says whether thelzma_lzma_preset()function (preset compression configuration) is found in liblzma. Required.
๐ Deprecated Variables
These are kept around purely for backward compatibility:
LIBLZMA_FOUNDโ Deprecated since version 4.2: useLibLZMA_FOUND, which holds the same value. Boolean, says whether (the requested version of) liblzma was found.LIBLZMA_VERSIONโ Added in version 3.26. Deprecated since version 4.2: superseded byLibLZMA_VERSION. The version of liblzma that was found.LIBLZMA_VERSION_STRINGโ Deprecated since version 3.26: superseded byLIBLZMA_VERSION(andLibLZMA_VERSION). The version of liblzma that was found.LIBLZMA_VERSION_MAJORโ Deprecated since version 3.26. The major version of liblzma that was found.LIBLZMA_VERSION_MINORโ Deprecated since version 3.26. The minor version of liblzma that was found.LIBLZMA_VERSION_PATCHโ Deprecated since version 3.26. The patch version of liblzma that was found.
๐ฅ Examples
Finding liblzma and linking it to a project target:
find_package(LibLZMA)
target_link_libraries(project_target PRIVATE LibLZMA::LibLZMA)
๐ FindLibXml2
Finds the XML processing library, aka libxml2:
find_package(LibXml2 [<version>] [...])
๐ Imported Targets
This module provides these Imported Targets:
LibXml2::LibXml2โ Added in version 3.12. The target encapsulating libxml2's usage requirements, available only if the library is found.LibXml2::xmllintโ Added in version 3.17. The target encapsulating thexmllintcommand-line executable, available only if thexmllintexecutable is found.
โจ Result Variables
This module defines these variables:
LibXml2_FOUNDโ Added in version 3.3. Boolean, says whether the (requested version of the) libxml2 library was found.LibXml2_VERSIONโ Added in version 4.2. The version of libxml2 that was found.LIBXML2_INCLUDE_DIRSโ the include directories you need to use libxml2.LIBXML2_LIBRARIESโ the libraries you need to link against to use libxml2.LIBXML2_DEFINITIONSโ the compiler switches required for using libxml2.
๐ Other Variables
LibXml2_USE_STATIC_LIBSโ Added in version 4.3. Set it toTRUEto use static libraries. The default isFALSE.
๐ Cache Variables
These cache variables might also get set:
LIBXML2_INCLUDE_DIRโ the include directory containing the libxml2 headers.LIBXML2_LIBRARYโ the path to the libxml2 library itself, bestie.LIBXML2_XMLLINT_EXECUTABLEโ the path to the XML checking toolxmllintthat ships with libxml2. yes it's a whole vibe, it comes free with the library ๐
๐ฅ Deprecated Variables
okay so these are the OG variables, kept around purely for backward compatibility. still here, still slaying, justโฆ retired:
LIBXML2_FOUNDโ Deprecated since version 4.2: useLibXml2_FOUNDinstead, they literally have the same value fr fr. Boolean telling you whether the (requested version of the) libxml2 library was found.LIBXML2_VERSION_STRINGโ Deprecated since version 4.2: superseded byLibXml2_VERSION. It's the version of libxml2 that was found.
๐ Examples
finding the libxml2 library and linking it to a project target, iconic behaviour:
find_package(LibXml2)
target_link_libraries(project_target PRIVATE LibXml2::LibXml2)
๐ FindLibXslt
she finds the XSL Transformations, Extensible Stylesheet Language Transformations (XSLT) library โ libxslt, duh:
find_package(LibXslt [<version>] [...])
๐ Imported Targets
Added in version 3.18.
this module gives you these imported targets, and honestly? they ate:
LibXslt::LibXsltโ target that encapsulates the usage requirements of the libxslt library. only available if libxslt is actually found, obviously.LibXslt::LibExsltโ target that encapsulates the usage requirements for the libexslt library. she's part of the libxslt package, and libexslt provides optional extensions to XSLT on top of libxslt. available only if the main libxslt library is found.LibXslt::xsltprocโ target that encapsulates the command-line XSLT processor (xsltproc). this tool is part of the libxslt package and applies XSLT stylesheets to XML documents as a command-line alternative to the libxslt library. available only if thexsltprocexecutable is found. main character energy ๐ง
โจ Result Variables
this module defines the following variables:
LibXslt_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) libxslt was found.LibXslt_VERSIONโ Added in version 4.2. The version of libxslt found.LIBXSLT_LIBRARIESโ the libraries you need to link to libxslt.LIBXSLT_DEFINITIONSโ compiler switches required for using libxslt.LIBXSLT_EXSLT_LIBRARIESโ libraries needed when linking against the exslt library. heads up: these are available and needed only when you're using the exslt library.
๐ฆ Cache Variables
these cache variables may also get set:
LIBXSLT_INCLUDE_DIRโ the directory containinglibxslt/xslt.hand the other libxslt header files.LIBXSLT_EXSLT_INCLUDE_DIRโ Added in version 3.18. the directory containinglibexslt/exslt.hand the other exslt-related headers. these are needed only when you're using exslt (the extensions to XSLT).LIBXSLT_XSLTPROC_EXECUTABLEโ full path to the XSLT processor executablexsltproc, if it was found. this path is optional, no pressure ๐ซถ
๐ฅ Deprecated Variables
again, backward compatibility only:
LIBXSLT_FOUNDโ Deprecated since version 4.2: useLibXslt_FOUND, which has the same value. Boolean indicating whether (the requested version of) libxslt was found.LIBXSLT_VERSION_STRINGโ Deprecated since version 4.2: superseded byLibXslt_VERSION. The version of libxslt found.
๐ Examples
finding the libxslt library and linking it to a project target:
find_package(LibXslt)
target_link_libraries(foo PRIVATE LibXslt::LibXslt)
when your project also needs the extensions to XSLT (exslt) library, you link both targets. both. not one. both ๐
find_package(LibXslt)
target_link_libraries(foo PRIVATE LibXslt::LibXslt LibXslt::LibExslt)
and here's how you'd use the XSLT processor in a custom command build rule, lowkey a serve:
find_package(LibXslt)
if(TARGET LibXslt::xsltproc)
# Executed when some build rule depends on example.html.
add_custom_command(
OUTPUT example.html
COMMAND LibXslt::xsltproc -o example.html transform.xslt example.xml
)
endif()
๐ธ FindLTTngUST
Added in version 3.6.
finds the LTTng (https://lttng.org/) โ that's Linux Trace Toolkit: next generation โ user space tracing library, aka LTTng-UST:
find_package(LTTngUST [<version>] [...])
๐ Imported Targets
this module provides this imported target:
LTTng::USTโ the target providing the LTTng-UST library usage requirements. available only when LTTng-UST is found, periodt.
โจ Result Variables
this module defines the following variables:
LTTngUST_FOUNDโ Boolean indicating whether the (requested version of) LTTng-UST library was found.LTTngUST_VERSIONโ Added in version 4.2. The LTTng-UST version.LTTNGUST_HAS_TRACEFโTRUEif thetracef()API is available in the system's LTTng-UST.LTTNGUST_HAS_TRACELOGโTRUEif thetracelog()API is available in the system's LTTng-UST.
๐ฆ Cache Variables
these cache variables may also get set:
LTTNGUST_INCLUDE_DIRSโ the LTTng-UST include directories.LTTNGUST_LIBRARIESโ the libraries needed to use LTTng-UST.
๐ฅ Deprecated Variables
backward compatibility club, membership: these two:
LTTNGUST_FOUNDโ Deprecated since version 4.2: useLTTngUST_FOUND, which has the same value. Boolean indicating whether the (requested version of) the LTTng-UST library was found.LTTNGUST_VERSION_STRINGโ Deprecated since version 4.2: superseded byLTTngUST_VERSION. The LTTng-UST version.
๐ Examples
finding the LTTng-UST library and linking it to a project target:
find_package(LTTugNST)
target_link_libraries(project_target PRIVATE LTTng::UST)
๐ FindLua
finds the Lua library:
find_package(Lua [<version>] [...])
Lua is a embeddable scripting language. (the original said "a embeddable", we don't fix, we report ๐ซก)
Added in version 3.18: support for Lua 5.4.
Added in version 4.3: support for Lua 5.5.
okay so when you're working with Lua, its library headers are intended to be included in project source code like this:
#include <lua.h>
and not like this:
#include <lua/lua.h>
why? because the location of Lua headers may differ across platforms and may exist in locations other than lua/. so write it the first way, bestie, trust ๐
โจ Result Variables
this module defines the following variables:
Lua_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) Lua was found.Lua_VERSIONโ Added in version 4.2. The version of Lua found.Lua_VERSION_MAJORโ Added in version 4.2. The major version of Lua found.Lua_VERSION_MINORโ Added in version 4.2. The minor version of Lua found.Lua_VERSION_PATCHโ Added in version 4.2. The patch version of Lua found.LUA_LIBRARIESโ the libraries you need to link against to use Lua. this list includes both theluaandlualiblibraries, no crumbs left behind.
๐ฆ Cache Variables
this cache variable may also get set:
LUA_INCLUDE_DIRโ the directory containing the Lua header files, such aslua.h,lualib.h, andlauxlib.h, needed to use Lua.
๐ฅ Deprecated Variables
the backward-compat crew:
LUA_FOUNDโ Deprecated since version 4.2: useLua_FOUND, which has the same value. Boolean indicating whether (the requested version of) Lua was found.LUA_VERSION_STRINGโ Deprecated since version 4.2: superseded byLua_VERSION. The version of Lua found.LUA_VERSION_MAJORโ Deprecated since version 4.2: superseded byLua_VERSION_MAJOR. The major version of Lua found.LUA_VERSION_MINORโ Deprecated since version 4.2: superseded byLua_VERSION_MINOR. The minor version of Lua found.LUA_VERSION_PATCHโ Deprecated since version 4.2: superseded byLua_VERSION_PATCH. The patch version of Lua found.
๐ Examples
finding the Lua library and creating an interface imported target that encapsulates its usage requirements for linking to a project target. look at her go:
find_package(Lua)
if(Lua_FOUND AND NOT TARGET Lua::Lua)
add_library(Lua::Lua INTERFACE IMPORTED)
set_target_properties(
Lua::Lua
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${LUA_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE Lua::Lua)
๐ฆ FindLua50
Note: this module is intended specifically for Lua version branch 5.0, which is obsolete and not maintained anymore. obsolete. not maintained. gone but not forgotten ๐ญ in new code, use the latest supported Lua version and the version-agnostic module FindLua instead. please. for me.
finds the Lua library:
find_package(Lua50 [...])
Lua is a embeddable scripting language.
when working with Lua, its library headers are intended to be included in project source code as:
#include <lua.h>
and not:
#include <lua/lua.h>
because the location of Lua headers may differ across platforms and may exist in locations other than lua/. same deal as before, it's not a phase ๐
โจ Result Variables
this module defines this variable:
Lua50_FOUNDโ Added in version 3.3. Boolean indicating whether Lua was found.
๐ฆ Cache Variables
these cache variables may also get set:
LUA_INCLUDE_DIRโ the directory containing the Lua header files, such aslua.h,lualib.h, andlauxlib.h, needed to use Lua.LUA_LIBRARIESโ the libraries needed to link against to use Lua. this list includes both theluaandlualiblibraries.
๐ฅ Deprecated Variables
one singular legend, kept for backward compatibility:
LUA50_FOUNDโ Deprecated since version 4.2: useLua50_FOUND, which has the same value. Boolean indicating whether Lua was found.
๐ Examples
finding the Lua 5.0 library and creating an interface imported target that encapsulates its usage requirements for linking to a project target. retro but make it cute:
find_package(Lua50)
if(Lua50_FOUND AND NOT TARGET Lua50::Lua50)
add_library(Lua50::Lua50 INTERFACE IMPORTED)
set_target_properties(
Lua50::Lua50
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${LUA_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE Lua50::Lua50)
โจ See Also
- The
FindLuamodule ๐ โ for finding Lua in a version-agnostic way (iykyk, this is the one you actually want most of the time).
๐ FindLua51
โ ๏ธ Note, bestie: this module is intended specifically for Lua version branch 5.1, which is obsolete and not maintained anymore. In new code, use the latest supported Lua version and the version-agnostic FindLua module instead. Likeโฆ fr fr, 5.1 is giving vintage. Cute, but no.
Finds the Lua library:
find_package(Lua51 [<version>] [...])
Lua is an embeddable scripting language ๐ธ.
When working with Lua, its library headers are intended to be included in project source code as:
#include <lua.h>
and not as:
#include <lua/lua.h>
Why? Because the location of Lua headers may differ across platforms and may exist in locations other than lua/. The way that path is not universal ๐ญ.
๐ Result Variables
This module defines the following variables:
Lua51_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) Lua was found.Lua51_VERSIONโ Added in version 4.2. The version of Lua 5.1 found.
๐ Cache Variables
The following cache variables may also be set:
LUA_INCLUDE_DIRโ the directory containing the Lua header files, such aslua.h,lualib.h, andlauxlib.h, needed to use Lua.LUA_LIBRARIESโ libraries needed to link against to use Lua.
๐ฆ Deprecated Variables
The following variables are provided for backward compatibility (aka legacy era ๐):
LUA51_FOUNDโ Deprecated since version 4.2: useLua51_FOUND, which has the same value. Boolean indicating whether (the requested version of) Lua was found.LUA_VERSION_STRINGโ Deprecated since version 4.2: useLua51_VERSION, which has the same value. The version of Lua 5.1 found.
๐ Examples
Finding the Lua 5.1 library and creating an imported target that encapsulates its usage requirements for linking to a project target โ this is the glow-up, bestie:
find_package(Lua51)
if(Lua51_FOUND AND NOT TARGET Lua51::Lua51)
add_library(Lua51::Lua51 INTERFACE IMPORTED)
set_target_properties(
Lua51::Lua51
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${LUA_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE Lua51::Lua51)
โจ See Also
- The
FindLuamodule ๐ โ for finding Lua in a version-agnostic way.
๐งฎ FindMatlab
Finds MATLAB or MATLAB Compiler Runtime (MCR) and provides its tools, libraries and compilers to CMake:
find_package(Matlab [<version>] [COMPONENTS <components>...] [REGISTRY_VIEW <view>] [...])
The primary purpose of this module is to find the libraries associated with MATLAB or the MCR in order to be able to build MATLAB extensions (MEX files) ๐ฅ. But it can also be used:
- to run specific commands in MATLAB in case MATLAB is available
- for declaring MATLAB unit tests
- to retrieve various information from MATLAB (MEX extensions, versions and release queries, ...)
Added in version 3.12: MATLAB Compiler Runtime (MCR) support ๐ซถ.
Added in version 3.30: support for specifying a version range to find_package(), support for specifying the REGISTRY_VIEW argument to find_package(), plus the matlab_extract_all_installed_versions_from_registry() and matlab_get_all_valid_matlab_roots_from_registry() commands. The default behavior remained unchanged, by using the registry view TARGET. No cap, it just kept the old vibe โจ.
๐ Note: the version given to thefind_package()argument is the MATLAB version, which should not be confused with the MATLAB release name (e.g.R2023b). Thematlab_get_version_from_release_name()andmatlab_get_release_name_from_version()commands provide a mapping between the release name and the version. Two different name systems, iconic of them honestly ๐.
๐งฉ Components
This module supports optional components which can be specified using the find_package() command:
find_package(Matlab [COMPONENTS <components>...])
Supported components include:
ENG_LIBRARYโ Added in version 3.3. Finds the ENG library of MATLAB.MAT_LIBRARYโ Added in version 3.7. Finds the MAT library of MATLAB.MAIN_PROGRAMโ Added in version 3.3. Finds the MATLAB binary program. Note that this component is not available on the MCR version, and will yield an error if the MCR is found instead of the regular MATLAB installation ๐ญ.MEX_COMPILERโ Added in version 3.3. Finds the MEX compiler.MCC_COMPILERโ Added in version 3.13. Finds the MCC compiler, included with the MATLAB Compiler add-on.SIMULINKโ Added in version 3.3. Finds the Simulink environment.
๐ Implicitly Found Components
The following components are always found unconditionally, without needing to be specified explicitly โ they just show up, main character energy:
MX_LIBRARYโ Changed in version 3.14: this component has been removed and is now always found unconditionally. Added in version 3.3. Finds the MATLAB mx library.ENGINE_LIBRARYโ Changed in version 3.14: this component has been removed and is now always found unconditionally. Added in version 3.13. Finds the MATLAB engine library.DATAARRAY_LIBRARYโ Changed in version 3.14: this component has been removed and is now always found unconditionally. Added in version 3.13. Finds the C++ MATLAB data array library.
If no components are specified, the module looks for the MX_LIBRARY, ENGINE_LIBRARY, and DATAARRAY_LIBRARY by default. So you're covered either way ๐
.
๐ฏ Imported Targets
This module provides the following imported targets:
Matlab::mexโ Added in version 3.22. Target encapsulating the mex library usage requirements, always available for MATLAB installations. Available for MCR installations if provided by MCR.Matlab::mxโ Added in version 3.22. Target encapsulating the usage requirements of the mx library of MATLAB (arrays), always available for MATLAB installations. Available for MCR installations if provided by MCR.Matlab::engโ Added in version 3.22. Target encapsulating the MATLAB engine library usage requirements. Available only if theENG_LIBRARYcomponent is requested.Matlab::matโ Added in version 3.22. Target encapsulating the MATLAB matrix library usage requirements. Available only if theMAT_LIBRARYcomponent is requested.Matlab::MatlabEngineโ Added in version 3.22. Target encapsulating the MATLAB C++ engine library usage requirements, always available for MATLAB R2018a and newer. Available for MCR installations if provided by MCR.Matlab::MatlabDataArrayโ Added in version 3.22. Target encapsulating the MATLAB C++ data array library usage requirements, always available for MATLAB R2018a and newer. Available for MCR installations if provided by MCR.
๐ Result Variables
This module defines the following variables:
Matlab_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) MATLAB installation was found. All variables below are defined if MATLAB is found.Matlab_VERSIONโ Added in version 3.27. The numerical version (e.g.23.2.0) of MATLAB found. Not to be confused with the MATLAB release name (e.g.R2023b) that can be obtained withmatlab_get_release_name_from_version(). When a MATLAB/MCR installation is found automatically and theMatlab_VERSIONis not given, the version is queried from MATLAB directly (on Windows this may pop up a MATLAB window ๐) or from the MCR installation.Matlab_ROOT_DIRโ Added in version 3.3. The final root of the MATLAB installation determined by this module.Matlab_MAIN_PROGRAMโ Added in version 3.3. The MATLAB binary program. Available only if the componentMAIN_PROGRAMis given in thefind_package()argument.Matlab_INCLUDE_DIRSโ Added in version 3.3. The path of the MATLAB libraries headers.Matlab_MEX_LIBRARYโ library for MEX, always available for MATLAB installations. Available for MCR installations if provided by MCR.Matlab_MX_LIBRARYโ the mx library of MATLAB (arrays), always available for MATLAB installations. Available for MCR installations if provided by MCR.Matlab_ENG_LIBRARYโ MATLAB engine library. Available only if the componentENG_LIBRARYis requested.Matlab_MAT_LIBRARYโ Added in version 3.7. MATLAB matrix library. Available only if the componentMAT_LIBRARYis requested.Matlab_ENGINE_LIBRARYโ Added in version 3.13. MATLAB C++ engine library, always available for MATLAB R2018a and newer. Available for MCR installations if provided by MCR.Matlab_DATAARRAY_LIBRARYโ Added in version 3.13. MATLAB C++ data array library, always available for MATLAB R2018a and newer. Available for MCR installations if provided by MCR.Matlab_LIBRARIESโ the whole set of libraries of MATLAB. The full collection, the entire friend group ๐ซถ.Matlab_MEX_COMPILERโ Added in version 3.3. The MEX compiler of MATLAB. Currently not used. Available only if the componentMEX_COMPILERis requested.Matlab_MCC_COMPILERโ Added in version 3.13. The mcc compiler of MATLAB. Included with the MATLAB Compiler add-on. Available only if the componentMCC_COMPILERis requested.
๐ Cache Variables
The following cache variables may also be set:
Matlab_MEX_EXTENSIONโ Added in version 3.3. The extension of the MEX files for the current platform (given by MATLAB).Matlab_ROOT_DIRโ Added in version 3.3. The location of the root of the MATLAB installation found. If this value is changed by the user, the result variables are recomputed. Live update behavior, slay โจ.
๐ง Input Variables
Users or projects may set the following variables to configure the module behavior before calling find_package(Matlab):
Matlab_ROOTโ Added in version 3.25. Default value for theMatlab_ROOT_DIRvariable, the root of the MATLAB installation.Matlab_ROOT_DIRโ Added in version 3.3.
The root folder of the MATLAB installation. If you set this before the call to find_package(), the module will go look for the components in that path. If you don't set it, an automatic search for MATLAB happens instead. If you do set it, it should point to a valid version of MATLAB. โจ
You can specify this variable to hand over the path of the exact MATLAB version you want. Otherwise, the behavior is platform specific, bestie:
- Windows: the installed versions of MATLAB/MCR are retrieved from the Windows registry. The
REGISTRY_VIEWargument may optionally be specified to manually control whether 32bit or 64bit versions shall be searched for. - macOS: the installed versions of MATLAB/MCR are given by the MATLAB default installation paths under
$HOME/Applicationsand/Applications. If no such application is found, it falls back to the one that might be accessible from thePATH. - Unix: the desired MATLAB should be accessible from the
PATH. This does not work for MCR installation, andMatlab_ROOT_DIRshould be specified on this platform. ๐ญ
MATLAB_FIND_DEBUGโ Added in version 3.3. If set to a boolean true, extra debug information gets outputted to the console, like the lookup of MATLAB and the intermediate configuration steps. Your lil' peek behind the curtain ๐ต๏ธโโ๏ธMATLAB_ADDITIONAL_VERSIONSโ Added in version 3.3. If set, it specifies additional versions of MATLAB for the automatic retrieval of the installed versions that may be handled and looked for.
The mapping of the release names and the version of MATLAB is performed by defining pairs (name, version). This variable should be a list of strings, organized by pairs of release name and versions, like this:
set(
MATLAB_ADDITIONAL_VERSIONS
"release_name1=corresponding_version1"
"release_name2=corresponding_version2"
# ...
)
find_package(Matlab)
Example, because we love a concrete example ๐:
set(
MATLAB_ADDITIONAL_VERSIONS
"R2013b=8.2"
"R2013a=8.1"
"R2012b=8.0"
# ...
)
find_package(Matlab)
The order of entries in this list matters when several versions of MATLAB are installed โ priority is set according to the ordering in this list. So put your fave first, no cap. ๐
๐ป Commands ๐ป
This module provides the following commands, and yes, we're going through every single one:
matlab_get_version_from_release_name()matlab_get_release_name_from_version()matlab_get_version_from_matlab_run()matlab_extract_all_installed_versions_from_registry()matlab_get_all_valid_matlab_roots_from_registry()matlab_add_mex()matlab_get_mex_suffix()matlab_add_unit_test()
matlab_get_version_from_release_name
Added in version 3.3.
Returns the version of MATLAB from a release name:
matlab_get_version_from_release_name(<release-name> <version-var>)
The arguments are:
<release-name>โ input release name string (e.g.R2023b).<version-var>โ the name of the variable in which to store the version of MATLAB. The output result is e.g.23.2.0.
Note: this command provides correct versions mappings for MATLAB but not MCR. ๐
matlab_get_release_name_from_version
Added in version 3.3.
Returns the release name from the version of MATLAB:
matlab_get_release_name_from_version(<version> <release-name-var>)
The arguments are:
<version>โ input MATLAB version string (e.g.23.2.0).<release-name-var>โ the name of the variable in which to store the MATLAB release name. The output result is e.g.R2023b.
Note: this command provides correct version mappings for MATLAB but not MCR. Same energy as above, the MCR girlies are on their own. ๐
matlab_get_version_from_matlab_run
Added in version 3.3.
Runs the specified MATLAB program and extracts the version of MATLAB/MCR, given the full directory of the MATLAB/MCR installation path:
matlab_get_version_from_matlab_run(<matlab-binary> <matlab-versions-var>)
The arguments are:
<matlab-binary>โ the path to thematlabbinary executable.<matlab-versions-var>โ the name of the variable in which a list of extracted MATLAB versions are stored.
If the path provided for the MATLAB installation points to an MCR installation, the version is extracted from the installed files. Sneaky but valid. ๐ง
matlab_extract_all_installed_versions_from_registry
Added in version 3.3.
Parses the Windows registry and finds all installed MATLAB versions:
matlab_extract_all_installed_versions_from_registry(<versions-var>
[REGISTRY_VIEW <view>])
The arguments are:
<versions-var>โ the name of the variable in which to store the list of all MATLAB versions found.REGISTRY_VIEW <view>โ Added in version 3.30. Optional registry view argument that provides a more precise interface on how to interact with the Windows Registry. The argument is passed (or omitted) tocmake_host_system_information()without further checks or modification. For example,<view>value can be one of64,32,64_32,32_64,HOST,TARGET,BOTH.
The old signature is:
matlab_extract_all_installed_versions_from_registry(<win64>
<versions-var>)
The arguments are:
<win64>โ boolean whether to search for the 64-bit version of MATLAB. If set to boolean true, the 64-bit registry view will be searched. If set to boolean false, the 32-bit registry view will be searched. For finer control, use the above signature. โจ<versions-var>โ the name of the variable in which to store the list of all MATLAB versions found.
This command is available on Windows only. The part of the registry parsed is dependent on the host processor.
The returned list contains all versions under HKLM\SOFTWARE\Mathworks\MATLAB, HKLM\SOFTWARE\Mathworks\MATLAB Runtime and HKLM\SOFTWARE\Mathworks\MATLAB Compiler Runtime, or an empty list in case an error occurred (or nothing found). Bestie, if it's empty, it's empty. ๐ซถ
Note: only the versions are provided. No check is made over the existence of the installation referenced in the registry. So likeโฆ it might be lying to you and that's by design. ๐ญ
matlab_get_all_valid_matlab_roots_from_registry
Added in version 3.3.
Returns all the possible MATLAB or MCR paths, according to a previously given list:
matlab_get_all_valid_matlab_roots_from_registry(
<matlab-versions>
<matlab-roots-var>
[REGISTRY_VIEW <view>]
)
This command populates the MATLAB root with valid versions of MATLAB or MATLAB Runtime (MCR) and is mainly useful for the searching of all possible MATLAB installations. Only the existing/accessible paths are kept โ ghost paths get ghosted. ๐ป
The arguments are:
<matlab-versions>โ a semicolon-separated list of each of the MATLAB or MCR installations. Specify it as a single string value.<matlab-roots-var>โ the name of the variable in which to store a list of locations of each of the MATLAB or MCR installations.
The value of this variable is organized in triplets (type,version_number,matlab_root_path), where type indicates either MATLAB or MCR. Triplets! It's giving coordinated outfit. ๐
REGISTRY_VIEW <view>โ Added in version 3.30. Optional registry view argument that provides a more precise interface on how to interact with the Windows Registry. The argument is passed (or omitted) tocmake_host_system_information()without further checks or modification. For example,<view>value can be one of64,32,64_32,32_64,HOST,TARGET,BOTH.
matlab_add_mex
Added in version 3.3.
Adds a target that compiles MATLAB MEX target file:
matlab_add_mex(
NAME <name>
[EXECUTABLE | MODULE | SHARED]
SRC <sources>...
[OUTPUT_NAME <output-name>]
[DOCUMENTATION <file>]
[LINK_TO <targets>...]
[R2017b | R2018a]
[EXCLUDE_FROM_ALL]
[NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES]
[...]
)
This command compiles the given sources with the current tool-chain in order to produce a MEX file. The final name of the produced output may be specified, as well as additional link libraries, and a documentation entry for the MEX file. Remaining arguments of the call are passed to the add_library() or add_executable() command. It's giving "we handle the MEX stuff, you handle the rest". ๐
The arguments are:
NAME <name>โ the name of the target.SRC <sources>...โ one or more source files to be compiled.LINK_TO <targets>...โ a list of additional link dependencies. The target links tolibmexandlibmxby default, unless theNO_IMPLICIT_LINK_TO_MATLAB_LIBRARIESoption is passed.OUTPUT_NAME <output-name>โ if given, overrides the default name. The default name is the name of the target without any prefix and withMatlab_MEX_EXTENSIONsuffix.DOCUMENTATION <file>โ if given, the<file>will be considered as being the documentation file for the MEX file. This file is copied into the same folder without any processing, with the same name as the final MEX file, and with extension.m. In that case, typinghelp <name>in MATLAB prints the documentation contained in this file. Iconic behavior honestly. ๐
โฆand just so we're clear, that documentation file does not get processed at all โ it literally just has to look like this, no notes:
% This is the documentation
function ret = mex_target_output_name(input1)
R2017borR2018aโ added in version 3.14. You can pass this to pick which version of the C API gets used:R2017b= the traditional (separate complex) C API, and it lines up with the-R2017bflag for themexcommand.R2018a= the new interleaved complex C API, and it lines up with the-R2018aflag for themexcommand. It's ignored for MATLAB versions prior to R2018a. Defaults toR2017b, bestie.MODULEorSHAREDโ added in version 3.7. Pass this to say what type of library you want created.EXECUTABLEโ added in version 3.7. Pass this and you get an executable instead of a library. If you don't explicitly give a type, the default type isSHARED.EXCLUDE_FROM_ALLโ this one means exactly the same thing as theEXCLUDE_FROM_ALLtarget property, and it gets forwarded straight to theadd_library(), oradd_executable()command.NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIESโ added in version 3.24. This option permits to disable the automatic linking of MATLAB libraries, so that only the libraries that are actually required can be linked via theLINK_TOoption. Chef's kiss for keeping your link line clean ๐
matlab_get_mex_suffix
Added in version 3.3.
Returns the extension to be used for the MEX files (aka the suffix):
matlab_get_mex_suffix(<matlab-root> <mex-suffix-var>)
The arguments are:
<matlab-root>โ the root of MATLAB/MCR installation. For example, the value of theMatlab_ROOT_DIRvariable.<mex-suffix-var>โ the name of the variable in which the suffix will be returned.
Heads up, babe: this command is platform and architecture dependent. Do not call it before the appropriate MATLAB root has been found. Like, don't. It will not slay.
matlab_add_unit_test
Added in version 3.3.
Adds a MATLAB unit test file to the project's test set of CMake/CTest:
matlab_add_unit_test(
NAME <name>
UNITTEST_FILE <matlab-file-containing-unittest.m>
[CUSTOM_TEST_COMMAND <matlab-command-to-run-as-test>]
[UNITTEST_PRECOMMAND <matlab-command-to-run>]
[TIMEOUT <timeout>]
[ADDITIONAL_PATH <paths>...]
[MATLAB_ADDITIONAL_STARTUP_OPTIONS <options>...]
[TEST_ARGS <args>...]
[NO_UNITTEST_FRAMEWORK]
[WORKING_DIRECTORY <dir>]
)
By default, the MATLAB unit test framework will be used (>= 2013a) to run the added MATLAB script, but regular .m files returning an exit code can be used as well (0 indicating a success). Testing era โจ
This command requires the component MAIN_PROGRAM and hence is not available for an MCR installation. ๐
The unit test uses the MATLAB unittest framework (default, available starting MATLAB 2013b+) except if the option NO_UNITTEST_FRAMEWORK is given.
The command expects one MATLAB test script file to be given. In the case NO_UNITTEST_FRAMEWORK is given, the unittest script file should contain the script to be run, plus an exit command with the exit value. This exit value will be passed to the ctest framework (0 success, non 0 failure). Additional arguments accepted by add_test() can be passed through TEST_ARGS (e.g. CONFIGURATIONS <config> ...).
The arguments are:
NAME <name>โ the name of the unittest in ctest.UNITTEST_FILE <matlab-file-containing-unittest.m>โ the MATLAB unittest file. Its path will be automatically added to the MATLAB path.CUSTOM_TEST_COMMAND <matlab-command-to-run-as-test>โ MATLAB script command to run as the test. If this is not set, then the following is run:runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))wherematlab_file_nameis theUNITTEST_FILEwithout the extension.UNITTEST_PRECOMMAND <matlab-command-to-run>โ MATLAB script command to be ran before the file containing the test (e.g. GPU device initialization based on CMake variables).TIMEOUT <timeout>โ the test timeout in seconds. Defaults to 180 seconds as the MATLAB unit test may hang. ๐ญADDITIONAL_PATH <paths>...โ a list of paths to add to the MATLAB path prior to running the unit test.MATLAB_ADDITIONAL_STARTUP_OPTIONS <options>โ a list of additional option in order to run MATLAB from the command line. The-nosplash,-nodesktop, and-nodisplayoptions are always added automatically. Built-in slay.TEST_ARGS <args>...โ additional options provided to theadd_testcommand. These options are added to the default options (e.g.CONFIGURATIONS Release).NO_UNITTEST_FRAMEWORKโ when set, indicates that the test should not use the unittest framework of MATLAB (available for versions >= R2013a).WORKING_DIRECTORY <dir>โ this will be the working directory for the test. If specified it will also be the output directory used for the log file of the test run. If not specified the temporary directory${CMAKE_BINARY_DIR}/Matlabwill be used as the working directory and the log location.
Known Issues
Symbol clash in a MEX target
By default, every symbol inside a MEX file defined with the command matlab_add_mex() have hidden visibility, except for the entry point. This is the default behavior of the MEX compiler, which lowers the risk of symbol collision between the libraries shipped with MATLAB, and the libraries to which the MEX file is linking to. This is also the default on Windows platforms.
However, this is not sufficient in certain case, where for instance the MEX file is linking against libraries that are already loaded by MATLAB, even if those libraries have different SONAMES. A possible solution is to hide the symbols of the libraries to which the MEX target is linking to. This can be achieved in GNU GCC compilers with the linker option -Wl,--exclude-libs,ALL.
Tests using GPU resources
In case the MEX file is using the GPU and in order to be able to run unit tests on this MEX file, the GPU resources should be properly released by MATLAB. A possible solution is to make MATLAB aware of the use of the GPU resources in the session, which can be performed by a command, such as D = gpuDevice(), at the beginning of the test script (or via a fixture).
Examples
Finding MATLAB and linking imported target to a project target:
find_package(Matlab)
target_link_libraries(example PRIVATE Matlab::mx)
FindMFC
Finds the native Microsoft Foundation Class Library (MFC) for developing MFC applications on Windows:
find_package(MFC [...])
Note: MFC is an optional component in Visual Studio and must be installed separately for this module to succeed. No MFC component, no luck, bestie. ๐
Once the MFC libraries and headers are found, no additional manual linking is needed, as they are part of the development environment. Iconic, honestly.
Result Variables
This module defines the following variables:
MFC_FOUNDโ Boolean indicating whether MFC support was found.
Examples
Using this module to check if the application can link to the MFC libraries:
find_package(MFC)
if(MFC_FOUND)
# Example logic when MFC is available...
set(CMAKE_MFC_FLAG 2)
add_executable(app WIN32 main.cpp)
target_compile_definitions(app PRIVATE _AFXDLL)
endif()
See Also
- The
CMAKE_MFC_FLAGvariable.
FindMotif
Finds Motif (or LessTif) graphical user interface toolkit:
find_package(Motif [...])
Result Variables
This module defines the following variables:
Motif_FOUNDโ added in version 3.3. Boolean indicating whether Motif was found.
Cache Variables
The following cache variables may also be set:
MOTIF_INCLUDE_DIRโ include directories needed to use Motif.MOTIF_LIBRARIESโ libraries needed to link to Motif.
Deprecated Variables
The following variables are provided for backward compatibility:
MOTIF_FOUNDโ deprecated since version 4.2: useMotif_FOUND, which has the same value. Boolean indicating whether Motif was found.
She's giving legacy support, not main character energy โ reach for Motif_FOUND instead, okay? ๐ซถ
Examples
Finding Motif and creating an imported interface target for linking it to a project target:
find_package(Motif)
if(Motif_FOUND AND NOT TARGET Motif::Motif)
add_library(Motif::Motif INTERFACE IMPORTED)
set_target_properties(
Motif::Motif
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${MOTIF_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${MOTIF_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE Motif::Motif)
FindMPEG
Finds the native MPEG library (libmpeg2):
find_package(MPEG [...])
Note: this module is functionally identical to theFindMPEG2module, which also finds thelibmpeg2library. Both modules were introduced in the past to provide flexibility in handling potential differences in future versions of the MPEG library and to maintain backward compatibility across CMake releases.
TheFindMPEG2module additionally checks for the SDL dependency and includes it in its usage requirements. For working withlibmpeg2, it is recommended to use theFindMPEG2module instead of this one. Like, genuinely โ use the other one. ๐
Result Variables
This module defines the following variables:
MPEG_FOUNDโ Boolean indicating whether thelibmpeg2library was found.MPEG_LIBRARIESโ libraries needed to link against to uselibmpeg2.
๐พ Cache Variables
okay so these are the cache variables the module may set for you, bestie โ look them up, don't guess:
MPEG_INCLUDE_DIRโ the directory that hasmpeg2.hand all the related headers you need to actually use thelibmpeg2library. ๐MPEG_mpeg2_LIBRARYโ the path to thelibmpeg2library itself.MPEG_vo_LIBRARYโ the path to the vo (Video Out) library.
โจ Examples
so here's how you find the libmpeg2 library AND build an imported interface target to link it into one of your project targets. it's giving "two birds, one stone" energy ๐ฆ:
find_package(MPEG)
if(MPEG_FOUND AND NOT TARGET MPEG::MPEG)
add_library(MPEG::MPEG INTERFACE IMPORTED)
set_target_properties(
MPEG::MPEG
PROPERTIES
INTERFACE_LINK_LIBRARIES "${MPEG_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MPEG_INCLUDE_DIR}"
)
endif()
target_link_libraries(project_target PRIVATE MPEG::MPEG)
๐ FindMPEG2
same vibe, different module โ FindMPEG2 finds the native MPEG2 library (libmpeg2):
find_package(MPEG2 [...])
๐ Note: depending on how the native libmpeg2 library got built and installed, it may depend on the SDL (Simple DirectMedia Layer) library. If SDL is found, this module includes it in its usage requirements when used. so like, it handles that for you, no cap.
๐ซถ Result Variables
this module defines these variables, periodt:
MPEG2_FOUNDโ boolean that tells you whether thelibmpeg2library was found. true/false, iconic.MPEG2_LIBRARIESโ the libraries you need to link against to uselibmpeg2.
๐ Cache Variables
and these cache variables may also be set:
MPEG2_INCLUDE_DIRโ the directory containingmpeg2.hand the related headers needed to use thelibmpeg2library.MPEG2_mpeg2_LIBRARYโ the path to thelibmpeg2library.MPEG2_vo_LIBRARYโ the path to the vo (Video Out) library.
๐ Examples
finding libmpeg2 and making an imported interface target so you can link it to a project target โ literally the same slay as before:
find_package(MPEG2)
if(MPEG2_FOUND AND NOT TARGET MPEG2::MPEG2)
add_library(MPEG2::MPEG2 INTERFACE IMPORTED)
set_target_properties(
MPEG2::MPEG2
PROPERTIES
INTERFACE_LINK_LIBRARIES "${MPEG2_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MPEG2_INCLUDE_DIR}"
)
endif()
target_link_libraries(project_target PRIVATE MPEG2::MPEG2)
๐ FindMPI
okay THIS one is the main character ๐ โ FindMPI finds a Message Passing Interface (MPI) implementation:
find_package(MPI [<version>] [COMPONENTS <langs>...] [...])
so what even IS MPI? it's a library used to write high-performance distributed-memory parallel applications, and it's typically deployed on a cluster. MPI is a standard interface (defined by the MPI forum) and there are like, a LOT of implementations of it out there. ๐ฅ๏ธโจ
Added in version 3.10: major overhaul of the module โ many new variables, per-language components, and support for a wider variety of runtimes. glow-up fr fr.
๐ธ Components
this module supports optional components that you can specify with the find_package() command to control which MPI languages it searches for:
find_package(MPI [COMPONENTS <langs>...])
supported components include:
Cโ Added in version 3.10. finds the MPI C API.CXXโ Added in version 3.10. finds the MPI C API that is usable from C++. (yes, the C API, from C++ โ that's the whole bit ๐)MPICXXโ Added in version 3.10. finds the MPI-2 C++ API that was removed in MPI-3. rip to a real one ๐ญFortranโ Added in version 3.10. finds the MPI Fortran API.
if you specify no components at all, the module searches for the C, CXX, and Fortran components automatically, depending on which languages are enabled in the project. automatic. effortless. ๐ง
โญ Imported Targets
this module provides these Imported Targets:
MPI::MPI_<lang>โ Added in version 3.9. a target encapsulating the usage requirements for using MPI from language<lang>, available if MPI is found. the<lang>is a specified component name as listed above. so clean, so modern. ๐ซถ
๐ฆ Result Variables
this module defines the following variables:
MPI_FOUNDโ boolean indicating that MPI settings for all requested components (languages) were found. if no components are specified, this variable is set to boolean true if MPI settings for all enabled languages were detected. and heads up: note that theMPICXXcomponent does not affect this variable. ๐MPI_VERSIONโ the minimal version of MPI detected among the requested languages, or all enabled languages if no components were specified.
then the module sets the following variables per language in your CMake project, where <lang> is one of C, CXX, or Fortran:
MPI_<lang>_FOUNDโ boolean indicating the MPI settings for<lang>were found and that simple MPI test programs compile with the provided settings.MPI_<lang>_COMPILERโ the MPI compiler for<lang>, if such a program exists.MPI_<lang>_COMPILE_OPTIONSโ compilation options for MPI programs in<lang>, given as a semicolon-separated list.MPI_<lang>_COMPILE_DEFINITIONSโ compilation definitions for MPI programs in<lang>, given as a semicolon-separated list.MPI_<lang>_INCLUDE_DIRSโ include path(s) for the MPI header.MPI_<lang>_LINK_FLAGSโ linker flags for MPI programs.MPI_<lang>_LIBRARIESโ all libraries to link MPI programs against.
the following variables, which tell you which bindings are present, will be defined too:
MPI_MPICXX_FOUNDโ boolean indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3).MPI_Fortran_HAVE_F77_HEADERโ true if the Fortran 77 header<mpif.h>is available.MPI_Fortran_HAVE_F90_MODULEโ true if the Fortran 90 modulempican be used for accessing MPI (MPI-2 and higher only).MPI_Fortran_HAVE_F08_MODULEโ true if the Fortran 2008mpi_f08is available to MPI programs (MPI-3 and higher only).
if possible, the MPI version will be determined by this module. the facilities to detect the MPI version were introduced with MPI-1.2, and therefore cannot be found for older MPI versions โ so if you're on something ancient, sorry bestie, no version for you ๐.
MPI_<lang>_VERSIONโ the MPI version implemented for<lang>by the MPI distribution.MPI_<lang>_VERSION_MAJORโ major version of MPI implemented for<lang>by the MPI distribution.MPI_<lang>_VERSION_MINORโ minor version of MPI implemented for<lang>by the MPI distribution.
๐ก note that there's no variable for the C bindings being accessible through <mpi.h>, since the MPI standards always have required this binding to work in both C and C++ code. it's just... a given. iykyk.
for running MPI programs, the module sets these variables:
MPIEXEC_EXECUTABLEโ executable for running MPI programs, if such exists.MPIEXEC_NUMPROC_FLAGโ flag to pass tompiexecbefore giving it the number of processors to run on.MPIEXEC_MAX_NUMPROCSโ number of MPI processors to utilize. defaults to the number of processors detected on the host system.MPIEXEC_PREFLAGSโ flags to pass tompiexecdirectly before the executable to run.MPIEXEC_POSTFLAGSโ flags to pass tompiexecafter other flags.
๐ฅ Variables for Locating MPI
this module performs a four-step search for an MPI implementation:
- Searches for
MPIEXEC_EXECUTABLEand, if found, uses its base directory. - Checks if the compiler has MPI support built-in. this is the case if the user passed a compiler wrapper as
CMAKE_<LANG>_COMPILERor if they use Cray system compiler wrappers. - Attempts to find an MPI compiler wrapper and determines the compiler information from it.
- Tries to find an MPI implementation that does not ship such a wrapper by guessing settings. currently, only Microsoft MPI and MPICH2 on Windows are supported.
for controlling the MPIEXEC_EXECUTABLE step, you may set these variables:
MPIEXEC_EXECUTABLEโ manually specify the location ofmpiexec.MPI_HOMEโ specify the base directory of the MPI installation.ENV{MPI_HOME}โ environment variable to specify the base directory of the MPI installation.ENV{I_MPI_ROOT}โ environment variable to specify the base directory of the MPI installation.
for controlling the compiler wrapper step, you may set these variables:
MPI_<lang>_COMPILERโ search for the specified compiler wrapper and use it.MPI_<lang>_COMPILER_FLAGSโ flags to pass to the MPI compiler wrapper during interrogation. some compiler wrappers support linking debug or tracing libraries if a specific flag is passed, and this variable may be used to obtain them. ๐ฏMPI_COMPILER_FLAGSโ used to initializeMPI_<lang>_COMPILER_FLAGSif no language specific flag has been given. empty by default.MPI_EXECUTABLE_SUFFIXโ a suffix which is appended to all names that are being looked for. for instance, it may be set to.mpichor.openmpito prefer the one or the other on Debian and its derivatives. sneaky but useful ๐
in order to control the guessing step, you may set this variable:
MPI_GUESS_LIBRARY_NAMEโ valid values areMSMPIandMPICH2. if set, only the given library will be searched for. by default,MSMPIwill be preferred overMPICH2if both are available. this also sets theMPI_SKIP_COMPILER_WRAPPERvariable to true, which may be overridden. โ ๏ธ
each of the search steps may be skipped with these control variables:
MPI_ASSUME_NO_BUILTIN_MPIโ if true, the module assumes that the compiler itself does not provide an MPI implementation and skips to step 2.MPI_SKIP_COMPILER_WRAPPERโ if true, no compiler wrapper will be searched for.MPI_SKIP_GUESSINGโ if true, the guessing step will be skipped.
additionally, this control variable is available to change search behavior:
MPI_CXX_SKIP_MPICXXโ add some definitions that will disable the MPI-2 C++ bindings. currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof, for example, MVAPICH or Intel MPI.
and finally โ if the find procedure fails for the module's internal variable MPI_<lang>_WORKS, then the settings detected by or passed to the module did not work, and even a simple MPI test program failed to compile. ๐ญ that's your sign that something's cooked, bestie.
MPI_<lang>_LIBRARIES and a whole list of include dirs in MPI_<lang>_ADDITIONAL_INCLUDE_DIRS? bestie, that's the โจmanual overrideโจ โ it straight-up disables the entire autodetection process. and yeah, you can set any other variable in addition to those two, no biggie. the module will then validate your MPI settings and store them in the cache. respect. ๐ซถ
๐ง Cache Variables
the variable MPI_<lang>_INCLUDE_DIRS gets assembled from the following variables, iykyk:
for C and CXX:
MPI_<lang>_HEADER_DIRโ where the<mpi.h>header lives on disk ๐๏ธ
for Fortran:
MPI_Fortran_F77_HEADER_DIRโ where the Fortran 77 header<mpif.h>lives, if it existsMPI_Fortran_MODULE_DIRโ where thempiormpi_f08modules live, if they're available
and for all the languages, these get considered too:
MPI_<lang>_ADDITIONAL_INCLUDE_DIRSโ a semicolon-separated list of paths you need on top of the normal include directoriesMPI_<include-name>_INCLUDE_DIRโ path variables for include folders referred to by<include-name>MPI_<lang>_ADDITIONAL_INCLUDE_VARSโ a semicolon-separated list of<include-name>that will be added to the include locations of<lang>
and the variable MPI_<lang>_LIBRARIES gets assembled from these:
MPI_<lib-name>_LIBRARYโ the location of a library called<lib-name>for use with MPI ๐MPI_<lang>_LIB_NAMESโ a semicolon-separated list of<lib-name>that will be added to the include locations of<lang>
๐ฌ Advanced Variables for Using MPI
okay so this module can do some advanced feature detections โ but only upon explicit request, no surprise poking around โจ
Note: these checks literally cannot be performed without executing an MPI test program. so pls consider the special considerations for the behavior of try_run() during cross compilation ๐ญ and also, running an MPI program can cause extra issues, like a firewall notification on some systems. only enable these detections if the info is absolutely needed. fr fr.
if the following variables are set to true, the respective search will be performed:
MPI_DETERMINE_Fortran_CAPABILITIESโ determines, for all available Fortran bindings, what the values ofMPI_SUBARRAYS_SUPPORTEDandMPI_ASYNC_PROTECTS_NONBLOCKINGare, and makes those values available asMPI_Fortran_<binding>_SUBARRAYSandMPI_Fortran_<binding>_ASYNCPROT, where<binding>is one ofF77_HEADER,F90_MODULEandF08_MODULE๐MPI_DETERMINE_LIBRARY_VERSIONโ for each language, finds the output ofMPI_Get_library_versionand makes it available asMPI_<lang>_LIBRARY_VERSION_STRING. this info is usually tied to the runtime component of an MPI implementation and might differ depending on<lang>. note that the return value is entirely implementation defined ๐ this information might be used to identify the MPI vendor and, for example, pick the correct one of multiple third party binaries that matches the MPI vendor.
๐ Deprecated Variables
these are kept around purely for backward compatibility (we love a legacy queen but she's retired):
MPI_COMPILERโ Deprecated since version 2.8.5: use theMPI_<lang>_COMPILERinstead.MPI_LIBRARYโ Deprecated since version 2.8.5: use theMPI_<lang>_LIBRARIESinstead.MPI_EXTRA_LIBRARYโ Deprecated since version 2.8.5: use theMPI_<lang>_LIBRARIESinstead.MPI_COMPILE_FLAGSโ Deprecated since version 2.8.5: useMPI_<lang>_COMPILE_OPTIONSandMPI_<lang>_COMPILE_DEFINITIONSinstead.MPI_INCLUDE_PATHโ Deprecated since version 2.8.5: use theMPI_<lang>_INCLUDE_DIRSinstead.MPI_LINK_FLAGSโ Deprecated since version 2.8.5: use theMPI_<lang>_LINK_FLAGSinstead.MPI_LIBRARIESโ Deprecated since version 2.8.5: use theMPI_<lang>_LIBRARIESinstead.MPI_<lang>_COMPILE_FLAGSโ Deprecated since version 3.10: use theMPI_<lang>_COMPILE_OPTIONSandMPI_<lang>_COMPILE_DEFINITIONSinstead.MPI_<lang>_INCLUDE_PATHโ Deprecated since version 3.10: for consumption useMPI_<lang>_INCLUDE_DIRSand for specifying folders useMPI_<lang>_ADDITIONAL_INCLUDE_DIRSinstead.MPIEXECโ Deprecated since version 3.10: useMPIEXEC_EXECUTABLEinstead.
๐ธ Examples
๐ Example: Basic Usage
finding MPI and linking the imported target to your project target โ the classic slay:
find_package(MPI)
target_link_libraries(example PRIVATE MPI::MPI_C)
๐ Example: Usage of mpiexec
when you're using MPIEXEC_EXECUTABLE to execute MPI applications, typically all of the MPIEXEC_EXECUTABLE flags should be used, like this:
in the following example, the command is executed in a process. <executable> should be replaced with the MPI program, and <args> with the arguments to pass to the MPI program. ๐ซก
find_package(MPI)
if(MPI_FOUND)
execute_process(
COMMAND
${MPIEXEC_EXECUTABLE}
${MPIEXEC_NUMPROC_FLAG}
${MPIEXEC_MAX_NUMPROCS}
${MPIEXEC_PREFLAGS}
<executable>
${MPIEXEC_POSTFLAGS}
<args>
)
endif()
๐ฆ FindMsys
Added in version 3.21.
finds MSYS โ the POSIX-compatible environment that runs natively on Microsoft Windows ๐ปโจ
find_package(Msys [...])
Note: this module is primarily intended for use in other Find Modules to help locate programs when using thefind_*()commands, such asfind_program(). in most cases, direct use of those commands is sufficient. use this module only if a specific program is known to be installed via MSYS and is usable from Windows.
โญ Result Variables
this module defines the following variables:
Msys_FOUNDโ Added in version 4.2. Boolean indicating whether MSYS was found.MSYS_INSTALL_PATHโ the path to the MSYS root installation directory ๐
๐ Examples
finding the MSYS installation and using its path in a custom find module โ here's FindFoo.cmake:
find_package(Msys)
find_program(Foo_EXECUTABLE NAMES foo PATHS ${MSYS_INSTALL_PATH}/usr/bin)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo REQUIRED_VARS Foo_EXECUTABLE)
๐ See Also
- the
FindCygwinmodule, to find Cygwin path in a similar way ๐ง
๐ FindODBC
Added in version 3.12.
finds the Open Database Connectivity (ODBC) library, which implements a standard API for accessing database systems ๐๏ธโจ
find_package(ODBC [...])
so like โ ODBC enables applications to communicate with different database management systems (DBMS) using a common set of functions. communication with a specific database is handled through ODBC drivers, which the library loads at runtime. iconique.
on Windows, when building with Visual Studio, this module assumes the ODBC library is provided by the available Windows SDK ๐ช
on Unix-like systems, this module searches for the ODBC library provided by unixODBC or iODBC implementations of the ODBC API. by default, this module looks for the ODBC config program to determine the ODBC library and include directory โ first from unixODBC, then from iODBC. if no config program is found, it searches for the ODBC header and library in standard locations. no cap.
๐ฏ Imported Targets
this module provides the following Imported Targets:
ODBC::ODBCโ target encapsulating the ODBC usage requirements, available if ODBC is found ๐
๐ Result Variables
this module defines the following variables:
ODBC_FOUNDโ Boolean indicating whether ODBC was found.ODBC_INCLUDE_DIRSโ include directories containing headers needed to use ODBC.ODBC_LIBRARIESโ libraries needed to link against to use ODBC.
๐ง Cache Variables
the following cache variables may also be set:
ODBC_INCLUDE_DIRโ the path to the directory containingsql.hand other ODBC headers. may be empty on Windows, where the include directory corresponding to the expected Windows SDK is already available in the compilation environment.ODBC_LIBRARYโ the path to the ODBC library or a library name. on Windows, this may be only a library name, because the library directory corresponding to the expected Windows SDK is already available in the compilation environment.ODBC_CONFIGโ the path to the ODBC config program if found or specified. for example,odbc_configfor unixODBC, oriodbc-configfor iODBC ๐ง
โ ๏ธ Limitations
- on Windows, this module does not search for iODBC.
- on Unix-like systems, there is no built-in mechanism to prefer unixODBC over iODBC, or vice versa. to bypass this limitation, explicitly set the
ODBC_CONFIGvariable to the path of the desired ODBC config program. - this module does not support searching for or selecting a specific ODBC driver. sorry bestie ๐ญ
๐ Examples
๐ง Example: Finding and Using ODBC
finding ODBC and linking it to a project target โ in CMakeLists.txt:
find_package(ODBC)
target_link_libraries(project_target PRIVATE ODBC::ODBC)
๐ฅ Example: Finding a Custom ODBC Installation
the following examples are for Unix-like systems and demonstrate how to set hint and cache variables during the CMake configuration phase to help this module find a custom ODBC implementation (e.g. one not supported by default). we love a DIY moment.
to specify the installation prefix using CMAKE_PREFIX_PATH:
$ cmake -D CMAKE_PREFIX_PATH=/path/to/odbc-installation -B build
or using the dedicated ODBC_ROOT variable:
$ cmake -D ODBC_ROOT=/path/to/odbc-installation -B build
to manually specify the ODBC config program, if available, so that the ODBC installation can be automatically determined based on the config tool:
$ cmake -D ODBC_CONFIG=/path/to/odbc/bin/odbc-config -B build
to manually specify the ODBC library and include directory:
$ cmake \
-D ODBC_LIBRARY=/path/to/odbc/lib/libodbc.so \
-D ODBC_INCLUDE_DIR=/path/to/odbc/include \
-B build
๐ง FindOpenACC
Added in version 3.10.
finds and detects the OpenACC support in a compiler ๐โก
find_package(OpenACC [<version>] [...])
if the compiler supports OpenACC, the flags required to compile with OpenACC support are returned in variables for the different languages. currently, only NVHPC, PGI, GNU and Cray compilers are supported. periodt. ๐
โจ Imported Targets โจ
Ok so this module hands you some imported targets <#imported-targets> and they're honestly so useful:
OpenACC::OpenACC_<lang>โ added in version 3.16. This target bundles up all the usage requirements for using OpenACC from<lang>. Heads up though: it only exists if OpenACC support was actually found. And<lang>is one ofC,CXX, orFortran. That's it, those three, no extras.
๐ Result Variables ๐
Here's what the module sets for you:
OpenACC_FOUNDโ added in version 3.25. A boolean that says hey, we found OpenACC flags for at least ONE language. Just one is enough, bestie.
Then, per language in your project (where <lang> is one of C, CXX, or Fortran), it sets:
OpenACC_<lang>_FOUNDโ boolean, was OpenACC support for<lang>detected or not.OpenACC_<lang>_FLAGSโ the OpenACC compiler flags for<lang>, separated by spaces.OpenACC_<lang>_OPTIONSโ added in version 3.16. Same flags for<lang>but as a proper LIST. Perfect fortarget_compile_optionsortarget_link_options. Chefs kiss.
And it'll also try to give you the OpenACC version variables:
OpenACC_<lang>_SPEC_DATEโ the date of the OpenACC spec your<lang>compiler implements.OpenACC_<lang>_VERSION_MAJORโ major version of OpenACC implemented by the<lang>compiler.OpenACC_<lang>_VERSION_MINORโ minor version, same deal.OpenACC_<lang>_VERSIONโ the whole OpenACC version implemented by the<lang>compiler.
Quick note on the spec date: it's formatted the way the OpenACC standard does it โyyyymmโ whereyyyyandmmare the year and month of the OpenACC specification that<lang>compiler implements. ๐ธ
๐ Input Variables ๐
This module takes this one:
OpenACC_ACCEL_TARGET=<target>โ if you set it, the correct target accelerator flag set for that<target>gets returned in theOpenACC_<lang>_FLAGSvariable. Slay.
๐ Examples ๐
Finding OpenACC support and linking the imported target to a project target โ literally just this:
find_package(OpenACC)
target_link_libraries(example PRIVATE OpenACC::OpenACC_C)
๐ฆ FindOpenAL ๐ฆ
Finds the Open Audio Library (OpenAL):
find_package(OpenAL [...])
So OpenAL is this cross-platform 3D audio API, right? It's built for efficient rendering of multichannel, three-dimensional positional audio. It's the go-to in games and multimedia apps when you want immersive, spatialized sound. Gamer vibes fr fr. ๐ฎ
Important, bestie: if your project uses this module, include the OpenAL header like#include <al.h>, and NOT like#include <AL/al.h>. The second one is not portable, and here's why: Windows/Creative Labs doesn't put OpenAL headers inAL/by default, and macOS does its own thing with<OpenAL/al.h>. So yeah โ#include <al.h>. Periodt.
Imported Targets
OpenAL::OpenALโ added in version 3.25. This target wraps up the OpenAL library usage requirements, and it's only available if the OpenAL library is found. Simple as that.
Result Variables
OpenAL_FOUNDโ added in version 3.3. A boolean saying whether OpenAL was found.
Cache Variables
These cache variables may also get set:
OPENAL_INCLUDE_DIRโ the include directory holding the headers you need to actually use the OpenAL library.OPENAL_LIBRARYโ the path to the OpenAL library itself.
Hints
This module accepts:
OPENALDIRโ an environment variable you can use to set the installation prefix of OpenAL when it lives somewhere non-standard.
Here's the tea on the search order โ OpenAL gets searched like this:
- By default on macOS, the system framework is searched first:
/System/Library/Frameworks, and you can change its priority by setting theCMAKE_FIND_FRAMEWORK<#variable:CMAKE_FIND_FRAMEWORK> variable. - The environment variable
ENV{OPENALDIR}. - System paths.
- User-compiled framework:
~/Library/Frameworks. - Manually compiled framework:
/Library/Frameworks. - Add-on package:
/opt.
Deprecated Variables
These are hanging around for backward compatibility:
OPENAL_FOUNDโ deprecated since version 4.2: useOpenAL_FOUND, which has the same value. Boolean indicating whether OpenAL was found.
Examples
Find the OpenAL library and link it to a project target:
find_package(OpenAL)
target_link_libraries(project_target PRIVATE OpenAL::OpenAL)
๐ฅ FindOpenCL ๐ฅ
Added in version 3.1.
Finds Open Computing Language (OpenCL):
find_package(OpenCL [<version>] [...])
OpenCL is the framework for writing programs that execute across heterogeneous platforms โ think CPUs, GPUs, and other accelerators. Multi-platform main character energy. ๐
Added in version 3.24: detection of OpenCL 3.0. Added in version 3.10: detection of OpenCL 2.1 and 2.2. We stay updated.
Imported Targets
OpenCL::OpenCLโ added in version 3.7. Target encapsulating the OpenCL usage requirements, available if OpenCL has been found. ๐
Result Variables
OpenCL_FOUNDโ boolean, did we find (the requested version of) OpenCL?OpenCL_VERSIONโ added in version 4.2. Highest supported OpenCL version found, in the form<major>.<minor>(e.g.,1.2).OpenCL_VERSION_MAJORโ the major version of the OpenCL implementation.OpenCL_VERSION_MINORโ the minor version of the OpenCL implementation.OpenCL_INCLUDE_DIRSโ include directories needed to use OpenCL.OpenCL_LIBRARIESโ libraries needed to link to OpenCL.
Cache Variables
May also be set:
OpenCL_INCLUDE_DIRโ the OpenCL include directory.OpenCL_LIBRARYโ the path to the OpenCL library.
Deprecated Variables
Backward compatibility corner:
OpenCL_VERSION_STRINGโ deprecated since version 4.2: useOpenCL_VERSION, which has the same value. Highest supported OpenCL version found, in the form<major>.<minor>.
Examples
Finding OpenCL and linking it to a project target:
find_package(OpenCL)
target_link_libraries(project_target PRIVATE OpenCL::OpenCL)
โญ FindOpenGL โญ
Finds OpenGL and the OpenGL Utility Library (GLU), so you can use OpenGL in a CMake project:
find_package(OpenGL [COMPONENTS <components>...] [...])
OpenGL (Open Graphics Library) is a cross-platform API for rendering 2D and 3D graphics. It's everywhere in CAD, games, and visualization software. Literally iconic.
- GL is the core OpenGL library โ the fundamental graphics rendering API.
- GLU (OpenGL Utility Library) is a companion library that gives you utility functions built on top of OpenGL, like tessellation and drawing more complex shapes.
Changed in version 3.2: X11 is no longer added as a dependency on Unix/Linux systems. Added in version 3.10: GLVND (GL Vendor-Neutral Dispatch library) support on Linux โ see the Linux-specific section below for that.
Components
This module supports optional components, which you specify with the find_package() <#command:find_package> command:
find_package(OpenGL [COMPONENTS <components>...])
Supported components are:
EGLโ added in version 3.10. The EGL interface between OpenGL, OpenGL ES and the underlying windowing system.GLXโ added in version 3.10. An extension to X that interfaces OpenGL and OpenGL ES with the X window system.OpenGLโ added in version 3.10. The cross-platform API for 3D graphics.GLES2โ added in version 3.27. A subset of the OpenGL API for embedded systems with limited capabilities.GLES3โ added in version 3.27. A subset of the OpenGL API for embedded systems with more capabilities.
Imported Targets
OpenGL::GLโ added in version 3.8. Target encapsulating the usage requirements of platform-specific OpenGL libraries, available if OpenGL is found.OpenGL::GLUโ added in version 3.8. Target encapsulating the OpenGL Utility Library (GLU) usage requirements, available if GLU is found.
And also, the GLVND-specific library imported targets:
OpenGL::OpenGLโ added in version 3.10. Target encapsulating thelibOpenGLusage requirements, available if the system is GLVND-based and OpenGL is found.OpenGL::GLXโ added in version 3.10. Target encapsulating the usage requirements of the OpenGL Extension to the X Window System (GLX), available if OpenGL and GLX are found.OpenGL::EGLโ added in version 3.10. Target encapsulating the EGL usage requirements, available if OpenGL and EGL are found.OpenGL::GLES2โ added in version 3.27. Target encapsulating the GLES2 usage requirements, available if OpenGL and GLES2 are found.OpenGL::GLES3โ added in version 3.27. Target encapsulating the GLES3 usage requirements, available if OpenGL and GLES3 are found.
Result Variables
OpenGL_FOUNDโ added in version 3.3. Boolean indicating whether OpenGL AND all requested components were found. All of them, no partial credit.OPENGL_XMESA_FOUNDโ boolean indicating whether OpenGL XMESA was found.OPENGL_GLU_FOUNDโ boolean indicating whether GLU was found.OpenGL_OpenGL_FOUNDโ added in version 3.10. Boolean indicating whether the GLVND OpenGL library was found.OpenGL_GLX_FOUNDโ added in version 3.10. Boolean indicating whether GLVND GLX was found.OpenGL_EGL_FOUNDโ added in version 3.10. Boolean indicating whether GLVND EGL was found.OpenGL_GLES2_FOUNDโ added in version 3.27. Boolean indicating whether GLES2 was found.OpenGL_GLES3_FOUNDโ added in version 3.27. Boolean indicating whether GLES3 was found.OPENGL_INCLUDE_DIRSโ added in version 3.29. Paths to the OpenGL include directories.OPENGL_EGL_INCLUDE_DIRSโ added in version 3.10. Path to the EGL include directory.OPENGL_LIBRARIESโ the paths to the OpenGL library, the windowing system libraries, and the GLU libraries, all bundled together ๐ซถ. Heads up tho: on Linux this assumes GLX and is never correct for EGL-based targets. Clients are encouraged to use theOpenGL::*imported targets instead โ like, do that, bestie, it's giving best practice ๐ .
๐ Cache Variables ๐
The following cache variables may also be set:
OPENGL_INCLUDE_DIRโ the path to the OpenGL include directory. But theOPENGL_INCLUDE_DIRSvariable is preferred (it's the cooler older sibling, lowkey).OPENGL_GLU_INCLUDE_DIRโ added in version 3.29. Path to the OpenGL GLU include directory โจ.OPENGL_egl_LIBRARYโ added in version 3.10. Path to the GLVND EGL library.OPENGL_glu_LIBRARYโ path to the GLU library.OPENGL_glx_LIBRARYโ added in version 3.10. Path to the GLVND GLX library.OPENGL_opengl_LIBRARYโ added in version 3.10. Path to the GLVND OpenGL library.OPENGL_gl_LIBRARYโ path to the OpenGL library.OPENGL_gles2_LIBRARYโ added in version 3.27. Path to the OpenGL GLES2 library.OPENGL_gles3_LIBRARYโ added in version 3.27. Path to the OpenGL GLES3 library.
๐ก Hints ๐ก
This module accepts the following variables:
OpenGL_GL_PREFERENCEโ added in version 3.10. This one's supported on Linux systems to specify the preferred way to provide legacy GL interfaces in case multiple choices are available. The value may be one of:GLVNDโ if the GLVND OpenGL and GLX libraries are available, prefer them. This forcesOPENGL_gl_LIBRARYto be empty. Changed in version 3.11: this is the default, unless policyCMP0072is set toOLDand no components are requested (since components correspond to GLVND libraries). โจLEGACYโ prefer to use the legacy libGL library, if available. This makesOPENGL_opengl_LIBRARYandOPENGL_glx_LIBRARYpoint toOPENGL_gl_LIBRARY. ๐ซก
๐ง Linux-specific ๐ง
Some Linux systems utilize GLVND as a new ABI for OpenGL. GLVND separates context libraries from OpenGL itself; OpenGL lives in "libOpenGL", and contexts are defined in "libGLX" or "libEGL". GLVND is currently the only way to get OpenGL 3+ functionality via EGL in a manner portable across vendors. Projects may use GLVND explicitly with target OpenGL::OpenGL and either OpenGL::GLX or OpenGL::EGL.
Projects may use the OpenGL::GL target (or the OPENGL_LIBRARIES variable) to use legacy GL interfaces. Depending on OpenGL_GL_PREFERENCE, these will either use the legacy GL library or the GLVND OpenGL::OpenGL and OpenGL::GLX. So like, for non-EGL-based Linux targets, the OpenGL::GL target is most portable ๐.
The OpenGL_GL_PREFERENCE variable may be set to specify the preferred way to provide legacy GL interfaces in case multiple choices are available.
For EGL targets the client must rely on GLVND support on the user's system. Linking should use the OpenGL::OpenGL and OpenGL::EGL targets. Using GLES* libraries is theoretically possible in place of OpenGL::OpenGL, but this module does not currently support that; contributions welcome ๐ (yes, that's you, go off).
OPENGL_egl_LIBRARY and OPENGL_EGL_INCLUDE_DIRS are defined in the case of GLVND. For non-GLVND Linux and other systems these are left undefined.
๐ macOS-Specific ๐
On macOS this module defaults to using the macOS-native framework version of OpenGL. To use the X11 version of OpenGL on macOS, one can disable searching of frameworks using the CMAKE_FIND_FRAMEWORK variable. For example:
find_package(X11)
if(APPLE AND X11_FOUND)
set(CMAKE_FIND_FRAMEWORK NEVER)
find_package(OpenGL)
unset(CMAKE_FIND_FRAMEWORK)
else()
find_package(OpenGL)
endif()
An end user building this project may need to point CMake at their X11 installation, e.g., with -DOpenGL_ROOT=/opt/X11. ๐
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OPENGL_FOUNDโ Deprecated since version 4.2: useOpenGL_FOUND, which has the same value. (Yes. That is literally what it says. Both names, same value. It's giving "we haveOPENGL_FOUNDat home" ๐ญ.) Boolean indicating whether OpenGL and all requested components were found.
๐ Examples ๐
Finding the OpenGL library and linking it to a project target:
find_package(OpenGL)
target_link_libraries(project_target PRIVATE OpenGL::OpenGL)
๐ See Also ๐
- The
FindGLEWmodule to find OpenGL Extension Wrangler Library (GLEW). - The
FindGLUTmodule to find OpenGL Utility Toolkit (GLUT) library. - The
FindVulkanmodule to find Vulkan graphics API.
๐ฅ FindOpenMP ๐ฅ
Finds Open Multi-Processing (OpenMP) support in a compiler:
find_package(OpenMP [<version>] [COMPONENTS <langs>...] [...])
If the compiler supports OpenMP, the flags required to compile with OpenMP support are returned in variables for the different languages. The variables may be empty if the compiler does not need a special flag to support OpenMP. (Iconic behaviour honestly ๐ .)
Added in version 3.5: Clang support. โจ
๐งฉ Components ๐งฉ
This module supports components that can be specified using the standard syntax:
find_package(OpenMP [COMPONENTS <langs>...])
Each of these components controls the various languages to search OpenMP support for. The following components are exposed:
Cโ added in version 3.10.CXXโ added in version 3.10.Fortranโ added in version 3.10.CUDAโ added in version 3.31. The CUDA language component is supported when using a CUDA compiler that supports OpenMP on the host ๐ซถ.
If no components are specified, module checks for all of them automatically, depending on the enabled languages in the project.
๐ Imported Targets ๐
This module provides the following Imported Targets:
OpenMP::OpenMP_<lang>โ added in version 3.9. Target encapsulating the OpenMP usage requirements for language<lang>. This is the main character, fr fr ๐.
๐ ๏ธ Input Variables ๐ ๏ธ
The following variables may be set to influence this module's behavior:
OpenMP_RUNTIME_MSVCโ added in version 3.30. Specify the OpenMP Runtime when compiling with MSVC. If set to a non-empty value, such asexperimentalorllvm, it will be passed as the value of the-openmp:flag. ๐
๐ Result Variables ๐
This module defines the following variables:
OpenMP_FOUNDโ added in version 3.10. Boolean indicating that OpenMP flags for all requested languages were found. If no components are specified, this variable is set to boolean true if OpenMP settings for all enabled languages were detected.OpenMP_VERSIONโ added in version 4.2. Minimal version of the OpenMP standard detected among the requested languages, or all enabled languages if no components were specified.
This module will set the following variables per language in the project, where <lang> is one of C, CXX, CUDA, or Fortran:
OpenMP_<lang>_FOUNDโ added in version 3.9. Boolean indicating whether the (requested version of) OpenMP support for<lang>was detected.OpenMP_<lang>_VERSIONโ added in version 3.9. OpenMP version implemented by the<lang>compiler, if available.OpenMP_<lang>_VERSION_MAJORโ added in version 3.9. Major version of OpenMP implemented by the<lang>compiler, if available.OpenMP_<lang>_VERSION_MINORโ added in version 3.9. Minor version of OpenMP implemented by the<lang>compiler, if available.OpenMP_<lang>_SPEC_DATEโ added in version 3.7. Date of the OpenMP specification implemented by the<lang>compiler, if available. The specification date is formatted as given in the OpenMP standard:yyyymmwhereyyyyandmmrepresents the year and month of the OpenMP specification implemented by the<lang>compiler.OpenMP_<lang>_FLAGSโ OpenMP compiler flags for<lang>, separated by spaces.OpenMP_<lang>_INCLUDE_DIRSโ added in version 3.16. Directories that must be added to the header search path for<lang>when using OpenMP.
For linking with OpenMP code written in <lang>, the following variables are provided:
OpenMP_<lang>_LIB_NAMESโ added in version 3.9. A semicolon-separated list of OpenMP programs libraries for<lang>.OpenMP_<libname>_LIBRARYโ added in version 3.9. Location of the individual libraries needed for OpenMP support in<lang>. The<libname>names are stored in theOpenMP_<lang>_LIB_NAMESlist.OpenMP_<lang>_LIBRARIESโ added in version 3.9. A list of libraries needed to link with OpenMP code written in<lang>.
Specifically for Fortran, the module sets the following variables:
OpenMP_Fortran_HAVE_OMPLIB_HEADERโ added in version 3.9. Boolean indicating whether OpenMP is accessible through theomp_lib.hFortran header.OpenMP_Fortran_HAVE_OMPLIB_MODULEโ added in version 3.9. Boolean indicating whether OpenMP is accessible through theomp_libFortran module.
For some compilers, it may be necessary to add a header search path to find the relevant OpenMP headers. This location may be language-specific. Where this is needed, the module may attempt to find the location, but it can be provided directly by setting the OpenMP_<lang>_INCLUDE_DIR cache variable. ๐ Note that this variable is an input control to the module. Project code should use the OpenMP_<lang>_INCLUDE_DIRS output variable if it needs to know what include directories are needed, or preferably the OpenMP::OpenMP_<lang> imported target. (Read your inputs vs outputs, bestie, it matters ๐ญ.)
๐ธ Examples ๐ธ
Finding OpenMP support and linking the imported target to a project target using the C language component:
find_package(OpenMP)
target_link_libraries(project_target PRIVATE OpenMP::OpenMP_C)
๐ฆ FindOpenSceneGraph ๐ฆ
Finds OpenSceneGraph (OSG), a 3D graphics application programming interface:
find_package(OpenSceneGraph [<version>] [COMPONENTS <components>...] [...])
Note: OpenSceneGraph development has largely transitioned to its successor project, VulkanSceneGraph, which should be preferred for new code. Refer to the upstream documentation for guidance on using VulkanSceneGraph with CMake. ๐ซถ (Like, new code should go to the successor โ not a drill, just a heads up ๐.)
This module is out here hunting down the OpenSceneGraph core osg library, its dependency OpenThreads, and any extra OpenSceneGraph libraries you asked for โ some of which also go by the name NodeKits, iykyk ๐
When you're working with OpenSceneGraph, the core library headers are intended to be included in C++ project source code like this, in example.cxx:
#include <osg/PositionAttitudeTransform>
Headers for the OpenSceneGraph libraries and NodeKits follow a similar inclusion structure, bestie, like so โ example.cxx:
#include <osgAnimation/Animation>
#include <osgDB/DatabasePager>
#include <osgFX/BumpMapping>
// ...
๐งฉ Components ๐งฉ
The OpenSceneGraph toolkit is literally the core library osg plus a whole squad of additional libraries, and you can optionally name them as components with the find_package() command:
find_package(OpenSceneGraph [COMPONENTS <components>...])
Here's the guest list of supported components โจ
osgโ finds the coreosglibrary (libosg), which you need to use OpenSceneGraph. This component is always automatically implied, no cap.OpenThreadsโ finds the dependentOpenThreadslibrary (libOpenThreads) via theFindOpenThreadsmodule. Also always automatically implied, because OpenSceneGraph genuinely cannot function without it.osgAnimationโ finds theosgAnimationlibrary, which serves up general purpose utility classes for animation.osgDBโ finds theosgDBlibrary, giving you the reading and writing scene graphs support.osgFXโ finds theosgFXNodeKit, the framework for implementing special effects.osgGAโ finds theosgGA(GUI Abstraction) library, which hands you facilities for working with all the varying window systems.osgIntrospectionโ finds theosgIntrospectionlibrary, a reflection framework for accessing and invoking class properties and methods at runtime without modifying the classes.
Note: the osgIntrospection library has been removed from the OpenSceneGraph toolkit as of OpenSceneGraph version 3.0. gone, bestie ๐ญ
osgManipulatorโ finds theosgManipulatorNodeKit, which supports 3D interactive manipulators.osgParticleโ finds theosgParticleNodeKit, which supports particle effects. sparkly โจosgPresentationโ finds theosgPresentationNodeKit, which supports 3D scene graph based presentations.
Note: this NodeKit was added in OpenSceneGraph 3.0.0.
osgProducerโ finds theosgProducerutility library, which provides functionality for window management and event handling.
Note:osgProducerhas been removed from early versions of the OpenSceneGraph toolkit 1.x, and has been superseded by theosgViewerlibrary.
osgQtโ finds theosgQtutility library, which provides various classes to aid the integration of Qt.
Note: as of OpenSceneGraph version 3.6, this library has been moved to its own repository.
osgShadowโ finds theosgShadowNodeKit, which supports a range of shadow techniques. spooky ๐osgSimโ finds theosgSimNodeKit, which adds support for simulation features like navigation lights and OpenFlight-style movement controls.osgTerrainโ finds theosgTerrainNodeKit, which provides geospecifc terrain rendering support.osgTextโ finds theosgTextNodeKit, which provides high quality text support.osgUtilโ finds theosgUtillibrary, which provides general-purpose utilities like update, cull, and draw traversals, plus scene graph tools such as optimization, triangle stripping, and tessellation.osgViewerโ finds theosgViewerlibrary, which provides high level viewer functionality. main character energy ๐osgVolumeโ finds theosgVolumeNodeKit, which provides volume rendering support.osgWidgetโ finds theosgWidgetNodeKit, which supports 2D and 3D GUI widget sets.
If you don't specify any components at all, this module searches for the osg and OpenThreads components by default. easy ๐
๐ Result Variables ๐
This module defines the following variables:
OpenSceneGraph_FOUNDโ Added in version 3.3.
Boolean telling you whether (the requested version of) OpenSceneGraph with all the specified components was found.
OpenSceneGraph_VERSIONโ Added in version 4.2.
The version of OpenSceneGraph that was found.
OPENSCENEGRAPH_INCLUDE_DIRSโ the include directories containing the headers you need to use OpenSceneGraph.OPENSCENEGRAPH_LIBRARIESโ the libraries you need to link against to use OpenSceneGraph.
๐ก Hints ๐ก
This module accepts the following variables:
OpenSceneGraph_DEBUGโ set this variable to boolean true and this module will spit out debugging output.OpenSceneGraph_MARK_AS_ADVANCEDโ set this variable to boolean true and the cache variables of this module get marked as advanced automatically.
To help this module find OpenSceneGraph and its various components when they're installed in a custom location, you can use the CMAKE_PREFIX_PATH variable. And on top of that, these variables are also respected:
<COMPONENT>_DIRโ environment or CMake variable you can set to the root of the OSG common installation, where<COMPONENT>is the uppercase form of a component listed above. For example,OSGVOLUME_DIRto find theosgVolumecomponent.OSG_DIRโ environment or CMake variable you can set to influence detection of the OpenSceneGraph installation root location as a whole.OSGDIRโ environment variable treated the same asOSG_DIR.OSG_ROOTโ environment variable treated the same asOSG_DIR.
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OPENSCENEGRAPH_FOUNDโ Deprecated since version 4.2: useOpenSceneGraph_FOUND, which has the same value.
Boolean indicating whether (the requested version of) OpenSceneGraph with all specified components was found.
OPENSCENEGRAPH_VERSIONโ Deprecated since version 4.2: superseded by theOpenSceneGraph_VERSION.
The version of OpenSceneGraph found.
๐ธ Examples ๐ธ
Finding OpenSceneGraph with the osgDB and osgUtil libraries specified as components, then creating an interface imported target that encapsulates its usage requirements so you can link it to a project target:
find_package(OpenSceneGraph 2.0.0 REQUIRED COMPONENTS osgDB osgUtil)
if(OpenSceneGraph_FOUND AND NOT TARGET OpenSceneGraph::OpenSceneGraph)
add_library(OpenSceneGraph::OpenSceneGraph INTERFACE IMPORTED)
set_target_properties(
OpenSceneGraph::OpenSceneGraph
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OPENSCENEGRAPH_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${OPENSCENEGRAPH_LIBRARIES}"
)
endif()
add_executable(example example.cxx)
target_link_libraries(example PRIVATE OpenSceneGraph::OpenSceneGraph)
๐ See Also ๐
The following OpenSceneGraph-related helper find modules get used internally by this module when it's finding specific OpenSceneGraph components. These modules are not intended to be included or invoked directly by project code during typical use of find_package(OpenSceneGraph). However โ and this is the good part โ they can be useful for advanced scenarios where you need finer control over component detection. Like, for example, to find them explicitly and override or bypass the detection of specific OpenSceneGraph components:
- The
Findosgmodule to find the coreosglibrary. - The
FindosgAnimationmodule to findosgAnimation. - The
FindosgDBmodule to findosgDB. - The
FindosgFXmodule to findosgDB. - The
FindosgGAmodule to findosgGA. - The
FindosgIntrospectionmodule to findosgIntrospection. - The
FindosgManipulatormodule to findosgManipulator. - The
FindosgParticlemodule to findosgParticle. - The
FindosgPresentationmodule to findosgPresentation. - The
FindosgProducermodule to findosgProducer. - The
FindosgQtmodule to findosgQt. - The
FindosgShadowmodule to findosgShadow. - The
FindosgSimmodule to findosgSim. - The
FindosgTerrainmodule to findosgTerrain. - The
FindosgTextmodule to findosgText. - The
FindosgUtilmodule to findosgUtil. - The
FindosgViewermodule to findosgViewer. - The
FindosgVolumemodule to findosgVolume. - The
FindosgWidgetmodule to findosgWidget.
๐ FindOpenSP ๐
Added in version 3.25.
Finds the OpenSP library, fr fr:
find_package(OpenSP [<version>] [...])
OpenSP is an open-source implementation of the SGML (Standard Generalized Markup Language) parser. iconic ๐
๐ฏ Imported Targets ๐ฏ
This module provides the following Imported Targets:
OpenSP::OpenSPโ target encapsulating the OpenSP library usage requirements, available only if OpenSP is found.
๐ Result Variables ๐
This module defines the following variables:
OpenSP_FOUNDโ boolean indicating whether (the requested version of) OpenSP is available.OpenSP_VERSIONโ the version of the found OpenSP.OpenSP_VERSION_MAJORโ the major version of OpenSP.OpenSP_VERSION_MINORโ the minor version of OpenSP.OpenSP_VERSION_PATCHโ the patch version of OpenSP.OpenSP_INCLUDE_DIRSโ the include directories containing headers needed to use the OpenSP library.OpenSP_LIBRARIESโ libraries required to link against to use OpenSP. You can pass these to thetarget_link_libraries()command when you're not using theOpenSP::OpenSPimported target.
๐๏ธ Cache Variables ๐๏ธ
The following cache variables may also be set:
OpenSP_INCLUDE_DIRโ the OpenSP include directory.OpenSP_LIBRARYโ the absolute path of theosplibrary.OpenSP_MULTI_BYTEโ straight-up<green>True</green>ifSP_MULTI_BYTEwas found chillin' in OpenSP'sconfig.hheader file, which is the whole tell that the OpenSP library got compiled with multi-byte character support baked in. ๐ฆ Lowkey important: the consuming target has to define theSP_MULTI_BYTEpreprocessor macro to match this value, otherwise you get character decoding drama. No cap.
๐ Examples
Finding the OpenSP library and linking it to a project target โ iconic, effortless:
find_package(OpenSP)
target_link_libraries(project_target PRIVATE OpenSP::OpenSP)
๐ FindOpenSSL
Finds the installed OpenSSL encryption library and figures out its version. She's the main character of crypto, fr:
find_package(OpenSSL [<version>] [COMPONENTS <components>...] [...])
Added in version 3.20: Support for specifying version range when calling the find_package() command. When a version is requested, it can be specified as a single value like before โ and now a version range can be used too. For the full tea on version range usage and capabilities, go read the find_package() command docs. ๐
Added in version 3.18: Support for OpenSSL 3.0. She's modern, she's upgraded.
๐ธ Components
This module supports the following optional components:
Cryptoโ Added in version 3.12. Ensures that the OpenSSL crypto library is found. Slay.SSLโ Added in version 3.12. Ensures that the OpenSSL ssl library is found.
Components can be optionally specified using the standard syntax:
find_package(OpenSSL [COMPONENTS <components>...])
If no components are requested, the module by default searches for Crypto as a required component and SSL as an optional one. Bestie behaviour honestly.
๐ Imported Targets
This module provides the following Imported Targets:
OpenSSL::Cryptoโ Added in version 3.4. Target encapsulating the OpenSSL crypto library usage requirements, available only if the crypto library is found.OpenSSL::SSLโ Added in version 3.4. Target encapsulating the OpenSSL ssl library usage requirements, available only if the ssl library is found. For convenience, this target also linksOpenSSL::Crypto, since the ssl library depends on the crypto library. She's generous like that. ๐ซถOpenSSL::applinkโ Added in version 3.18. Target encapsulating the OpenSSL application-side interface (openssl/applink.c) usage requirements, available only if OpenSSL is found and its version is at least0.9.8.
This interface provides a glue between the OpenSSL BIO layer and the Windows compiler runtime environment and may need to be compiled into projects when using MSVC. By linking this target, the other OpenSSL imported targets can be linked even if the project uses a different MSVC runtime configuration. Linking this target on platforms other than MSVC has no effect โ literally nothing, she just vibes.
Note: The interface file is added using theINTERFACE_SOURCEStarget property. Due to how interface sources are propagated in CMake, it is recommended to link theOpenSSL::applinktarget asPRIVATEto make sure it's linked only once in the entire dependency graph of any library or executable:cmake target_link_libraries(project_target PRIVATE OpenSSL::applink)Using other scopes for this target specifically can lead to unexpected issues during the build or link process, because both the ISO C and ISO C++ standards place very few requirements on how linking should behave. โ ๏ธ Like, they just didn't make rules for that, so pls be careful.
โญ Result Variables
This module defines the following variables:
OpenSSL_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) OpenSSL library was found.OpenSSL_VERSIONโ Added in version 4.2. The OpenSSL version found. This is set to<major>.<minor>.<revision><patch>(e.g.,0.9.8s).OPENSSL_INCLUDE_DIRโ The OpenSSL include directory.OPENSSL_CRYPTO_LIBRARYโ The OpenSSL crypto library.OPENSSL_CRYPTO_LIBRARIESโ The OpenSSL crypto library and its dependencies.OPENSSL_SSL_LIBRARYโ The OpenSSL ssl library.OPENSSL_SSL_LIBRARIESโ The OpenSSL ssl library and its dependencies.OPENSSL_LIBRARIESโ All OpenSSL libraries and their dependencies.OPENSSL_APPLINK_SOURCEโ The sources in the targetOpenSSL::applinkmentioned above. This variable is only defined if the found OpenSSL version is at least0.9.8and the platform is MSVC.
๐ง Hints
This module accepts the following variables to control the search behavior:
OPENSSL_ROOT_DIRโ Set to the root directory of an OpenSSL installation to search for the OpenSSL libraries in custom locations.OPENSSL_USE_STATIC_LIBSโ Added in version 3.4. Set toTRUEto prefer static OpenSSL libraries over shared ones.OPENSSL_MSVC_STATIC_RTโ Added in version 3.5. Set toTRUEto search for the OpenSSL libraries built with the MSVC static runtime (MT).ENV{PKG_CONFIG_PATH}โ On UNIX-like systems,pkg-configis used to locate OpenSSL. Set thePKG_CONFIG_PATHenvironment variable to specify alternate locations, which is useful on systems with multiple library installations.
๐ Deprecated Variables
The following variables are provided for backward compatibility (they're giving legacy, ngl):
OPENSSL_FOUNDโ Deprecated since version 4.2: UseOpenSSL_FOUND, which has the same value. Boolean indicating whether the (requested version of) OpenSSL library was found.OPENSSL_VERSIONโ Deprecated since version 4.2: Superseded by theOpenSSL_VERSION. The version of OpenSSL found.
๐ Examples
Finding the OpenSSL crypto library and linking it to a project target:
find_package(OpenSSL)
target_link_libraries(project_target PRIVATE OpenSSL::Crypto)
The following example shows how to find the OpenSSL crypto and ssl libraries and link them to a project target. The SSL component is explicitly specified to ensure that the find module reports an error if the ssl library is not found โ so she's not gonna silently ghost you:
find_package(OpenSSL COMPONENTS SSL)
target_link_libraries(project_target PRIVATE OpenSSL::SSL)
๐งต FindOpenThreads
Finds the OpenThreads C++ based threading library:
find_package(OpenThreads [...])
OpenThreads header files are intended to be included as:
example.cxx
#include <OpenThreads/Thread>
โจ Result Variables
This module defines the following variables:
OpenThreads_FOUNDโ Added in version 3.3. Boolean indicating whether the OpenThreads library was found.OPENTHREADS_LIBRARYโ Libraries needed to link against to use OpenThreads. This provides either the release (optimized) or debug library variant, which are found separately depending on the project's Build Configurations.
๐ Cache Variables
The following cache variables may also be set:
OPENTHREADS_INCLUDE_DIRโ The directory containing the header files needed to use OpenThreads.
๐ Hints
This module accepts the following variables:
OPENTHREADS_DIRโ An environment or CMake variable that can be set to help find an OpenThreads library installed in a custom location. It should point to the installation destination that was used when configuring, building, and installing the OpenThreads library:./configure --prefix=$OPENTHREADS_DIR.
This module was originally introduced to support the FindOpenSceneGraph module and its components. To simplify one-step automated configuration and builds when the OpenSceneGraph package is developed and distributed upstream, this module supports additional environment variables to find dependencies in specific locations. This approach is used by the upstream package over specifying -DVAR=value on the command line because it offers better isolation from internal changes to the module and allows more flexibility when specifying individual OSG components independently of the CMAKE_*_PATH variables. Explicit -DVAR=value arguments can still override these settings if needed. Since OpenThreads is an optional standalone dependency of OpenSceneGraph, this module also honors the following variables for convenience:
OSG_DIRโ May be set as an environment or CMake variable. Treated the same asOPENTHREADS_DIR.OSGDIRโ Environment variable treated the same asOPENTHREADS_DIR.
๐ Deprecated Variables
The following variables are provided for backward compatibility:
OPENTHREADS_FOUNDโ Deprecated since version 4.2: UseOpenThreads_FOUND, which has the same value. Boolean indicating whether the OpenThreads library was found.
๐ฆ Examples
Finding the OpenThreads library and creating an interface imported target that encapsulates its usage requirements for linking to a project target โ okay this one's actually so satisfying:
find_package(OpenThreads)
if(OpenThreads_FOUND AND NOT TARGET OpenThreads::OpenThreads)
add_library(OpenThreads::OpenThreads INTERFACE IMPORTED)
set_target_properties(
OpenThreads::OpenThreads
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OPENTHREADS_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OPENTHREADS_LIBRARY}"
)
endif()
target_link_libraries(example PRIVATE OpenThreads::OpenThreads)
๐ธ Findosg
Finds the core OpenSceneGraph osg library (libosg).
Note: In most cases, it's recommended to use theFindOpenSceneGraphmodule instead, which automatically finds the osg core library along with its required dependencies like OpenThreads:cmake find_package(OpenSceneGraph)
This module is used internally by FindOpenSceneGraph to find the osg library. It is not intended to be included directly during typical use of the find_package() command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed, such as explicitly finding the osg library or bypassing automatic component detection:
find_package(osg)
OpenSceneGraph core library headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. ๐
โญ Result Variables
This module defines the following variables:
osg_FOUNDโ Added in version 3.3.
Boolean indicating whether the osg library was found. ๐ (and that wraps the osg_FOUND situation โ now back to the rest of the result variables, bestie โจ)
OSG_LIBRARIESโ the libraries you gotta link against to actually use the osg library ๐ฅOSG_LIBRARYโ a result variable, and it's literally set to the exact same value as theOSG_LIBRARIESvariable. same energy, different name ๐
๐พ Cache Variables
The following cache variables may also be set:
OSG_INCLUDE_DIRโ the include directory holding the headers you need to use the osg library ๐OSG_LIBRARY_DEBUGโ the path to the osg debug library ๐ฆ
๐ธ Hints
This module accepts the following variables:
OSGDIRโ an environment variable you can set to help locate the OpenSceneGraph toolkit (including its osg library) when it's installed in a custom location. It should point to the OpenSceneGraph installation prefix that was used when it got configured, built, and installed:./configure --prefix=$OSGDIRโจ
๐ซถ Deprecated Variables
The following variables are provided for backward compatibility:
OSG_FOUNDโ > Deprecated since version 4.2: useosg_FOUND, which has the same value.
Boolean indicating whether the osg library was found. (it's the same vibe, just a different capitalization era, okay ๐ญ)
๐ Examples
Finding the osg library explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it into a project target:
find_package(osg)
if(osg_FOUND AND NOT TARGET osg::osg)
add_library(osg::osg INTERFACE IMPORTED)
set_target_properties(
osg::osg
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSG_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSG_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osg::osg)
๐ See Also
- The
FindOpenSceneGraphmodule, for finding the OpenSceneGraph toolkit.
๐ง FindosgAnimation
Finds the osgAnimation library from the OpenSceneGraph toolkit. slay ๐
Note: in most cases it's recommended to use theFindOpenSceneGraphmodule instead and listosgAnimationas a component. That automatically handles dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgAnimation)
This module is used internally by FindOpenSceneGraph to find the osgAnimation library. It is not intended to be included directly during typical use of the find_package() command. BUT โ it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgAnimation explicitly or to bypass automatic component detection:
find_package(osgAnimation)
OpenSceneGraph and osgAnimation headers are intended to be included in C++ project source code like this ๐
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgAnimation/Animation>
// ...
When you're working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. no cap ๐ฅ
๐ Result Variables
This module defines the following variables:
osgAnimation_FOUNDโ Added in version 3.3.
Boolean indicating whether the osgAnimation library of the OpenSceneGraph toolkit was found ๐
OSGANIMATION_LIBRARIESโ the libraries needed to link against to useosgAnimation.OSGANIMATION_LIBRARYโ a result variable that is set to the same value as theOSGANIMATION_LIBRARIESvariable. literally twins ๐ซถ
๐พ Cache Variables
The following cache variables may also be set:
OSGANIMATION_INCLUDE_DIRโ the include directory containing headers needed to useosgAnimation.OSGANIMATION_LIBRARY_DEBUGโ the path to theosgAnimationdebug library ๐ฆ
๐ธ Hints
This module accepts the following variables:
OSGDIRโ environment variable you can set to help locate the OpenSceneGraph toolkit, including itsosgAnimationlibrary, when it's installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIRโจ
๐ซถ Deprecated Variables
The following variables are provided for backward compatibility:
OSGANIMATION_FOUNDโ > Deprecated since version 4.2: useosgAnimation_FOUND, which has the same value.
Boolean indicating whether the osgAnimation library of the OpenSceneGraph toolkit was found.
๐ Examples
Finding the osgAnimation library explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target:
find_package(osgAnimation)
if(osgAnimation_FOUND AND NOT TARGET osgAnimation::osgAnimation)
add_library(osgAnimation::osgAnimation INTERFACE IMPORTED)
set_target_properties(
osgAnimation::osgAnimation
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGANIMATION_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGANIMATION_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgAnimation::osgAnimation)
๐ See Also
- The
FindOpenSceneGraphmodule, for finding the OpenSceneGraph toolkit.
๐ FindosgDB
Finds the osgDB library from the OpenSceneGraph toolkit ๐
Note: in most cases it's recommended to use theFindOpenSceneGraphmodule instead and listosgDBas a component. That automatically handles dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgDB)
This module is used internally by FindOpenSceneGraph to find the osgDB library. It is not intended to be included directly during typical use of the find_package() command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed โ for example, to find the osgDB explicitly or to bypass automatic component detection:
find_package(osgDB)
OpenSceneGraph and osgDB headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgDB/DatabasePager>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐
๐ Result Variables
This module defines the following variables:
osgDB_FOUNDโ Added in version 3.3.
Boolean indicating whether the osgDB library of the OpenSceneGraph toolkit was found.
OSGDB_LIBRARIESโ the libraries needed to link against to useosgDB.OSGDB_LIBRARYโ a result variable that is set to the same value as theOSGDB_LIBRARIESvariable ๐
๐พ Cache Variables
The following cache variables may also be set:
OSGDB_INCLUDE_DIRโ the include directory containing headers needed to useosgDB.OSGDB_LIBRARY_DEBUGโ the path to theosgDBdebug library.
๐ธ Hints
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including itsosgDBlibrary, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR๐
๐ซถ Deprecated Variables
The following variables are provided for backward compatibility:
OSGDB_FOUNDโ > Deprecated since version 4.2: useosgDB_FOUND, which has the same value.
Boolean indicating whether the osgDB library of the OpenSceneGraph toolkit was found.
๐ Examples
Finding osgDB explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target:
find_package(osgDB)
if(osgDB_FOUND AND NOT TARGET osgDB::osgDB)
add_library(osgDB::osgDB INTERFACE IMPORTED)
set_target_properties(
osgDB::osgDB
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGDB_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGDB_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgDB::osgDB)
๐ See Also
- The
FindOpenSceneGraphmodule, for finding the OpenSceneGraph toolkit.
๐ FindosgFX
Finds the osgFX NodeKit from the OpenSceneGraph toolkit โจ (a NodeKit, bestie, not just a library โ respect the terminology ๐
)
Note: in most cases it's recommended to use theFindOpenSceneGraphmodule instead and listosgFXas a component. That automatically handles dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgFX)
This module is used internally by FindOpenSceneGraph to find the osgFX NodeKit. It is not intended to be included directly during typical use of the find_package() command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgFX explicitly or bypass automatic component detection:
find_package(osgFX)
OpenSceneGraph and osgFX headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgFX/BumpMapping>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐ฅ
๐ Result Variables
This module defines the following variables:
osgFX_FOUNDโ Added in version 3.3.
Boolean indicating whether the osgFX NodeKit of the OpenSceneGraph toolkit was found ๐
OSGFX_LIBRARIESโ the libraries needed to link against to useosgFX.OSGFX_LIBRARYโ a result variable that is set to the same value as theOSGFX_LIBRARIESvariable ๐ซถ
๐พ Cache Variables
The following cache variables may also be set:
OSGFX_INCLUDE_DIRโ the include directory containing headers needed to useosgFX.OSGFX_LIBRARY_DEBUGโ the path to theosgFXdebug library ๐ฆ
๐ธ Hints
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including itsosgFXNodeKit, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR๐
๐ซถ Deprecated Variables
The following variables are provided for backward compatibility:
OSGFX_FOUNDโ โ ๏ธ deprecated since version 4.2, bestie: useosgFX_FOUNDinstead, it's literally the same value. It's a boolean saying whether the osgFX NodeKit of the OpenSceneGraph toolkit was found. ๐
โจ Examples โจ
Okay so finding osgFX explicitly with this module and then making an interface imported target <#imported-targets> that bundles up all its usage requirements so you can link it to a project target? It's giving organized. ๐
find_package(osgFX)
if(osgFX_FOUND AND NOT TARGET osgFX::osgFX)
add_library(osgFX::osgFX INTERFACE IMPORTED)
set_target_properties(
osgFX::osgFX
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGFX_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGFX_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgFX::osgFX)
๐ธ See Also ๐ธ
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module, which finds the whole OpenSceneGraph toolkit. Go check it out ๐ซถ
๐ FindosgGA ๐
Finds the osgGA library from the OpenSceneGraph toolkit. Slay.
Note: ngl, in most cases you should use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and just listosgGAas a component. It handles the dependencies for you, like OpenThreads and the core osg libraries โ no cap:cmake find_package(OpenSceneGraph COMPONENTS osgGA)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgGA library. It's not meant to be included directly during a typical find_package() <#command:find_package> call, okay? But it IS available as a standalone module for advanced use cases where you need finer control over detection. Like, for example, to find osgGA explicitly or to bypass the automatic component detection:
find_package(osgGA)
OpenSceneGraph and osgGA headers are intended to be included in your C++ project source code like this ๐
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgGA/FlightManipulator>
// ...
When you're working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. Just so you know ๐ซ
โญ Result Variables โญ
This module defines these variables, bestie:
osgGA_FOUNDโ Added in version 3.3. Boolean indicating whether theosgGAlibrary of the OpenSceneGraph toolkit was found. ๐OSGGA_LIBRARIESโ the libraries you need to link against to useosgGA.OSGGA_LIBRARYโ a result variable that's set to the same value as theOSGGA_LIBRARIESvariable. Same energy, different name.
๐ฆ Cache Variables ๐ฆ
These cache variables may also be set:
OSGGA_INCLUDE_DIRโ the include directory containing the headers you need to useosgGA.OSGGA_LIBRARY_DEBUGโ the path to theosgGAdebug library. Debug era ๐
๐ Hints ๐
This module accepts the following variables:
OSGDIRโ an environment variable you can set to help locate the OpenSceneGraph toolkit (including itsosgGAlibrary) when it's installed in a custom location. It should point to the OpenSceneGraph installation prefix that was used when it was configured, built, and installed:./configure --prefix=$OSGDIR. Iconic behavior tbh.
๐ Deprecated Variables ๐
These are provided for backward compatibility, no hate:
OSGGA_FOUNDโ โ ๏ธ deprecated since version 4.2: useosgGA_FOUND, which has the same value. Boolean indicating whether theosgGAlibrary of the OpenSceneGraph toolkit was found.
โจ Examples โจ
Finding osgGA explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target โ obsessed with this pattern:
find_package(osgGA)
if(osgGA_FOUND AND NOT TARGET osgGA::osgGA)
add_library(osgGA::osgGA INTERFACE IMPORTED)
set_target_properties(
osgGA::osgGA
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGGA_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGGA_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgGA::osgGA)
๐ธ See Also ๐ธ
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find the OpenSceneGraph toolkit. ๐ซถ
๐ FindosgIntrospection ๐
Finds the osgIntrospection library from the OpenSceneGraph toolkit.
Note: heads up โ the osgIntrospection library was removed from the OpenSceneGraph toolkit as of OpenSceneGraph version 3.0. ๐ญ Gone but not forgotten.
Note: in most cases, it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and listosgIntrospectionas a component. That automatically handles dependencies like OpenThreads and the core osg libraries:cmake find_package(OpenSceneGraph COMPONENTS osgIntrospection)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgIntrospection library. It's not intended to be included directly during typical use of the find_package() <#command:find_package> command. But it is available as a standalone module for advanced use cases where you need finer control over detection. For example, to find osgIntrospection explicitly or bypass automatic component detection:
find_package(osgIntrospection)
OpenSceneGraph and osgIntrospection headers are intended to be included in C++ project source code like this:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgIntrospection/Reflection>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. Periodt. ๐
โญ Result Variables โญ
This module defines the following variables:
osgIntrospection_FOUNDโ Added in version 3.3. Boolean indicating whether theosgIntrospectionlibrary of the OpenSceneGraph toolkit was found. โจOSGINTROSPECTION_LIBRARIESโ the libraries needed to link against to useosgIntrospection.OSGINTROSPECTION_LIBRARYโ a result variable set to the same value as theOSGINTROSPECTION_LIBRARIESvariable.
๐ฆ Cache Variables ๐ฆ
The following cache variables may also be set:
OSGINTROSPECTION_INCLUDE_DIRโ the include directory containing headers needed to useosgIntrospection.OSGINTROSPECTION_LIBRARY_DEBUGโ the path to theosgIntrospectiondebug library. ๐
๐ Hints ๐
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including itsosgIntrospectionlibrary, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR. ๐
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGINTROSPECTION_FOUNDโ โ ๏ธ deprecated since version 4.2: useosgIntrospection_FOUND, which has the same value. Boolean indicating whether theosgIntrospectionlibrary of the OpenSceneGraph toolkit was found.
โจ Examples โจ
Finding osgIntrospection explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target:
find_package(osgIntrospection)
if(osgIntrospection_FOUND AND NOT TARGET osgIntrospection::osgIntrospection)
add_library(osgIntrospection::osgIntrospection INTERFACE IMPORTED)
set_target_properties(
osgIntrospection::osgIntrospection
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGINTROSPECTION_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGINTROSPECTION_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgIntrospection::osgIntrospection)
๐ธ See Also ๐ธ
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find the OpenSceneGraph toolkit. ๐ซถ
๐ FindosgManipulator ๐
Finds the osgManipulator NodeKit from the OpenSceneGraph toolkit. Main character NodeKit honestly.
Note: in most cases, it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and listosgManipulatoras a component. It'll automatically handle dependencies such as the OpenThreads and core osg libraries:cmake find_package(OpenSceneGraph COMPONENTS osgManipulator)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgManipulator NodeKit. It's not intended to be included directly during typical use of the find_package() <#command:find_package> command. However โ and this is the fun part โ it's available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find osgManipulator explicitly or bypass automatic component detection:
find_package(osgManipulator)
OpenSceneGraph and osgManipulator headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgManipulator/TrackballDragger>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. Just a lil heads up ๐ธ
โญ Result Variables โญ
This module defines the following variables:
osgManipulator_FOUNDโ Added in version 3.3. Boolean indicating whether theosgManipulatorNodeKit of the OpenSceneGraph toolkit was found. ๐ฅOSGMANIPULATOR_LIBRARIESโ the libraries needed to link against to useosgManipulator.OSGMANIPULATOR_LIBRARYโ a result variable that is set to the same value as theOSGMANIPULATOR_LIBRARIESvariable.
๐ฆ Cache Variables ๐ฆ
The following cache variables may also be set:
OSGMANIPULATOR_INCLUDE_DIRโ the include directory containing headers needed to useosgManipulator.OSGMANIPULATOR_LIBRARY_DEBUGโ the path to theosgManipulatordebug library. ๐
๐ Hints ๐
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including itsosgManipulatorNodeKit, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR. ๐ซถ
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGMANIPULATOR_FOUNDโ โ ๏ธ deprecated since version 4.2: useosgManipulator_FOUND, which has the same value. Boolean indicating whether theosgManipulatorNodeKit of the OpenSceneGraph toolkit was found.
โจ Examples โจ
Finding osgManipulator explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target:
find_package(osgManipulator)
...and the example keeps going, bestie โ here's the rest of that code block from last time ๐
if(osgManipulator_FOUND AND NOT TARGET osgManipulator::osgManipulator)
add_library(osgManipulator::osgManipulator INTERFACE IMPORTED)
set_target_properties(
osgManipulator::osgManipulator
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGMANIPULATOR_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGMANIPULATOR_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgManipulator::osgManipulator)
See Also ๐
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
FindosgParticle ๐
Finds the osgParticle NodeKit from the OpenSceneGraph toolkit. Slay.
Note: ngl, in most cases it's way better to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and just list osgParticle as a component. That way all the dependency stuff โ OpenThreads, the core osg libraries, all of it โ gets handled for you automatically:
find_package(OpenSceneGraph COMPONENTS osgParticle)
So here's the tea: this module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgParticle NodeKit. It is not intended to be included directly during typical use of the find_package() <#command:find_package> command. But it is available as a standalone module for the advanced use cases where you need finer control over detection. Like, say, when you want to find osgParticle explicitly or bypass the automatic component detection entirely:
find_package(osgParticle)
OpenSceneGraph and osgParticle headers are meant to be included in C++ project source code like this ๐ซถ
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgParticle/FireEffect>
// ...
And heads up: when you're working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. Don't forget 'em ๐ญ
Result Variables โจ
This module defines the following variables:
osgParticle_FOUNDโ Added in version 3.3. A boolean indicating whether theosgParticleNodeKit of the OpenSceneGraph toolkit was found.OSGPARTICLE_LIBRARIESโ the libraries you need to link against to use theosgParticleNodeKit.OSGPARTICLE_LIBRARYโ a result variable that's set to the same value as theOSGPARTICLE_LIBRARIESvariable.
Cache Variables ๐
The following cache variables may also be set:
OSGPARTICLE_INCLUDE_DIRโ the include directory containing the headers you need to use theosgParticleNodeKit.OSGPARTICLE_LIBRARY_DEBUGโ the path to theosgParticledebug library.
Hints ๐ฟ
This module accepts the following variables:
OSGDIRโ an environment variable you can set to help locate the OpenSceneGraph toolkit (including itsosgParticleNodeKit) when it's installed in a custom location. It should point to the OpenSceneGraph installation prefix that was used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGPARTICLE_FOUNDโ Deprecated since version 4.2: useosgParticle_FOUND, which has the same value. A boolean indicating whether theosgParticleNodeKit of the OpenSceneGraph toolkit was found.
Examples ๐ฅ
Finding osgParticle explicitly with this module, and then creating an interface imported target <#imported-targets> that encapsulates all its usage requirements so you can link it to a project target:
find_package(osgParticle)
if(osgParticle_FOUND AND NOT TARGET osgParticle::osgParticle)
add_library(osgParticle::osgParticle INTERFACE IMPORTED)
set_target_properties(
osgParticle::osgParticle
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGPARTICLE_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGPARTICLE_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgParticle::osgParticle)
See Also ๐
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
FindosgPresentation ๐ฆ
Finds the osgPresentation NodeKit from the OpenSceneGraph toolkit โ and yes, it's available since OpenSceneGraph version 3.0.0. Periodt.
Note: in most cases it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and list osgPresentation as a component. That automatically handles dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgPresentation)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgPresentation NodeKit. It is not intended to be included directly during typical use of the find_package() <#command:find_package> command. However โ plot twist โ it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find osgPresentation explicitly or to bypass automatic component detection:
find_package(osgPresentation)
OpenSceneGraph and osgPresentation headers are intended to be included in C++ project source code like this:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgPresentation/SlideEventHandler>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐
Result Variables โจ
This module defines the following variables:
osgPresentation_FOUNDโ Added in version 3.3. Boolean indicating whether theosgPresentationNodeKit of the OpenSceneGraph toolkit was found.OSGPRESENTATION_LIBRARIESโ the libraries needed to link against to useosgPresentation.OSGPRESENTATION_LIBRARYโ a result variable that is set to the same value as theOSGPRESENTATION_LIBRARIESvariable.
Cache Variables ๐
The following cache variables may also be set:
OSGPRESENTATION_INCLUDE_DIRโ the include directory containing headers needed to useosgPresentation.OSGPRESENTATION_LIBRARY_DEBUGโ the path to theosgPresentationdebug library.
Hints ๐ฟ
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit (including itsosgPresentationNodeKit) when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGPRESENTATION_FOUNDโ Deprecated since version 4.2: useosgPresentation_FOUND, which has the same value. Boolean indicating whether theosgPresentationNodeKit of the OpenSceneGraph toolkit was found.
Examples ๐ฅ
Finding osgPresentation explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target:
find_package(osgPresentation)
if(osgPresentation_FOUND AND NOT TARGET osgPresentation::osgPresentation)
add_library(osgPresentation::osgPresentation INTERFACE IMPORTED)
set_target_properties(
osgPresentation::osgPresentation
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGPRESENTATION_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGPRESENTATION_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgPresentation::osgPresentation)
See Also ๐
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
FindosgProducer ๐
Finds the osgProducer utility library from the OpenSceneGraph toolkit. It's giving vintage, bestie.
Note: okay so this is a whole lore drop โ theosgProducerlibrary has been removed from the OpenSceneGraph toolkit in early OpenSceneGraph versions (pre 1.0 release) and replaced withosgViewer. Its development shifted at time to a standalone project and repository called Producer, which you can find with the FindProducer <#module:FindProducer> module. Rip to a real one ๐ฏ๏ธ
Note: in most cases, it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and list osgProducer as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgProducer)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgProducer library. It is not intended to be included directly during typical use of the find_package() <#command:find_package> command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find osgProducer explicitly or bypass automatic component detection:
find_package(osgProducer)
OpenSceneGraph and osgProducer headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgProducer/OsgSceneHandler>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. Fr fr.
Result Variables โจ
This module defines the following variables:
osgProducer_FOUNDโ Added in version 3.3. Boolean indicating whether theosgProducerlibrary of the OpenSceneGraph toolkit was found.OSGPRODUCER_LIBRARIESโ the libraries needed to link against to useosgProducer.OSGPRODUCER_LIBRARYโ a result variable that is set to the same value as theOSGPRODUCER_LIBRARIESvariable.
Cache Variables ๐
The following cache variables may also be set:
OSGPRODUCER_INCLUDE_DIRโ the include directory containing headers needed to useosgProducer.OSGPRODUCER_LIBRARY_DEBUGโ the path to theosgProducerdebug library.
Hints ๐ฟ
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit (including itsosgProducerlibrary) when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGPRODUCER_FOUNDโ Deprecated since version 4.2: useosgProducer_FOUND, which has the same value. Boolean indicating whether theosgProducerlibrary of the OpenSceneGraph toolkit was found.
Examples ๐ฅ
Finding osgProducer explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target:
find_package(osgProducer)
if(osgProducer_FOUND AND NOT TARGET osgProducer::osgProducer)
add_library(osgProducer::osgProducer INTERFACE IMPORTED)
set_target_properties(
osgProducer::osgProducer
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGPRODUCER_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGPRODUCER_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgProducer::osgProducer)
๐ See Also
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
- The FindProducer <#module:FindProducer> module, which finds the standalone Producer library that evolved from the legacy osgProducer.
๐ FindosgQt ๐
Bestie, this one finds the osgQt utility library from the OpenSceneGraph toolkit ๐
Note: lowkey in most cases you should NOT use this directly โ it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and list osgQt as a component. That way it automatically handles dependencies such as the OpenThreads and core osg libraries, which is the whole vibe:
find_package(OpenSceneGraph COMPONENTS osgQt)
So here's the tea ๐ต โ this module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgQt library. It is not intended to be included directly during typical use of the find_package() <#command:find_package> command. BUT! It's still available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgQt explicitly or bypass automatic component detection:
find_package(osgQt)
OpenSceneGraph and osgQt headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgQt/GraphicsWindowQt>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐ (just so you're not surprised later, fr fr).
โจ Result Variables
This module defines the following variables:
osgQt_FOUNDโ Added in version 3.3. A Boolean indicating whether the osgQt library of the OpenSceneGraph toolkit was found ๐ฆOSGQT_LIBRARIESโ The libraries needed to link against to use osgQt.OSGQT_LIBRARYโ A result variable that is set to the same value as theOSGQT_LIBRARIESvariable.
๐ Cache Variables
The following cache variables may also be set:
OSGQT_INCLUDE_DIRโ The include directory containing headers needed to use osgQt.OSGQT_LIBRARY_DEBUGโ The path to the osgQt debug library.
๐ธ Hints
This module accepts the following variables:
OSGDIRโ Environment variable that can be set to help locate the OpenSceneGraph toolkit, including its osgQt library, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
๐ Deprecated Variables
The following variables are provided for backward compatibility:
OSGQT_FOUNDโ Deprecated since version 4.2: useosgQt_FOUND, which has the same value. A Boolean indicating whether the osgQt library of the OpenSceneGraph toolkit was found.
Warning: it's giving legacy ๐ญ โOSGQT_FOUNDis deprecated since version 4.2, so please useosgQt_FOUNDinstead. Same value, cuter casing.
๐ฅ Examples
Finding osgQt explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target โ iconic behavior, honestly:
find_package(osgQt)
if(osgQt_FOUND AND NOT TARGET osgQt::osgQt)
add_library(osgQt::osgQt INTERFACE IMPORTED)
set_target_properties(
osgQt::osgQt
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGQT_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGQT_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgQt::osgQt)
๐ See Also
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
๐ฆ FindosgShadow ๐ฆ
Finds the osgShadow NodeKit from the OpenSceneGraph toolkit โจ
Note: in most cases, it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and list osgShadow as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgShadow)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgShadow NodeKit. It is not intended to be included directly during typical use of the find_package() <#command:find_package> command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgShadow explicitly or bypass automatic component detection:
find_package(osgShadow)
OpenSceneGraph and osgShadow headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgShadow/ShadowTexture>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐
โจ Result Variables
This module defines the following variables:
osgShadow_FOUNDโ Added in version 3.3. Boolean indicating whether the osgShadow NodeKit of the OpenSceneGraph toolkit was found.OSGSHADOW_LIBRARIESโ The libraries needed to link against to use osgShadow.OSGSHADOW_LIBRARYโ A result variable that is set to the same value as theOSGSHADOW_LIBRARIESvariable.
๐ Cache Variables
The following cache variables may also be set:
OSGSHADOW_INCLUDE_DIRโ The include directory containing headers needed to use osgShadow.OSGSHADOW_LIBRARY_DEBUGโ The path to the osgShadow debug library.
๐ธ Hints
This module accepts the following variables:
OSGDIRโ Environment variable that can be set to help locate the OpenSceneGraph toolkit, including its osgShadow NodeKit, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
๐ Deprecated Variables
The following variables are provided for backward compatibility:
OSGSHADOW_FOUNDโ Deprecated since version 4.2: useosgShadow_FOUND, which has the same value. Boolean indicating whether the osgShadow NodeKit of the OpenSceneGraph toolkit was found.
This one is also a legacy era relic ๐ญ โOSGSHADOW_FOUNDis deprecated since version 4.2, so swap inosgShadow_FOUND. Same value, no drama.
๐ฅ Examples
Finding osgShadow explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target:
find_package(osgShadow)
if(osgShadow_FOUND AND NOT TARGET osgShadow::osgShadow)
add_library(osgShadow::osgShadow INTERFACE IMPORTED)
set_target_properties(
osgShadow::osgShadow
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGSHADOW_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGSHADOW_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgShadow::osgShadow)
๐ See Also
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
๐ FindosgSim ๐
Finds the osgSim NodeKit from the OpenSceneGraph toolkit ๐
Note: in most cases, it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and list osgSim as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgSim)
This module is used internally by FindOpenSceneGraph <#module:FindOpenSceneGraph> to find the osgSim NodeKit. It is not intended to be included directly during typical use of the find_package() <#command:find_package> command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgSim explicitly or bypass automatic component detection:
find_package(osgSim)
OpenSceneGraph and osgSim headers are intended to be included in C++ project source code as:
example.cxx
#include <osg/PositionAttitudeTransform>
#include <osgSim/ImpostorSprite>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐ซถ
โจ Result Variables
This module defines the following variables:
osgSim_FOUNDโ Added in version 3.3. Boolean indicating whether the osgSim NodeKit of the OpenSceneGraph toolkit was found.OSGSIM_LIBRARIESโ The libraries needed to link against to use osgSim.OSGSIM_LIBRARYโ A result variable that is set to the same value as theOSGSIM_LIBRARIESvariable.
๐ Cache Variables
The following cache variables may also be set:
OSGSIM_INCLUDE_DIRโ The include directory containing headers needed to use osgSim.OSGSIM_LIBRARY_DEBUGโ The path to the osgSim debug library.
๐ธ Hints
This module accepts the following variables:
OSGDIRโ Environment variable that can be set to help locate the OpenSceneGraph toolkit, including its osgSim NodeKit, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
๐ Deprecated Variables
The following variables are provided for backward compatibility:
OSGSIM_FOUNDโ Deprecated since version 4.2: useosgSim_FOUND, which has the same value. Boolean indicating whether the osgSim NodeKit of the OpenSceneGraph toolkit was found.
Not me having to say it again ๐ญ โOSGSIM_FOUNDis deprecated since version 4.2, bestie. UseosgSim_FOUND, which has the same value.
๐ฅ Examples
Finding osgSim explicitly with this module and creating an interface imported target <#imported-targets> that encapsulates its usage requirements for linking it to a project target:
find_package(osgSim)
if(osgSim_FOUND AND NOT TARGET osgSim::osgSim)
add_library(osgSim::osgSim INTERFACE IMPORTED)
set_target_properties(
osgSim::osgSim
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGSIM_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGSIM_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgSim::osgSim)
๐ See Also
- The FindOpenSceneGraph <#module:FindOpenSceneGraph> module to find OpenSceneGraph toolkit.
๐ง FindosgTerrain ๐ง
Finds the osgTerrain NodeKit from the OpenSceneGraph toolkit โญ
Note: in most cases, it's recommended to use the FindOpenSceneGraph <#module:FindOpenSceneGraph> module instead and list osgTerrain as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgTerrain)
...so yeah, that's the whole "this is a standalone module for advanced use cases" thing. Continuing:
find_package(osgTerrain)
The OpenSceneGraph and osgTerrain headers are literally meant to be #included in your C++ source like this, bestie โ file example.cxx:
#include <osg/PositionAttitudeTransform>
#include <osgTerrain/Terrain>
// ...
And heads up ๐ธ โ when you're working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required. Not optional, not a vibe, just facts.
๐ Result Variables ๐
This module defines the following variables:
osgTerrain_FOUNDโ added in version 3.3 โจ Boolean indicating whether the osgTerrain NodeKit of the OpenSceneGraph toolkit was found.OSGTERRAIN_LIBRARIESโ the libraries needed to link against to use osgTerrain.OSGTERRAIN_LIBRARYโ a result variable that is set to the same value as theOSGTERRAIN_LIBRARIESvariable.
๐ง Cache Variables ๐ง
The following cache variables may also be set:
OSGTERRAIN_INCLUDE_DIRโ the include directory containing headers needed to use osgTerrain.OSGTERRAIN_LIBRARY_DEBUGโ the path to the osgTerrain debug library.
๐ฆ Hints ๐ฆ
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including its osgTerrain NodeKit, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGTERRAIN_FOUNDโ deprecated since version 4.2: useosgTerrain_FOUND, which has the same value. Boolean indicating whether the osgTerrain NodeKit of the OpenSceneGraph toolkit was found.
๐ Examples ๐
Finding osgTerrain explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target โ iconic, honestly:
find_package(osgTerrain)
if(osgTerrain_FOUND AND NOT TARGET osgTerrain::osgTerrain)
add_library(osgTerrain::osgTerrain INTERFACE IMPORTED)
set_target_properties(
osgTerrain::osgTerrain
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGTERRAIN_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGTERRAIN_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgTerrain::osgTerrain)
๐ See Also ๐
- The
FindOpenSceneGraphmodule to find OpenSceneGraph toolkit.
๐ฆ FindosgText ๐ฆ
Finds the osgText NodeKit from the OpenSceneGraph toolkit.
๐
Note: in most cases, it's recommended to use the FindOpenSceneGraph module instead and list osgText as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgText)
This module is used internally by FindOpenSceneGraph to find the osgText NodeKit. It is not intended to be included directly during typical use of the find_package() command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. Like, for example, to find the osgText explicitly or bypass automatic component detection:
find_package(osgText)
The OpenSceneGraph and osgText headers are intended to be included in C++ project source code as โ file example.cxx:
#include <osg/PositionAttitudeTransform>
#include <osgText/Text>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required.
๐ Result Variables ๐
This module defines the following variables:
osgText_FOUNDโ added in version 3.3 โจ Boolean indicating whether the osgText NodeKit of the OpenSceneGraph toolkit was found.OSGTEXT_LIBRARIESโ the libraries needed to link against to use osgText.OSGTEXT_LIBRARYโ a result variable that is set to the same value as theOSGTEXT_LIBRARIESvariable.
๐ง Cache Variables ๐ง
The following cache variables may also be set:
OSGTEXT_INCLUDE_DIRโ the include directory containing headers needed to use osgText.OSGTEXT_LIBRARY_DEBUGโ the path to the osgText debug library.
๐ฆ Hints ๐ฆ
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including its osgText NodeKit, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGTEXT_FOUNDโ deprecated since version 4.2: useosgText_FOUND, which has the same value. Boolean indicating whether the osgText NodeKit of the OpenSceneGraph toolkit was found.
๐ Examples ๐
Finding osgText explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target โ slay:
find_package(osgText)
if(osgText_FOUND AND NOT TARGET osgText::osgText)
add_library(osgText::osgText INTERFACE IMPORTED)
set_target_properties(
osgText::osgText
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGTEXT_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGTEXT_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgText::osgText)
๐ See Also ๐
- The
FindOpenSceneGraphmodule to find OpenSceneGraph toolkit.
๐ซถ FindosgUtil ๐ซถ
Finds the osgUtil library from the OpenSceneGraph toolkit.
๐
Note: in most cases, it's recommended to use the FindOpenSceneGraph module instead and list osgUtil as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgUtil)
This module is used internally by FindOpenSceneGraph to find the osgUtil library. It is not intended to be included directly during typical use of the find_package() command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgUtil explicitly or bypass automatic component detection:
find_package(osgUtil)
The OpenSceneGraph and osgUtil headers are intended to be included in C++ project source code as โ file example.cxx:
#include <osg/PositionAttitudeTransform>
#include <osgUtil/SceneView>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required.
๐ Result Variables ๐
This module defines the following variables:
osgUtil_FOUNDโ added in version 3.3 โจ Boolean indicating whether the osgUtil library of the OpenSceneGraph toolkit was found.OSGUTIL_LIBRARIESโ the libraries needed to link against to use osgUtil.OSGUTIL_LIBRARYโ a result variable that is set to the same value as theOSGUTIL_LIBRARIESvariable.
๐ง Cache Variables ๐ง
The following cache variables may also be set:
OSGUTIL_INCLUDE_DIRโ the include directory containing headers needed to use osgUtil.OSGUTIL_LIBRARY_DEBUGโ the path to the osgUtil debug library.
๐ฆ Hints ๐ฆ
This module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including its osgUtil library, when installed in a custom location. It should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:./configure --prefix=$OSGDIR.
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
OSGUTIL_FOUNDโ deprecated since version 4.2: useosgUtil_FOUND, which has the same value. Boolean indicating whether the osgUtil library of the OpenSceneGraph toolkit was found.
๐ Examples ๐
Finding osgUtil explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target โ no cap, this is the move:
find_package(osgUtil)
if(osgUtil_FOUND AND NOT TARGET osgUtil::osgUtil)
add_library(osgUtil::osgUtil INTERFACE IMPORTED)
set_target_properties(
osgUtil::osgUtil
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGUTIL_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGUTIL_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgUtil::osgUtil)
๐ See Also ๐
- The
FindOpenSceneGraphmodule to find OpenSceneGraph toolkit.
โญ FindosgViewer โญ
Finds the osgViewer library from the OpenSceneGraph toolkit.
๐
Note: in most cases, it's recommended to use the FindOpenSceneGraph module instead and list osgViewer as a component. This will automatically handle dependencies such as the OpenThreads and core osg libraries:
find_package(OpenSceneGraph COMPONENTS osgViewer)
This module is used internally by FindOpenSceneGraph to find the osgViewer library. It is not intended to be included directly during typical use of the find_package() command. However, it is available as a standalone module for advanced use cases where finer control over detection is needed. For example, to find the osgViewer explicitly or bypass automatic component detection:
find_package(osgViewer)
The OpenSceneGraph and osgViewer headers are intended to be included in C++ project source code as โ file example.cxx:
#include <osg/PositionAttitudeTransform>
#include <osgViewer/Viewer>
// ...
When working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required.
๐ Result Variables ๐
This module defines the following variables:
osgViewer_FOUNDโ added in version 3.3 โจ boolean bestie, tells you if theosgViewerlibrary from the OpenSceneGraph toolkit was actually found. yep or nope, that's it ๐OSGVIEWER_LIBRARIESโ the libraries you gotta link against to useosgViewer. no cap ๐ซถOSGVIEWER_LIBRARYโ a result variable that's set to the exact same value as theOSGVIEWER_LIBRARIESvariable. literally twins ๐ฏ
๐ Cache Variables ๐
the following cache variables may also be set, bestie:
OSGVIEWER_INCLUDE_DIRโ the include directory holding the headers you need to useosgViewer๐OSGVIEWER_LIBRARY_DEBUGโ the path to theosgViewerdebug library ๐
๐ธ Hints ๐ธ
this module accepts the following variables:
OSGDIRโ an environment variable you can set to help locate the OpenSceneGraph toolkit (including itsosgViewerlibrary) when it's installed in a custom location ๐ซ it should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:. /configure --prefix=$OSGDIR. ok the exact thing is:
./configure --prefix=$OSGDIR
๐ Deprecated Variables ๐
the following variables are provided for backward compatibility, iykyk:
OSGVIEWER_FOUNDโ deprecated since version 4.2: useosgViewer_FOUND, which has the same value.
boolean indicating whether the osgViewer library of the OpenSceneGraph toolkit was found. (yes it's literally the same thing, that's the whole point of the rename ๐)
๐ฅ Examples ๐ฅ
finding osgViewer explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target โ main character energy fr:
find_package(osgViewer)
if(osgViewer_FOUND AND NOT TARGET osgViewer::osgViewer)
add_library(osgViewer::osgViewer INTERFACE IMPORTED)
set_target_properties(
osgViewer::osgViewer
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGVIEWER_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGVIEWER_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgViewer::osgViewer)
โญ See Also โญ
- the
FindOpenSceneGraphmodule to find the OpenSceneGraph toolkit ๐
๐ฆ FindosgVolume ๐ฆ
finds the osgVolume NodeKit from the OpenSceneGraph toolkit. slay ๐
Note: in most cases it's recommended to use theFindOpenSceneGraphmodule instead and listosgVolumeas a component. this will automatically handle dependencies such as theOpenThreadsand coreosglibraries:
find_package(OpenSceneGraph COMPONENTS osgVolume)
this module is used internally by FindOpenSceneGraph to find the osgVolume NodeKit. it is not intended to be included directly during typical use of the find_package() command ๐ซฃ however, it is available as a standalone module for advanced use cases where finer control over detection is needed. for example, to find the osgVolume explicitly or bypass automatic component detection:
find_package(osgVolume)
OpenSceneGraph and osgVolume headers are intended to be included in C++ project source code as โ in example.cxx:
#include <osg/PositionAttitudeTransform>
#include <osgVolume/Volume>
// ...
when working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐
๐ฆ Result Variables ๐ฆ
this module defines the following variables:
osgVolume_FOUNDโ added in version 3.3. โจ boolean indicating whether theosgVolumeNodeKit of the OpenSceneGraph toolkit was found.OSGVOLUME_LIBRARIESโ the libraries needed to link against to useosgVolume.OSGVOLUME_LIBRARYโ a result variable that is set to the same value as theOSGVOLUME_LIBRARIESvariable. matching, as always ๐
๐ Cache Variables ๐
the following cache variables may also be set:
OSGVOLUME_INCLUDE_DIRโ the include directory containing headers needed to useosgVolume.OSGVOLUME_LIBRARY_DEBUGโ the path to theosgVolumedebug library ๐
๐ธ Hints ๐ธ
this module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including itsosgVolumeNodeKit, when installed in a custom location. it should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:
./configure --prefix=$OSGDIR
๐ Deprecated Variables ๐
the following variables are provided for backward compatibility:
OSGVOLUME_FOUNDโ deprecated since version 4.2: useosgVolume_FOUND, which has the same value.
boolean indicating whether the osgVolume NodeKit of the OpenSceneGraph toolkit was found. same value, new name, iconic โจ
๐ฅ Examples ๐ฅ
finding osgVolume explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target:
find_package(osgVolume)
if(osgVolume_FOUND AND NOT TARGET osgVolume::osgVolume)
add_library(osgVolume::osgVolume INTERFACE IMPORTED)
set_target_properties(
osgVolume::osgVolume
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGVOLUME_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGVOLUME_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgVolume::osgVolume)
โญ See Also โญ
- the
FindOpenSceneGraphmodule to find the OpenSceneGraph toolkit ๐ซถ
๐ FindosgWidget ๐
finds the osgWidget NodeKit from the OpenSceneGraph toolkit ๐
Note: in most cases, it's recommended to use theFindOpenSceneGraphmodule instead and listosgWidgetas a component. this will automatically handle dependencies such as theOpenThreadsand coreosglibraries:
find_package(OpenSceneGraph COMPONENTS osgWidget)
this module is used internally by FindOpenSceneGraph to find the osgWidget NodeKit. it is not intended to be included directly during typical use of the find_package() command ๐ however, it is available as a standalone module for advanced use cases where finer control over detection is needed. for example, to find the osgWidget explicitly or bypass automatic component detection:
find_package(osgWidget)
OpenSceneGraph and osgWidget headers are intended to be included in C++ project source code as โ in example.cxx:
#include <osg/PositionAttitudeTransform>
#include <osgWidget/Widget>
// ...
when working with the OpenSceneGraph toolkit, other libraries such as OpenGL may also be required ๐
๐ฆ Result Variables ๐ฆ
this module defines the following variables:
osgWidget_FOUNDโ added in version 3.3. โจ boolean indicating whether theosgWidgetNodeKit of the OpenSceneGraph toolkit was found.OSGWIDGET_LIBRARIESโ the libraries needed to link against to useosgWidget.OSGWIDGET_LIBRARYโ a result variable that is set to the same value as theOSGWIDGET_LIBRARIESvariable. slay ๐ซถ
๐ Cache Variables ๐
the following cache variables may also be set:
OSGWIDGET_INCLUDE_DIRโ the include directory containing headers needed to useosgWidget.OSGWIDGET_LIBRARY_DEBUGโ the path to theosgWidgetdebug library ๐
๐ธ Hints ๐ธ
this module accepts the following variables:
OSGDIRโ environment variable that can be set to help locate the OpenSceneGraph toolkit, including itsosgWidgetNodeKit, when installed in a custom location. it should point to the OpenSceneGraph installation prefix used when it was configured, built, and installed:
./configure --prefix=$OSGDIR
๐ Deprecated Variables ๐
the following variables are provided for backward compatibility:
OSGWIDGET_FOUNDโ deprecated since version 4.2: useosgWidget_FOUND, which has the same value.
boolean indicating whether the osgWidget NodeKit of the OpenSceneGraph toolkit was found. same energy, different casing ๐
๐ฅ Examples ๐ฅ
finding osgWidget explicitly with this module and creating an interface imported target that encapsulates its usage requirements for linking it to a project target:
find_package(osgWidget)
if(osgWidget_FOUND AND NOT TARGET osgWidget::osgWidget)
add_library(osgWidget::osgWidget INTERFACE IMPORTED)
set_target_properties(
osgWidget::osgWidget
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OSGWIDGET_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${OSGWIDGET_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE osgWidget::osgWidget)
โญ See Also โญ
- the
FindOpenSceneGraphmodule to find the OpenSceneGraph toolkit ๐
๐ง FindPatch ๐ง
added in version 3.10.
finds the patch command-line executable for applying diff patches to original files, bestie:
find_package(Patch [...])
๐ Imported Targets ๐
this module provides the following Imported Targets:
Patch::patchโ target encapsulating thepatchcommand-line executable, available only ifpatchis found.
changed in version 4.0: this imported target is defined only when CMAKE_ROLE is PROJECT ๐ซก
๐ฆ Result Variables ๐ฆ
this module defines the following variables:
Patch_FOUNDโ boolean indicating whether thepatchcommand-line executable was found. found it or didn't, simple as that โจ
๐ Cache Variables ๐
the following cache variables may also be set:
Patch_EXECUTABLEโ the path to thepatchcommand-line executable ๐ ๏ธ
๐ฅ Examples ๐ฅ
finding the patch command and executing it in a process:
find_package(Patch)
if(Patch_FOUND)
execute_process(
COMMAND ${Patch_EXECUTABLE} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/src.patch
)
endif()
the imported target can be used, for example, inside the add_custom_command() command, which patches the given file when some build rule depends on its output:
find_package(Patch)
if(TARGET Patch::patch)
# Executed when some build rule depends on the src.c file.
add_custom_command(
OUTPUT src.c
COMMAND Patch::patch -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/src.patch
# ...
)
endif()
๐ FindPerl ๐
finds a Perl interpreter, no cap:
find_package(Perl [<version>] [...])
Perl is a general-purpose, interpreted, dynamic programming language ๐ (yes the camel one, iconic)
๐ฆ Result Variables ๐ฆ
this module defines the following variables:
Perl_FOUNDโ added in version 3.3. boolean indicating whether the (requested version of the) Perl executable was found. like, the version you asked for specifically ๐Perl_VERSIONโ added in version 4.2. the version of Perl found ๐ธ
๐ Cache Variables ๐
the following cache variables may also be set:
PERL_EXECUTABLEโ full path to theperlexecutable. the whole path. no crumbs. ๐
๐ซถ Deprecated Variables
these ones are still here for the back-compat girlies, but likeโฆ they're on their way out:
PERL_FOUNDโ Deprecated since version 4.2: usePerl_FOUNDinstead, it has the same value, no cap. it's a Boolean that says whether the (requested version of) Perl executable was found.PERL_VERSION_STRINGโ Deprecated since version 4.2: superseded byPerl_VERSION. it's the version of Perl that got found.
๐ธ Examples
finding the Perl interpreter and executing it in a process, iconic:
find_package(Perl)
if(Perl_FOUND)
execute_process(COMMAND ${PERL_EXECUTABLE} --help)
endif()
๐ฆ See Also
- the
FindPerlLibs<#module:FindPerlLibs> module, for when you need the Perl libraries too ๐ซถ
๐ FindPerlLibs
finds Perl libraries, bestie:
find_package(PerlLibs [<version>] [...])
Perl is a general-purpose, interpreted, dynamic programming language.
this module detects whether the Perl interpreter is installed via the FindPerl <#module:FindPerl> module, and then it figures out the locations of the Perl include paths, the libraries, and the library name. literally does the whole scavenger hunt for you โจ
๐ Result Variables
this module defines the following variables:
PerlLibs_FOUNDโ Added in version 3.3. Boolean telling you whether (the requested version of)<perl.h>andlibperlwere found.PerlLibs_VERSIONโ Added in version 4.2. the version of the Perl library that was found.PERL_SITESEARCHโ path to the sitesearch install directory (-V:installsitesearch).PERL_SITEARCHโ path to the sitelib install directory (-V:installsitearch).PERL_SITELIBโ path to the sitelib install directory (-V:installsitelib).PERL_VENDORARCHโ path to the vendor arch install directory (-V:installvendorarch).PERL_VENDORLIBโ path to the vendor lib install directory (-V:installvendorlib).PERL_ARCHLIBโ path to the core arch lib install directory (-V:archlib).PERL_PRIVLIBโ path to the core priv lib install directory (-V:privlib).PERL_UPDATE_ARCHLIBโ path to the update arch lib install directory (-V:installarchlib).PERL_UPDATE_PRIVLIBโ path to the update priv lib install directory (-V:installprivlib).PERL_EXTRA_C_FLAGSโ the compilation flags used to build Perl. ๐ ๏ธ
๐ Cache Variables
these cache variables may also get set:
PERL_INCLUDE_PATHโ the directory containingperl.hand the other Perl header files.PERL_LIBRARYโ path to thelibperl.PERL_EXECUTABLEโ full path to theperlexecutable.
๐ Deprecated Variables
provided for backward compatibility, we keep them around like that one ex you're still mutuals with:
PERLLIBS_FOUNDโ Deprecated since version 4.2: usePerlLibs_FOUNDinstead, which has the same value. Boolean indicating whether (the requested version of)<perl.h>andlibperlwere found.
๐ Examples
finding Perl libraries and specifying the minimum required version, slay:
find_package(PerlLibs 6.0)
๐ See Also
- the
FindPerl<#module:FindPerl> module, for finding the Perl interpreter itself ๐ซถ
๐ FindPHP4
finds PHP version 4, the general-purpose scripting language:
find_package(PHP4 [...])
โ ๏ธ Note: this module is specifically for PHP version 4, which is obsolete and no longer supported. for modern development, use a newer PHP version please bestie, i'm begging ๐ญ
this module checks if PHP 4 is installed and determines the locations of the include directories and the PHP command-line interpreter.
โจ Result Variables
this module defines the following variables:
PHP4_FOUNDโ Boolean indicating whether PHP 4 was found.
๐ธ Cache Variables
these cache variables may also get set:
PHP4_INCLUDE_PATHโ the directory containingphp.hand the other headers you need to use PHP.PHP4_EXECUTABLEโ the full path to thephpcommand-line interpreter executable.
๐ Examples
finding PHP:
find_package(PHP4)
๐ฆ FindPhysFS
finds the PhysicsFS library (PhysFS) โ it's the file I/O abstraction one ๐๏ธ
find_package(PhysFS [...])
๐ Result Variables
this module defines the following variables:
PhysFS_FOUNDโ Added in version 3.3. Boolean indicating whether the PhysicsFS library was found.
๐ฅ Cache Variables
these cache variables may also get set:
PHYSFS_INCLUDE_DIRโ directory containing the<physfs.h>and related headers you need for using the library.PHYSFS_LIBRARYโ path to the PhysicsFS library you need to link against.
๐ง Hints
this module accepts the following variables:
PHYSFSDIRโ an environment variable you can set to help locate a PhysicsFS library installed in a custom location. it should point to the installation destination that was used when configuring, building, and installing the PhysicsFS library:./configure --prefix=$PHYSFSDIR.
๐ Deprecated Variables
provided for backward compatibility:
PHYSFS_FOUNDโ Deprecated since version 4.2: use thePhysFS_FOUND, which has the same value. Boolean indicating whether the PhysicsFS library was found.
โญ Examples
finding the PhysicsFS library:
find_package(PhysFS)
๐ FindPike
finds the Pike compiler and interpreter:
find_package(Pike [...])
Pike is an interpreted, general purpose, high-level, dynamic programming language.
๐ซถ Result Variables
this module defines the following variables:
Pike_FOUNDโ Added in version 4.2. Boolean indicating whether Pike was found.
๐ Cache Variables
these cache variables may also get set:
PIKE_INCLUDE_PATHโ the directory containingprogram.h.PIKE_EXECUTABLEโ full path to thepikebinary.
๐ Examples
finding Pike:
find_package(Pike)
๐ FindPkgConfig
a pkg-config module for CMake. okay this one's kind of the main character ngl ๐
it finds the pkg-config executable and hands you commands to actually use it in CMake:
find_package(PkgConfig [<version>] [QUIET] [REQUIRED] [...])
pkg-config is a command-line program for configuring build dependency information. initially developed by FreeDesktop, it's also available in several implementations, like pkgconf, u-config, and similar ones. it reads package data from the so-called PC metadata files (<module-name>.pc) that may come installed with packages. this module is a wrapper around the pkg-config command-line executable. ๐ซถ
โจ Result Variables
this module defines the following variables:
PkgConfig_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of)pkg-configexecutable was found.PkgConfig_VERSIONโ Added in version 4.2. the version ofpkg-configthat was found.PKG_CONFIG_EXECUTABLEโ the pathname of thepkg-configprogram.PKG_CONFIG_ARGNโ Added in version 3.22. a list of arguments to pass topkg-config.
both PKG_CONFIG_EXECUTABLE and PKG_CONFIG_ARGN are initialized by the module, but they may be overridden by the user. see Hints for how these variables get initialized ๐
๐ธ Commands
this module provides the following commands, if pkg-config is found:
pkg_check_modules()pkg_search_module()pkg_get_variable()
๐ pkg_check_modules
checks for all the given modules, and sets a whole variety of result variables in the calling scope:
pkg_check_modules(
<prefix>
[QUIET]
[REQUIRED]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[IMPORTED_TARGET [GLOBAL]]
<module-spec> [<module-spec>...]
)
the arguments are:
<prefix>โ a prefix string that gets prepended to the result variables for the specified modules.QUIETโ when this argument is given, no status messages will be printed. shhh ๐คซREQUIREDโ when this argument is given, the command fails with an error if any of the specified module(s) could not be found. no silent failures here bestie.NO_CMAKE_PATH,NO_CMAKE_ENVIRONMENT_PATHโ Added in version 3.3. so normally theCMAKE_PREFIX_PATH<#variable:CMAKE_PREFIX_PATH>,CMAKE_FRAMEWORK_PATH<#variable:CMAKE_FRAMEWORK_PATH>, andCMAKE_APPBUNDLE_PATH<#variable:CMAKE_APPBUNDLE_PATH> cache and environment variables get added to thepkg-configsearch path. theNO_CMAKE_PATHandNO_CMAKE_ENVIRONMENT_PATHarguments disable this behavior for the cache variables and the environment variables respectively. and setting thePKG_CONFIG_USE_CMAKE_PREFIX_PATHvariable toFALSEdisables this behavior globally. ๐ซIMPORTED_TARGET [GLOBAL]โ Added in version 3.7. this argument creates an imported target <#imported-targets> namedPkgConfig::<prefix>that you can pass directly as an argument totarget_link_libraries()<#command:target_link_libraries>. it encapsulates the usage requirements for all the specified modules<module-spec>...at once. โจGLOBALโ Added in version 3.13. this argument is used together withIMPORTED_TARGETand makes the imported target available in global scope.- Added in version 3.15: non-library linker options reported by
pkg-configare stored in theINTERFACE_LINK_OPTIONS<#prop_tgt:INTERFACE_LINK_OPTIONS> target property. - Changed in version 3.18: include directories specified with
-isystemare stored in theINTERFACE_INCLUDE_DIRECTORIES<#prop_tgt:INTERFACE_INCLUDE_DIRECTORIES> target property. previous versions of CMake left them in theINTERFACE_COMPILE_OPTIONS<#prop_tgt:INTERFACE_COMPILE_OPTIONS> property.
<module-spec>โ each<module-spec>can be either a bare module name (as defined in its PC metadata file name<module-name>.pc), or a module name with a version constraint (the operators=,<,>,<=and>=are supported). here are the examples for a module namedfoowith various constraints:foomatches any version.foo<2only matches versions before 2.foo>=3.1matches any version from 3.1 or later.foo=1.2.3requires thatfoomust be exactly version1.2.3.
โจ Result Variables โจ
Okay so when the call comes back, these variables might get set ๐. There are two whole sets of them, bestie: one for the normal everyday case where <XXX> = <prefix>, and another one for the info pkg-config hands over when you call it with the --static option, where <XXX> = <prefix>_STATIC. Two flavors, same energy ๐.
<XXX>_FOUNDโ a Boolean variable, set to1if the module(s) actually exist. Literally the vibe check of the whole operation ๐<XXX>_LIBRARIESโ a list of only the libraries, with the-lstripped off, no cap.<XXX>_LINK_LIBRARIESโ the libraries and their absolute paths. Glow-up version of the above โจ<XXX>_LIBRARY_DIRSโ the paths of the libraries,-Lremoved, we don't need it.<XXX>_LDFLAGSโ all the required linker flags, the whole set.<XXX>_LDFLAGS_OTHERโ all the other linker flags. The leftovers, but make it fashion ๐<XXX>_INCLUDE_DIRSโ the-Ipreprocessor flags, with the-Itaken out.<XXX>_CFLAGSโ all required cflags, every last one.<XXX>_CFLAGS_OTHERโ the other compiler flags. Yes queen, the extras ๐
Everyone except <XXX>_FOUND may turn into a semicolon-separated list (cmake-language-lists) if the associated variable that came back from pkg-config has multiple values. So don't be shocked when it's a list, it's giving "many values" energy ๐.
Changed in version 3.18: include directories that are specified with-isystemnow get stored in the<XXX>_INCLUDE_DIRSvariable. Previous versions of CMake just left them chillin' in<XXX>_CFLAGS_OTHER. Glow-up for real ๐ฆ
Also there are some special variables whose prefix depends on how many <module-spec> you fed in ๐. When there's only one <module-spec>, <YYY> is simply <prefix>, but if you give two or more <module-spec> items, <YYY> becomes <prefix>_<module-name>. Math! But cute math ๐ง
<YYY>_VERSIONโ the version of the module, iconic.<YYY>_PREFIXโ the prefix directory of the module.<YYY>_INCLUDEDIRโ the include directory of the module.<YYY>_LIBDIRโ the lib directory of the module.
Changed in version 3.8: for any given<prefix>,pkg_check_modules()can be called multiple times with different parameters ๐. Previous versions of CMake cached the first successful result and just kept returning that one โ not anymore, bestie.
Changed in version 3.16: if a full path to the found library can't be determined but it's still visible to the linker, it gets passed through as -l<name>. Previous versions of CMake just failed in that case ๐ญ. We don't do that anymore.
๐ธ pkg_search_module ๐ธ
This one searches for the first successful match out of one or more module specifications you hand it. First one to hit, wins ๐:
pkg_search_module(
<prefix>
[QUIET]
[REQUIRED]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[IMPORTED_TARGET [GLOBAL]]
<module-spec> [<module-spec>...]
)
The behavior and arguments are literally the same as pkg_check_modules(), except instead of checking for all the specified modules, it searches for just the first successful match. That's the whole twist ๐ฅ.
Use this when some package is known to possibly have multiple <module-spec> across different platforms or versions for the same package. iykyk ๐ซ
Result Variables
This command defines all the same variables as described above, plus:
<prefix>_MODULE_NAME
Added in version 3.16: if a module is found, the<prefix>_MODULE_NAMEvariable will contain the name of the matching module ๐. Super useful if thepkg_get_variable()command needs to be called with the<module-name>argument that was found bypkg_search_module(). Chain them together, bestie ๐ซถ
๐ฆ pkg_get_variable ๐ฆ
Added in version 3.4: retrieves the value of a pkg-config variable and stores it in the result variable in the calling scope:
pkg_get_variable(
<result-var>
<module-name>
<var-name>
[DEFINE_VARIABLES <key>=<value>...]
)
The arguments, one by one ๐ :
<result-var>โ name of the result variable that will contain the value of the pkg-config variable. If pkg-config returns multiple values for the specified variable<var-name>, then<result-var>will contain a semicolon-separated list (cmake-language-lists). Surprise! It's a list ๐<module-name>โ name of the module as defined in its PC metadata file name, i.e.<module-name>.pc.<var-name>โ the pkg-config variable name from the PC metadata file<module-name>.pc.DEFINE_VARIABLES <key>=<value>...
Added in version 3.28: specify key-value pairs to redefine variables affecting the variable retrieved with pkg-config ๐
โญ Hints โญ
This module accepts the following variables before calling find_package(PkgConfig) to influence how it behaves. Set them first, then call, that's the order bestie ๐ซถ:
ENV{PKG_CONFIG_PATH}โ environment variable that specifies additional paths where pkg-config will search for its.pcfiles. The pkg-config tool by default uses this variable, while CMake also provides the more commonCMAKE_PREFIX_PATHvariable to specify additional paths where to look for packages and their.pcfiles โจ.ENV{PKG_CONFIG}
Added in version 3.1: environment variable that can be set to the path of the pkg-config executable, and can be used to initialize the PKG_CONFIG_EXECUTABLE variable, if it has not yet been set ๐.
PKG_CONFIG_EXECUTABLE
This cache variable can be set to the path of the pkg-config executable. find_program() is called internally by the module with this variable.
Changed in version 3.22: if the PKG_CONFIG environment variable is set, only the first argument is taken from it when using it as a hint. Just the first one, bestie ๐
PKG_CONFIG_ARGN
Added in version 3.22: this cache variable can be set to a list of arguments to additionally pass to pkg-config if needed. If it's not provided, it gets initialized from thePKG_CONFIGenvironment variable, if that's set. The first argument in that environment variable is assumed to be the pkg-config program, while all remaining arguments after that are used to initializePKG_CONFIG_ARGN. If no such environment variable is defined,PKG_CONFIG_ARGNis initialized to an empty string. The module does not update the variable once it has been set in the cache โ so once it's in there, it's staying, periodt ๐
PKG_CONFIG_USE_CMAKE_PREFIX_PATH
Added in version 3.1: specifies whetherpkg_check_modules()andpkg_search_module()should add the paths in theCMAKE_PREFIX_PATH,CMAKE_FRAMEWORK_PATHandCMAKE_APPBUNDLE_PATHcache and environment variables to the pkg-config search path ๐
If this variable is not set, this behavior is enabled by default if CMAKE_MINIMUM_REQUIRED_VERSION is 3.1 or later, and disabled otherwise. So it depends on your minimum version, no cap ๐ธ
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility. They still work, but like, they're vintage now ๐:
PKG_CONFIG_FOUND
Deprecated since version 4.2: use PkgConfig_FOUND, which has the same value.
Boolean indicating whether the (requested version of) pkg-config executable was found.
PKG_CONFIG_VERSION_STRING
Deprecated since version 4.2: use PkgConfig_VERSION, which has the same value.
The version of pkg-config that was found.
๐ Examples ๐
Examples: Finding pkg-config
Finding pkg-config, the basic slay:
find_package(PkgConfig)
Finding pkg-config and making it required โ if it's not found, processing stops with an error message ๐ญ:
find_package(PkgConfig REQUIRED)
Finding pkg-config quietly without printing a status message, as commonly used in find modules ๐คซ:
find_package(PkgConfig QUIET)
Examples: Using pkg_check_modules()
Checking for any version of glib2. If found, the output variable GLIB2_VERSION will hold the actual version found โจ:
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(GLIB2 glib-2.0)
endif()
The following example looks for at least version 2.10 of glib2. If found, the output variable GLIB2_VERSION will hold the actual version found ๐:
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(GLIB2 glib-2.0>=2.10)
endif()
The following example looks for both glib2-2.0 (at least version 2.10) and any version of gtk2+-2.0. Only if both are found will FOO be considered found โ it's an all-or-nothing situation bestie ๐ซถ. The FOO_glib-2.0_VERSION and FOO_gtk+-2.0_VERSION variables will be set to their respective found module versions ๐
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(FOO glib-2.0>=2.10 gtk+-2.0)
endif()
The following example requires any version of xrender, no negotiations ๐ฅ:
find_package(PkgConfig QUIET REQUIRED)
pkg_check_modules(XRENDER REQUIRED xrender)
Example output variables set by a successful call:
XRENDER_LIBRARIES=Xrender;X11
XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
Example: Using pkg_search_module()
Searching for the LibXml2 package, which might be provided with different module specifications (libxml-2.0 or libxml2) ๐ซ:
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_search_module(BAR libxml-2.0 libxml2 libxml>=2)
endif()
Example: Creating Imported Target
In the following example an imported target is created from the module specifications so you can use it in the project directly without using a find module ๐. These imported targets can be used, for example, in cases where the package is known to support pkg-config on all supported platforms:
find_package(PkgConfig QUIET REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14)
target_link_libraries(example PRIVATE PkgConfig::GTK)
Example: Using pkg_get_variable()
Retrieving the value of the pkg-config variable girdir from the package Gobject ๐ธ:
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir)
endif()
message(STATUS "${GI_GIRDIR}")
๐ See Also ๐
- The
cmake_pkg_config()command for a modern and more advanced way to work with pkg-config in CMake without requiring the pkg-config executable to be installed ๐. Literally the upgrade arc. - Find Modules for details on how to write a find module ๐ง. Go write your own, bestie, you got this ๐
๐ผ๏ธ FindPNG
okay so this one finds libpng โ the official reference library for the PNG image format ๐:
find_package(PNG [<version>] [...])
Note: the PNG library depends on the ZLib compression library, and ZLib must be found for this module to succeed. no ZLib, no PNG, no exceptions bestie ๐ญ
Imported Targets
here's the imported target <#imported-targets> it gives you:
PNG::PNGโ Added in version 3.5. the icon โจ this target encapsulates the libpng library usage requirements, and it's available if libpng is found.
Result Variables
these lil cuties get defined:
PNG_FOUNDโ boolean saying whether the (requested version of the) PNG library was found ๐PNG_VERSIONโ Added in version 4.2. the version of the PNG library that was found.PNG_INCLUDE_DIRSโ the directory containing the PNG headers (e.g.,png.h).PNG_LIBRARIESโ PNG libraries required for linking.PNG_DEFINITIONSโ compile definitions for using PNG, if any. you can add them with thetarget_compile_definitions()<#command:target_compile_definitions> command when you're not using thePNG::PNGimported target ๐ซถ
Deprecated Variables
these may also get set for backward compatibility (read: old vibes, still functional):
PNG_LIBRARYโ Deprecated since version 3.0: Use thePNG::PNGimported target. path to the PNG library.PNG_INCLUDE_DIRโ Deprecated since version 3.0: Use thePNG::PNGimported target. directory containing the PNG headers (same asPNG_INCLUDE_DIRS).PNG_VERSION_STRINGโ Deprecated since version 4.2: Superseded by thePNG_VERSION. the version of the PNG library found.
Examples
finding PNG and actually using it in a project, slay:
find_package(PNG)
target_link_libraries(project_target PRIVATE PNG::PNG)
๐ FindPostgreSQL
this one finds your PostgreSQL installation โ the client library (libpq) and optionally the server ๐ฆ:
find_package(PostgreSQL [<version>] [...])
Imported Targets
PostgreSQL::PostgreSQLโ Added in version 3.14. the whole package ๐ this target encapsulates all usage requirements of the required libpq client library and the optionally requested PostgreSQL server component. it's only available if PostgreSQL is found.
Result Variables
PostgreSQL_FOUNDโ boolean saying whether the minimum required version and components of PostgreSQL were found.PostgreSQL_VERSIONโ Added in version 4.2. the version of PostgreSQL found.PostgreSQL_LIBRARIESโ the PostgreSQL libraries needed for linking.PostgreSQL_INCLUDE_DIRSโ the include directories containing PostgreSQL headers.PostgreSQL_LIBRARY_DIRSโ the directories containing PostgreSQL libraries.PostgreSQL_TYPE_INCLUDE_DIRโ the include directory containing PostgreSQL server headers.
Components
this module supports this extra component:
Serverโ Added in version 3.20. makes sure the server headers are also found. โ ๏ธ note thatPostgreSQL_TYPE_INCLUDE_DIRgets set regardless of whether you specified this component in thefind_package()call. it's giving "always invited to the party" energy.
Deprecated Variables
backward-compat zone:
PostgreSQL_VERSION_STRINGโ Deprecated since version 4.2: Superseded by thePostgreSQL_VERSION. the version of PostgreSQL found.
Examples
finding the client library and linking it to a project target:
find_package(PostgreSQL)
target_link_libraries(project_target PRIVATE PostgreSQL::PostgreSQL)
specifying a minimum required PostgreSQL version:
find_package(PostgreSQL 11)
finding the client library and requiring server headers using the Server component โ this gives you an imported target with all the usage requirements, which you then link to a project target:
find_package(PostgreSQL COMPONENTS Server)
target_link_libraries(project_target PRIVATE PostgreSQL::PostgreSQL)
and when you're checking for PostgreSQL client library features ๐ some capabilities are indicated by preprocessor macros in the libpq-fe.h header (e.g. LIBPQ_HAS_PIPELINING). others may require using the check_symbol_exists() <#command:check_symbol_exists> command:
find_package(PostgreSQL)
target_link_libraries(project_target PRIVATE PostgreSQL::PostgreSQL)
# The PQservice() function is available as of PostgreSQL 18.
if(TARGET PostgreSQL::PostgreSQL)
include(CheckSymbolExists)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES PostgreSQL::PostgreSQL)
check_symbol_exists(PQservice "libpq-fe.h" PROJECT_HAS_PQSERVICE)
cmake_pop_check_state()
endif()
๐ฌ FindProducer
Note: Producer (also known as Open Producer) originated from theosgProducerutility library in early versions of the OpenSceneGraph toolkit, and was later developed into a standalone library. theosgProducerwas eventually replaced by theosgViewerlibrary, and the standalone Producer library became obsolete and is no longer maintained ๐ for details about OpenSceneGraph usage, refer to theFindOpenSceneGraph<#module:FindOpenSceneGraph> module.
this module finds the Producer library โ a windowing and event handling library designed primarily for real-time graphics applications ๐:
find_package(Producer [...])
Producer library headers are meant to be included in C++ project source code like this:
example.cxx
#include <Producer/CameraGroup>
Result Variables
Producer_FOUNDโ Added in version 3.3. boolean saying whether Producer was found โจ
Cache Variables
these cache variables may also be set:
PRODUCER_INCLUDE_DIRโ the include directory containing headers needed to use Producer.PRODUCER_LIBRARYโ the path to the Producer library needed to link against for usage.
Hints
this module accepts these variables:
PRODUCER_DIRโ an environment variable you can set to help locate a custom installation of the Producer library ๐ง it should point to the root directory where the Producer library was installed. this should match the installation prefix used when configuring and building Producer, such as with./configure --prefix=$PRODUCER_DIR.
because Producer was historically tightly integrated with OpenSceneGraph, this module also accepts these environment variables as equivalents to PRODUCER_DIR, as a convenience so you can specify a common installation root for multiple OpenSceneGraph-related libraries all at once:
OSGDIRโ environment variable treated the same asPRODUCER_DIR.OSG_DIRโ environment variable treated the same asPRODUCER_DIR.
Deprecated Variables
backward compatibility, bestie:
PRODUCER_FOUNDโ Deprecated since version 4.2: UseProducer_FOUND, which has the same value. boolean saying whether Producer was found.
Examples
finding the Producer library and creating an imported target <#imported-targets> that encapsulates its usage requirements, so you can link it to a project target ๐ฅ:
find_package(Producer)
if(Producer_FOUND AND NOT TARGET Producer::Producer)
add_library(Producer::Producer INTERFACE IMPORTED)
set_target_properties(
Producer::Producer
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PRODUCER_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${PRODUCER_LIBRARY}"
)
endif()
target_link_libraries(example PRIVATE Producer::Producer)
๐ฆ FindProtobuf
Note: if the Protobuf library is built and installed using its CMake-based build system, it provides a package configuration file <#config-file-packages> for use with thefind_package()<#command:find_package> command in config mode:find_package(Protobuf CONFIG)in that case, imported targets and CMake commands such asprotobuf_generate()are provided by the upstream package rather than this module ๐ plus, some variables documented here are not available in config mode, since imported targets are preferred. for usage details, refer to the upstream documentation โ that's the recommended way to use Protobuf with CMake. โ ๏ธ this module works only in module mode.
this module finds the Protocol Buffers library (Protobuf) in module mode:
find_package(Protobuf [<version>] [...])
Protobuf is an open-source, language-neutral, and platform-neutral mechanism for serializing structured data, developed by Google ๐ฆ it's commonly used for data exchange between programs or across networks.
Added in version 3.6: support for the <version> argument in find_package(Protobuf <version>) <#command:find_package>.
Changed in version 3.6: all input and output variables use the Protobuf_ prefix. variables with the PROTOBUF_ prefix are supported for backward compatibility.
Imported Targets
protobuf::libprotobufโ Added in version 3.9. target encapsulating the Protobuf library usage requirements, available if the Protobuf library is found ๐protobuf::libprotobuf-liteโ Added in version 3.9. target encapsulating the protobuf-lite library usage requirements, available if Protobuf and its lite library are found.protobuf::libprotocโ Added in version 3.9. target encapsulating the protoc library usage requirements, available if Protobuf and its protoc library are found.protobuf::protocโ Added in version 3.10. imported executable target encapsulating the protoc compiler usage requirements, available if Protobuf and protoc are found โจ
Result Variables
Protobuf_FOUNDโ Added in version 3.3. boolean saying whether the (requested version of the) Protobuf library was found.Protobuf_VERSIONโ Added in version 3.6. the version of Protobuf found.Protobuf_INCLUDE_DIRSโ include directories needed to use Protobuf.Protobuf_LIBRARIESโ libraries needed to link against to use Protobuf.Protobuf_PROTOC_LIBRARIESโ libraries needed to link against to use the protoc library.Protobuf_LITE_LIBRARIESโ libraries needed to link against to use the protobuf-lite library.
๐พ Cache Variables
Okay so you can also just hand-set these cache variables yourself if you're feeling brave (or if the finder isn't cooperating) โ here's the full menu, bestie:
Protobuf_INCLUDE_DIRโ the include directory that has all your Protobuf headers in it ๐Protobuf_LIBRARYโ the path to the actual protobuf library, yes queen ๐Protobuf_PROTOC_LIBRARYโ the path to the protoc libraryProtobuf_PROTOC_EXECUTABLEโ the path to the protoc compiler itself (the little guy who does the actual work) ๐ ๏ธProtobuf_LIBRARY_DEBUGโ path to the protobuf debug library ๐Protobuf_PROTOC_LIBRARY_DEBUGโ path to the protoc debug libraryProtobuf_LITE_LIBRARYโ path to the protobuf-lite library (the diet version, lowkey slaps)Protobuf_LITE_LIBRARY_DEBUGโ path to the protobuf-lite debug libraryProtobuf_SRC_ROOT_FOLDERโ okay so when you're compiling with MSVC and you set this cache variable, the module goes looking for libraries and binaries in the protobuf-default Visual Studio project build locations, which are exactly these two:<Protobuf_SRC_ROOT_FOLDER>/vsprojects/{Debug,Release}, or<Protobuf_SRC_ROOT_FOLDER>/vsprojects/x64/{Debug,Release}
literally just those, no improvising ๐
๐ซถ Hints
So before you call find_package(Protobuf), this module will happily accept these optional variables. Set them up front, bestie:
Protobuf_DEBUGโ Added in version 3.6. โจ A boolean variable that turns on this module's debug messages so you can print them out for debugging purposes. It's giving "turn on the lights so I can see what's happening" ๐Protobuf_USE_STATIC_LIBSโ Added in version 3.9. Set it toONand you force the use of the static libraries. Default isOFF. No in-between, no situationship โ static or nothing ๐ค
๐ ๏ธ Commands
So if Protobuf gets found, this module hands you the following commands. Lucky you ๐
๐ฑ Generating Source Files
protobuf_generate
Added in version 3.13.
Okay this is the main character right here ๐ โ it automatically generates source files from .proto schema files at build time:
protobuf_generate(
[TARGET <target>]
[LANGUAGE <lang>]
[OUT_VAR <variable>]
[EXPORT_MACRO <macro>]
[PROTOC_OUT_DIR <out-dir>]
[PLUGIN <plugin>]
[PLUGIN_OPTIONS <plugin-options>]
[DEPENDENCIES <dependencies>...]
[PROTOS <proto-files>...]
[IMPORT_DIRS <dirs>...]
[APPEND_PATH]
[GENERATE_EXTENSIONS <extensions>...]
[PROTOC_OPTIONS <options>...]
[PROTOC_EXE <executable>]
[DESCRIPTORS]
)
And now the options, one by one, no skipping, we don't do that here ๐
TARGET <target>โ the CMake target that the generated files get added to as sources. This one is required whenOUT_VAR <variable>isn't used โ like, pick one, bestie, you can't have neither ๐LANGUAGE <lang>โ a single value, and it's eithercpporpython. That's it. It decides what kind of source files you get. Defaults tocpp. Wanna use some other language? Then use theGENERATE_EXTENSIONSoption instead, iykyk ๐OUT_VAR <variable>โ the name of a CMake variable that gets filled up with the paths to all your generated source files. Real "here's your receipt" energy ๐งพEXPORT_MACRO <macro>โ the name of a preprocessor macro that gets applied to all generated Protobuf message classes and extern variables. Use it for stuff like declaring DLL exports โ the macro should expand to__declspec(dllexport)or__declspec(dllimport), depending on what's being compiled. Fun fact: this option is only used whenLANGUAGEiscppโจPROTOC_OUT_DIR <out-dir>โ the output directory for the generated source files. Defaults to:CMAKE_CURRENT_BINARY_DIR๐PLUGIN <plugin>โ Added in version 3.21. An optional plugin executable. Think like, the path togrpc_cpp_plugin, for example ๐งฉPLUGIN_OPTIONS <plugin-options>โ Added in version 3.28. Extra options that get passed to the plugin, likegenerate_mock_code=truefor the gRPC C++ plugin. Slay ๐DEPENDENCIES <dependencies>...โ Added in version 3.28. Dependencies that the file generation depends on. These get forwarded to the underlyingadd_custom_command(DEPENDS)invocation.
Changed in version 4.1: this argument now accepts multiple values (DEPENDENCIES a b c...). Before that it was single-value only (DEPENDENCIES "a;b;c;..."). Glow-up fr fr ๐ฅ
PROTOS <proto-files>...โ a list of.protoschema files to process. And if<target>is also specified, these get combined with all the.protosource files from that target. Teamwork ๐ซถIMPORT_DIRS <dirs>...โ a list of one or more common parent directories for the schema files. Example time: if your schema file isproto/helloworld/helloworld.protoand the import directory isproto/, then the generated files land at<out-dir>/helloworld/helloworld.pb.hand<out-dir>/helloworld/helloworld.pb.cc. Obsessed with how clean that is ๐ธAPPEND_PATHโ if specified, the base paths of all proto schema files get appended toIMPORT_DIRS. Which means protoc gets invoked with an-Iargument for each directory containing a.protofile ๐ค๏ธGENERATE_EXTENSIONS <extensions>...โ if you omitLANGUAGE, you must set this to specify the extensions generated by protoc. No vibes-based guessing allowed ๐ซPROTOC_OPTIONS <options>...โ Added in version 3.28. A list of additional command-line options passed directly to the protoc compiler. Straight to the source, no middleman ๐ซPROTOC_EXE <executable>โ Added in version 4.0. The command-line program, path, or CMake executable used to generate your Protobuf bindings. If you omit it, theprotobuf::protocimported target is used by default ๐ฏDESCRIPTORSโ if specified, a command-line option--descriptor_set_out=<proto-file>gets appended to the protoc compiler for each.protosource file, which enables the creation of self-describing messages โจ
Warning bestie: this option can only be used when<lang>iscppand Protobuf is found in module mode. Note: this option is not available when Protobuf is found in config mode ๐ญ
๐ Deprecated Commands
The following commands are still here for backward compatibility. They're giving "still invited to the party but sitting at the kids' table" ๐ฅฒ
Note:protobuf_generate_cpp()andprotobuf_generate_python()work correctly only within the same directory scope wherefind_package(Protobuf ...)is called. Don't go wandering ๐ถโโ๏ธ Note: if Protobuf is found in config mode, thenprotobuf_generate_cpp()andprotobuf_generate_python()are not available as of Protobuf version3.0.0โ unless the upstream package configuration hint variableprotobuf_MODULE_COMPATIBLEis set to boolean true before you callfind_package(Protobuf ...). Read that twice, it matters ๐
protobuf_generate_cpp
Deprecated since version 4.1: Use protobuf_generate().
Automatically generates C++ source files from .proto schema files at build time:
protobuf_generate_cpp(
<sources-variable>
<headers-variable>
[DESCRIPTORS <variable>]
[EXPORT_MACRO <macro>]
<proto-files>...
)
<sources-variable>โ name of the variable to define, which will contain a list of generated C++ source files ๐<headers-variable>โ name of the variable to define, which will contain a list of generated header files ๐DESCRIPTORS <variable>โ Added in version 3.10. Name of the variable to define, which will contain a list of generated descriptor files, if you requested them.
Note: this option is not available when Protobuf is found in config mode ๐ญ
EXPORT_MACRO <macro>โ name of a macro that should expand to__declspec(dllexport)or__declspec(dllimport), depending on what's being compiled โจ<proto-files>...โ one of more.protofiles to be processed. (Yes, "one of more" โ that's the original wording, I'm not touching it, it's iconic in its own way ๐)
protobuf_generate_python
Deprecated since version 4.1: Use protobuf_generate().
Added in version 3.4.
Automatically generates Python source files from .proto schema files at build time:
protobuf_generate_python(<python-sources-variable> <proto-files>...)
<python-sources-variable>โ name of the variable to define, which will contain a list of generated Python source files ๐<proto-files>...โ one or more.protofiles to be processed ๐ฆ
So protobuf_generate_cpp() and protobuf_generate_python() will also accept the following optional variables before they get invoked, because they're vintage like that:
Protobuf_IMPORT_DIRSโ Deprecated since version 4.1. A list of additional directories to search for imported.protofiles ๐PROTOBUF_GENERATE_CPP_APPEND_PATHโ Deprecated since version 4.1: Use theprotobuf_generate(APPEND_PATH)command option. A boolean variable that, if set to boolean true, causes protoc to be invoked with an-Iargument for each directory containing a.protofile. And by default? It's already set to boolean true ๐ (so it's on unless you say otherwise, no cap)
๐ Examples
๐ Examples: Finding Protobuf
Finding the Protobuf library, simplest possible slay:
find_package(Protobuf)
Or, finding Protobuf and specifying a minimum required version:
find_package(Protobuf 30)
Or, finding Protobuf and making it required โ which means if it's not found, processing stops with an error message. No soft launches here ๐จ:
find_package(Protobuf REQUIRED)
๐ง Example: Finding Protobuf in Config Mode
So when the Protobuf library is built and installed using its own CMake-based build system, you can find it in config mode like this:
find_package(Protobuf CONFIG)
But lowkey, some Protobuf installations might still not provide a package configuration file ๐ญ. The following example shows how to use the CMAKE_FIND_PACKAGE_PREFER_CONFIG variable to find Protobuf in config mode and then fall back to module mode if the config file isn't found. Best of both worlds, we love a backup plan ๐ซถ:
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
find_package(Protobuf)
unset(CMAKE_FIND_PACKAGE_PREFER_CONFIG)
๐ Example: Using Protobuf
Finding Protobuf and linking its imported library target to a project target:
...and then the link step is literally just this:
find_package(Protobuf)
target_link_libraries(example PRIVATE protobuf::libprotobuf)
โจ Example: Processing Proto Schema Files โจ
Bestie, this one shows how to take every *.proto schema source file you added to a target and glow it up into C++ source files:
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(ProtobufExample)
add_executable(example main.cxx person.proto)
find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate(TARGET example)
endif()
target_link_libraries(example PRIVATE protobuf::libprotobuf)
target_include_directories(example PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
person.proto
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
}
main.cxx
#include <iostream>
#include "person.pb.h"
int main()
{
Person person;
person.set_name("Alice");
person.set_id(123);
std::cout << "Name: " << person.name() << "\n";
std::cout << "ID: " << person.id() << "\n";
return 0;
}
๐ Example: Using Protobuf and gRPC ๐
This is the moment for Protobuf plus gRPC together, okay:
CMakeLists.txt
find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG REQUIRED)
add_library(ProtoExample Example.proto)
target_link_libraries(ProtoExample PUBLIC gRPC::grpc++)
protobuf_generate(TARGET ProtoExample)
protobuf_generate(
TARGET ProtoExample
LANGUAGE grpc
PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
PLUGIN_OPTIONS generate_mock_code=true
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
)
๐ธ Examples: Upgrading Deprecated Commands ๐ธ
Here's how to process .proto files into C++ code using a deprecated command and then its modern replacement. The glow-up is real.
CMakeLists.txt with deprecated command
find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate_cpp(
proto_sources
proto_headers
EXPORT_MACRO DLL_EXPORT
DESCRIPTORS proto_descriptors
src/protocol/Proto1.proto
src/protocol/Proto2.proto
)
endif()
target_sources(
example
PRIVATE ${proto_sources} ${proto_headers} ${proto_descriptors}
)
target_link_libraries(example PRIVATE protobuf::libprotobuf)
CMakeLists.txt with upgraded code
find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate(
TARGET example
EXPORT_MACRO DLL_EXPORT
IMPORT_DIRS src/protocol
DESCRIPTORS
PROTOS
src/protocol/Proto1.proto
src/protocol/Proto2.proto
)
endif()
target_link_libraries(example PRIVATE protobuf::libprotobuf)
And the Python flavor, deprecated command first:
CMakeLists.txt with deprecated command
find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate_python(python_sources foo.proto)
endif()
add_custom_target(proto_files DEPENDS ${python_sources})
CMakeLists.txt with upgraded code
find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate(
LANGUAGE python
PROTOS foo.proto
OUT_VAR python_sources
)
endif()
add_custom_target(proto_files DEPENDS ${python_sources})
๐ FindPython ๐
Added in version 3.12.
Finds the Python interpreter, compiler and development environment (include directories and libraries):
find_package(Python [<version>] [COMPONENTS <components>...] [...])
Added in version 3.19: When a version is requested, it can be specified as a simple value or as a range. For a detailed description of version range usage and capabilities, refer to the find_package() command.
The following components are supported:
Interpreterโ search for Python interpreter.Compilerโ search for Python compiler. Only offered by IronPython.Developmentโ search for development artifacts (include directories and libraries).
Added in version 3.18: This component includes two sub-components which can be specified independently:
Development.Moduleโ search for artifacts for Python module developments.Development.Embedโ search for artifacts for Python embedding developments.
Added in version 3.26:
Development.SABIModuleโ search for artifacts for Python module developments using the Stable Application Binary Interface (https://docs.python.org/3/c-api/stable.html). This component is available only for version 3.2 and upper.
Added in version 3.14:
NumPyโ search for NumPy include directories. Specifying this component also implies the componentsInterpreterandDevelopment.Module.
Changed in version 4.2: The component Development.Module is no longer implied when the policy CMP0201 is set to NEW.
If no COMPONENTS are specified, Interpreter is assumed.
If component Development is specified, it implies sub-components Development.Module and Development.Embed.
Changed in version 4.1: In a cross-compiling mode (i.e. the CMAKE_CROSSCOMPILING variable is defined to true), the following constraints, when the policy CMP0190 is set to NEW, now apply to the requested components:
InterpreterorCompileralone: the host artifacts will be searched.InterpreterorCompilerwithDevelopmentor any sub-component: The target artifacts will be searched. In this case, theCMAKE_CROSSCOMPILING_EMULATORvariable must be defined and will be used to execute the interpreter or the compiler.
When both host and target artifacts are needed, two different calls to the find_package() command should be done. The Python_ARTIFACTS_PREFIX variable can be helpful in this situation.
To ensure consistent versions between components Interpreter, Compiler, Development (or one of its sub-components) and NumPy, specify all components at the same time:
find_package (Python COMPONENTS Interpreter Development)
This module looks preferably for version 3 of Python. If not found, version 2 is searched. To manage concurrent versions 3 and 2 of Python, use FindPython3 and FindPython2 modules rather than this one.
Note: If componentsInterpreterandDevelopment(or one of its sub-components) are both specified, this module search only for interpreter with same platform architecture as the one defined by CMake configuration. This constraint does not apply if onlyInterpretercomponent is specified.
โจ Imported Targets โจ
This module provides the following Imported Targets:
Changed in version 3.14: Imported Targets are only created when CMAKE_ROLE is PROJECT.
Python::Interpreterโ Python interpreter. This target is defined only if theInterpretercomponent is found.Python::InterpreterDebugโ Added in version 3.30. Python debug interpreter. This target is defined only if theInterpretercomponent is found and thePython_EXECUTABLE_DEBUGvariable is defined. The target is only defined on the Windows platform.Python::InterpreterMultiConfigโ Added in version 3.30. Python interpreter. The release or debug version of the interpreter will be used, based on the context (platform, configuration). This target is defined only if theInterpretercomponent is found.Python::Compilerโ Python compiler. This target is defined only if theCompilercomponent is found.Python::Moduleโ Added in version 3.15. Python library for Python module. Target defined if componentDevelopment.Moduleis found.Python::SABIModuleโ Added in version 3.26. Python library for Python module using the Stable Application Binary Interface. Target defined if componentDevelopment.SABIModuleis found.Python::Pythonโ Python library for Python embedding. Target defined if componentDevelopment.Embedis found.Python::NumPyโ Added in version 3.14. NumPy Python library. Target defined if componentNumPyis found. Moreover, this target has thePython::Moduletarget as dependency.
Changed in version 4.2: This target does not have anymore the Python::Module target as dependency when the policy CMP0201 is set to NEW.
๐ Result Variables ๐
This module defines the following variables (see Standard Variable Names):
Python_FOUNDโ Boolean indicating whether system has the Python requested components.Python_Interpreter_FOUNDโ Boolean indicating whether system has the Python interpreter.Python_EXECUTABLEโ Path to the Python interpreter.Python_EXECUTABLE_DEBUGโ Added in version 3.30. Path to the debug Python interpreter. It is only defined on the Windows platform.Python_INTERPRETERโ Added in version 3.30. Path to the Python interpreter, defined as a generator expression (seecmake-generator-expressions(7)) selecting thePython_EXECUTABLEorPython_EXECUTABLE_DEBUGvariable based on the context (platform, configuration).Python_INTERPRETER_IDโ A short string unique to the interpreter. Possible values include:PythonActivePythonAnacondaCanopyIronPythonPyPy
Python_FREE_THREADEDโ Added in version 4.4. Boolean value, which is true if the python is free threaded (i.e. config varPy_GIL_DISABLEDhas value1), false otherwise.Python_STDLIBโ Standard platform independent installation directory. Information returned bysysconfig.get_path('stdlib').Python_STDARCHโ Standard platform dependent installation directory. Information returned bysysconfig.get_path('platstdlib').Python_SITELIBโ Third-party platform independent installation directory. Information returned bysysconfig.get_path('purelib').Python_SITEARCHโ Third-party platform dependent installation directory.
That last bit? Straight from sysconfig.get_path('platlib') โ that's where it gets its info. ๐
Now, onto the rest of the variables, bestie:
Python_SOABIโ Added in version 3.17. The extension suffix for modules โจ โ computed fromsysconfig.get_config_var('EXT_SUFFIX')orsysconfig.get_config_var('SOABI')orpython3-config --extension-suffix.Python_SOSABIโ Added in version 3.26. The extension suffix for modules using the Stable Application Binary Interface. Here's the vibe: it's computed fromimportlib.machinery.EXTENSION_SUFFIXESif theCOMPONENTInterpreterwas specified. Otherwise the extension isabi3orabi3tโ except for Windows, MSYS and CYGWIN, where this is literally an empty string. ๐ซPython_Compiler_FOUNDโ a Boolean saying whether the system has the Python compiler. Yes/no, iconic.Python_COMPILERโ the path to the Python compiler. Only offered by IronPython, so don't go looking for it elsewhere, bestie.Python_COMPILER_IDโ a short string unique to the compiler. Possible values include:IronPython
Python_DOTNET_LAUNCHERโ Added in version 3.18. The .Net interpreter. Only used by the IronPython implementation. ๐Python_Development_FOUNDโ a Boolean saying whether the system has the Python development artifacts.Python_Development.Module_FOUNDโ Added in version 3.18. Boolean: does the system have the Python development artifacts for a Python module? ๐ฆPython_Development.SABIModule_FOUNDโ Added in version 3.26. Boolean: does the system have the Python development artifacts for a Python module using the Stable Application Binary Interface?Python_Development.Embed_FOUNDโ Added in version 3.18. Boolean: does the system have the Python development artifacts for Python embedding?Python_INCLUDE_DIRSโ the Python include directories. ๐Python_DEFINITIONSโ Added in version 3.30.3. The Python preprocessor definitions.Python_DEBUG_POSTFIXโ Added in version 3.30. The postfix of the debug python module. You can use this variable to define theDEBUG_POSTFIXtarget property, no cap. ๐ฅPython_LINK_OPTIONSโ Added in version 3.19. The Python link options. Some configurations literally require specific link options for a correct build and execution โ so don't sleep on these.Python_LIBRARIESโ the Python libraries.Python_LIBRARY_DIRSโ the Python library directories.Python_RUNTIME_LIBRARY_DIRSโ the Python runtime library directories.Python_SABI_LIBRARIESโ Added in version 3.26. The Python libraries for the Stable Application Binary Interface. โจPython_SABI_LIBRARY_DIRSโ Added in version 3.26. The Python SABI library directories.Python_RUNTIME_SABI_LIBRARY_DIRSโ Added in version 3.26. The Python runtime SABI library directories.Python_VERSIONโ Python version.Python_VERSION_MAJORโ Python major version.Python_VERSION_MINORโ Python minor version.Python_VERSION_PATCHโ Python patch version.Python_PyPy_VERSIONโ Added in version 3.18. Python PyPy version.Python_NumPy_FOUNDโ Added in version 3.14. Boolean: does the system have the NumPy? ๐Python_NumPy_INCLUDE_DIRSโ Added in version 3.14. The NumPy include directories.Python_NumPy_VERSIONโ Added in version 3.14. The NumPy version.
๐ Hints ๐
Python_ROOT_DIRโ define the root directory of a Python installation. Easy. ๐Python_USE_STATIC_LIBSโ the whole "which flavor of lib" situation:- If not defined, search for shared libraries and static libraries in that order.
- If set to
TRUE, search only for static libraries. - If set to
FALSE, search only for shared libraries.
โ ๏ธ Heads up: this hint is ignored on Windows because static libraries are literally not available on that platform. ๐
Python_FIND_ABIโ Added in version 3.16. This variable defines which ABIs, as defined in PEP 3149 (https://peps.python.org/pep-3149/), should be searched.
โ ๏ธ Note: this hint is honored only when searching for Python version 3.
So the Python_FIND_ABI variable is a 4-tuple specifying, in this exact order: pydebug (d), pymalloc (m), unicode (u) and gil_disabled (t) flags.
Added in version 3.30: a fourth element specifying the gil_disabled flag (i.e. free threaded python) is added and is optional. If not specified, the value is OFF.
Added in version 4.4.1: the pydebug flag is now supported on Windows systems for Python 3.14+.
Each element can be set to one of these:
ON: corresponding flag is selected. โOFF: corresponding flag is not selected. โANY: both possibilities (ONandOFF) will be searched. ๐ฒ
โ ๏ธ Note: ifPython_FIND_ABIis not defined, the following defaults apply: - On POSIX systems:ANY,ANY,ANY,OFF. - On Windows systems:OFF,OFF,OFF,OFF.
From this 4-tuple, various ABIs get searched starting from the most specialized to the most general. And when ANY is specified for pydebug and gil_disabled, the debug and free threaded versions are searched after the non-debug and non-gil-disabled ones. Order matters, bestie. ๐
For example, if we have:
set (Python_FIND_ABI "ON" "ANY" "ANY" "ON")
The following flag combinations will be appended, in that order, to the artifact names:
- On POSIX systems:
tdmu,tdm,tdu, andtd. - On Windows systems:
tmu_d,tm_d,tu_d, andt_d.
And to search any possible ABIs:
set (Python_FIND_ABI "ANY" "ANY" "ANY" "ANY")
The following combinations, in that order, will be used:
- On POSIX systems:
mu,m,u,<empty>,dmu,dm,du,d,tmu,tm,tu,t,tdmu,tdm,tdu, andtd. - On Windows systems:
mu,m,u,<empty>,mu_d,m_d,u_d,_d,tmu,tm,tu,t,tmu_d,tm_d,tu_d, andt_d.
โ ๏ธ Note: this hint is fully usable on POSIX systems. On Windows systems, only thegil_disabledandpydebugflags are supported. And thepydebugflag is only supported for Python 3.14+. So on Windows, whenPython_FIND_ABIis defined, Python distributions from python.org (https://www.python.org/) will be found only if the value for the flagspymallocandunicodeisOFForANY. That's the fine print, iykyk. ๐ญ
Python_FIND_STRATEGYโ Added in version 3.15. This variable defines how the lookup will be done. You can setPython_FIND_STRATEGYto one of these:VERSION: try to find the most recent version in all specified locations. This is the default if policyCMP0094is undefined or set toOLD. ๐ฅLOCATION: stops lookup as soon as a version satisfying version constraints is founded. This is the default if policyCMP0094is set toNEW.
See also Python_FIND_UNVERSIONED_NAMES.
Python_FIND_REGISTRYโ Added in version 3.13. On Windows, thePython_FIND_REGISTRYvariable determines the order of preference between registry and environment variables. Set it to one of these:FIRST: try to use registry before environment variables. This is the default. ๐LAST: try to use registry after environment variables.NEVER: never try to use registry.
Python_FIND_FRAMEWORKโ Added in version 3.15. On macOS, thePython_FIND_FRAMEWORKvariable determines the order of preference between Apple-style and unix-style package components. It can take the same values as theCMAKE_FIND_FRAMEWORKvariable.
โ ๏ธ Note: the valueONLYis not supported, soFIRSTwill be used instead.
If Python_FIND_FRAMEWORK is not defined, the CMAKE_FIND_FRAMEWORK variable will be used, if any.
Python_FIND_VIRTUALENVโ Added in version 3.15. This variable defines the handling of virtual environments managed byvirtualenvorconda. It's meaningful only when a virtual environment is active (i.e. the activate script has been evaluated). In that case, it takes precedence over thePython_FIND_REGISTRYandCMAKE_FIND_FRAMEWORKvariables. SetPython_FIND_VIRTUALENVto one of these:FIRST: the virtual environment is used before any other standard paths to look-up for the interpreter. This is the default. ๐ฆONLY: only the virtual environment is used to look-up for the interpreter.STANDARD: the virtual environment is not used to look-up for the interpreter, but environment variablePATHis always considered. In this case, variablePython_FIND_REGISTRY(Windows) orCMAKE_FIND_FRAMEWORK(macOS) can be set with valueLASTorNEVERto select preferably the interpreter from the virtual environment. ๐ง
Added in version 3.17: added support for conda environments.
โ ๏ธ Note: if the componentDevelopmentis requested (or one of its sub-components) and is not found or the wrong artifacts are returned, including also the componentInterpretermay be helpful. ๐ก
Python_FIND_IMPLEMENTATIONSโ Added in version 3.18. This variable defines, in an ordered list, the different implementations which will be searched. It can hold the following values:CPython: this is the standard implementation. Various products, like Anaconda or ActivePython, rely on this implementation. โญIronPython: this implementation uses the CSharp language for .NET Framework on top of the Dynamic Language Runtime (DLR). See IronPython athttps://ironpython.net.PyPy: this implementation uses the RPython language and the RPython translation toolchain to produce the python interpreter. See PyPy athttps://pypy.org.
The default value is:
- Windows platform:
CPython,IronPython
- Other platforms: CPython โ literally the default one, no surprise ๐
Note: this hint has the lowest priority of all hints, bestie. So even if you, like, putIronPythonfirst andCPythonsecond, a Python product based onCPythoncan still get picked โ because, for example withPython_FIND_STRATEGY=LOCATION, each location gets searched forIronPythonfirst andCPythonsecond. The order of the hints does not fully save you ๐ญ
Note: whenIronPythonis specified, on platforms other than Windows the .Net interpreter (i.e. themonocommand) is expected to be available through thePATHvariable. No mono, no party ๐
Python_FIND_UNVERSIONED_NAMES
Added in version 3.20. โจ
This variable defines how the generic names will be searched. Currently, it only applies to the generic names of the interpreter โ namely python3 or python2 and python. You can set Python_FIND_UNVERSIONED_NAMES to one of these values:
FIRSTโ the generic names are searched before the more specialized ones (such aspython2.5, for example).LASTโ the generic names are searched after the more specialized ones. This is the default. ๐NEVERโ the generic names are not searched at all. ๐ซ
See also Python_FIND_STRATEGY.
Artifacts Specification
Added in version 3.16.
To solve special cases, it's possible to specify the artifacts directly by setting the following variables โ no searching, you just tell it where stuff lives ๐
Python_EXECUTABLE
The path to the interpreter.
Python_COMPILER
The path to the compiler.
Python_DOTNET_LAUNCHER
Added in version 3.18.
The .Net interpreter. Only used by the IronPython implementation.
Python_LIBRARY
The path to the library. It will be used to compute the variables Python_LIBRARIES, Python_LIBRARY_DIRS and Python_RUNTIME_LIBRARY_DIRS.
Python_SABI_LIBRARY
Added in version 3.26.
The path to the library for Stable Application Binary Interface. It will be used to compute the variables Python_SABI_LIBRARIES, Python_SABI_LIBRARY_DIRS and Python_RUNTIME_SABI_LIBRARY_DIRS.
Python_INCLUDE_DIR
The path to the directory of the Python headers. It will be used to compute the variable Python_INCLUDE_DIRS.
Python_NumPy_INCLUDE_DIR
The path to the directory of the NumPy headers. It will be used to compute the variable Python_NumPy_INCLUDE_DIRS.
Note: all paths must be absolute. Any artifact specified with a relative path will just be ignored, sorry babe ๐
Note: when an artifact is specified, all HINTS will be ignored and no search will be performed for this artifact. If more than one artifact is specified, it is the user's responsibility to ensure the consistency of the various artifacts. That's on you, bestie ๐ซถ
By default, this module supports multiple calls in different directories of a project with different version/component requirements while providing correct and consistent results for each call. To support this behavior, the CMake cache is not used in the traditional way, which can be problematic for interactive specification. So, to enable also interactive specification, the module behavior can be controlled with the following variable:
Python_ARTIFACTS_INTERACTIVE
Added in version 3.18.
Selects the behavior of the module. It's a boolean variable:
- If set to
TRUE: create CMake cache entries for the above artifact specification variables so that users can edit them interactively. This disables support for multiple version/component requirements. โ ๏ธ - If set to
FALSEor undefined: enable multiple version/component requirements.
Python_ARTIFACTS_PREFIX
Added in version 4.0.
Define a custom prefix which will be used for the definition of all the result variables, targets, and commands. By using this variable, this module supports multiple calls in the same directory with different version/component requirements. For example, in case of cross-compilation, development components are needed but the native python interpreter can also be required:
find_package(Python COMPONENTS Development)
set(Python_ARTIFACTS_PREFIX "_HOST")
find_package(Python COMPONENTS Interpreter)
# Here Python_HOST_EXECUTABLE and Python_HOST::Interpreter artifacts are defined
Note: for consistency with standard behavior of modules, the various standard_FOUNDvariables (i.e. the ones without the custom prefix) are also defined by each call to thefind_package()command.
Commands
This module defines the command Python_add_library (when CMAKE_ROLE is PROJECT), which has the same semantics as add_library() and adds a dependency to target Python::Python or, when the library type is MODULE, to target Python::Module or Python::SABIModule (when the USE_SABI option is specified) โ and takes care of Python module naming rules ๐
Python_add_library (<name> [STATIC | SHARED | MODULE [USE_SABI <version>] [WITH_SOABI]]
<source1> [<source2> ...])
If the library type is not specified, MODULE is assumed.
Added in version 3.17: for MODULE library type, if the option WITH_SOABI is specified, the module suffix will include the Python_SOABI value, if any. โจ
Added in version 3.26: for MODULE type, if the option USE_SABI is specified, the preprocessor definition Py_LIMITED_API will be specified, as PRIVATE, for the target <name> with the value computed from the <version> argument. The expected format for <version> is major[.minor], where each component is a numeric value. If the minor component is specified, the version should be, at least, 3.2, which is the version where the Stable Application Binary Interface was introduced. Specifying only major version 3 is equivalent to 3.2.
Changed in version 4.4: when USE_SABI is specified, if Python_FREE_THREADED is true and the Python version is 3.15 or upper, the Py_TARGET_ABI3T preprocessor definition will be defined rather than Py_LIMITED_API (see PEP 803 for more details). ๐
When the option WITH_SOABI is also specified, the module suffix will include the Python_SOSABI value, if any.
Added in version 3.30: for MODULE type, the DEBUG_POSTFIX target property is initialized with the value of the Python_DEBUG_POSTFIX variable if defined.
FindPython2
Added in version 3.12.
Finds the Python 2 interpreter, compiler and development environment (include directories and libraries):
find_package(Python2 [<version>] [COMPONENTS <components>...] [...])
Added in version 3.19: when a version is requested, it can be specified as a simple value or as a range. For a detailed description of version range usage and capabilities, refer to the find_package() command.
The following components are supported:
Interpreterโ search for Python 2 interpreter ๐Compilerโ search for Python 2 compiler. Only offered byIronPython.Developmentโ search for development artifacts (include directories and libraries). Added in version 3.18: this component includes two sub-components which can be specified independently:Development.Moduleโ search for artifacts for Python 2 module developments.Development.Embedโ search for artifacts for Python 2 embedding developments.
- Added in version 3.14:
NumPyโ search for NumPy include directories. Specifying this component implies also the componentsInterpreterandDevelopment.Module.
Changed in version 4.2: the component Development.Module is no longer implied when the policy CMP0201 is set to NEW.
If no COMPONENTS are specified, Interpreter is assumed.
If component Development is specified, it implies the sub-components Development.Module and Development.Embed.
Changed in version 4.1: in a cross-compiling mode (i.e. the CMAKE_CROSSCOMPILING variable is defined to true), the following constraints, when the policy CMP0190 is set to NEW, now apply to the requested components:
InterpreterorCompileralone: the host artifacts will be searched. ๐ฅ๏ธInterpreterorCompilerwithDevelopmentor any sub-component: the target artifacts will be searched. In this case, theCMAKE_CROSSCOMPILING_EMULATORvariable must be defined and will be used to execute the interpreter or the compiler. โ ๏ธ
When both host and target artifacts are needed, two different calls to the find_package() command should be done. The Python_ARTIFACTS_PREFIX variable can be helpful in this situation. ๐ก
To ensure consistent versions between components Interpreter, Compiler, Development (or one of its sub-components) and NumPy, specify all components at the same time:
find_package (Python2 COMPONENTS Interpreter Development)
This module looks only for version 2 of Python. This module can be used concurrently with the FindPython3 module to use both Python versions. Slay ๐
The FindPython module can be used if the Python version does not matter for you.
Note: if componentsInterpreterandDevelopment(or one of its sub-components) are both specified, this module searches only for an interpreter with the same platform architecture as the one defined by the CMake configuration. This constraint does not apply if only theInterpretercomponent is specified.
Imported Targets
This module provides the following Imported Targets:
Changed in version 3.14: Imported Targets are only created when CMAKE_ROLE is PROJECT. ๐
Python2::Interpreter
Python 2 interpreter. This target is defined only if the Interpreter component is found.
Python2::InterpreterDebug
Added in version 3.30.
Python 2 debug interpreter. This target is defined only if the Interpreter component is found and the Python2_EXECUTABLE_DEBUG variable is defined. The target is only defined on the Windows platform. ๐ช
Python2::InterpreterMultiConfig
Added in version 3.30.
Python 2 interpreter. The release or debug version of the interpreter will be used, based on the context (platform, configuration). This target is defined only if the Interpreter component is found ๐
Python2::Compilerโ the Python 2 compiler, bestie. This target only shows up if theCompilercomponent is found. no compiler, no target, that's the vibe ๐Python2::Moduleโ Added in version 3.15. It's the Python 2 library for a Python module. Target gets defined if the componentDevelopment.Moduleis found โจPython2::Pythonโ the Python 2 library for Python embedding. Target is defined if componentDevelopment.Embedis found ๐ซถPython2::NumPyโ Added in version 3.14. The NumPy library for Python 2. Target is defined if componentNumPyis found. And also โ this target has thePython2::Moduletarget as a dependency, iykyk.
Changed in version 4.2: this target does not have the Python2::Module target as a dependency anymore when the policy CMP0201 is set to NEW. periodt.
๐ธ Result Variables ๐ธ
This module defines the following variables (peep the Standard Variable Names page for the lore):
Python2_FOUNDโ boolean, tells you whether the system has the Python 2 components you asked for ๐Python2_Interpreter_FOUNDโ boolean, tells you whether the system has the Python 2 interpreter.Python2_EXECUTABLEโ path to the Python 2 interpreter.Python2_EXECUTABLE_DEBUGโ Added in version 3.30. Path to the debug Python 2 interpreter. It's only defined on the Windows platform, ngl.Python2_INTERPRETERโ Added in version 3.30. Path to the Python 2 interpreter, defined as a generator expression that picks thePython2_EXECUTABLEorPython2_EXECUTABLE_DEBUGvariable based on the context (platform, configuration). lowkey genius โจPython2_INTERPRETER_IDโ a short string unique to the interpreter. Possible values include:PythonActivePythonAnacondaCanopyIronPythonPyPy
Python2_STDLIBโ standard platform independent installation directory. Info comes back fromsysconfig.get_path('stdlib')or elsedistutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True).Python2_STDARCHโ standard platform dependent installation directory. Info returned bysysconfig.get_path('platstdlib')or elsedistutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True).Python2_SITELIBโ third-party platform independent installation directory. Info returned bysysconfig.get_path('purelib')or elsedistutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False).Python2_SITEARCHโ third-party platform dependent installation directory. Info returned bysysconfig.get_path('platlib')or elsedistutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False).Python2_Compiler_FOUNDโ boolean, tells you whether the system has the Python 2 compiler.Python2_COMPILERโ path to the Python 2 compiler. Only offered by IronPython, fun fact ๐ฆPython2_COMPILER_IDโ a short string unique to the compiler. Possible values include:IronPython
Python2_DOTNET_LAUNCHERโ Added in version 3.18. The .Net interpreter. Only used by the IronPython implementation.Python2_Development_FOUNDโ boolean, tells you whether the system has the Python 2 development artifacts.Python2_Development.Module_FOUNDโ Added in version 3.18. Boolean, tells you whether the system has the Python 2 development artifacts for a Python module.Python2_Development.Embed_FOUNDโ Added in version 3.18. Boolean, tells you whether the system has the Python 2 development artifacts for Python embedding.Python2_INCLUDE_DIRSโ the Python 2 include directories ๐Python2_DEBUG_POSTFIXโ Added in version 3.30. Postfix of the debug python module. You can use this variable to define theDEBUG_POSTFIXtarget property.Python2_LINK_OPTIONSโ Added in version 3.19. The Python 2 link options. Some configurations need specific link options for a correct build and execution, so likeโฆ don't skip these ๐Python2_LIBRARIESโ the Python 2 libraries.Python2_LIBRARY_DIRSโ the Python 2 library directories.Python2_RUNTIME_LIBRARY_DIRSโ the Python 2 runtime library directories.Python2_VERSIONโ Python 2 version.Python2_VERSION_MAJORโ Python 2 major version.Python2_VERSION_MINORโ Python 2 minor version.Python2_VERSION_PATCHโ Python 2 patch version.Python2_PyPy_VERSIONโ Added in version 3.18. Python 2 PyPy version.Python2_NumPy_FOUNDโ Added in version 3.14. Boolean, tells you whether the system has NumPy.Python2_NumPy_INCLUDE_DIRSโ Added in version 3.14. The NumPy include directories.Python2_NumPy_VERSIONโ Added in version 3.14. The NumPy version.
๐ Hints ๐
Python2_ROOT_DIRโ define the root directory of a Python 2 installation. like, "hey, it's over here" energy ๐Python2_USE_STATIC_LIBSโ the whole static-vs-shared situation:- If not defined, search for shared libraries and static libraries in that order.
- If set to
TRUE, search only for static libraries. - If set to
FALSE, search only for shared libraries.
Note: this hint gets ignored on Windows because static libraries are not available on this platform. not me finding out the hard way ๐
Python2_FIND_STRATEGYโ Added in version 3.15. This variable defines how the lookup will be done. You can setPython2_FIND_STRATEGYto one of these:VERSION: try to find the most recent version in all specified locations. This is the default if policyCMP0094is undefined or set toOLD.LOCATION: stops the lookup as soon as a version satisfying the version constraints is found. This is the default if policyCMP0094is set toNEW.
See also Python2_FIND_UNVERSIONED_NAMES. ๐ซถ
Python2_FIND_REGISTRYโ Added in version 3.13. On Windows, thePython2_FIND_REGISTRYvariable determines the order of preference between registry and environment variables. It can be set to one of the following:FIRST: try to use the registry before environment variables. This is the default.LAST: try to use the registry after environment variables.NEVER: never try to use the registry.
Python2_FIND_FRAMEWORKโ Added in version 3.15. On macOS, thePython2_FIND_FRAMEWORKvariable determines the order of preference between Apple-style and unix-style package components. This variable can take the same values as theCMAKE_FIND_FRAMEWORKvariable.
Note: the valueONLYis not supported, soFIRSTwill be used instead. ok werk ๐
If Python2_FIND_FRAMEWORK is not defined, the CMAKE_FIND_FRAMEWORK variable will be used, if any.
Python2_FIND_VIRTUALENVโ Added in version 3.15. This variable defines the handling of virtual environments managed byvirtualenvorconda. It's only meaningful when a virtual environment is active (i.e. theactivatescript has been evaluated). In that case, it takes precedence over thePython2_FIND_REGISTRYandCMAKE_FIND_FRAMEWORKvariables. You can setPython2_FIND_VIRTUALENVto one of the following:FIRST: the virtual environment is used before any other standard paths to look up the interpreter. This is the default.ONLY: only the virtual environment is used to look up the interpreter.STANDARD: the virtual environment is not used to look up the interpreter, but the environment variablePATHis always considered. In this case, the variablePython2_FIND_REGISTRY(Windows) orCMAKE_FIND_FRAMEWORK(macOS) can be set with the valueLASTorNEVERto preferably select the interpreter from the virtual environment.
Added in version 3.17: added support for conda environments. ๐
Note: if the componentDevelopmentis requested (or one of its sub-components) and it's not found, or the wrong artifacts come back, including the componentInterpretertoo may be helpful. little pro move, you're welcome โจ
Python2_FIND_IMPLEMENTATIONSโ Added in version 3.18. This variable defines, as an ordered list, the different implementations that will be searched.Python2_FIND_IMPLEMENTATIONScan hold the following values:CPython: this is the standard implementation. Various products, like Anaconda or ActivePython, rely on this implementation.IronPython: this implementation uses the CSharp language for .NET Framework on top of the Dynamic Language Runtime (DLR). See IronPython athttps://ironpython.net.PyPy: this implementation uses the RPython language and the RPython translation toolchain to produce the python interpreter. See PyPy athttps://pypy.org.
The default value is:
- Windows platform:
CPython, IronPython - Other platforms:
CPython
Note: this hint has the lowest priority of all the hints, so even if, for example, you specifyIronPythonfirst andCPythonsecond, a python product based on CPython can still be selected โ because, for example withPython2_FIND_STRATEGY=LOCATION, each location will be searched first for IronPython and second for CPython. the way that ordering is not what you think ๐ญ
Note: whenIronPythonis specified on platforms other than Windows, the .Net interpreter (i.e. themonocommand) is expected to be available through thePATHvariable.
Python2_FIND_UNVERSIONED_NAMESโ Added in version 3.20. This variable defines how the generic names will be searched. Currently it only applies to the generic names of the interpreter, namelypython2andpython. You can setPython2_FIND_UNVERSIONED_NAMESto one of the following values:FIRST: the generic names are searched before the more specialized ones (such aspython2.5, for example).
LASTโ the generic names get searched after the more specialized ones. This is the default, bestie, so if you don't touch anything, this is what you're getting. ๐NEVERโ the generic names are not searched at all. Like, zero, none, don't even look. ๐
Also peep Python2_FIND_STRATEGY for the full picture on this one, iykyk.
โจ Artifacts Specification โจ
Added in version 3.16.
Okay so sometimes stuff is extra and you just gotta skip the whole search and say "bestie, here's the artifact, take it." That's literally what this is โ you set these variables directly:
Python2_EXECUTABLEโ the path to the interpreter. ๐Python2_COMPILERโ the path to the compiler.Python2_DOTNET_LAUNCHERโ Added in version 3.18. The .Net interpreter. Only used by the IronPython implementation.Python2_LIBRARYโ the path to the library. It will be used to compute the variablesPython2_LIBRARIES,Python2_LIBRARY_DIRSandPython2_RUNTIME_LIBRARY_DIRS.Python2_INCLUDE_DIRโ the path to the directory of the Python headers. It will be used to compute the variablePython2_INCLUDE_DIRS.Python2_NumPy_INCLUDE_DIRโ the path to the directory of the NumPy headers. It will be used to compute the variablePython2_NumPy_INCLUDE_DIRS.
Note: all paths must be absolute. Any artifact specified with a relative path will be, like, completely ignored. No cap. ๐ซ
Note: when an artifact is specified, all HINTS will be ignored and no search will be performed for this artifact. And if more than one artifact is specified, it is the user's responsibility to ensure the consistency of the various artifacts. That's on you, queen. ๐
By default, this module supports multiple calls in different directories of a project with different version/component requirements while providing correct and consistent results for each call. To support this behavior, the CMake cache is not used in the traditional way โ which can be problematic for interactive specification. So, to enable also interactive specification, module behavior can be controlled with the following variable:
Python2_ARTIFACTS_INTERACTIVEโ Added in version 3.18. Selects the behavior of the module. This is a boolean variable:- If set to
TRUE: create CMake cache entries for the above artifact specification variables so that users can edit them interactively. This disables support for multiple version/component requirements. - If set to
FALSEor undefined: enable multiple version/component requirements.
- If set to
Python2_ARTIFACTS_PREFIXโ Added in version 4.0. Defines a custom prefix which will be used for the definition of all the result variables, targets, and commands. By using this variable, this module supports multiple calls in the same directory with different version/component requirements. Like, for example, in case of cross-compilation, development components are needed but the native python interpreter can also be required:
find_package(Python2 COMPONENTS Development)
set(Python2_ARTIFACTS_PREFIX "_HOST")
find_package(Python2 COMPONENTS Interpreter)
# Here Python2_HOST_EXECUTABLE and Python2_HOST::Interpreter artifacts are defined
Note: for consistency with standard behavior of modules, the various standard_FOUNDvariables (i.e. without the custom prefix) are also defined by each call to thefind_package()command. ๐ซถ
๐ ๏ธ Commands ๐ ๏ธ
This module defines the command Python2_add_library (when CMAKE_ROLE is PROJECT), which has the same semantics as add_library() and adds a dependency to target Python2::Python or, when the library type is MODULE, to target Python2::Module โ and it takes care of Python module naming rules:
Python2_add_library (<name> [STATIC | SHARED | MODULE]
<source1> [<source2> ...])
If the library type is not specified, MODULE is assumed.
Added in version 3.30: for MODULE type, the DEBUG_POSTFIX target property is initialized with the value of the Python2_DEBUG_POSTFIX variable if defined. ๐
๐ FindPython3 ๐
Added in version 3.12.
Finds the Python 3 interpreter, compiler and development environment (include directories and libraries):
find_package(Python3 [<version>] [COMPONENTS <components>...] [...])
Added in version 3.19: when a version is requested, it can be specified as a simple value or as a range. For a detailed description of version range usage and capabilities, refer to the find_package() command.
The following components are supported:
Interpreter: search for Python 3 interpreter.Compiler: search for Python 3 compiler. Only offered by IronPython.Development: search for development artifacts (include directories and libraries).- Added in version 3.18: this component includes two sub-components which can be specified independently:
Development.Module: search for artifacts for Python 3 module developments.Development.Embed: search for artifacts for Python 3 embedding developments.
- Added in version 3.26:
Development.SABIModule: search for artifacts for Python 3 module developments using the Stable Application Binary Interface. This component is available only for version3.2and upper. ๐
- Added in version 3.18: this component includes two sub-components which can be specified independently:
- Added in version 3.14:
NumPy: search for NumPy include directories. Specifying this component implies also the componentsInterpreterandDevelopment.Module.
Changed in version 4.2: the component Development.Module is no longer implied when the policy CMP0201 is set to NEW.
If no COMPONENTS are specified, Interpreter is assumed.
If component Development is specified, it implies sub-components Development.Module and Development.Embed.
Changed in version 4.1: in a cross-compiling mode (i.e. the CMAKE_CROSSCOMPILING variable is defined to true), the following constraints, when the policy CMP0190 is set to NEW, now apply to the requested components:
InterpreterorCompileralone: the host artifacts will be searched.InterpreterorCompilerwithDevelopmentor any sub-component: the target artifacts will be searched. In this case, theCMAKE_CROSSCOMPILING_EMULATORvariable must be defined and will be used to execute the interpreter or the compiler.
When both host and target artifacts are needed, two different calls to the find_package() command should be done. The Python_ARTIFACTS_PREFIX variable can be helpful in this situation. โจ
To ensure consistent versions between components Interpreter, Compiler, Development (or one of its sub-components) and NumPy, specify all components at the same time:
find_package (Python3 COMPONENTS Interpreter Development)
This module looks only for version 3 of Python. This module can be used concurrently with the FindPython2 module to use both Python versions. ๐ฏ
The FindPython module can be used if the Python version does not matter for you.
Note: if componentsInterpreterandDevelopment(or one of its sub-components) are both specified, this module searches only for an interpreter with the same platform architecture as the one defined by the CMake configuration. This constraint does not apply if only theInterpretercomponent is specified. ๐ง
๐ Imported Targets ๐
This module provides the following Imported Targets:
Changed in version 3.14: Imported Targets are only created when CMAKE_ROLE is PROJECT.
Python3::Interpreterโ Python 3 interpreter. This target is defined only if theInterpretercomponent is found.Python3::InterpreterDebugโ Added in version 3.30. Python 3 debug interpreter. This target is defined only if theInterpretercomponent is found and thePython3_EXECUTABLE_DEBUGvariable is defined. The target is only defined on the Windows platform. ๐ชPython3::InterpreterMultiConfigโ Added in version 3.30. Python 3 interpreter. The release or debug version of the interpreter will be used, based on the context (platform, configuration). This target is defined only if theInterpretercomponent is found.Python3::Compilerโ Python 3 compiler. This target is defined only if theCompilercomponent is found.Python3::Moduleโ Added in version 3.15. Python 3 library for Python module. Target defined if componentDevelopment.Moduleis found.Python3::SABIModuleโ Added in version 3.26. Python 3 library for Python module using the Stable Application Binary Interface. Target defined if componentDevelopment.SABIModuleis found. ๐Python3::Pythonโ Python 3 library for Python embedding. Target defined if componentDevelopment.Embedis found.Python3::NumPyโ Added in version 3.14. NumPy library for Python 3. Target defined if componentNumPyis found. Moreover, this target has thePython3::Moduletarget as dependency.- Changed in version 4.2: this target does not have anymore the
Python3::Moduletarget as dependency when the policyCMP0201is set toNEW.
- Changed in version 4.2: this target does not have anymore the
๐ Result Variables ๐
This module defines the following variables (see Standard Variable Names):
Python3_FOUNDโ Boolean indicating whether the system has the Python 3 requested components.Python3_Interpreter_FOUNDโ Boolean indicating whether the system has the Python 3 interpreter.Python3_EXECUTABLEโ path to the Python 3 interpreter. ๐Python3_EXECUTABLE_DEBUGโ Added in version 3.30. Path to the debug Python 3 interpreter. It is only defined on the Windows platform.Python3_INTERPRETERโ Added in version 3.30. Path to the Python 3 interpreter, defined as a generator expression selecting thePython3_EXECUTABLEorPython3_EXECUTABLE_DEBUGvariable based on the context (platform, configuration). โจPython3_INTERPRETER_IDโ a short string unique to the interpreter. Possible values include:PythonActivePythonAnacondaCanopyIronPythonPyPy
Python3_FREE_THREADEDโ Added in version 4.4.
Boolean value, which is true if the python is free threaded (i.e. config var Py_GIL_DISABLED has value 1), false otherwise. ๐งต
Python3_STDLIBโ the standard platform independent installation directory. This is literally just whatsysconfig.get_path('stdlib')hands back, no cap. โจPython3_STDARCHโ the standard platform dependent installation directory. Comes straight fromsysconfig.get_path('platstdlib'). ๐Python3_SITELIBโ the third-party platform independent installation directory, akasysconfig.get_path('purelib'). ๐Python3_SITEARCHโ the third-party platform dependent installation directory, akasysconfig.get_path('platlib'). ๐ฆPython3_SOABIโ Added in version 3.17. The extension suffix for modules. It's computed fromsysconfig.get_config_var('EXT_SUFFIX')orsysconfig.get_config_var('SOABI')orpython3-config --extension-suffix. ๐ธPython3_SOSABIโ Added in version 3.26. The extension suffix for modules using the Stable Application Binary Interface. Computed fromimportlib.machinery.EXTENSION_SUFFIXESif theCOMPONENTInterpreterwas specified. Otherwise the extension isabi3orabi3tโ except on Windows, MSYS and CYGWIN, where it's just an empty string. ๐Python3_Compiler_FOUNDโ boolean, tells you whether the system has the Python 3 compiler. ๐Python3_COMPILERโ path to the Python 3 compiler. Only IronPython offers this one. ๐ฅPython3_COMPILER_IDโ a short string that's unique to the compiler. Possible values include:IronPython
Python3_DOTNET_LAUNCHERโ Added in version 3.18. The .Net interpreter. Only used by the IronPython implementation. โญPython3_Development_FOUNDโ boolean, tells you whether the system has the Python 3 development artifacts.Python3_Development.Module_FOUNDโ Added in version 3.18. Boolean, tells you whether the system has the Python 3 development artifacts for a Python module. ๐Python3_Development.SABIModule_FOUNDโ Added in version 3.26. Boolean, tells you whether the system has the Python 3 development artifacts for a Python module using the Stable Application Binary Interface. ๐Python3_Development.Embed_FOUNDโ Added in version 3.18. Boolean, tells you whether the system has the Python 3 development artifacts for Python embedding. ๐
Python3_INCLUDE_DIRSโ the Python 3 include directories.Python3_DEFINITIONSโ Added in version 3.30.3. The Python 3 preprocessor definitions. ๐Python3_DEBUG_POSTFIXโ Added in version 3.30. The postfix of the debug python module. You can use this variable to define theDEBUG_POSTFIXtarget property. โจPython3_LINK_OPTIONSโ Added in version 3.19. The Python 3 link options. Heads up: some configurations genuinely need specific link options to build and execute correctly. ๐Python3_LIBRARIESโ the Python 3 libraries.Python3_LIBRARY_DIRSโ the Python 3 library directories.Python3_RUNTIME_LIBRARY_DIRSโ the Python 3 runtime library directories.Python3_SABI_LIBRARIESโ Added in version 3.26. The Python 3 libraries for the Stable Application Binary Interface. ๐ฆPython3_SABI_LIBRARY_DIRSโ Added in version 3.26. The Python 3 SABI library directories.Python3_RUNTIME_SABI_LIBRARY_DIRSโ Added in version 3.26. The Python 3 runtime SABI library directories.Python3_VERSIONโ the Python 3 version.Python3_VERSION_MAJORโ the Python 3 major version.Python3_VERSION_MINORโ the Python 3 minor version.Python3_VERSION_PATCHโ the Python 3 patch version.Python3_PyPy_VERSIONโ Added in version 3.18. The Python 3 PyPy version. ๐Python3_NumPy_FOUNDโ Added in version 3.14. Boolean, tells you whether the system has NumPy. ๐Python3_NumPy_INCLUDE_DIRSโ Added in version 3.14. The NumPy include directories.Python3_NumPy_VERSIONโ Added in version 3.14. The NumPy version.
โจ Hints โจ
Python3_ROOT_DIRโ define the root directory of a Python 3 installation. ๐Python3_USE_STATIC_LIBSโ this one's a vibe check on which libraries you want:- If it's not defined, it searches for shared libraries and static libraries, in that order.
- If it's set to
TRUE, it searches only for static libraries. - If it's set to
FALSE, it searches only for shared libraries.
Note: this hint gets ignored on Windows, because static libraries literally aren't available on that platform. ๐ญ
Python3_FIND_ABIโ Added in version 3.16. This variable defines which ABIs โ as defined in PEP 3149 (https://peps.python.org/pep-3149/) โ should be searched. ๐
The Python3_FIND_ABI variable is a 4-tuple specifying, in that order, the pydebug (d), pymalloc (m), unicode (u) and gil_disabled (t) flags.
Added in version 3.30: a fourth element, specifying the gil_disabled flag (i.e. free threaded python), is added and is optional. If it's not specified, the value is OFF.
Added in version 4.4.1: the pydebug flag is now supported on Windows systems for Python 3.14+.
Each element can be set to one of these:
ON: the corresponding flag is selected.OFF: the corresponding flag is not selected.ANY: both possibilities (ONandOFF) will be searched. ๐
Note: ifPython3_FIND_ABIis not defined, these are the defaults that apply: - On POSIX systems:ANY,ANY,ANY,OFF. - On Windows systems:OFF,OFF,OFF,OFF.
From this 4-tuple, various ABIs get searched starting from the most specialized and going to the most general. Also, when ANY is specified for pydebug and gil_disabled, debug and free threaded versions get searched after the non-debug and non-gil-disabled ones. ๐ซ
For example, if we have:
set (Python3_FIND_ABI "ON" "ANY" "ANY" "ON")
The following flag combinations will be appended, in that order, to the artifact names:
- On POSIX systems:
tdmu,tdm,tdu, andtd. - On Windows systems:
tmu_d,tm_d,tu_d, andt_d.
And to search any possible ABIs:
set (Python3_FIND_ABI "ANY" "ANY" "ANY" "ANY")
The following combinations, in that order, will be used:
- On POSIX systems:
mu,m,u,<empty>,dmu,dm,du,d,tmu,tm,tu,t,tdmu,tdm,tdu, andtd. - On Windows systems:
mu,m,u,<empty>,mu_d,m_d,u_d,_d,tmu,tm,tu,t,tmu_d,tm_d,tu_d, andt_d. ๐
Note: this hint is fully usable on POSIX systems. On Windows systems, only thegil_disabledandpydebugflags are supported. And on top of that, thepydebugflag is only supported for Python 3.14+. So on Windows systems, whenPython3_FIND_ABIis defined, Python distributions from python.org (https://www.python.org/) will be found only if the value for the flagspymallocandunicodeisOFForANY. ๐
Python3_FIND_STRATEGYโ Added in version 3.15. Defines how lookup gets done. You can setPython3_FIND_STRATEGYto one of these:VERSION: try to find the most recent version in all the specified locations. This is the default if policyCMP0094is undefined or set toOLD.LOCATION: stops lookup as soon as a version satisfying the version constraints is found. This is the default if policyCMP0094is set toNEW. ๐ฏ
See also Python3_FIND_UNVERSIONED_NAMES.
Python3_FIND_REGISTRYโ Added in version 3.13. On Windows, this variable determines the order of preference between registry and environment variables. You can set it to one of these:FIRST: try to use the registry before environment variables. This is the default.LAST: try to use the registry after environment variables.NEVER: never try to use the registry. ๐ โโ๏ธ
Python3_FIND_FRAMEWORKโ Added in version 3.15. On macOS, this variable determines the order of preference between Apple-style and unix-style package components. It can take the same values as theCMAKE_FIND_FRAMEWORKvariable.
Note: the valueONLYis not supported, soFIRSTgets used instead. ๐
If Python3_FIND_FRAMEWORK isn't defined, the CMAKE_FIND_FRAMEWORK variable gets used, if there is one. ๐
Python3_FIND_VIRTUALENVโ Added in version 3.15. This one defines the handling of virtual environments managed byvirtualenvorconda. It's only meaningful when a virtual environment is active (i.e. theactivatescript has been evaluated). When that's the case, it takes precedence over thePython3_FIND_REGISTRYandCMAKE_FIND_FRAMEWORKvariables. You can setPython3_FIND_VIRTUALENVto one of these:FIRST: the virtual environment gets used before any other standard paths when looking up the interpreter. This is the default. ๐ONLY: only the virtual environment is used to look up the interpreter.STANDARD: the virtual environment isn't used to look up the interpreter, but the environment variablePATHis always considered. In this case, the variablePython3_FIND_REGISTRY(Windows) orCMAKE_FIND_FRAMEWORK(macOS) can be set with the valueLASTorNEVERto select preferably the interpreter from the virtual environment. ๐ธ
Added in version 3.17: added support for conda environments.
Note: if the componentDevelopmentis requested (or one of its sub-components) and it isn't found, or the wrong artifacts get returned, including the componentInterpreteras well may be helpful. ๐ซถ
Python3_FIND_IMPLEMENTATIONSโ Added in version 3.18.
This variable defines, in an ordered list, the different implementations which will be searched. The Python3_FIND_IMPLEMENTATIONS variable can hold the following values:
CPythonโ this is the standard implementation. Various products, like Anaconda or ActivePython, rely on this implementation. ๐IronPythonโ This implementation use the CSharp language for .NET Framework on top of the Dynamic Language Runtime (DLR). See IronPython <https://ironpython.net>. ๐ฆPyPyโ This implementation use RPython language and RPython translation toolchain to produce the python interpreter. See PyPy <https://pypy.org>. ๐ธ
The default value is:
- Windows platform:
CPython,IronPython๐ - Other platforms:
CPythonโจ
Note: This hint has the lowest priority of all hints, so even if, for example, you specifyIronPythonfirst andCPythonin second, a python product based onCPythoncan be selected because, for example withPython3_FIND_STRATEGY=LOCATION, each location will be search first forIronPythonand second forCPython. ๐ like, it's a hint, bestie, not a command, okay??
Note: WhenIronPythonis specified, on platforms other than Windows, the .Net interpreter (i.e.monocommand) is expected to be available through thePATHvariable. ๐ซถ
Python3_FIND_UNVERSIONED_NAMES โ Added in version 3.20.
This variable defines how the generic names will be searched. Currently, it only applies to the generic names of the interpreter, namely, python3 and python. The Python3_FIND_UNVERSIONED_NAMES variable can be set to one of the following values:
FIRSTโ The generic names are searched before the more specialized ones (such aspython3.5for example). ๐ฅLASTโ The generic names are searched after the more specialized ones. This is the default. ๐NEVERโ The generic name are not searched at all. ๐
See also Python3_FIND_STRATEGY. ๐
โจ Artifacts Specification โจ
Added in version 3.16.
To solve special cases, it is possible to specify directly the artifacts by setting the following variables:
Python3_EXECUTABLEโ The path to the interpreter. ๐งPython3_COMPILERโ The path to the compiler. ๐Python3_DOTNET_LAUNCHERโ Added in version 3.18. The .Net interpreter. Only used byIronPythonimplementation. ๐ฆPython3_LIBRARYโ The path to the library. It will be used to compute the variablesPython3_LIBRARIES,Python3_LIBRARY_DIRSandPython3_RUNTIME_LIBRARY_DIRS. ๐Python3_SABI_LIBRARYโ Added in version 3.26. The path to the library for Stable Application Binary Interface. It will be used to compute the variablesPython3_SABI_LIBRARIES,Python3_SABI_LIBRARY_DIRSandPython3_RUNTIME_SABI_LIBRARY_DIRS. โญPython3_INCLUDE_DIRโ The path to the directory of the Python headers. It will be used to compute the variablePython3_INCLUDE_DIRS. ๐ธPython3_NumPy_INCLUDE_DIRโ The path to the directory of the NumPy headers. It will be used to compute the variablePython3_NumPy_INCLUDE_DIRS. ๐
Note: All paths must be absolute. Any artifact specified with a relative path will be ignored. no cap, it will simply not see it ๐ญ
Note: When an artifact is specified, all HINTS will be ignored and no search will be performed for this artifact. If more than one artifact is specified, it is the user's responsibility to ensure the consistency of the various artifacts. ๐ that's on you, bestie
By default, this module supports multiple calls in different directories of a project with different version/component requirements while providing correct and consistent results for each call. To support this behavior, CMake cache is not used in the traditional way which can be problematic for interactive specification. So, to enable also interactive specification, module behavior can be controlled with the following variable:
Python3_ARTIFACTS_INTERACTIVE โ Added in version 3.18.
Selects the behavior of the module. This is a boolean variable:
- If set to
TRUE: Create CMake cache entries for the above artifact specification variables so that users can edit them interactively. This disables support for multiple version/component requirements. ๐ - If set to
FALSEor undefined: Enable multiple version/component requirements. โจ
Python3_ARTIFACTS_PREFIX โ Added in version 4.0.
Define a custom prefix which will be used for the definition of all the result variables, targets, and commands. By using this variable, this module supports multiple calls in the same directory with different version/component requirements. For example, in case of cross-compilation, development components are needed but the native python interpreter can also be required:
find_package(Python3 COMPONENTS Development)
set(Python3_ARTIFACTS_PREFIX "_HOST")
find_package(Python3 COMPONENTS Interpreter)
# Here Python3_HOST_EXECUTABLE and Python3_HOST::Interpreter artifacts are defined
Note: For consistency with standard behavior of modules, the various standard_FOUNDvariables (i.e. without the custom prefix) are also defined by each call to thefind_package()command. ๐
๐ Commands ๐
This module defines the command Python3_add_library (when CMAKE_ROLE is PROJECT), which has the same semantics as add_library() and adds a dependency to target Python3::Python or, when library type is MODULE, to target Python3::Module or Python3::SABIModule (when USE_SABI option is specified) and takes care of Python module naming rules:
Python3_add_library (<name> [STATIC | SHARED | MODULE [USE_SABI <version>] [WITH_SOABI]]
<source1> [<source2> ...])
If the library type is not specified, MODULE is assumed. ๐ซถ
Added in version 3.17: For MODULE library type, if option WITH_SOABI is specified, the module suffix will include the Python3_SOABI value, if any.
Added in version 3.26: For MODULE type, if the option USE_SABI is specified, the preprocessor definition Py_LIMITED_API will be specified, as PRIVATE, for the target <name> with the value computed from <version> argument. The expected format for <version> is major[.minor], where each component is a numeric value. If minor component is specified, the version should be, at least, 3.2 which is the version where the Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html> was introduced. Specifying only major version 3 is equivalent to 3.2. ๐ค
Changed in version 4.4: When USE_SABI is specified, if Python3_FREE_THREADED is true and Python version is 3.15 or upper, Py_TARGET_ABI3T preprocessor definition will be defined rather than Py_LIMITED_API (see PEP 803 <https://peps.python.org/pep-0803/> for more details). ๐
When option WITH_SOABI is also specified, the module suffix will include the Python3_SOSABI value, if any.
Added in version 3.30: For MODULE type, the DEBUG_POSTFIX target property is initialized with the value of Python3_DEBUG_POSTFIX variable if defined. ๐
๐ FindQt3 ๐
Finds Qt3, a cross-platform application development framework for creating graphical user interfaces and applications:
find_package(Qt3 [<version>] [...])
Note: This module is for Qt version 3. As of Qt version 5, the Qt upstream also provides an exported configuration to find Qt. New code should follow the cmake-qt(7) instead of using this module. ๐ like, she's iconic but she's retired, bestie
๐ Result Variables ๐
This module defines the following variables:
Qt3_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) Qt3 was found. โจQT_FOUNDโ Same asQt3_FOUND. Boolean indicating whether (the requested version of) Qt3 was found. This variable is provided for compatibility with other Qt find modules. ๐ฆQt3_VERSIONโ Added in version 4.2. The version of Qt3 that was found. ๐QT_LIBRARIESโ Libraries needed to link against for using Qt3. ๐ฅQT_DEFINITIONSโ A list of compile definitions to use when compiling code that uses Qt3. ๐ธ
๐ Cache Variables ๐
The following cache variables may also be set:
QT_INCLUDE_DIRโ The directory containingqt.hand other Qt3 header files. ๐
The following cache variables may also be set but are not meant for general use:
QT_MOC_EXECUTABLEโ Path to themoctool. ๐งQT_UIC_EXECUTABLEโ Path to theuictool. ๐งQT_QT_LIBRARYโ Path to the Qt3 library. โญQT_QTMAIN_LIBRARYโ Path to theqtmainlibrary. This is only required by Qt3 on Windows. ๐
๐ Hints ๐
QT_MT_REQUIREDโ To search for the multithreaded version of Qt3, set this variable toTRUEbefore looking for Qt3. ๐ซถ
๐ Deprecated Variables ๐
The following variables are provided for backward compatibility:
QT_VERSION_STRINGโ Deprecated since version 4.2: UseQt3_VERSION, which has the same value. The version of Qt3 that was found. ๐ญ
โญ Examples โญ
Finding Qt3 on the system:
find_package(Qt3)
if(Qt3_FOUND)
target_link_libraries(foo PRIVATE ${QT_LIBRARIES})
target_include_directories(foo PRIVATE ${QT_INCLUDE_DIR})
target_compile_definitions(foo PRIVATE ${QT_DEFINITIONS})
endif()
Looking for the multithreaded version of Qt3:
set(QT_MT_REQUIRED TRUE)
find_package(Qt3)
๐ธ FindQt4 ๐ธ
Finds Qt4, a cross-platform application development framework for creating graphical user interfaces and applications:
find_package(Qt4 [<version>] [...])
This module defines a number of imported targets, macros, and variables to use Qt4 in the project. โจ
Note: This module is for Qt version 4. As of Qt version 5, the Qt upstream also provides an exported configuration to find Qt. New code should follow the cmake-qt(7) instead of using this module. ๐
To detect the Qt4 package, the Qt4 qmake tool is required and must be available in the system path. ๐
Note: When you're using Imported Targets, theqtmain.libstatic library gets linked automatically on Windows forWIN32executables (that's theWIN32_EXECUTABLEtarget property btw). Wanna kill it for the whole project? Set theQT4_NO_LINK_QTMAINvariable before you find Qt4. Wanna kill it for just one executable? Set theQT4_NO_LINK_QTMAINtarget property toTRUEon that executable. Easy ๐
๐ ๏ธ Qt Build Tools ๐ ๏ธ
Qt lowkey relies on some bundled tools for code generation, and they are so iconic:
mocโ meta-object code generation, the moment โจuicโ widget layout and population ๐rccโ virtual filesystem content generation ๐ฆ
These tools may get automatically invoked by cmake(1) if the right conditions are met. Peep cmake-qt(7) for more, bestie.
๐ Imported Targets ๐
You can link Qt libraries using their corresponding Imported Target with the target_link_libraries() command:
target_link_libraries(myexe Qt4::QtGui Qt4::QtXml)
The way that linking to an imported target automatically applies the correct include directories and compile definitions when building myexe?? Obsessed. ๐ซถ
Imported targets also manage their own dependencies, so listing Qt4::QtCore is literally unnecessary if another Qt library already depends on it. Likewise, Qt4::QtGui is automatically included when you link Qt4::QtDeclarative. And you can vibe-check whether a target exists with the if(TARGET) command ๐
If both the debug and release versions of a Qt toolkit library are available, CMake selects the appropriate one based on the build configuration. Bestie behavior fr fr.
This module provides the following imported targets, if found:
Qt4::QtCoreโ The QtCore targetQt4::QtGuiโ The QtGui targetQt4::Qt3Supportโ The Qt3Support targetQt4::QtAssistantโ The QtAssistant targetQt4::QtAssistantClientโ The QtAssistantClient targetQt4::QAxContainerโ The QAxContainer target (Windows only)Qt4::QAxServerโ The QAxServer target (Windows only)Qt4::QtDBusโ The QtDBus targetQt4::QtDeclarativeโ The QtDeclarative targetQt4::QtDesignerโ The QtDesigner targetQt4::QtDesignerComponentsโ The QtDesignerComponents targetQt4::QtHelpโ The QtHelp targetQt4::QtMotifโ The QtMotif targetQt4::QtMultimediaโ The QtMultimedia targetQt4::QtNetworkโ The QtNetwork targetQt4::QtNsPluginโ The QtNsPlugin targetQt4::QtOpenGLโ The QtOpenGL targetQt4::QtScriptโ The QtScript targetQt4::QtScriptToolsโ The QtScriptTools targetQt4::QtSqlโ The QtSql targetQt4::QtSvgโ The QtSvg targetQt4::QtTestโ The QtTest targetQt4::QtUiToolsโ The QtUiTools targetQt4::QtWebKitโ The QtWebKit targetQt4::QtXmlโ The QtXml targetQt4::QtXmlPatternsโ The QtXmlPatterns targetQt4::phononโ The phonon target
๐ Result Variables ๐
This module defines the following variables, and yes you should absolutely check them:
Qt4_FOUNDโ Boolean indicating whether (the requested version of) Qt4 was found. ๐QT_FOUNDโ Same asQt4_FOUND. Boolean indicating whether (the requested version of) Qt4 was found. This variable is available for compatibility with other Qt find modules.QT_VERSION_MAJORโ The major version of Qt found.QT_VERSION_MINORโ The minor version of Qt found.QT_VERSION_PATCHโ The patch version of Qt found.
๐ก Hints ๐ก
QT4_NO_LINK_QTMAINโ If set to boolean true before finding Qt4, it globally disables linking theqtmain.libstatic library on Windows. Periodt.
๐ง Macros ๐ง
Sometimes it's necessary or useful to invoke the Qt build tools in a more-manual way โ like, hand-crafted, artisanal build rules ๐. This module provides the following macros to add targets for such uses:
qt4_wrap_cpp
Creates build rules for running moc on a given list of input files:
qt4_wrap_cpp(<variable> <files>... [TARGET <target>] [OPTIONS <options>...])
This macro creates build rules for processing a list of input files <files> that contain Qt classes with the Q_OBJECT declaration. Per-directory preprocessor definitions are also added.
<variable>โ Name of a variable where a list of generated output files is stored.<files>โ One or more input source files.TARGETโ If specified, theINTERFACE_INCLUDE_DIRECTORIESandINTERFACE_COMPILE_DEFINITIONStarget properties from the<target>are passed tomoc.OPTIONSโ Optional list of options given tomoc, such as those found when executingmoc -help.
Note: Instead of usingqt4_wrap_cpp(), theCMAKE_AUTOMOCvariable can be set to process source files withmocautomatically. Let the machine do the work, bestie ๐
qt4_wrap_ui
Creates build rules for running uic on a given list of Qt designer ui input files:
qt4_wrap_ui(<variable> <files>... [OPTIONS <options>...])
<variable>โ Name of a variable where a list of generated output filenames is stored.<files>โ One or more Qt designer ui input source files.OPTIONSโ Optional list of options given touic, such as those found when executinguic -help.
Note: Instead of usingqt4_wrap_ui(), theCMAKE_AUTOUICvariable can be set to process ui files withuicautomatically. So slay ๐
qt4_add_resources
Creates build rules for running rcc on a given list of input Qt resource files:
qt4_add_resources(<variable> <files>... [OPTIONS <options>...])
<variable>โ Name of a variable where a list of generated output filenames is stored.<files>โ One or more Qt resource input source files.OPTIONSโ Optional list of options given torcc, such as those found when executingrcc -help.
Note: Instead of usingqt4_add_resources(), theCMAKE_AUTORCCvariable can be set to process resource files withrccautomatically. Iykyk ๐
qt4_generate_moc
Creates a build rule that generates an output file by running moc on a given input file:
qt4_generate_moc(<input-file> <output-file> [TARGET <target>])
This macro creates a build rule for <input-file> to generate <output-file>. Use this if for some reason qt4_wrap_cpp() isn't feasible โ like, e.g. because a custom filename is needed for the moc file or similar. No judgment ๐ซถ
TARGETโ If specified, theINTERFACE_INCLUDE_DIRECTORIESandINTERFACE_COMPILE_DEFINITIONStarget properties from the<target>are passed tomoc.
qt4_add_dbus_interface
Creates the interface header and implementation files from an interface XML file:
qt4_add_dbus_interface(<variable> <interface-file> <basename>)
This macro creates the interface header (<basename>.h) and implementation files (<basename>.{cpp,moc}) from the given interface XML file <interface-file> and adds it to the variable which contains a list of sources (specified as variable name <variable>).
You can pass additional parameters to the qdbusxml2cpp call by setting the following source file properties on the input file <interface-file>:
INCLUDEโ The given file will be included in the generated interface header.CLASSNAMEโ The name of the generated class.NO_NAMESPACEโ The generated class will not be wrapped in a namespace.
qt4_add_dbus_interfaces
Creates the interface header and implementation files from multiple interface XML files:
qt4_add_dbus_interfaces(<variable> <interface-files>...)
This macro creates the interface header and implementation files for all listed interface XML files <interface-files>. The basename will be automatically determined from the name of the XML file. The resulting output files list is stored in a variable <variable>.
The source file properties described for qt4_add_dbus_interface() also apply here. Same energy, batch mode โจ
qt4_add_dbus_adaptor
Generates an adaptor class for a D-Bus interface:
qt4_add_dbus_adaptor(<variable> <xmlfile> <parent-header> <parent-classname>
[<basename>] [<classname>])
Creates a D-Bus adaptor (header and implementation file) from the XML file describing the interface, and adds it to the list of sources. The adaptor forwards the calls to a parent class, defined in <parent-header> and named <parent-classname>. The generated filenames will be <basename>adaptor.{cpp,h} where <basename> defaults to the basename of the XML file if not given. If <classname> is provided, then it will be used as the classname of the adaptor itself. Generated filenames are stored in a variable <variable>.
qt4_generate_dbus_interface
Generates a D-Bus XML interface file from a given header file:
qt4_generate_dbus_interface(<header> [<interface>] [OPTIONS <options>...])
This macro creates a build rule to extract declaration from the given <header> file to generate a corresponding XML interface file.
<header>โ Path to header file from which the XML interface file is generated.<interface>โ Path to the generated XML interface file. If this optional argument is omitted, the name of the interface file is constructed from the basename of the header with the suffix.xmlappended. A relative path is interpreted as relative toCMAKE_CURRENT_BINARY_DIR.OPTIONSโ A list of options that may be given toqdbuscpp2xml, such as those found when executingqdbuscpp2xml --help.
qt4_create_translation
Creates build rules for generating TS and QM files:
qt4_create_translation(<qm-files-var> <directories>... <sources>...
<ts-files>... [OPTIONS <options>...])
Okay so that one's got a lot going on and we're gonna get into it right after this ๐
This macro is basically the โจtranslation factoryโจ โ it creates build rules that generate TS (Translation Source, .ts) files via lupdate and QM (Qt Message, .qm) files via lrelease, all from the <directories> and/or <sources> you hand it. The TS files get created and/or updated in the source tree (unless you gave full paths). The QM files are generated in the build tree. ๐
<qm-files-var>โ the list of generated QM files gets stashed in this variable. Want your translations updated? Either add<qm-files-var>to the source list of the project library/executable so they're always updated, or add a custom target to control when they get updated/generated. You've got options, bestie. ๐<directories>โ a list of directories containing source files.<sources>โ a list of source files.<ts-files>โ a list of TS (Translation Source) files.
OPTIONS
Optional list of flags passed straight through to lupdate, such as -extensions, to specify file extensions for directory scanning. ๐ฆ
qt4_add_translation
Creates build rules for generating QM files from the given TS files:
qt4_add_translation(<qm-files-var> <ts-files>...)
This macro creates build rules for generating QM files from the given TS files, and it stores a list of the generated filenames of QM files in the <qm-files-var> variable. Heads up though: the <ts-files> must exist and are not updated in any way. No cap, it will not touch them. ๐
qt4_automoc
Deprecated since version 2.8.11: Use feature provided by the CMAKE_AUTOMOC variable instead. ๐ญ
Runs moc on input files:
qt4_automoc(<source-files>... [TARGET <target>])
This macro can be used to have moc automatically handled. For example, if there are foo.h and foo.cpp files, and in foo.h a class uses the Q_OBJECT preprocessor macro, moc has to run on it. If using qt4_wrap_cpp() isn't wanted (however, it is reliable and mature, just saying ๐), the #include "foo.moc" can be inserted in foo.cpp and then foo.cpp given as an argument to qt4_automoc(). This will scan all listed files <source-files> at configuration phase for such included moc files, and if it finds them, a rule is generated to run moc at build time on the accompanying header file foo.h. If a source file has the SKIP_AUTOMOC property set, that file will be ignored by this macro.
TARGET โ If specified, the INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_COMPILE_DEFINITIONS target properties from the <target> are passed to moc.
qt4_use_modules
Deprecated since version 2.8.11: Use target_link_libraries() with Imported Targets instead. ๐
Provides Qt modules to a project so you can link them to a target:
qt4_use_modules(<target> [<LINK_PUBLIC|LINK_PRIVATE>] <modules>...)
This function makes <target> use the <modules> from Qt. Using a Qt module means linking to the library, adding the relevant include directories for the module, and adding the relevant compiler defines for using the module. Modules are roughly equivalent to Qt4 components. Slay. โญ
LINK_PUBLIC or LINK_PRIVATE โ Optional linking mode, used as the corresponding argument in the target_link_libraries() call.
For example, calling qt4_use_modules(myexe Core Gui Declarative) will use the QtCore, QtGui and QtDeclarative components on the project target myexe.
Deprecated Variables
The following variables are provided for backward compatibility:
QT4_FOUND
Deprecated since version 2.8.11: Use Qt4_FOUND, which has the same value. ๐ซถ
Examples
Typical usage to find Qt4 could be something like:
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt4 4.4.3 REQUIRED QtGui QtXml)
add_executable(myexe main.cpp)
target_link_libraries(myexe PRIVATE Qt4::QtGui Qt4::QtXml)
FindQuickTime
Finds the QuickTime multimedia framework, which provides support for video, audio, and interactive media:
find_package(QuickTime [...])
Note: This module is for the QuickTime framework, which has been deprecated by Apple and is no longer supported. On Apple systems, use AVFoundation and AVKit instead. ๐ Not me finding out the framework itself is retired...
Result Variables
This module defines the following variables:
QuickTime_FOUND
Added in version 3.3.
Boolean indicating whether QuickTime was found. โจ
Cache Variables
The following cache variables may also be set:
QUICKTIME_LIBRARY โ The path to the QuickTime library.
QUICKTIME_INCLUDE_DIR โ Directory containing QuickTime headers. ๐
Hints
This module accepts the following variables:
QUICKTIME_DIR โ Environment variable that can be set to help locate a QuickTime library installed in a custom location. It should point to the installation destination that was used when configuring, building, and installing the QuickTime library:
./configure --prefix=$QUICKTIME_DIR
Deprecated Variables
The following variables are provided for backward compatibility:
QUICKTIME_FOUND
Deprecated since version 4.2: Use QuickTime_FOUND, which has the same value. ๐ญ
Boolean indicating whether QuickTime was found.
Examples
Finding the QuickTime library and creating an imported interface target for linking it to a project target:
find_package(QuickTime)
if(QuickTime_FOUND AND NOT TARGET QuickTime::QuickTime)
add_library(QuickTime::QuickTime INTERFACE IMPORTED)
set_target_properties(
QuickTime::QuickTime
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${QUICKTIME_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${QUICKTIME_LIBRARY}"
)
endif()
target_link_libraries(example PRIVATE QuickTime::QuickTime)
FindRTI
Finds HLA RTI standard libraries and their include directories:
find_package(RTI [...])
RTI (Run-Time Infrastructure) is a simulation infrastructure standardized by IEEE and SISO, and it's required when implementing HLA (High Level Architecture). The wiki vibes live at https://en.wikipedia.org/wiki/Run-time_infrastructure_(simulation) iykyk. It provides a well-defined C++ API, which ensures that M&S (Modeling and Simulation) applications remain independent of any particular RTI implementation. It's giving "plug and play but for simulations". ๐ง
Result Variables
This module defines the following variables:
RTI_FOUND โ Boolean indicating whether HLA RTI was found.
RTI_LIBRARIES โ The libraries to link against to use RTI.
RTI_DEFINITIONS โ Compile definitions for using RTI. Default value is set to -DRTI_USES_STD_FSTREAM. ๐ฅ
Cache Variables
The following cache variables may also be set:
RTI_INCLUDE_DIR โ Directory where RTI include files are found.
Examples
Finding RTI and creating an imported interface target for linking it to a project target:
find_package(RTI)
if(RTI_FOUND AND NOT TARGET RTI::RTI)
add_library(RTI::RTI INTERFACE IMPORTED)
set_target_properties(
RTI::RTI
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${RTI_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${RTI_LIBRARIES}"
INTERFACE_COMPILE_DEFINITIONS "${RTI_DEFINITIONS}"
)
endif()
target_link_libraries(example PRIVATE RTI::RTI)
FindRuby
Finds the Ruby installation and the locations of its include files and libraries:
find_package(Ruby [<version>] [COMPONENTS <components>...] [...])
Ruby is a general-purpose programming language (and a whole personality, honestly ๐). This module supports Ruby 2.0 through 4.0. Virtual environments, such as RVM or RBENV, are also supported. ๐
Components
Added in version 4.3.
This module supports the following components:
Interpreter โ The Ruby interpreter executable.
Development โ Headers and libraries needed to build Ruby extensions or embed Ruby.
If no components are specified, both Interpreter and Development are searched for. FOMO avoided. ๐
Imported Targets
Added in version 4.3.
This module defines the following IMPORTED targets:
Ruby::Interpreter โ Ruby interpreter. Target defined if component Interpreter is found.
Ruby::Ruby โ Ruby library for embedding Ruby in C/C++ applications. Target defined if component Development is found.
Ruby::Module โ Ruby library for building Ruby extension modules. Target defined if component Development is found. Use this target when creating native extensions that will be loaded into Ruby via require. On most platforms, extension modules do not link directly to libruby. Includes appropriate symbol visibility settings. ๐ฆ
Result Variables
This module defines the following variables:
Ruby_FOUND
Added in version 3.3.
Boolean indicating whether (the requested version of) ruby was found.
Ruby_VERSION โ The version of ruby which was found, e.g. 3.2.6.
Ruby_VERSION_MAJOR โ Ruby major version.
Ruby_VERSION_MINOR โ Ruby minor version.
Ruby_VERSION_PATCH โ Ruby patch version. ๐
Ruby_EXECUTABLE โ The full path to the ruby binary.
Ruby_INCLUDE_DIRS โ Include dirs to be used when using the ruby library.
Ruby_LIBRARIES
Added in version 3.18.
Libraries needed to use ruby from C.
Changed in version 3.18: Previous versions of CMake used the RUBY_ prefix for all variables. ๐ญ So if you're on an old version, that's why nothing matches, bestie.
Hints
This module accepts the following variables:
Ruby_FIND_VIRTUALENV
Added in version 3.18.
This variable defines the handling of virtual environments. It can be left empty or be set to one of the following values:
FIRST: Virtual Ruby environments are searched for first, then the system Ruby installation. This is the default.ONLY: Only virtual environments are searched.STANDARD: Only the system Ruby installation is searched.
Virtual environments may be provided by:
rvmโ Requires that theMY_RUBY_HOMEenvironment is defined.rbenvโ Requires thatrbenvis installed in~/.rbenv/binor that theRBENV_ROOTenvironment variable is defined. ๐
Deprecated Variables
The following variables are provided for backward compatibility:
Deprecated since version 4.0: bestie, these variables are deprecated. See policy CMP0185.
RUBY_FOUNDโ literally the same thing asRuby_FOUND.RUBY_VERSIONโ same asRuby_VERSION.RUBY_EXECUTABLEโ same asRuby_EXECUTABLE.RUBY_INCLUDE_DIRSโ same asRuby_INCLUDE_DIRS.RUBY_INCLUDE_PATHโ same asRuby_INCLUDE_DIRS.RUBY_LIBRARYโ same asRuby_LIBRARY.
โจ Examples โจ
Finding Ruby and specifying the minimum required version, no cap:
find_package(Ruby 3.2.6 EXACT REQUIRED)
# or
find_package(Ruby 3.2)
๐ FindSDL ๐
Finds the SDL (Simple DirectMedia Layer) library:
find_package(SDL [<version>] [...])
SDL is that iconic cross-platform library for building multimedia software โ games, emulators, the whole vibe. ๐ฎ
Note: this module is specifically intended for SDL version 1. Starting with version 2, SDL ships a CMake package configuration file when it's built with CMake, so you should find it withfind_package(SDL2)instead. Similarly, SDL version 3 can be found withfind_package(SDL3). Those newer versions give you separate Imported Targets that bundle up all the usage requirements. Check the official SDL documentation for more info. ๐
Also lowkey important: the include path for the SDL header changed in recent SDL 1 versions โ it went from SDL/SDL.h to just plain SDL.h. That change matches SDL's whole convention of using #include "SDL.h" for portability, because not every system installs the headers in an SDL/ subdirectory (FreeBSD, looking at you ๐).
When you're targeting macOS and using the SDL framework, make sure you include both SDLmain.h and SDLmain.m in the project. On other platforms, the SDLmain library is usually linked with -lSDLmain, and this module will try to locate it automatically for you. And on macOS specifically, this module adds the -framework Cocoa flag as needed.
๐ Imported Targets
This module serves up the following Imported Targets:
SDL::SDLโ Added in version 3.19. The target that encapsulates the SDL library usage requirements, available if SDL is found. ๐ซถ
๐ฆ Result Variables
This module defines these variables:
SDL_FOUNDโ boolean, tells you whether (the requested version of) SDL was found.SDL_VERSIONโ Added in version 3.19. The human-readable string containing the version of SDL that was found.SDL_VERSION_MAJORโ Added in version 3.19. The major version of SDL that was found.SDL_VERSION_MINORโ Added in version 3.19. The minor version of SDL that was found.SDL_VERSION_PATCHโ Added in version 3.19. The patch version of SDL that was found.SDL_INCLUDE_DIRSโ Added in version 3.19. The include directories you need to actually use SDL.SDL_LIBRARIESโ Added in version 3.19. The libraries you need to link against to use SDL.
๐ธ Cache Variables
You can optionally set these to help the module find the right files:
SDL_INCLUDE_DIRโ the directory that contains theSDL.hheader file.SDL_LIBRARYโ a list of libraries containing the path to the SDL library plus the libraries needed to link against to use SDL.
๐ Hints
This module accepts these variables:
SDL_BUILDING_LIBRARYโ when you set this to boolean true, theSDL_mainlibrary gets excluded from linking, because you don't need it when you're building the SDL library itself (only applications need amain()function, bestie). If it's not set, the module assumes you're building an application and tries to locate and include the appropriateSDL_mainlink flags in the returnedSDL_LIBRARYvariable.SDLDIRโ an environment variable you can set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building and installing the SDL library:./configure --prefix=$SDLDIR.
On macOS, setting this variable will prefer the Framework version (if one's found) over the others. In that case you'd have to manually change the cache value of SDL_LIBRARY to override that selection, or set the CMAKE_INCLUDE_PATH variable to modify the search paths. ๐
๐ฅ Troubleshooting
If the SDL library doesn't get found automatically, the SDL_LIBRARY_TEMP variable may be empty, and SDL_LIBRARY won't be set. That typically means CMake couldn't locate the SDL library at all (think SDL.dll, libSDL.so, SDL.framework, etc.). To fix it, manually set SDL_LIBRARY_TEMP to the correct path and reconfigure the project. Same energy with SDLMAIN_LIBRARY โ if it's unset, you may need to specify it manually too. These variables are what get used to construct the final SDL_LIBRARY value, so if they're not set, SDL_LIBRARY just stays undefined. ๐ญ
๐ Deprecated Variables
These are here purely for backward compatibility:
SDL_VERSION_STRINGโ Deprecated since version 3.19: superseded bySDL_VERSION, which has the same value. The human-readable string containing the version of SDL if it was found.
โญ Examples โญ
Finding the SDL library and linking it to a project target:
find_package(SDL)
target_link_libraries(project_target PRIVATE SDL::SDL)
When you're working with SDL version 2, the upstream package provides the SDL2::SDL2 imported target directly, so you can use it in a project without touching this module at all:
find_package(SDL2)
target_link_libraries(project_target PRIVATE SDL2::SDL2)
And same for SDL version 3, obviously:
find_package(SDL3)
target_link_libraries(project_target PRIVATE SDL3::SDL3)
๐ซ See Also
- The
FindSDL_gfxmodule, for finding the SDL_gfx library. ๐จ - The
FindSDL_imagemodule, for finding the SDL_image library. ๐ผ๏ธ - The
FindSDL_mixermodule, for finding the SDL_mixer library. ๐ต - The
FindSDL_netmodule, for finding the SDL_net library. ๐ - The
FindSDL_soundmodule, for finding the SDL_sound library. ๐ - The
FindSDL_ttfmodule, for finding the SDL_ttf library. ๐ค
๐ง FindSDL_gfx ๐ง
Added in version 3.25.
Finds the SDL_gfx library, the one that provides graphics support in SDL (Simple DirectMedia Layer) applications:
find_package(SDL_gfx [<version>] [...])
Note: this module is for SDL_gfx version 1. If you're on version 2 or newer, refer to the upstream documentation instead. ๐
๐ Imported Targets
SDL::SDL_gfxโ the target that encapsulates the SDL_gfx library usage requirements, available if SDL_gfx is found.
๐ฆ Result Variables
SDL_gfx_FOUNDโ boolean, tells you whether the (requested version of the) SDL_gfx library was found.SDL_gfx_VERSIONโ Added in version 4.2. The human-readable string containing the version of SDL_gfx that was found.
๐ธ Cache Variables
These cache variables may also be set:
SDL_GFX_INCLUDE_DIRSโ the directory containing the headers you need to use SDL_gfx.SDL_GFX_LIBRARIESโ the path to the SDL_gfx library you need to link against to use SDL_gfx.
๐ Hints
SDLDIRโ an environment variable you can set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building and installing the SDL library:./configure --prefix=$SDLDIR.
๐ Deprecated Variables
For backward compatibility only, bestie:
SDL_GFX_FOUNDโ Deprecated since version 4.2: useSDL_gfx_FOUND, which has the same value. Boolean indicating whether the (requested version of the) SDL_gfx library was found.SDL_GFX_VERSION_STRINGโ Deprecated since version 4.2: useSDL_gfx_VERSION. The human-readable string containing the version of SDL_gfx that was found.
โญ Examples โญ
Finding the SDL_gfx library and linking it to a project target:
find_package(SDL_gfx)
target_link_libraries(project_target PRIVATE SDL::SDL_gfx)
๐ซ See Also
- The
FindSDLmodule, for finding the main SDL library. ๐ซถ
๐ FindSDL_image ๐
Finds the SDL_image library โ the one that loads images of all kinds of formats as SDL (Simple DirectMedia Layer) surfaces:
find_package(SDL_image [<version>] [...])
Note: this module is specifically intended for SDL_image version 1. Starting with version 2.6, SDL_image ships a CMake package configuration file when built with CMake, so it should be found withfind_package(SDL2_image). Similarly, SDL_image version 3 can be found withfind_package(SDL3_image). Those newer versions provide Imported Targets that bundle up the usage requirements โ check the official SDL documentation for the details. ๐
๐ฆ Result Variables
SDL_image_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of the) SDL_image library was found.SDL_image_VERSIONโ Added in version 4.2. The human-readable string containing the version of SDL_image that was found.SDL_IMAGE_INCLUDE_DIRSโ include directories containing the headers you need to use the SDL_image library.SDL_IMAGE_LIBRARIESโ libraries you need to link against to use the SDL_image library.
๐ Hints
SDLDIRโ an environment variable you can set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building and installing the SDL library:./configure --prefix=$SDLDIR.
๐ Deprecated Variables
Backward-compat crew, reporting for duty:
SDL_IMAGE_VERSION_STRINGโ Deprecated since version 4.2: useSDL_image_VERSION, which has the same value. The human-readable string containing the version of SDL_image that was found.SDL_IMAGE_FOUNDโ Deprecated since version 4.2: useSDL_image_FOUND, which has the same value.SDLIMAGE_FOUNDโ Deprecated since version 2.8.10: useSDL_image_FOUND, which has the same value.SDLIMAGE_INCLUDE_DIRโ Deprecated since version 2.8.10: useSDL_IMAGE_INCLUDE_DIRS, which has the same value.SDLIMAGE_LIBRARYโ deprecated since version 2.8.10 ๐ like, useSDL_IMAGE_LIBRARIESinstead โ it's literally the same value, no cap ๐
๐ Examples ๐
Okay so here's how you find the SDL_image library and build yourself an imported interface target to link it to your project target โ iconic behavior honestly:
find_package(SDL_image)
if(SDL_image_FOUND AND NOT TARGET SDL::SDL_image)
add_library(SDL::SDL_image INTERFACE IMPORTED)
set_target_properties(
SDL::SDL_image
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SDL_IMAGE_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${SDL_IMAGE_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE SDL::SDL_image)
When you're working with SDL_image version 2, the upstream package provides the SDL2_image::SDL2_image imported target directly โ so like, you don't even need this module at all, you can just use it in a project straight up:
find_package(SDL2_image)
target_link_libraries(project_target PRIVATE SDL2_image::SDL2_image)
Similarly, for SDL_image version 3:
find_package(SDL3_image)
target_link_libraries(project_target PRIVATE SDL3_image::SDL3_image)
๐ See Also ๐
- The [FindSDL](#module:FindSDL) module to find the main SDL library ๐
๐ง FindSDL_mixer ๐ง
Finds the SDL_mixer library โ the one that provides an audio mixer with support for various file formats in SDL (Simple DirectMedia Layer) applications ๐ตโจ:
find_package(SDL_mixer [<version>] [...])
Note: this module is specifically intended for SDL_mixer version 1 bestie, don't get it twisted ๐ซถ Starting with version 2.5, SDL_mixer provides a CMake package configuration file when built with CMake and should be found using find_package(SDL2_mixer). These newer versions provide [Imported Targets](#imported-targets) that encapsulate usage requirements โ so much cleaner. Refer to the official SDL documentation for more information ๐
โจ Result Variables โจ
This module defines the following variables:
SDL_mixer_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) SDL_mixer library was found โSDL_mixer_VERSIONโ Added in version 4.2. The human-readable string containing the version of SDL_mixer found ๐ท๏ธSDL_MIXER_INCLUDE_DIRSโ Include directories containing headers needed to use the SDL_mixer library ๐SDL_MIXER_LIBRARIESโ Libraries needed to link against to use SDL_mixer ๐
๐ก Hints ๐ก
This module accepts the following variables:
SDLDIRโ Environment variable that can be set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building, and installing SDL library:./configure --prefix=$SDLDIR๐ ๏ธ
๐ซ๏ธ Deprecated Variables ๐ซ๏ธ
The following variables are provided for backward compatibility (aka, they're giving retired icon energy ๐):
SDL_MIXER_VERSION_STRINGโ Deprecated since version 4.2: UseSDL_mixer_VERSION, which has the same value. The human-readable string containing the version of SDL_mixer found ๐SDL_MIXER_FOUNDโ Deprecated since version 4.2: UseSDL_mixer_FOUND, which has the same value ๐SDLMIXER_FOUNDโ Deprecated since version 2.8.10: UseSDL_mixer_FOUND, which has the same value ๐SDLMIXER_INCLUDE_DIRโ Deprecated since version 2.8.10: UseSDL_MIXER_INCLUDE_DIRS, which has the same value ๐SDLMIXER_LIBRARYโ Deprecated since version 2.8.10: UseSDL_MIXER_LIBRARIES, which has the same value ๐
๐ Examples ๐
Finding the SDL_mixer library and creating an imported interface target for linking it to a project target โ slay:
find_package(SDL_mixer)
if(SDL_mixer_FOUND AND NOT TARGET SDL::SDL_mixer)
add_library(SDL::SDL_mixer INTERFACE IMPORTED)
set_target_properties(
SDL::SDL_mixer
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SDL_MIXER_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${SDL_MIXER_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE SDL::SDL_mixer)
When working with SDL_mixer version 2, the upstream package provides the SDL2_mixer::SDL2_mixer imported target directly. It can be used in a project without using this module:
find_package(SDL2_mixer)
target_link_libraries(project_target PRIVATE SDL2_mixer::SDL2_mixer)
๐ See Also ๐
- The [FindSDL](#module:FindSDL) module to find the main SDL library ๐
๐ FindSDL_net ๐
Finds the SDL_net library โ a cross-platform network library for use with SDL (Simple DirectMedia Layer) applications, networking era fr fr ๐ฆ:
find_package(SDL_net [<version>] [...])
Note: this module is specifically intended for SDL_net version 1 ๐ซถ Starting with version 2.1, SDL_net provides a CMake package configuration file when built with CMake and should be found using find_package(SDL2_net). These newer versions provide [Imported Targets](#imported-targets) that encapsulate usage requirements. Refer to the official SDL documentation for more information ๐
โจ Result Variables โจ
This module defines the following variables:
SDL_net_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) SDL_net library was found โSDL_net_VERSIONโ Added in version 4.2. The human-readable string containing the version of SDL_net found ๐ท๏ธSDL_NET_INCLUDE_DIRSโ Include directories containing headers needed to use the SDL_net library ๐SDL_NET_LIBRARIESโ Libraries needed to link against to use the SDL_net library ๐
๐ก Hints ๐ก
This module accepts the following variables:
SDLDIRโ Environment variable that can be set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building, and installing SDL library:./configure --prefix=$SDLDIR๐ ๏ธ
๐ซ๏ธ Deprecated Variables ๐ซ๏ธ
The following variables are provided for backward compatibility:
SDL_NET_VERSION_STRINGโ Deprecated since version 4.2: UseSDL_net_VERSION, which has the same value. The human-readable string containing the version of SDL_net found ๐SDL_NET_FOUNDโ Deprecated since version 4.2: UseSDL_net_FOUND, which has the same value ๐SDLNET_FOUNDโ Deprecated since version 2.8.10: UseSDL_net_FOUND, which has the same value ๐SDLNET_INCLUDE_DIRโ Deprecated since version 2.8.10: UseSDL_NET_INCLUDE_DIRS, which has the same value ๐SDLNET_LIBRARYโ Deprecated since version 2.8.10: UseSDL_NET_LIBRARIES, which has the same value ๐
๐ Examples ๐
Finding the SDL_net library and creating an imported interface target for linking it to a project target:
find_package(SDL_net)
if(SDL_net_FOUND AND NOT TARGET SDL::SDL_net)
add_library(SDL::SDL_net INTERFACE IMPORTED)
set_target_properties(
SDL::SDL_net
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SDL_NET_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${SDL_NET_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE SDL::SDL_net)
When working with SDL_net version 2, the upstream package provides the SDL2_net::SDL2_net imported target directly. It can be used in a project without using this module:
find_package(SDL2_net)
target_link_libraries(project_target PRIVATE SDL2_net::SDL2_net)
๐ See Also ๐
- The [FindSDL](#module:FindSDL) module to find the main SDL library ๐
๐ FindSDL_sound ๐
Finds the SDL_sound library โ an abstract soundfile decoder for use in SDL (Simple DirectMedia Layer) applications, we love a decoder moment ๐:
find_package(SDL_sound [<version>] [...])
Note: this module is specifically intended for SDL_sound version 1 bestie ๐ซถ Starting with version 2.0.2, SDL_sound provides a CMake package configuration file when built with CMake and should be found using find_package(SDL2_sound). These newer versions provide [Imported Targets](#imported-targets) that encapsulate usage requirements. Refer to the upstream SDL_sound documentation for more information ๐
Note: this module depends on SDL being found and must be called after the [find_package(SDL)](#module:FindSDL) ๐ญ Depending on how the SDL_sound library is built, it may require additional dependent libraries to be found for this module to succeed. These dependencies may include MikMod, ModPlug, Ogg, Vorbis, SMPEG, FLAC, and Speex ๐ถ
โจ Result Variables โจ
This module defines the following variables:
SDL_sound_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) SDL_sound library was found โSDL_sound_VERSIONโ Added in version 4.2. The human-readable string containing the version of SDL_sound found ๐ท๏ธSDL_SOUND_LIBRARIESโ Libraries needed to link against to use the SDL_sound library ๐
๐๏ธ Cache Variables ๐๏ธ
The following cache variables may also be set:
SDL_SOUND_INCLUDE_DIRโ The directory containing theSDL_sound.hand other headers needed to use the SDL_sound library ๐SDL_SOUND_LIBRARYโ The name of just the SDL_sound library you would link against. UseSDL_SOUND_LIBRARIESfor the link instructions and not this one ๐MIKMOD_LIBRARYโ The path to the dependent MikMod library ๐นMODPLUG_LIBRARYโ The path to the dependent ModPlug library (libmodplug) ๐๏ธOGG_LIBRARYโ The path to the dependent Ogg library ๐งVORBIS_LIBRARYโ The path to the dependent Vorbis library ๐ผSMPEG_LIBRARYโ The path to the dependent SMPEG library ๐ผFLAC_LIBRARYโ The path to the dependent FLAC library ๐ฟSPEEX_LIBRARYโ The path to the dependent Speex library ๐ฃ๏ธ
๐ก Hints ๐ก
This module accepts the following variables:
SDLDIRโ Environment variable that can be set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building, and installing SDL library:./configure --prefix=$SDLDIR๐ ๏ธ
On macOS, setting this variable will prefer the Framework version (if found) over others. In this case, the cache value of SDL_LIBRARY would need to be manually changed to override this selection or set the [CMAKE_INCLUDE_PATH](#variable:CMAKE_INCLUDE_PATH) variable to modify the search paths ๐
SDLSOUNDDIRโ Environment variable that works the same asSDLDIR๐SDL_SOUND_EXTRASโ okay so this one's an optional cache variable, and it's your little "bestie i need extra stuff" escape hatch ๐ซถ anything you drop in here gets prepended to theSDL_SOUND_LIBRARIESresult variable. It exists mostly for the cases this module lowkey failed to anticipate and you gotta bolt on some additional flags yourself. No cap, that's the whole vibe.
๐ Deprecated Variables ๐
These ones are here purely for backward compatibility โ legacy vibes only, they still work but they're giving "still using my old username" energy ๐ญ
SDL_SOUND_FOUNDโ Deprecated since version 4.2: useSDL_sound_FOUND, which has the same value. Boolean indicating whether the (requested version of) SDL_sound library was found.SDL_SOUND_VERSION_STRINGโ Deprecated since version 4.2: useSDL_sound_VERSION, which has the same value. The human-readable string containing the version of SDL_sound found.
๐ Examples ๐
Finding the SDL_sound library and creating an imported interface target for linking it to a project target โ literally the whole glow-up in one snippet:
find_package(SDL)
find_package(SDL_sound)
if(SDL_sound_FOUND AND NOT TARGET SDL::SDL_sound)
add_library(SDL::SDL_sound INTERFACE IMPORTED)
set_target_properties(
SDL::SDL_sound
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SDL_SOUND_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${SDL_SOUND_LIBRARIES}"
)
# Append the SDL dependency as imported target to be transitively linked:
set_property(
TARGET SDL::SDL_sound
APPEND
PROPERTY INTERFACE_LINK_LIBRARIES SDL::SDL
)
endif()
target_link_libraries(project_target PRIVATE SDL::SDL_sound)
When you're working with SDL_sound version 2, the upstream package provides the SDL2_sound::SDL2_sound imported target directly โ so you can skip this module entirely, no thoughts needed:
find_package(SDL2_sound)
target_link_libraries(project_target PRIVATE SDL2_sound::SDL2_sound)
๐ See Also ๐
- The FindSDL module to find the main SDL library. It's right there, go grab it ๐
๐ฆ FindSDL_ttf ๐ฆ
Finds the SDL_ttf library, aka the thing that lets you render text with TrueType fonts in SDL (Simple DirectMedia Layer) applications. Pretty text? Iconic. โจ
find_package(SDL_ttf [<version>] [...] )
Note: this module is specifically intended for SDL_ttf version 1. Starting with version 2.0.15, SDL_ttf provides a CMake package configuration file when built with CMake and should be found usingfind_package(SDL2_ttf). Similarly, SDL_ttf version 3 can be found usingfind_package(SDL3_ttf). These newer versions provide Imported Targets that encapsulate usage requirements. Refer to the official SDL documentation for more information. So like โ check your version first, bestie ๐
๐ Result Variables ๐
This module defines the following variables:
SDL_ttf_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) SDL_ttf library was found. ๐SDL_ttf_VERSIONโ Added in version 4.2. The human-readable string containing the version of SDL_ttf found.SDL_TTF_INCLUDE_DIRSโ Include directories containing headers needed to use the SDL_ttf library.SDL_TTF_LIBRARIESโ Libraries needed to link against to use SDL_ttf.
๐ก Hints ๐ก
This module accepts the following variables:
SDLDIRโ environment variable that can be set to help locate an SDL library installed in a custom location. It should point to the installation destination that was used when configuring, building, and installing the SDL library:./configure --prefix=$SDLDIR. Yes, exactly like that ๐ฏ
๐ Deprecated Variables ๐
Backward-compat crew, reporting for duty:
SDL_TTF_VERSION_STRINGโ Deprecated since version 4.2: useSDL_ttf_VERSION, which has the same value. The human-readable string containing the version of SDL_ttf found.SDL_TTF_FOUNDโ Deprecated since version 4.2: useSDL_ttf_FOUND, which has the same value.SDLTTF_FOUNDโ Deprecated since version 2.8.10: replaced withSDL_ttf_FOUND, which has the same value.SDLTTF_INCLUDE_DIRโ Deprecated since version 2.8.10: replaced withSDL_TTF_INCLUDE_DIRS, which has the same value.SDLTTF_LIBRARYโ Deprecated since version 2.8.10: replaced withSDL_TTF_LIBRARIES, which has the same value.
๐ Examples ๐
Finding the SDL_ttf library and creating an imported interface target for linking it to a project target:
find_package(SDL_ttf)
if(SDL_ttf_FOUND AND NOT TARGET SDL::SDL_ttf)
add_library(SDL::SDL_ttf INTERFACE IMPORTED)
set_target_properties(
SDL::SDL_ttf
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SDL_TTF_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${SDL_TTF_LIBRARIES}"
)
endif()
target_link_libraries(project_target PRIVATE SDL::SDL_ttf)
When working with SDL_ttf version 2, the upstream package provides the SDL2_ttf::SDL2_ttf imported target directly. It can be used in a project without using this module:
find_package(SDL2_ttf)
target_link_libraries(project_target PRIVATE SDL2_ttf::SDL2_ttf)
Similarly, for SDL_ttf version 3:
find_package(SDL3_ttf)
target_link_libraries(project_target PRIVATE SDL3_ttf::SDL3_ttf)
๐ See Also ๐
- The FindSDL module to find the main SDL library. Same energy as before, still slaps ๐
๐ FindSelfPackers ๐
Finds UPX, the Ultimate Packer for eXecutables โ yes that capitalization is real, and honestly? iconic ๐
find_package(SelfPackers [...] )
This module searches for executable packer-tools that compress executables or shared libraries into on-the-fly, self-extracting versions. It currently supports UPX. That's it, that's the list ๐
๐ Result Variables ๐
This module defines the following variables:
SelfPackers_FOUNDโ Added in version 4.2. Boolean indicating whether packer tools were found.
๐๏ธ Cache Variables ๐๏ธ
The following cache variables may also be set:
SELF_PACKER_FOR_EXECUTABLEโ Path to the executable packer for compressing executables.SELF_PACKER_FOR_SHARED_LIBโ Path to the executable packer for compressing shared libraries.SELF_PACKER_FOR_EXECUTABLE_FLAGSโ Command-line options to use when compressing executables.SELF_PACKER_FOR_SHARED_LIB_FLAGSโ Command-line options to use when compressing shared libraries.
๐ Examples ๐
Finding UPX. That's the whole example. It's one line. It ate. โจ
find_package(SelfPackers)
๐ง FindSQLite3 ๐ง
Added in version 3.14.
Finds the SQLite 3 library:
find_package(SQLite3 [<version>] [...] )
SQLite is a small, fast, self-contained, high-reliability, and full-featured SQL database engine written in C, intended for embedding in applications. Like, it's a whole database in a tiny little file and it literally never lets you down. Main character energy fr fr ๐
๐ฏ Imported Targets ๐ฏ
This module provides the following Imported Targets:
SQLite3::SQLite3โ target encapsulating SQLite library usage requirements. It is available only when SQLite is found. Added in version 4.3. ๐ฅSQLite::SQLite3โ Deprecated. Identical toSQLite3::SQLite3.
If your project needs to support CMake < 4.3, consider adding the following to your project after calling find_package(SQLite3 ...):
if(NOT TARGET SQLite3::SQLite3) # CMake < 4.3
add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3)
endif()
This will allow your project to use the new name while still permitting it to compile with older versions of CMake. Bestie, it's giving "have your cake and eat it too" and honestly we love that for you ๐ซถ
๐ Result Variables ๐
This module defines the following variables:
SQLite3_FOUNDโ Boolean indicating whether the (requested version of) the SQLite library was found.SQLite3_VERSIONโ the version of the SQLite library found.SQLite3_INCLUDE_DIRSโ include directories containing the<sqlite3.h>and related headers needed to use SQLite.SQLite3_LIBRARIESโ libraries needed to link against to use SQLite.
๐ Examples ๐
Finding the SQLite library and linking it to a project target. Two lines. Flawless. ๐
find_package(SQLite3)
target_link_libraries(project_target PRIVATE SQLite3::SQLite3)
โญ FindSquish โญ
Finds Squish, a cross-platform automated GUI testing framework for applications built on various GUI technologies:
find_package(Squish [<version>] [...] )
Squish supports testing of both native and cross-platform toolkits, such as Qt, Java, and Tk. GUI testing but make it fancy โจ
๐ Result Variables ๐
This module defines the following variables:
Squish_FOUNDโ Added in version 3.3. Boolean indicating whether (the requested version of) Squish was found.Squish_VERSIONโ Added in version 4.2. The full version of the Squish found.SQUISH_INSTALL_DIR_FOUNDโ Boolean indicating whether the Squish installation directory was found.SQUISH_SERVER_EXECUTABLE_FOUNDโ Boolean indicating whether the Squish server executable was found.SQUISH_CLIENT_EXECUTABLE_FOUNDโ Boolean indicating whether the Squish client executable was found.
๐๏ธ Cache Variables ๐๏ธ
The following cache variables may also be set:
SQUISH_INSTALL_DIRโ the Squish installation directory containingbin,lib,etc.SQUISH_SERVER_EXECUTABLEโ the path to thesquishserverexecutable.SQUISH_CLIENT_EXECUTABLEโ the path to thesquishrunnerexecutable.
๐ ๏ธ Commands ๐ ๏ธ
This module provides the following commands, if Squish is found:
squish_add_test
Adds a Squish test to the project:
squish_add_test(
<name>
AUT <target>
SUITE <suite-name>
TEST <squish-test-case-name>
[PRE_COMMAND <command>]
[POST_COMMAND <command>]
[SETTINGSGROUP <group>]
)
This command is built on top of the add_test() command and adds a Squish test called <name> to the CMake project. It supports Squish versions 4 and newer. ๐
During the CMake testing phase, the Squish server is started, the test is executed on the client, and the server is stopped once the test completes. If any of these steps fail (including if the test itself fails), a fatal error is raised indicating the test did not pass. So yeah โ if it breaks, it breaks loudly. No quiet failures here ๐
The arguments are:
<name>โ the name of the test. This is passed as the first argument to theadd_test()command.AUT <target>โ the name of the CMake target to be used as the AUT (Application Under Test), i.e., the executable that will be tested. Yes, AUT = the one on stage getting examined ๐SUITE<suite-name> โ either the full path to the Squish test suite or just the suite name (like, literally just the last directory name of the suite, no path). And if you go the short way? Then theCMakeLists.txtthat callssquish_add_test()has to live in the parent directory of the suite. Like, non-negotiable. ๐ซถTEST<squish-test-case-name> โ the name of the Squish test, which lines up with the subdirectory of the test inside the suite directory.PRE_COMMAND<command> โ an optional command to run before the Squish test kicks off. Pass it as a string. Could be a single command, or a semicolon-separated list of command and arguments. โจPOST_COMMAND<command> โ an optional command to run after the Squish test has finished. Same deal: pass it as a string, single command or semicolon-separated list of command and arguments. ๐SETTINGSGROUP<group> โ Deprecated since version 3.18: this argument is now just... ignored. Bestie it does nothing. It used to specify a settings group name for running the test instead of the default valueCTest_<username>. RIP to a real one ๐
Changed in version 3.18: in previous CMake versions, this command was named squish_v4_add_test(). So if you see that old name floating around, that's why. iykyk
๐ง squish_v3_add_test
Adds a Squish test to the project, but for when you're on Squish version 3.x:
squish_v3_add_test(
<test-name>
<application-under-test>
<squish-test-case-name>
<environment-variables>
<test-wrapper>
)
Note: this command is for Squish version 3, which is not maintained anymore. Like, genuinely please use a newer Squish version and the squish_add_test() command instead. This is giving legacy energy ๐ฐ๏ธ
The arguments are:
<name>โ the name of the test.<application-under-test>โ the path to the executable used as the AUT (Application Under Test), aka the executable that's gonna get tested.<squish-test-case-name>โ the name of the Squish test, matching the subdirectory of the test within the suite directory.<environment-variables>โ a semicolon-separated list of environment variables and their values (VAR=VALUE).<test-wrapper>โ a string of one or more (semicolon-separated list) test wrappers that the test case needs.
๐ Deprecated Variables
These following variables are hanging around purely for backward compatibility:
SQUISH_FOUNDโ Deprecated since version 4.2: useSquish_FOUND, which has the exact same value. Boolean indicating whether (the requested version of) Squish was found.SQUISH_VERSIONโ Deprecated since version 4.2: superseded bySquish_VERSION. The full version of the Squish that was found.SQUISH_VERSION_MAJORโ Deprecated since version 4.2: superseded bySquish_VERSION. The major version of the Squish found.SQUISH_VERSION_MINORโ Deprecated since version 4.2: superseded bySquish_VERSION. The minor version of the Squish found.SQUISH_VERSION_PATCHโ Deprecated since version 4.2: superseded bySquish_VERSION. The patch version of the Squish found.
๐ธ Examples
Finding Squish and specifying a minimum required version:
find_package(Squish 6.5)
Adding a Squish test:
enable_testing()
find_package(Squish 6.5)
if(Squish_FOUND)
squish_add_test(
projectTestName
AUT projectApp
SUITE ${CMAKE_CURRENT_SOURCE_DIR}/tests/projectSuite
TEST someSquishTest
)
endif()
Example, how to use the squish_v3_add_test() command:
enable_testing()
find_package(Squish 3.0)
if(Squish_FOUND)
squish_v3_add_test(
projectTestName
$<TARGET_FILE:projectApp>
someSquishTest
"FOO=1;BAR=2"
testWrapper
)
endif()
๐ฆ FindSubversion
Finds a Subversion command-line client executable (svn) and hands you commands for pulling info out of a Subversion working copy:
find_package(Subversion [<version>] [...])
โญ Result Variables
This module defines the following variables:
Subversion_FOUNDโ boolean indicating whether the (requested version of the) Subversion command-line client was found.Subversion_VERSIONโ Added in version 4.2. Version of thesvncommand-line client that was found.
๐ Cache Variables
These cache variables may also get set:
Subversion_SVN_EXECUTABLEโ path to thesvncommand-line client.
๐ Commands
This module provides the following commands if the Subversion command-line client is found:
๐ Subversion_WC_INFO
Extracts information from a Subversion working copy sitting at a specified directory:
Subversion_WC_INFO(<dir> <var-prefix> [IGNORE_SVN_FAILURE])
This command defines the following variables if running Subversion's info subcommand on <dir> succeeds; otherwise a SEND_ERROR message gets generated (not cute ๐ญ):
<var-prefix>_WC_URLโ URL of the repository (at<dir>).<var-prefix>_WC_ROOTโ root URL of the repository.<var-prefix>_WC_REVISIONโ current revision.<var-prefix>_WC_LAST_CHANGED_AUTHORโ author of last commit.<var-prefix>_WC_LAST_CHANGED_DATEโ date of last commit.<var-prefix>_WC_LAST_CHANGED_REVโ revision of last commit.<var-prefix>_WC_INFOโ output of the commandsvn info <dir>
The options are:
IGNORE_SVN_FAILUREโ Added in version 3.13. When specified, errors from the Subversion operation will not trigger aSEND_ERRORmessage. And in case of an error, those<var-prefix>_*variables just stay undefined. No drama ๐ซถ
๐ง Subversion_WC_LOG
Retrieves the log message of the base revision of a Subversion working copy at a given location:
Subversion_WC_LOG(<dir> <var-prefix>)
This command defines the following variable if running Subversion's log subcommand on <dir> succeeds; otherwise a SEND_ERROR message is generated:
<var-prefix>_LAST_CHANGED_LOGโ last log of the base revision of a Subversion working copy located at<dir>.
๐ Deprecated Variables
The following variables are provided for backward compatibility:
SUBVERSION_FOUNDโ Deprecated since version 4.2: useSubversion_FOUND, which has the same value. Boolean indicating whether the (requested version of the) Subversion command-line client was found.Subversion_VERSION_SVNโ Deprecated since version 4.2: use theSubversion_VERSION. Version of thesvncommand-line client that was found.
๐ Examples
๐ธ Examples: Finding Subversion
Finding Subversion:
find_package(Subversion)
Or, finding Subversion and specifying a minimum required version:
find_package(Subversion 1.4)
Or, finding Subversion and making it required (and if it's not found, processing just stops with an error message โ brutal but fair):
find_package(Subversion REQUIRED)
๐ Example: Using Subversion
Finding Subversion and retrieving info about the current project's working copy:
find_package(Subversion)
if(Subversion_FOUND)
Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project)
message("Current revision is ${Project_WC_REVISION}")
Subversion_WC_LOG(${PROJECT_SOURCE_DIR} Project)
message("Last changed log is ${Project_LAST_CHANGED_LOG}")
endif()
๐ฅ FindSWIG
Finds the installed Simplified Wrapper and Interface Generator (SWIG, https://swig.org) executable and figures out its version:
find_package(SWIG [<version>] [COMPONENTS <langs>...] [...])
Added in version 3.19: support for specifying a version range when calling the find_package() command. When a version is requested, you can still spec it as a single value like before, and now you can also use a version range. For the whole detailed breakdown of version range usage and capabilities, go look at the find_package() command. It's giving thorough ๐
โจ Components
Added in version 3.18.
This module supports optional components to specify target languages.
If a COMPONENTS or OPTIONAL_COMPONENTS argument is given to the find_package() command, it'll also figure out supported target languages. Obsessed with the flexibility honestly:
find_package(SWIG [COMPONENTS <langs>...] [OPTIONAL_COMPONENTS <langs>...])
Any COMPONENTS you give to find_package() should be the names of supported target languages as provided to the LANGUAGE argument of swig_add_library(), like python or perl5. And heads up: language names must be lowercase. no cap ๐
โญ Result Variables
This module defines the following variables:
SWIG_FOUNDโ boolean indicating whether the (requested version of) SWIG and any required components were found on the system.SWIG_VERSIONโ SWIG executable version (result ofswig -version).SWIG_<lang>_FOUNDโ ifCOMPONENTSorOPTIONAL_COMPONENTSare requested, each available target language <lang> (lowercase) gets set toTRUE.SWIG_DIRโ path to the installed SWIG Lib directory (result ofswig -swiglib).
๐ Cache Variables
The following cache variables may also be set:
SWIG_EXECUTABLEโ the path to the SWIG executable. This executable is what's used to retrieve all the information for this module. And you can also manually set it to change the version to be found, straight from the command line. main character variable energy ๐
๐ฆ Examples
Example usage requiring SWIG 4.0 or higher plus Python language support, with optional Fortran support:
find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran)
if(SWIG_FOUND)
message("SWIG found: ${SWIG_EXECUTABLE}")
if(NOT SWIG_fortran_FOUND)
message(WARNING "SWIG Fortran bindings cannot be generated")
endif()
endif()
This module is commonly used in conjunction with the UseSWIG module:
find_package(SWIG COMPONENTS python)
if(SWIG_FOUND)
include(UseSWIG)
swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
endif()
๐ See Also
- The
UseSWIGmodule to use SWIG in CMake. literally the go-to bestie for this ๐ซถ
FindTCL ๐
Okay so FindTCL finds Tcl (Tool Command Language), the dynamic programming language, bestie:
find_package(TCL [...])
This module locates a Tcl installation โ include dirs, libraries, the whole thing โ and determines the appropriate Tcl library name for linking. And because the Tcl ecosystem is a package, it also finds Tk, the GUI toolkit that gives you a library of basic widgets for building graphical user interfaces. ๐
Result Variables โจ
This module defines the following variables, fr fr:
TCL_FOUNDโ Boolean indicating whether Tcl was found.TK_FOUNDโ Boolean indicating whether Tk was found.TCLTK_FOUNDโ Boolean indicating whether both Tcl and Tk were found.
Cache Variables ๐ซถ
The following cache variables may also be set:
TCL_LIBRARYโ The path to the Tcl library (e.g.,tcl, etc.).TCL_INCLUDE_PATHโ The directory containingtcl.hand other Tcl-related headers needed to use Tcl.TCL_TCLSHโ The path to thetclshcommand-line executable.TK_LIBRARYโ The path to the Tk library (e.g.,tk, etc.).TK_INCLUDE_PATHโ The directory containingtk.hand other Tk-related headers needed to use Tk.TK_WISHโ The path to thewishwindowing shell command-line executable.
Other Libraries ๐
The Tcl Stub Library can be found using the separate FindTclStub <# module:FindTclStub> module.
Examples ๐ธ
Finding Tcl:
find_package(TCL)
See Also ๐
- The
FindTclsh <#module:FindTclsh>module to find the Tcl shell command-line executable. - The
FindTclStub <#module:FindTclStub>module to find the Tcl Stubs Library. - The
FindWish <#module:FindWish>module to find thewishwindowing shell command-line executable .
FindTclsh ๐
Finds the Tcl shell command-line executable (tclsh), which includes the Tcl (Tool Command Language) interpreter:
find_package(Tclsh [<version>] [...])
Result Variables โจ
This module defines the following variables:
Tclsh_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of)tclshexecutable was found.Tclsh_VERSIONโ Added in version 4.2. The version oftclshfound.
Cache Variables ๐ซถ
The following cache variables may also be set:
TCL_TCLSHโ The path to thetclshexecutable.
Deprecated Variables ๐
The following variables are provided for backward compatibility:
TCLSH_FOUNDโ Deprecated since version 4.2: UseTclsh_FOUND, which has the same value. Boolean indicating whether the (requested version of)tclshexecutable was found.TCLSH_VERSION_STRINGโ Deprecated since version 4.2: UseTclsh_VERSION, which has the same value. The version oftclshfound.
Examples ๐ธ
In the following example, this module is used to find the tclsh command-line executable, which is then executed in a process to evaluate TCL code from the script file located in the project source directory:
find_package(Tclsh)
if(Tclsh_FOUND)
execute_process(COMMAND ${TCL_TCLSH} example-script.tcl)
endif()
See Also ๐
- The
FindTCL <#module:FindTCL>module to find the Tcl installation. - The
FindTclStub <#module:FindTclStub>module to find the Tcl Stubs Library.
FindTclStub ๐งฉ
Finds the Tcl Stub Library, which is used for building version-independent Tcl extensions:
find_package(TclStub [...])
Tcl (Tool Command Language) is a dynamic programming language, and the Tcl Stub Library provides a mechanism to allow Tcl extensions to be compiled in a way that they can work across multiple Tcl versions, without requiring recompilation. Slay. ๐
This module is typically used in conjunction with Tcl development projects that aim to be portable across different Tcl releases. It first calls the FindTCL <#module:FindTCL> module to locate Tcl installation and then attempts to find the stub libraries corresponding to the located Tcl version.
Result Variables โจ
This module defines the following variables:
TclStub_FOUNDโ Added in version 4.2. Boolean indicating whether the Tcl Stub Library was found.
Cache Variables ๐ซถ
The following cache variables may also be set:
TCL_STUB_LIBRARYโ The path to the Tcl stub library.TK_STUB_LIBRARYโ The path to the Tk stub library.TTK_STUB_LIBRARYโ The path to thettkstub library.
Examples ๐ธ
Finding Tcl Stubs Library:
find_package(TclStub)
See Also ๐
- The
FindTCL <#module:FindTCL>module to find the Tcl installation. - The
FindTclsh <#module:FindTclsh>module to find the Tcl shell command-line executable.
Online references:
- How to Use the Tcl Stubs Library โ
https://www.tcl-lang.org/doc/howto/stubs.html - Practical Programming in Tcl and Tk โ
https://www.oreilly.com/library/view/practical-programming-in/0130385603/
FindThreads ๐งต
Finds and determines the thread library of the system for multithreading support:
find_package(Threads [...])
Multithreading enables concurrent execution within a single program, typically by creating multiple threads of execution. Most commonly, this is done using libraries such as POSIX Threads (pthreads) on Unix-like systems or Windows threads on Windows.
This module abstracts the platform-specific differences and detects how to enable thread support โ whether it requires linking to a specific library, adding compiler flags (like -pthread), or both. On some platforms, threading is also implicitly available in default libraries without the need to use additional flags or libraries.
This module is suitable for use in both C and C++ projects (and occasionally other compiled languages) that rely on system-level threading APIs.
Using this module ensures that project builds correctly across different platforms by handling the detection and setup of thread support in a portable way. iconic behavior, honestly. ๐ฆ
C and C++ Language Standards ๐งต
The C11 standard introduced a minimal cross-platform thread API via <threads.h> header file, and C++11 added <thread> header to the standard library, offering high-level multithreading support. These standard headers allow writing portable threaded code at the language level, without directly using platform-specific APIs like pthreads or Windows threads.
However, even with standard C11 or C++11 threads support available, there may still be a need for platform-specific compiler or linker flags (e.g., -pthread on Unix-like systems) for some applications. This is where FindThreads remains relevant โ it ensures these flags and any required libraries are correctly set up, even if not explicitly using system APIs.
In short:
- Use
<thread>(C++11 and later) or<threads.h>(C11) in source code for portability and simpler syntax. - Use
find_package(Threads)in CMake project when application needs the traditional threading support and to ensure code compiles and links correctly across different platforms.
Imported Targets ๐
This module provides the following Imported Targets <#imported-targets>:
Threads::Threadsโ Added in version 3.1. Target encapsulating the usage requirements to enable threading through flags or a threading library, if found. This target is available if threads are detected as supported.
Result Variables โจ
This module defines the following variables:
Threads_FOUNDโ Boolean indicating whether Threads is supported, either through a separate library or a standard library.CMAKE_THREAD_LIBS_INITโ The thread library to use. This may be empty if the thread functions are provided by the system libraries and no special flags are needed to use them.CMAKE_USE_WIN32_THREADS_INITโ If the found thread library is the win32 one.CMAKE_USE_PTHREADS_INITโ If the found thread library is pthread compatible.CMAKE_HP_PTHREADS_INITโ If the found thread library is the HP thread library.
Variables Affecting Behavior ๐
This module accepts the following variables before calling find_package(Threads):
THREADS_PREFER_PTHREAD_FLAGโ Added in version 3.1. If the use of the-pthreadcompiler and linker flag is preferred then the caller can set this variable to boolean true. The compiler flag can only be used with the imported target. Use of both the imported target as well as this switch is highly recommended for new code.
This variable has no effect if the system libraries provide the thread functions, i.e. when CMAKE_THREAD_LIBS_INIT will be empty.
Examples ๐ธ
Finding Threads and linking the imported target to a project target:
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads)
target_link_libraries(example PRIVATE Threads::Threads)
FindTIFF ๐ผ๏ธ
Finds the TIFF library https://libtiff.gitlab.io/libtiff/ (libtiff):
find_package(TIFF [<version>] [COMPONENTS <components>...] [...])
This module also takes into account the upstream TIFF library's exported CMake package configuration, if available.
Components ๐งฉ
This module supports optional components which can be specified with:
find_package(TIFF [COMPONENTS <components>...])
Supported components include:
CXXโ Added in version 3.19. Optional component that ensures that the C++ wrapper library (libtiffxx) is found.
Imported Targets ๐
This module provides the following Imported Targets <#imported-targets>:
TIFF::TIFFโ Added in version 3.5. Target encapsulating the TIFF library usage requirements, available only if the TIFF is found.TIFF::CXXโ Added in version 3.19. Target encapsulating the usage requirements for the C++ wrapper librarylibtiffxx, available only if TIFF is found. This target providesCXXusage requirements only if the compiler is not MSVC. It also has theTIFF::TIFFtarget linked in to simplify its usage.
Result Variables โจ
This module defines the following variables:
TIFF_FOUNDโ Boolean indicating whether (the requested version of) TIFF is found.TIFF_VERSIONโ Added in version 4.2. The version of TIFF library found.TIFF_INCLUDE_DIRSโ The directory containing the TIFF headers.TIFF_LIBRARIESโ TIFF libraries to be linked.
Cache Variables ๐ซถ
The following cache variables may also be set:
TIFF_INCLUDE_DIRโ The directory containing the TIFF headers.TIFF_LIBRARY_RELEASEโ Added in version 3.4. The path to the TIFF library for release configurations.TIFF_LIBRARY_DEBUGโ added in version 3.4. the path to the TIFF library for debug configs ๐ฉตTIFFXX_LIBRARY_RELEASEโ added in version 3.19. the path to the TIFFXX library for release configs.TIFFXX_LIBRARY_DEBUGโ added in version 3.19. the path to the TIFFXX library for debug configs. bestie the debug/release split is literally the whole personality of this module ๐
Deprecated Variables
okay so these are still here, but like... for backward compatibility only. they're giving "we keep it around for the old heads" โจ
TIFF_VERSION_STRINGโ deprecated since version 4.2: superseded by theTIFF_VERSION. just the version of the TIFF library that was found. she's retired, don't @ her ๐
Examples
finding TIFF and linking it to your project target, iconic behavior:
find_package(TIFF)
target_link_libraries(project_target PRIVATE TIFF::TIFF)
finding TIFF and TIFFXX by specifying the CXX component (yes you have to ask for it, it's not just gonna show up):
find_package(TIFF COMPONENTS CXX)
target_link_libraries(project_target PRIVATE TIFF::CXX)
๐ฆ FindVulkan
added in version 3.7. finds Vulkan โ the low-overhead, cross-platform 3D graphics and computing API โ plus all the related dev tools that the Vulkan SDK hands you, like:
find_package(Vulkan [<version>] [COMPONENTS <components>...] [...])
Vulkan ships with the commonly used utilities like shader compilers and SPIR-V tools (think DXC, glslc, glslang, etc. โ you know the ones) that support Vulkan-based dev workflows. no cap, the toolkit goes hard ๐ฅ
Components
added in version 3.24. this module supports several optional components that you can pass through find_package():
find_package(Vulkan [COMPONENTS <components>...])
each component gives you a matching imported target. the supported ones are:
glslcโ added in version 3.24. finds the SPIR-V compiler. note: this optional component is always implied automatically for backward compatibility, even if you don't request it. she invites herself, that's just how it is ๐glslangValidatorโ added in version 3.24. finds theglslangValidatortool used to compile GLSL and HLSL shaders into SPIR-V. also always implied automatically for backward compatibility, even if you don't ask. same energy.glslangโ added in version 3.24. finds the Khronos-reference front-end shader parser and SPIR-V code generation library (glslang).shaderc_combinedโ added in version 3.24. finds the Google static library used for Vulkan shader compilation.SPIRV-Toolsโ added in version 3.24. finds the Khronos library for analyzing and transforming SPIR-V modules.MoltenVKโ added in version 3.24. finds the Khronos MoltenVK library, which is available on macOS, and implements a subset of the Vulkan API over the Apple Metal graphics framework ๐dxcโ added in version 3.25. finds the DirectX Shader Compiler (DXC), library and command-line tool. heads up: Visual Studio also ships a DXC tool, but the version bundled with the Vulkan SDK is usually the one you need for Vulkan dev, since it has Vulkan capability enabled. not the same thing, don't get it twisted ๐volkโ added in version 3.25. finds the Vulkan meta-loadervolklibrary.
Imported Targets
this module hands you these imported targets:
Vulkan::Vulkanโ the target that encapsulates the main Vulkan library usage requirements. available if Vulkan is found. the main character fr ๐Vulkan::glslcโ added in version 3.19. imported executable target encapsulating the GLSLC SPIR-V compiler usage requirements. available ifglslcis found.Vulkan::Headersโ added in version 3.21. target encapsulating the usage requirements needed to include Vulkan headers. it provides only the include directories and does not link to any library โ which is exactly what you want if your app loads the Vulkan library dynamically at runtime ๐ซถ available if Vulkan is found.Vulkan::glslangValidatorโ added in version 3.21. imported executable target encapsulating theglslangValidatorusage requirements. available if this tool is found.Vulkan::glslangโ added in version 3.24. target encapsulating theglslanglibrary usage requirements. available ifglslangis found in the SDK.Vulkan::shaderc_combinedโ added in version 3.24. target encapsulating theshaderc_combinedlibrary usage requirements. available if this library is found in the SDK.Vulkan::SPIRV-Toolsโ added in version 3.24. target encapsulating theSPIRV-Toolslibrary usage requirements. available if this library is found in the SDK.Vulkan::MoltenVKโ added in version 3.24. target encapsulating theMoltenVKlibrary usage requirements. available if this library is found in the SDK.Vulkan::volkโ added in version 3.25. target encapsulating thevolklibrary usage requirements. available ifvolkis found in the SDK.Vulkan::dxc_libโ added in version 3.25. target encapsulating the usage requirements for the DirectX shader compiler library. available if the DXC library is found in the SDK.Vulkan::dxc_exeโ added in version 3.25. imported executable target providing usage requirements for the DirectX shader compiler CLI tool. available if the SDK has this tool.
Result Variables
this module defines these variables:
Vulkan_FOUNDโ boolean, tells you whether (the requested version of) Vulkan plus all required components were found. the vibe check of the whole operation โจVulkan_VERSIONโ added in version 3.23. the version of Vulkan that was found. the value is retrieved fromvulkan/vulkan_core.h.Vulkan_INCLUDE_DIRSโ include directories you need to use the main Vulkan library.Vulkan_LIBRARIESโ libraries you need to link against to use the main Vulkan library.Vulkan_glslc_FOUNDโ added in version 3.24. boolean, whether the SDK provides theglslcexecutable.Vulkan_glslangValidator_FOUNDโ added in version 3.24. boolean, whether the SDK provides theglslangValidatorexecutable.Vulkan_glslang_FOUNDโ added in version 3.24. boolean, whether the SDK provides theglslanglibrary.Vulkan_shaderc_combined_FOUNDโ added in version 3.24. boolean, whether the SDK provides theshaderc_combinedlibrary.Vulkan_SPIRV-Tools_FOUNDโ added in version 3.24. boolean, whether the SDK provides theSPIRV-Toolslibrary.Vulkan_MoltenVK_FOUNDโ added in version 3.24. boolean, whether the SDK provides theMoltenVKlibrary.Vulkan_volk_FOUNDโ added in version 3.25. boolean, whether the SDK provides thevolklibrary.Vulkan_dxc_lib_FOUNDโ added in version 3.25. boolean, whether the SDK provides the DirectX shader compiler library.Vulkan_dxc_exe_FOUNDโ added in version 3.25. boolean, whether the SDK provides the DirectX shader compiler CLI tool.
Cache Variables
these cache variables may also be set:
Vulkan_INCLUDE_DIRโ the directory containing the Vulkan headers.Vulkan_LIBRARYโ the path to the Vulkan library.Vulkan_GLSLC_EXECUTABLEโ added in version 3.19. the path to the GLSL SPIR-V compiler.Vulkan_GLSLANG_VALIDATOR_EXECUTABLEโ added in version 3.21. the path to theglslangValidatortool.Vulkan_glslang_LIBRARYโ added in version 3.24. the path to theglslanglibrary.Vulkan_shaderc_combined_LIBRARYโ added in version 3.24. the path to theshaderc_combinedlibrary.Vulkan_SPIRV-Tools_LIBRARYโ added in version 3.24. the path to theSPIRV-Toolslibrary.Vulkan_MoltenVK_LIBRARYโ added in version 3.24. the path to theMoltenVKlibrary.Vulkan_volk_LIBRARYโ added in version 3.25. the path to thevolklibrary.Vulkan_dxc_LIBRARYโ added in version 3.25. the path to the DirectX shader compiler library.Vulkan_dxc_EXECUTABLEโ added in version 3.25. the path to the DirectX shader compiler CLI tool.Vulkan_Layer_API_DUMP_LIBRARYโ added in version 4.4. path to theapi_dumpVulkan Layer library.Vulkan_Layer_CRASH_DIAGNOSTIC_LIBRARYโ added in version 4.4. path to thecrash_diagnosticVulkan Layer library.Vulkan_Layer_GFXRECONSTRUCT_LIBRARYโ added in version 4.4. path to thegfxreconstructVulkan Layer library.Vulkan_Layer_KHRONOS_PROFILES_LIBRARYโ added in version 4.4. path to thekhronos_profilesVulkan Layer library.Vulkan_Layer_KHRONOS_SHADER_OBJECT_LIBRARYโ added in version 4.4. path to thekhronos_shader_objectVulkan Layer library.Vulkan_Layer_KHRONOS_SYNCHRONIZATION2_LIBRARYโ added in version 4.4. path to thekhronos_synchronization2Vulkan Layer library.Vulkan_Layer_KHRONOS_VALIDATION_LIBRARYโ added in version 4.4. path to thekhronos_validationVulkan Layer library.Vulkan_Layer_MONITOR_LIBRARYโ added in version 4.4. path to themonitorVulkan Layer library.Vulkan_Layer_SCREENSHOT_LIBRARYโ added in version 4.4. path to thescreenshotVulkan Layer library. yes there's a screenshot layer, we love a documentation moment ๐ธ
Hints
this module accepts the following variable:
VULKAN_SDKโ this environment variable can optionally be set to specify the location of the Vulkan SDK root directory for the given architecture. it's typically set by sourcing the toplevelsetup-env.shscript of the Vulkan SDK directory into your shell environment. tldr: source the script, get the vibes ๐
Examples
finding the Vulkan library and linking it to a project target โ the classic:
find_package(Vulkan)
target_link_libraries(project_target PRIVATE Vulkan::Vulkan)
finding Vulkan plus extra components (in this case volk, because we're extra):
find_package(Vulkan COMPONENTS volk)
target_link_libraries(project_target PRIVATE Vulkan::Vulkan Vulkan::volk)
๐ธ FindWget
this module finds the wget command-line tool โ you know, the one for retrieving content from web servers:
find_package(Wget [...])
Result Variables
this module defines this variable:
Wget_FOUNDโ added in version 3.3. boolean, tells you whetherwgetwas found. just the one variable, she's lowkey and she knows it ๐
Cache Variables
Like, sometimes you gotta set these cache vars yourself, bestie:
WGET_EXECUTABLEโ the full path to thewgettool. that's it, that's the whole vibe ๐
Deprecated Variables
These ones are still here for backward-compat reasons (grandfathered in, no cap):
WGET_FOUNDโ deprecated since version4.2: useWget_FOUNDinstead, it literally has the same value. Boolean that says whetherwgetwas found. that's it. โจ
Examples
Finding wget and then executing it in a process โ iconic combo, honestly:
find_package(Wget)
if(Wget_FOUND)
execute_process(COMMAND ${WGET_EXECUTABLE} -h)
endif()
See Also
- The
file(DOWNLOAD)command to download the given URL to a local file. the way that just works ๐ซถ
FindWish
Finds wish, which is a simple windowing shell command-line executable:
find_package(Wish [...])
This module is commonly used in conjunction with finding a TCL installation (see the FindTCL module). It helps determine where the TCL include paths and libraries are, as well as identifying the name of the TCL library. multitasking queen ๐
If the UNIX variable is defined, the module will prioritize looking for the Cygwin version of the wish executable. not me prioritizing cygwin ๐
Result Variables
This module defines the following variables:
Wish_FOUNDโ added in version4.2. Boolean indicating whether thewishexecutable was found. slay โจ
Cache Variables
The following cache variables may also be set:
TK_WISHโ the path to thewishexecutable. ๐ฆ
Examples
Finding wish:
find_package(Wish)
message(STATUS "Found wish at: ${TK_WISH}")
FindwxWidgets
Finds a wxWidgets installation and provides usage requirements for usage in projects:
find_package(wxWidgets [<version>] [COMPONENTS <components>...] [...])
wxWidgets (formerly known as wxWindows) is a widget toolkit and tools library for creating graphical user interfaces (GUIs) for cross-platform applications. it's giving cross-platform GUI royalty ๐
Added in version 3.4: support for find_package() version argument.
Added in version 3.14: OPTIONAL_COMPONENTS support. we love an upgrade ๐
Components
wxWidgets is a modular library. This module supports components to specify which modules to use. Components can be specified with the find_package() command:
find_package(
wxWidgets
[COMPONENTS <components>...]
[OPTIONAL_COMPONENTS <components>...]
)
Supported components include:
baseโ finds the library that provides mandatory classes that any wxWidgets code depends on. This component is always required for applications implementing wxWidgets. no skipping, periodt.coreโ finds the library that provides basic GUI classes such as GDI classes or controls.glโ finds the OpenGL support. fancy โจmonoโ finds the wxWidgets monolithic library. one big slay.auiโ finds the Advanced User Interface docking library.netโ finds the library that provides network access. ๐webviewโ added in version3.4. finds the library that provides rendering of web documents (HTML/CSS/JavaScript). it's giving browser-in-your-app ๐
For a full list of supported wxWidgets components, refer to the upstream documentation. (iykyk, go read it)
If no components are specified, this module by default searches for core and base components. the defaults ate, honestly.
Imported Targets
This module provides the following Imported Targets:
wxWidgets::wxWidgetsโ added in version3.27. an interface imported target encapsulating the wxWidgets usage requirements for the found components, available if wxWidgets is found. main character target energy ๐โจ
Result Variables
This module defines the following variables:
wxWidgets_FOUNDโ boolean indicating whether (the requested version of) wxWidgets and all its requested components were found. ๐ซถwxWidgets_VERSIONโ added in version4.2. the version of the wxWidgets found. ๐wxWidgets_INCLUDE_DIRSโ include directories forWIN32, i.e., where to find<wx/wx.h>and<wx/setup.h>; possibly empty for Unix-like systems. lowkey empty on unix, that's fine.wxWidgets_LIBRARIESโ path to the wxWidgets libraries. the whole point, bestie ๐wxWidgets_LIBRARY_DIRSโ compile time link dirs, useful for setting rpath on Unix-like systems. typically an empty string inWIN32environment. okay windows why are you like this ๐ญwxWidgets_DEFINITIONSโ contains compile definitions required to compile/link against WX, e.g.WXUSINGDLL.wxWidgets_DEFINITIONS_DEBUGโ contains compile definitions required to compile/link against WX debug builds, e.g.__WXDEBUG__.wxWidgets_CXX_FLAGSโ include directories and compiler flags for Unix-like systems, empty on Windows. essentially the output ofwx-config --cxxflags. literally just that output. โจ
Hints
This module accepts the following variables before calling find_package(wxWidgets):
WX_CONFIGโ added in version3.11. environment variable to manually specify the name of the wxWidgets library configuration provider executable that will be searched besides the default namewx-config. ๐ธWXRC_CMDโ added in version3.11. environment variable to manually specify the name of the wxWidgets resource file compiler executable that will be searched besides the default namewxrc. ๐ฆ
There are two search branches: a Windows style and a Unix style. For Windows, the following variables are searched for and set to defaults in case of multiple choices. Change them if the defaults are not desired (i.e., these are the only variables that should be changed to select a configuration):
wxWidgets_ROOT_DIRโ base wxWidgets directory (e.g.,C:/wxWidgets-3.2.0). ๐wxWidgets_LIB_DIRโ path to wxWidgets libraries (e.g.,C:/wxWidgets-3.2.0/lib/vc_x64_lib).wxWidgets_CONFIGURATIONโ configuration to use (e.g.,msw,mswd,mswu,mswunivud, etc.) the alphabet soup is real ๐wxWidgets_EXCLUDE_COMMON_LIBRARIESโ set toTRUEto exclude linking of commonly required libs (e.g.,png,tiff,jpeg,zlib,webp,regex,expat,scintilla,lexilla, etc.). no cap, they mean all of those.
For Unix style this module uses the wx-config utility. Selecting between debug/release, unicode/ansi, universal/non-universal, and static/shared is possible in the QtDialog or ccmake interfaces by turning ON/OFF the following variables:
wxWidgets_USE_DEBUGโ if enabled, the wxWidgets debug build will be searched. ๐wxWidgets_USE_UNICODEโ if enabled, the wxWidgets unicode build will be searched. ๐wxWidgets_USE_UNIVERSALโ if enabled, the wxWidgets universal build will be searched. ๐wxWidgets_USE_STATICโ if enabled, static wxWidgets libraries will be linked. ๐wxWidgets_CONFIG_OPTIONSโ this variable can be used for all other options that need to be passed to thewx-configutility. for example, to use the base toolkit found on the system at/usrinstall prefix, set the variable (before calling thefind_package()command) as such:
set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr)
Deprecated Variables
The following variables are provided for backward compatibility:
wxWidgets_VERSION_STRINGโ deprecated since version4.2: usewxWidgets_VERSION, which has the same value. added in version3.4. the version of the wxWidgets found.wxWidgets_USE_FILEโ deprecated since version4.2: instead of using this variable, include theUsewxWidgetsmodule directly:
include(UsewxWidgets)
the path to the UsewxWidgets module for using wxWidgets in the current directory. for example:
find_package(wxWidgets)
if(wxWidgets_FOUND)
include(${wxWidgets_USE_FILE})
endif()
Examples
Example: Finding wxWidgets
Finding wxWidgets and making it required (if wxWidgets is not found, processing stops with an error message โ no wiggle room, bestie โ):
find_package(wxWidgets REQUIRED)
Example: Using Imported Target
Finding wxWidgets and using imported target in a project:
find_package(wxWidgets)
target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
Example: Using Components
Finding wxWidgets and specifying components:
find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
Example: Monolithic wxWidgets Build
Sample usage with monolithic wxWidgets build:
find_package(wxWidgets COMPONENTS mono)
target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
Example: Using Variables
Finding and using wxWidgets in CMake versions prior to 3.27, when the imported target wasn't yet available. retro era ๐
:
# Note that for MinGW users the order of libs is important.
find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
if(wxWidgets_FOUND)
include(UsewxWidgets)
# and for each of the project dependent executable/library targets:
target_link_libraries(example ${wxWidgets_LIBRARIES})
endif()
FindX11
Finds the X11 installation on Unix-like systems:
find_package(X11 [COMPONENTS <components>...] [...])
Result Variables
This module defines the following variables:
X11_FOUNDโ boolean indicating whether X11 was found. ๐ซถX11_<component>_FOUNDโ boolean indicating whether the<component>was found. (yes, one of these per component you asked for โ very demure, very per-component โจ)X11_INCLUDE_DIRโ include directories needed to use X11.X11_LIBRARIESโ libraries needed to link against to use X11. the actual goods ๐
and also the following more fine grained variables and targets:
Added in version 3.14: Imported targets. we been knew, iconic.
X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND, X11::ICE
X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND, X11::SM
X11_X11_INCLUDE_PATH, X11_X11_LIB, X11::X11
X11_Xaccessrules_INCLUDE_PATH,
X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND
X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND, X11::Xau
X11_xcb_INCLUDE_PATH, X11_xcb_LIB, X11_xcb_FOUND, X11::xcb
X11_X11_xcb_INCLUDE_PATH, X11_X11_xcb_LIB, X11_X11_xcb_FOUND, X11::X11_xcb
X11_xcb_composite_INCLUDE_PATH, X11_xcb_composite_LIB, X11_xcb_composite_FOUND, X11::xcb_composite
X11_xcb_cursor_INCLUDE_PATH, X11_xcb_cursor_LIB, X11_xcb_cursor_FOUND, X11::xcb_cursor
X11_xcb_damage_INCLUDE_PATH, X11_xcb_damage_LIB, X11_xcb_damage_FOUND, X11::xcb_damage
X11_xcb_dpms_INCLUDE_PATH, X11_xcb_dpms_LIB, X11_xcb_dpms_FOUND, X11::xcb_dpms
X11_xcb_dri2_INCLUDE_PATH, X11_xcb_dri2_LIB, X11_xcb_dri2_FOUND, X11::xcb_dri2
X11_xcb_dri3_INCLUDE_PATH, X11_xcb_dri3_LIB, X11_xcb_dri3_FOUND, X11::xcb_dri3
X11_xcb_errors_INCLUDE_PATH, X11_xcb_errors_LIB, X11_xcb_errors_FOUND, X11::xcb_errors
X11_xcb_ewmh_INCLUDE_PATH, X11_xcb_ewmh_LIB, X11_xcb_ewmh_FOUND, X11::xcb_ewmh
X11_xcb_glx_INCLUDE_PATH, X11_xcb_glx_LIB, X11_xcb_glx_FOUND, X11::xcb_glx
X11_xcb_icccm_INCLUDE_PATH, X11_xcb_icccm_LIB, X11_xcb_icccm_FOUND, X11::xcb_icccm
X11_xcb_image_INCLUDE_PATH, X11_xcb_image_LIB, X11_xcb_image_FOUND, X11::xcb_image
X11_xcb_keysyms_INCLUDE_PATH, X11_xcb_keysyms_LIB, X11_xcb_keysyms_FOUND, X11::xcb_keysyms
X11_xcb_present_INCLUDE_PATH, X11_xcb_present_LIB, X11_xcb_present_FOUND, X11::xcb_present
X11_xcb_randr_INCLUDE_PATH, X11_xcb_randr_LIB, X11_xcb_randr_FOUND, X11::xcb_randr
X11_xcb_record_INCLUDE_PATH, X11_xcb_record_LIB, X11_xcb_record_FOUND, X11::xcb_record
X11_xcb_render_INCLUDE_PATH, X11_xcb_render_LIB, X11_xcb_render_FOUND, X11::xcb_render
X11_xcb_render_util_INCLUDE_PATH,X11_xcb_render_util_LIB,X11_xcb_render_util_FOUND,X11::xcb_render_util
X11_xcb_res_INCLUDE_PATH, X11_xcb_res_LIB, X11_xcb_res_FOUND, X11::xcb_res
X11_xcb_screensaver_INCLUDE_PATH,X11_xcb_screensaver_LIB,X11_xcb_screensaver_FOUND,X11::xcb_screensaver
X11_xcb_shape_INCLUDE_PATH, X11_xcb_shape_LIB, X11_xcb_shape_FOUND, X11::xcb_shape
X11_xcb_shm_INCLUDE_PATH, X11_xcb_shm_LIB, X11_xcb_shm_FOUND, X11::xcb_shm
X11_xcb_sync_INCLUDE_PATH, X11_xcb_sync_LIB, X11_xcb_sync_FOUND, X11::xcb_sync
X11_xcb_util_INCLUDE_PATH, X11_xcb_util_LIB, X11_xcb_util_FOUND, X11::xcb_util
X11_xcb_xf86dri_INCLUDE_PATH, X11_xcb_xf86dri_LIB, X11_xcb_xf86dri_FOUND, X11::xcb_xf86dri
X11_xcb_xfixes_INCLUDE_PATH, X11_xcb_xfixes_LIB, X11_xcb_xfixes_FOUND, X11::xcb_xfixes
X11_xcb_xinerama_INCLUDE_PATH, X11_xcb_xinerama_LIB, X11_xcb_xinerama_FOUND, X11::xcb_xinerama
X11_xcb_xinput_INCLUDE_PATH, X11_xcb_xinput_LIB, X11_xcb_xinput_FOUND, X11::xcb_xinput
X11_xcb_xkb_INCLUDE_PATH, X11_xcb_xkb_LIB, X11_xcb_xkb_FOUND, X11::xcb_xkb
X11_xcb_xrm_INCLUDE_PATH, X11_xcb_xrm_LIB, X11_xcb_xrm_FOUND, X11::xcb_xrm
X11_xcb_xtest_INCLUDE_PATH, X11_xcb_xtest_LIB, X11_xcb_xtest_FOUND, X11::xcb_xtest
X11_xcb_xvmc_INCLUDE_PATH, X11_xcb_xvmc_LIB, X11_xcb_xvmc_FOUND, X11::xcb_xvmc
X11_xcb_xv_INCLUDE_PATH, X11_xcb_xv_LIB, X11_xcb_xv_FOUND X11::xcb_xv
X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite
X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND, X11::Xcursor
X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND, X11::Xdamage
X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND, X11::Xdmcp
X11_Xext_INCLUDE_PATH, X11_Xext_LIB, X11_Xext_FOUND, X11::Xext
X11_Xxf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_Xxf86misc_FOUND, X11::Xxf86misc
X11_Xxf86vm_INCLUDE_PATH, X11_Xxf86vm_LIB X11_Xxf86vm_FOUND, X11::Xxf86vm
X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND, X11::Xfixes
X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND, X11::Xft
X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND, X11::Xi
X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND, X11::Xinerama
X11_Xkb_INCLUDE_PATH,
X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND, X11::Xkb
X11_xkbcommon_INCLUDE_PATH, X11_xkbcommon_LIB, X11_xkbcommon_FOUND, X11::xkbcommon
X11_xkbcommon_X11_INCLUDE_PATH, X11_xkbcommon_X11_LIB, X11_xkbcommon_X11_FOUND, X11::xkbcommon_X11
X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND, X11::xkbfile
X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND, X11::Xmu
X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND, X11::Xpm
X11_Xpresent_INCLUDE_PATH, X11_Xpresent_LIB, X11_Xpresent_FOUND, X11::Xpresent
X11_Xtst_INCLUDE_PATH, X11_Xtst_LIB, X11_Xtst_FOUND, X11::Xtst
X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND, X11::Xrandr
X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND, X11::Xrender
X11_XRes_INCLUDE_PATH, X11_XRes_LIB, X11_XRes_FOUND, X11::XRes
X11_Xss_INCLUDE_PATH, X11_Xss_LIB, X11_Xss_FOUND, X11::Xss
X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND, X11::Xt
X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND, X11::Xutil
X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND, X11::Xv
X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND
X11_Xdbe_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xdbe_FOUND
X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND
X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND
X11_XSync_INCLUDE_PATH, (in X11_Xext_LIB), X11_XSync_FOUND
X11_Xaw_INCLUDE_PATH, X11_Xaw_LIB X11_Xaw_FOUND X11::Xaw
bestie that's the whole rest of the list, copypasted with love, commas and no-commas exactly as they live in the docs (yes some lines are missing commas, and yes that's just how it is, don't come for me ๐ ).
Added in version 3.14: Renamed Xxf86misc, X11_Xxf86misc, X11_Xxf86vm, X11_xkbfile, X11_Xtst, and X11_Xss libraries to match their file names. Deprecated the X11_Xinput library. Old names are still available for compatibility.
ok so the vibes here: some of these got renamed to look like their actual files, and X11_Xinput is officially deprecated ๐ญ โ but don't panic, the old names still hang around for compat, they're not ghosting you.
Added in version 3.14: Added the X11_Xext_INCLUDE_PATH variable.
Added in version 3.18: Added the xcb, X11-xcb, xcb-icccm, xcb-xkb, xkbcommon, and xkbcommon-X11 libraries.
Added in version 3.19: Added the Xaw, xcb_util, and xcb_xfixes libraries.
Added in version 3.24: Added the xcb_randr, xcb_xtext, and xcb_keysyms libraries.
Added in version 3.27: Added the xcb_composite, xcb_cursor, xcb_damage, xcb_dpms, xcb_dri2, xcb_dri3, xcb_errors, xcb_ewmh, xcb_glx, xcb_image, xcb_present, xcb_record, xcb_render, xcb_render_util, xcb_res, xcb_screensaver, xcb_shape, xcb_shm, xcb_sync, xcb_xf86dri, xcb_xinerama, xcb_xinput, xcb_xrm, xcb_xvmc, and xcb_xv libraries.
Added in version 3.29: Added coverage of double buffer extension (variables X11_Xdbe_INCLUDE_PATH and X11_Xdbe_FOUND).
๐ FindXalanC ๐
Added in version 3.5. โจ
So this one finds the Apache Xalan-C++ XSL transform processor headers and libraries ๐:
find_package(XalaxC [<version>] [...])
Note: the Xalan-C++ library depends on the Xerces-C++ library (that's the FindXercesC module, go look at it bestie), which must be found for this module to succeed. No Xerces, no Xalan, no slay ๐.
โจ Imported Targets โจ
This module gives you the following imported targets:
XalanC::XalanCโ the target that wraps up all the Xalan-C++ library usage requirements. It's only there if Xalan-C++ actually gets found ๐ซถ.
โจ Result Variables โจ
This module sets these variables:
XalanC_FOUNDโ boolean, tells you whether (the version you asked for of) Xalan-C++ was found ๐.XalanC_VERSIONโ the version of the Xalan-C++ library that got found.XalanC_INCLUDE_DIRSโ the include directories you need to use the Xalan-C++ library. These contain the Xalan-C++ and the Xerces-C++ headers ๐.XalanC_LIBRARIESโ the libraries you need to link against Xalan-C++. These contain the Xalan-C++ and the Xerces-C++ libraries, two-for-one deal fr fr.XalanC_LIBRARYโ the path to the Xalan-C++ library (xalan-c), either the release or the debug variant.
โจ Cache Variables โจ
These cache variables may also get set:
XalanC_INCLUDE_DIRโ the directory holding the Xalan-C++ headers.XalanC_LIBRARY_RELEASEโ the path to a release (optimized) variant of the Xalan-C++ library ๐ฅ.XalanC_LIBRARY_DEBUGโ the path to a debug variant of the Xalan-C++ library.
โจ Examples โจ
Finding the Xalan-C++ library and linking it to a project target โ literally this:
find_package(XalanC)
target_link_libraries(project_target PRIVATE XalanC::XalanC)
๐ฆ FindXCTest ๐ฆ
Added in version 3.3. ๐
This one finds the XCTest framework, the thing you use for writing unit tests in Xcode projects:
find_package(XCTest [...])
Note: Xcode 16 and later ships the Swift Testing framework for writing unit tests in the Swift programming language, and it supersedes XCTest. So if you're on the new-new, that's the vibe now ๐.
An XCTest bundle is a CFBundle (Core Foundation Bundle) with a special product type and a bundle extension ๐ง. Peep the Apple Developer Library, in the Testing with Xcode documentation, for more:
https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/
โจ Result Variables โจ
This module sets these variables:
XCTest_FOUNDโ boolean, says whether the XCTest framework and the executable were found ๐.XCTest_INCLUDE_DIRSโ the include directories containing the XCTest framework headers you need to use XCTest.XCTest_LIBRARIESโ the libraries you need to link against to use the XCTest framework.
โจ Cache Variables โจ
These cache variables may also get set:
XCTest_EXECUTABLEโ the path to thexctestcommand-line tool, the one used to execute XCTest bundles ๐ฅ.
โจ Commands โจ
When XCTest gets found, this module hands you the following commands to help create and run XCTest bundles โ
xctest_add_bundle
okay so this one creates an XCTest bundle to test a given target ๐
xctest_add_bundle(<bundle> <testee> [<sources>...])
This command creates an XCTest bundle named <bundle> that will test the specified <testee> target. literally that's the whole vibe ๐
The arguments are:
<bundle>โ name of the XCTest bundle to create. TheXCTESTtarget property will be set on this bundle. (yes bestie, the property is just calledXCTEST, iconic)<testee>โ name of the target to test. Supported types for the testee are Frameworks and App Bundles. that's the whole guest list, no random types allowed ๐<sources>...โ one or more source files to add to the bundle. If not provided, they must be added later using commands liketarget_sources(). so like, you can ghost the sources for now but you will have to come back for them ๐
Note: the CMAKE_OSX_SYSROOT variable must be set before using this command. non-negotiable, set it first or it's giving chaos ๐ธ
xctest_add_test
this one adds an XCTest bundle to the project so it actually gets run during the CTest phase ๐ฅ
xctest_add_test(<name> <bundle>)
This command registers an XCTest bundle to be executed by ctest(1). The test will be named <name> and will run the specified <bundle>. slay, now your tests show up in the test runner ๐
The arguments are:
<name>โ name of the test as it will appear in CTest. this is the name everybody sees, make it cute โจ<bundle>โ target name of the XCTest bundle. the actual bundle getting run, no cap
โจ Examples โจ
Finding XCTest and adding tests โ look at this whole little routine, it ate:
find_package(XCTest)
add_library(foo SHARED foo.c)
if(XCTest_FOUND)
xctest_add_bundle(TestAppBundle foo source.swift)
xctest_add_test(app.TestAppBundle TestAppBundle)
endif()
๐ FindXercesC
Added in version 3.1. (so it's been around, a real elder ๐ซถ)
Finds the Apache Xerces-C++ validating XML parser headers and libraries:
find_package(XercesC [<version>] [...])
Imported Targets
This module provides the following Imported Targets:
XercesC::XercesCโ Added in version 3.5. Target encapsulating the Xerces-C++ library (xerces-c) usage requirements, available only if Xerces-C++ is found. so if it's not found, this target simply does not exist, periodt ๐
Result Variables
This module defines the following variables:
XercesC_FOUNDโ Boolean indicating whether (the requested version of) Xerces-C++ was found. the vibe check โXercesC_VERSIONโ the version of the found Xerces-C++ library.XercesC_INCLUDE_DIRSโ include directories needed to use Xerces-C++.XercesC_LIBRARIESโ libraries needed to link for using Xerces-C++.XercesC_LIBRARYโ the path to the Xerces-C++ library (xerces-c), either release or debug variant. one path, your pick of flavor ๐
Cache Variables
The following cache variables may also be set:
XercesC_INCLUDE_DIRโ the directory containing the Xerces-C++ headers.XercesC_LIBRARY_RELEASEโ Added in version 3.4. The path to a release (optimized) variant of the Xerces-C++ library. optimized, she's fast ๐จXercesC_LIBRARY_DEBUGโ Added in version 3.4. The path to a debug variant of the Xerces-C++ library. debug, she talks a lot ๐ญ
โจ Examples โจ
Finding the Xerces-C++ library and linking it to a project target:
find_package(XercesC)
target_link_libraries(project_target PRIVATE XercesC::XercesC)
๐ FindXMLRPC
Finds the native XML-RPC library for C and C++:
find_package(XMLRPC [...] [COMPONENTS <components>...] [...])
ngl XML-RPC is a standard network protocol that enables remote procedure calls (RPC) between systems. It encodes requests and responses in XML and uses HTTP as the transport mechanism. old-school but lowkey still working, iykyk ๐
Components
The XML-RPC C/C++ library consists of various features (modules) that provide specific functionality. The availability of these features depends on the installed XML-RPC library version and system configuration. Some features also have dependencies on others โ so like, some of these girlies refuse to show up unless their friends come too ๐
To list the available features on a system, the xmlrpc-c-config command-line utility can be used. go ask it directly bestie ๐
In CMake, these features can be specified as components with the find_package() command:
find_package(XMLRPC [COMPONENTS <components>...])
Components may be:
c++2โ C++ wrapper API, replacing the legacyc++feature. the upgrade, the main character ๐c++โ the legacy C++ wrapper API (superseded byc++2). she's retired but still invited to the group chat ๐clientโ XML-RPC client functions (also available as the legacylibwww-based feature namedlibwww-client). yes it has an alias, we don't judge ๐ซถcgi-serverโ CGI-based server functions.abyss-serverโ Abyss-based server functions.pstream-serverโ the pstream-based server functions.server-utilโ basic server functions (they are automatically included with*-serverfeatures). automatic, she just shows up โจabyssโ Abyss HTTP server (not needed withabyss-server). redundant queen, skip her if you already have the server one ๐opensslโ OpenSSL convenience functions.
If no components are specified, this module searches for XML-RPC library and its include directories without additional features. no extras, just the base model, no cap ๐
Result Variables
This module defines the following variables:
XMLRPC_FOUNDโ Boolean indicating whether the XML-RPC library and all its requested components were found. all of them, or it's a no ๐XMLRPC_INCLUDE_DIRSโ include directories containingxmlrpc.hand other headers needed to use the XML-RPC library.XMLRPC_LIBRARIESโ list of libraries needed for linking to XML-RPC library and its requested features.
โจ Examples โจ
Finding XML-RPC library and its client feature, and conditionally creating an interface imported target that encapsulates its usage requirements for linking to a project target โ okay this one is a whole moment, look:
find_package(XMLRPC REQUIRED COMPONENTS client)
if(XMLRPC_FOUND AND NOT TARGET XMLRPC::XMLRPC)
add_library(XMLRPC::XMLRPC INTERFACE IMPORTED)
set_target_properties(
XMLRPC::XMLRPC
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${XMLRPC_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${XMLRPC_LIBRARIES}"
)
endif()
target_link_libraries(example PRIVATE XMLRPC::XMLRPC)
๐ FindZLIB
Finds the native zlib data compression library โ the squeeze queen herself ๐๏ธโจ
find_package(ZLIB [<version>] [...])
Imported Targets
This module provides the following Imported Targets:
ZLIB::ZLIBโ Added in version 3.1. Target that encapsulates the zlib usage requirements. It is available only when zlib is found. found only, otherwise she's simply not in the building ๐ฆ
Result Variables
This module defines the following variables:
ZLIB_FOUNDโ Boolean indicating whether (the requested version of) zlib was found.ZLIB_VERSIONโ Added in version 3.26. The version of zlib found.ZLIB_INCLUDE_DIRSโ include directories containingzlib.hand other headers needed to use zlib.ZLIB_LIBRARIESโ list of libraries needed to link to zlib.
Changed in version 3.4: Debug and Release library variants can be now found separately. two flavors, zero confusion ๐
Hints
This module accepts the following variables:
ZLIB_ROOTโ a user may set this variable to a zlib installation root to help locate zlib in custom installation paths. your custom path era, we support it ๐ซถZLIB_USE_STATIC_LIBSโ Added in version 3.24. Set this variable toONbefore callingfind_package(ZLIB)to look for static libraries. Default isOFF. static mode, activate her manually โจ
Deprecated Variables
The following variables are provided for backward compatibility โ they're still here for the old code, but like, they know they're legacy ๐
ZLIB_VERSION_MAJORโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The major version of zlib.ZLIB_VERSION_MINORโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The minor version of zlib.ZLIB_VERSION_PATCHโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The patch version of zlib.ZLIB_VERSION_TWEAKโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The tweak version of zlib.ZLIB_VERSION_STRINGโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The version of zlib found (x.y.z).ZLIB_MAJOR_VERSIONโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The major version of zlib.ZLIB_MINOR_VERSIONโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The minor version of zlib.ZLIB_PATCH_VERSIONโ Deprecated since version 3.26: Superseded byZLIB_VERSION. The patch version of zlib.
โจ Examples โจ
Finding zlib and linking it to a project target โ short, sweet, zero drama:
find_package(ZLIB)
target_link_libraries(project_target PRIVATE ZLIB::ZLIB)
๐ DEPRECATED MODULES ๐
okay so this is the retired shelf. they still exist, they still work, but likeโฆ respectfully, don't start anything new with them ๐
Deprecated Utility Modules
AddFileDependencies
Deprecated since version 3.20: Do not use this module in new code. fr fr, new code does not need this ๐ซ
Instead use the set_property() command to append to the OBJECT_DEPENDS source file property directly:
set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)
Load this module in a CMake project with:
include(AddFileDependencies)
Commands
This module provides the following command:
add_file_dependenciesโ adds dependencies to a source file:
add_file_dependencies(<source> <files>...)
This command adds the given <files> to the dependencies of file <source>. simple as that, she's a one-trick icon ๐
CMakeDetermineVSServicePack
Changed in version 4.1: This module is available only if policyCMP0196is not set toNEW. so if you set that policy toNEW, this module literally vanishes, bye ๐ญ
Deprecated since version 3.0: This module should no longer be used. The functionality of this module has been superseded by the CMAKE_<LANG>_COMPILER_VERSION variable that contains the compiler version number. that variable is the upgrade, use her instead โจ
This module provides a command to determine the installed Visual Studio service pack version for Visual Studio 2012 and earlier. ancient era, but we keep the receipts ๐บ
Load this module in a CMake project with:
include(CMakeDetermineVSServicePack)
Commands
This module provides the following command:
DetermineVSServicePackโ determines the Visual Studio service pack version of theclcompiler in use:
DetermineVSServicePack(<variable>)
The result is stored in the specified internal cache variable <variable>, which is set to one of the following values, or to an empty string if the service pack cannot be determined:
vc80,vc80sp1vc90,vc90sp1vc100,vc100sp1vc110,vc110sp1,vc110sp2,vc110sp3,vc110sp4
so like, it's giving dropdown menu of ancient service packs ๐ no cap, that's the full list
โจ Examples โจ
Determining the Visual Studio service pack version in a project:
if(MSVC)
include(CMakeDetermineVSServicePack)
DetermineVSServicePack(my_service_pack)
if(my_service_pack)
message(STATUS "Detected: ${my_service_pack}")
endif()
endif()
๐ CMakeExpandImportedTargets
Deprecated since version 3.4: bestie, this module should no longer be used. Like, at all. It's giving Blockbuster membership card. ๐ญ
Okay so history lesson real quick ๐ฐ๏ธ โ back in the day you needed this to replace Imported Targets with their actual on-disk libraries so you could pass them to try_compile() and try_run(). But those commands now support imported targets right in their LINK_LIBRARIES options (since CMake 2.8.11 for the try_compile() command and since CMake 3.2 for the try_run() command). So yeah. It ate its purpose and now it's just vibing. ๐
You load it in a CMake project like:
include(CMakeExpandImportedTargets)
Note: โ ๏ธ This module does not support theCMP0022NEWbehavior, and it does not use theINTERFACE_LINK_LIBRARIESproperty โ and the reason is genuinely iconic: generator expressions cannot be evaluated at the configuration phase. Periodt. ๐ซถ
Commands
This module provides the following command:
cmake_expand_imported_targets
Expands every imported target in a given list of libraries into its corresponding file paths on disk, and drops the resulting list into a local variable:
cmake_expand_imported_targets(
<result-var>
LIBRARIES <libs>...
[CONFIGURATION <config>]
)
The arguments are, bestie:
<result-var>โ the name of a CMake variable that'll hold the resulting list of file paths. โจLIBRARIES <libs>...โ a semicolon-separated list of system and imported targets. Imported targets in this list get replaced with their corresponding library file paths, including libraries from their link interfaces. ๐CONFIGURATION <config>โ if this option is given, it uses the respective build configuration of the imported targets if it exists. If omitted, it defaults to the first entry in theCMAKE_CONFIGURATION_TYPESvariable, or falls back toCMAKE_BUILD_TYPEifCMAKE_CONFIGURATION_TYPESis not set. ๐ธ
Examples
Using this module to get a list of library paths, lowkey a classic:
include(CMakeExpandImportedTargets)
cmake_expand_imported_targets(
expandedLibs
LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}"
)
๐ฆ CMakeFindFrameworks
Deprecated since version 3.31: this module does nothing, unless policyCMP0173is set toOLD. It's giving ghost ๐ป โ technically present, zero output.
Helper module to find OSX frameworks. ๐
This module reads hints about search locations from variables:
CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS - Extra directories
That's it. That's the whole hint list. Short king. ๐
๐ CMakeForceCompiler
Deprecated since version 3.6: Do not use. Like, I'm not even gonna soften that one. ๐ โโ๏ธ
The commands this module provides were once intended for cross-compiling toolchain files back when CMake couldn't automatically detect the compiler identification. But since the introduction of this module, CMake's compiler identification capabilities have improved so much and can now be taught to recognize any compiler. And honestly? The suite of information CMake detects from a compiler is now too extensive to be provided by toolchain files using these macros. It outgrew them. ๐
One common use case was skipping CMake's checks for a working compiler when using a cross-compiler that can't link binaries without special flags or custom linker scripts. That case is now supported by setting the CMAKE_TRY_COMPILE_TARGET_TYPE variable in the toolchain file instead. Slay, honestly. โจ
You load this module in a CMake toolchain file:
include(CMakeForceCompiler)
Commands
This module provides the following commands:
cmake_force_c_compilerโ Sets theCMAKE_C_COMPILERvariable to the given compiler and theCMAKE_C_COMPILER_IDvariable to the given compiler-id:
cmake_force_c_compiler(<compiler> <compiler-id>)
This command also bypasses the check for working compiler and basic compiler information tests. ๐จ
cmake_force_cxx_compilerโ Sets theCMAKE_CXX_COMPILERvariable to the given compiler and theCMAKE_CXX_COMPILER_IDvariable to the given compiler-id:
cmake_force_cxx_compiler(<compiler> <compiler-id>)
This command also bypasses the check for working compiler and basic compiler information tests. ๐จ
cmake_force_fortran_compilerโ Sets theCMAKE_Fortran_COMPILERvariable to the given compiler and theCMAKE_Fortran_COMPILER_IDvariable to the given compiler-id:
cmake_force_fortran_compiler(<compiler> <compiler-id>)
This command also bypasses the check for working compiler and basic compiler information tests. ๐จ
Examples
A simple toolchain file using this module could look like this ๐
cmake/toolchains/example-toolchain.cmake
include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME Generic)
cmake_force_c_compiler(chc12 MetrowerksHicross)
cmake_force_cxx_compiler(chc12 MetrowerksHicross)
In new CMake code, the compiler is detected automatically when setting the required variables instead โ look how much cleaner, I'm obsessed ๐ญโจ
cmake/toolchains/example-toolchain.cmake
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER chc12)
set(CMAKE_CXX_COMPILER chc12)
See Also
๐ CMakeParseArguments
Deprecated since version 3.5.
This module once implemented the cmake_parse_arguments() command that is now implemented natively by CMake. So now? It's literally just an empty placeholder for compatibility with projects that include it to get the command from CMake 3.4 and lower. A shell of its former self. It's giving alumni returning to campus. ๐
๐ Dart
Deprecated since version 3.27: this module is available only if policyCMP0145is not set toNEW. Do not use it in new code, fr fr. Use theCTestmodule instead. ๐ซถ
Configure a project for testing with CTest or the old Dart Tcl Client. ๐ฐ๏ธ
This file is the backwards-compatibility version of the CTest module. It supports using the old Dart 1 Tcl client for driving dashboard submissions, as well as testing with CTest. This module should be included in the CMakeLists.txt file at the top of a project. Typical usage, bestie:
include(Dart)
if(BUILD_TESTING)
# ... testing related CMake code ...
endif()
The BUILD_TESTING option is created by the Dart module to determine whether testing support should be enabled. The default is ON. โ
๐ Documentation
Deprecated since version 3.18: this module does nothing, unless policyCMP0106is set toOLD. Nothing! Zero! Nada! ๐
This module provides support for the VTK documentation framework. It relies on several tools (Doxygen, Perl, etc). Cute historical artifact ngl. ๐บ
๐ง GetPrerequisites
Deprecated since version 3.16: use file(GET_RUNTIME_DEPENDENCIES) instead. That's the upgrade, bestie, take it. ๐
This module provides commands to analyze and list the dependencies (prerequisites) of executable or shared library files. These commands list the shared libraries (.dll, .dylib, or .so files) required by an executable or shared library. ๐
Load this module in CMake with:
include(GetPrerequisites)
This module determines dependencies using the following platform-specific tools:
dumpbin(Windows)objdump(MinGW on Windows)ldd(Linux/Unix)otool(Apple operating systems)
Changed in version 3.16: the tool specified by the CMAKE_OBJDUMP variable will be used, if set. โญ
Commands
This module provides the following commands:
get_prerequisites()list_prerequisites()list_prerequisites_by_glob()gp_append_unique()is_file_executable()gp_item_default_embedded_path()(projects can override it withgp_item_default_embedded_path_override())gp_resolve_item()(projects can override it withgp_resolve_item_override())gp_resolved_file_type()(projects can override it withgp_resolved_file_type_override())gp_file_type()
get_prerequisites
Gets the list of shared library files required by the specified target:
get_prerequisites(<target> <prerequisites-var> <exclude-system> <recurse>
<exepath> <dirs> [<rpaths>])
The list in the variable named <prerequisites-var> should be empty on first entry to this command. On exit, <prerequisites-var> will contain the list of required shared library files. ๐
The arguments are:
<target>โ the full path to an executable or shared library file. ๐ฏ<prerequisites-var>โ the name of a CMake variable to contain the results.<exclude-system>โ if set to1, system prerequisites will be excluded; if set to0they will be included. ๐ฆ<recurse>โ if set to1, all prerequisites will be found recursively; if set to0, only direct prerequisites are listed. ๐<exepath>โ the path to the top level executable used for@executable_pathreplacement on Apple operating systems. ๐<dirs>โ a list of paths where libraries might be found: these paths are searched first when a target without any path info is given. Then standard system locations are also searched:PATH, Framework locations,/usr/lib... ๐<rpaths>โ optional run-time search paths for an executable file or library to help find files.
Added in version 3.14: the variable GET_PREREQUISITES_VERBOSE can be set to true before calling this command to enable verbose output. ๐ฃ๏ธ
list_prerequisites
Prints a message listing the prerequisites of the specified target:
list_prerequisites(<target> [<recurse> [<exclude-system> [<verbose>]]])
The arguments are:
<target>โ the name of a shared library or executable target, or the full path to a shared library or executable file. ๐<recurse>โ set it to1and every prerequisite gets found recursively (all the way down, no cap ๐ ); set it to0and you only get the direct prerequisites, nothing deeper.<exclude-system>โ set it to1and system prerequisites get left out; set it to0and they're included. Your call bestie.<verbose>โ0means you get just the full path names of the prerequisites, nothing extra.1means you get extra information displayed on top of that. The way that extra info just shows up โจ
list_prerequisites_by_glob
Prints the prerequisites of shared library and executable files matching a globbing pattern:
list_prerequisites_by_glob(<GLOB|GLOB_RECURSE>
<glob-exp>
[<optional-args>...])
The arguments are:
GLOBorGLOB_RECURSEโ the globbing mode: do you traverse only the match, or also its subdirectories recursively? Pick your fighter ๐ซถ<glob-exp>โ a globbing expression used withfile(GLOB)<#glob> orfile(GLOB_RECURSE)<#glob-recurse> to retrieve a list of matching files. If a matching file is executable, its prerequisites are listed. Only if it's executable, no cap.<optional-args>...โ any additional (optional) arguments you provide get passed along as the optional arguments to thelist_prerequisite()calls. Mmm, delegation ๐
gp_append_unique
Appends the value to the list only if it is not already in the list:
gp_append_unique(<list-var> <value>)
The arguments are:
<value>โ the value to be appended to the list. That's it, that's the whole job ๐<list-var>โ the list variable name that will have the value appended only if it is not already in the list. No duplicates allowed, we don't do repeats here ๐ซ
is_file_executable
Checks if given file is a binary executable:
is_file_executable(<file> <result-var>)
This command sets the <result-var> to 1 if <file> is a binary executable; otherwise it sets it to 0. Binary executable or not, that's the whole vibe check โ
gp_item_default_embedded_path
Determines the reference path for the specified item:
gp_item_default_embedded_path(<item> <default-embedded-path-var>)
This command determines the reference path for <item> when it is embedded inside a bundle and stores it to a variable <default-embedded-path-var>.
Projects can override this command by defining a custom gp_item_default_embedded_path_override() command. Override privileges: granted ๐
gp_resolve_item
Resolves a given item into an existing full path file and stores it to a variable:
gp_resolve_item(<context> <item> <exepath> <dirs> <resolved-item-var>
[<rpaths>])
The arguments are:
<context>โ the path to the top level loading path used for@loader_pathreplacement on Apple operating systems. When resolving item,@loader_pathreferences will be resolved relative to the directory of the given context value (presumably another library). Presumably ๐<item>โ the item to resolve. Short king of an argument.<exepath>โ see the argument description inget_prerequisites().<dirs>โ see the argument description inget_prerequisites().<resolved-item-var>โ the result variable where the resolved item is stored into.<rpaths>โ see the argument description inget_prerequisites().
Projects can override this command by defining a custom gp_resolve_item_override() command. Custom override era ๐
gp_resolved_file_type
Determines the type of a given file:
gp_resolved_file_type(<original-file> <file> <exepath> <dirs> <type-var>
[<rpaths>])
This command determines the type of <file> with respect to the <original-file>. The resulting type of prerequisite is stored in the <type-var> variable.
Use <exepath> and <dirs> if necessary to resolve non-absolute <file> values โ but only for non-embedded items. Read that again, it matters ๐ซถ
<rpaths>โ see the argument description inget_prerequisites().
The <type-var> variable will be set to one of the following values:
systemlocalembeddedother
Pick one of those four, those are the options, periodt.
Projects can override this command by defining a custom gp_resolved_file_type_override() command.
gp_file_type
Determines the type of a given file:
gp_file_type(<original-file> <file> <type-var>)
This command determines the type of <file> with respect to the <original-file>. The resulting type of prerequisite is stored in the <type-var> variable.
The <type-var> variable will be set to one of the following values:
systemlocalembeddedother
Same four vibes as before, just without the <exepath>/<dirs>/<rpaths> situation ๐ฆ
Examples ๐
Example: Basic Usage
Printing all dependencies of a shared library, including system libraries, with verbose output:
include(GetPrerequisites)
list_prerequisites("path/to/libfoo.dylib" 1 0 1)
Example: Upgrading Code
For example:
include(GetPrerequisites)
# ...
gp_append_unique(keys "${key}")
the gp_append_unique() can be in new code replaced with:
if(NOT key IN_LIST keys)
list(APPEND keys "${key}")
endif()
Glow-up complete ๐
MacroAddFileDependencies
Deprecated since version 3.14: Do not use this module in new code. ๐จ
Instead use the set_property() <#command:set_property> command to append to the OBJECT_DEPENDS <#prop_sf:OBJECT_DEPENDS> source file property directly:
set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)
Load this module in a CMake project with:
include(MacroAddFileDependencies)
Commands
This module provides the following command:
macro_add_file_dependencies
Adds dependencies to a source file:
macro_add_file_dependencies(<source> <files>...)
This command adds the given <files> to the dependencies of file <source>. Yeah. That's the whole thing ๐ญ (please use set_property() instead though, i'm literally begging)
TestBigEndian
Deprecated since version 3.20: Superseded by the CMAKE_<LANG>_BYTE_ORDER <#variable:CMAKE_<LANG>_BYTE_ORDER> variable. ๐
This module provides a command to check the endianness (byte order) of the target architecture.
Load this module in a CMake project with:
include(TestBigEndian)
Commands
This module provides the following command:
test_big_endian
Checks if the target architecture is big-endian or little-endian:
test_big_endian(<var>)
This command stores in variable <var> either 1 or 0 indicating whether the target architecture is big or little endian.
At least one of the supported languages must be enabled in CMake project when using this command. Don't skip this step bestie, it will Not work ๐ฅ
Supported languages are C, CXX.
Changed in version 3.20: This command is now mainly a wrapper around theCMAKE_<LANG>_BYTE_ORDER<#variable:CMAKE_<LANG>_BYTE_ORDER> where alsoOBJC,OBJCXX, andCUDAlanguages are supported. Modern era โจ
Examples
Example: Checking Endianness
Checking endianness of the target architecture with this module and storing the result in a CMake variable WORDS_BIGENDIAN:
include(TestBigEndian)
test_big_endian(WORDS_BIGENDIAN)
Example: Checking Endianness in New Code
As of CMake 3.20, this module should be replaced with the CMAKE_<LANG>_BYTE_ORDER <#variable:CMAKE_<LANG>_BYTE_ORDER> variable. For example, in a project, where C language is one of the enabled languages:
if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN")
set(WORDS_BIGENDIAN TRUE)
elseif(CMAKE_C_BYTE_ORDER STREQUAL "LITTLE_ENDIAN")
set(WORDS_BIGENDIAN FALSE)
else()
set(WORDS_BIGENDIAN FALSE)
message(WARNING "Endianness could not be determined.")
endif()
Look at that fallback branch handling the unknown case, we love a responsible queen ๐
TestCXXAcceptsFlag
Deprecated since version 3.0: This module should no longer be used. It has been superseded by theCheckCXXCompilerFlag<#module:CheckCXXCompilerFlag> module. As of CMake 3.19, theCheckCompilerFlag<#module:CheckCompilerFlag> module is also available for checking flags across multiple languages. ๐จ
This module provides a command to test whether the C++ (CXX) compiler supports specific flags.
Load this module in a CMake project with:
include(TestCXXAcceptsFlag)
Commands
This module provides the following command:
check_cxx_accepts_flag
Checks whether the CXX compiler accepts the specified flags:
check_cxx_accepts_flag(<flags> <result-variable>)
<flags>โ one or more compiler flags to test. For multiple flags, provide them as a space-separated string. Space. Separated. String. Not a list, bestie, i learned that the hard way ๐ญ<result-variable>โ name of an internal cache variable that stores the result. It is set to boolean true if the compiler accepts the flags and false otherwise. Internal cache variable, so it's giving secret keeper ๐
Examples
Checking if the C++ compiler supports specific flags:
include(TestCXXAcceptsFlag)
check_cxx_accepts_flag("-fno-common -fstack-clash-protection" HAVE_FLAGS)
Migrating to the CheckCompilerFlag <#module:CheckCompilerFlag> module:
include(CheckCompilerFlag)
check_compiler_flag(CXX "-fno-common;-fstack-clash-protection" HAVE_FLAGS)
Notice the semicolon instead of the space up in there โ that's a list now, and that is Not the same thing ๐
Use_wxWindows
Deprecated since version 2.8.10: This module should no longer be used. Use find_package(wxWidgets) <#module:FindwxWidgets> instead. ๐
This module serves as a convenience wrapper for finding the wxWidgets library (formerly known as wxWindows) and propagates its usage requirements, such as libraries, include directories, and compiler flags, into the current directory scope for use by targets.
Load this module in a CMake project with:
include(Use_wxWindows)
Examples
In earlier versions of CMake, wxWidgets (wxWindows) could be found and used in the current directory like this:
CMakeLists.txt
include(Use_wxWindows)
To request OpenGL support, the WXWINDOWS_USE_GL variable could be set before including this module:
CMakeLists.txt
set(WXWINDOWS_USE_GL ON)
include(Use_wxWindows)
add_library(example example.cxx)
Starting with CMake 3.0, wxWidgets can be found using the FindwxWidgets <#module:FindwxWidgets> module, which provides the wxWidgets usage requirements either using result variables or imported target as of CMake 3.27:
CMakeLists.txt
find_package(wxWidgets)
add_library(example example.cxx)
target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
Imported target wxWidgets::wxWidgets โ the main character of this migration, honestly ๐
UseJavaClassFilelist ๐ซถ
Changed in version 3.20: okay so this module was literally documented by mistake โ no cap, it was never meant for project code to include it directly ๐ญ. See the UseJava module instead, bestie.
UseJavaSymlinks ๐ซถ
Changed in version 3.20: same situation, same energy โ this one got documented by accident too and was never meant for direct inclusion by project code ๐. Go look at the UseJava module.
UsePkgConfig ๐
Deprecated since version 3.0: bestie, put it down. This module should no longer be used. Use theFindPkgConfigmodule or thecmake_pkg_config()command instead โจ
This module handed you a command for finding external packages by way of the pkg-config command-line utility. It's been replaced by the way more convenient FindPkgConfig module, which is what everyone actually uses in Find Modules ๐ธ.
And as of CMake 3.31, the built-in cmake_pkg_config() command gives you even more features for extracting package information ๐.
Load this module in a CMake project with:
include(UsePkgConfig)
Commands ๐
This module provides the following command:
pkgconfig
Finds an external package using pkg-config and sets the result variables:
pkgconfig(<package> <includedir> <libdir> <linkflags> <cflags>)
This command invokes the pkg-config command-line utility to pull the package information into the variables you specified. If pkg-config โ or the specified <package> โ is NOT found, the result variables just stay empty (no drama, but also no data ๐).
The arguments are:
<package>โ the name of the package as defined in its PC metadata file (<package>.pc).<includedir>โ variable name to store the package's include directory.<libdir>โ variable name to store the directory containing the package library.<linkflags>โ variable name to store the linker flags for the package.<cflags>โ variable name to store the compiler flags for the package.
Examples ๐
Using this module fills the desired info into the four given variables:
include(UsePkgConfig)
pkgconfig(
libart-2.0
LIBART_INCLUDEDIR
LIBART_LIBDIR
LIBART_LDFLAGS
LIBART_CFLAGS
)
Migrating to FindPkgConfig would look something like this:
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(LIBART QUIET libart-2.0)
endif()
message(STATUS "LIBART_INCLUDEDIR=${LIBART_INCLUDEDIR}")
message(STATUS "LIBART_LIBDIR=${LIBART_LIBDIR}")
message(STATUS "LIBART_LDFLAGS=${LIBART_LDFLAGS}")
message(STATUS "LIBART_CFLAGS=${LIBART_CFLAGS}")
WriteBasicConfigVersionFile ๐ฆ
Deprecated since version 3.0: use the identical commandwrite_basic_package_version_file()from moduleCMakePackageConfigHelpersinstead, bestie ๐
WRITE_BASIC_CONFIG_VERSION_FILE(filename
[VERSION major.minor.patch]
COMPATIBILITY (AnyNewerVersion|SameMajorVersion|SameMinorVersion|
SamePatchVersion|SameFullVersion|ExactVersion|
SemanticVersion)
[ARCH_INDEPENDENT]
)
WriteCompilerDetectionHeader ๐
Deprecated since version 3.20: this module is only available if policyCMP0120is not set toNEW. Do not use it in new code, fr fr ๐ซ
Added in version 3.1.
This module provides a command that generates a header full of preprocessor macros โจ.
Load this module in a CMake project with:
include(WriteCompilerDetectionHeader)
Commands ๐
This module provides the following command:
write_compiler_detection_header
This function can be used to generate a file that's suitable for preprocessor inclusion, containing macros you can use in your source code:
write_compiler_detection_header(
FILE <file>
PREFIX <prefix>
[OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>]
COMPILERS <compiler> [...]
FEATURES <feature> [...]
[BARE_FEATURES <feature> [...]]
[VERSION <version>]
[PROLOG <prolog>]
[EPILOG <epilog>]
[ALLOW_UNKNOWN_COMPILERS]
[ALLOW_UNKNOWN_COMPILER_VERSIONS]
)
This generates the file <file> with macros that all carry the prefix <prefix> ๐
.
By default, all the content is written straight into <file>. But you can specify OUTPUT_FILES_VAR to make the compiler-specific content get written to separate files instead. Those separate files then show up in <output_files_var> and can be consumed by the caller โ for installation, for example ๐. OUTPUT_DIR specifies a relative path from the main <file> to those compiler-specific files. Like so:
write_compiler_detection_header(
FILE climbingstats_compiler_detection.h
PREFIX ClimbingStats
OUTPUT_FILES_VAR support_files
OUTPUT_DIR compilers
COMPILERS GNU Clang MSVC Intel
FEATURES cxx_variadic_templates
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/climbingstats_compiler_detection.h
DESTINATION include
)
install(FILES
${support_files}
DESTINATION include/compilers
)
VERSION lets you specify the API version to generate. Future versions of CMake may introduce alternative APIs, and a given API is selected by any <version> value that's greater than or equal to the version of CMake that introduced that API and less than the version of CMake that introduced the API after it. If you don't specify an explicit version, the value of the CMAKE_MINIMUM_REQUIRED_VERSION variable gets used. (As of CMake version 4.4.5 there is only one API version โ so, one single icon, no competition ๐.)
PROLOG can be given as text content to write at the start of the header. EPILOG can be given as text content to write at the end of the header ๐ธ.
At least one <compiler> and one <feature> must be listed, periodt. Compilers that CMake knows about but that you did not specify get detected, and a preprocessor #error gets generated for them ๐ญ. A preprocessor macro matching <PREFIX>_COMPILER_IS_<compiler> is generated for each compiler known to CMake, containing the value 0 or 1.
The possible compiler identifiers are documented with the CMAKE_<LANG>_COMPILER_ID variable. The features available in this version of CMake are listed in the CMAKE_C_KNOWN_FEATURES and CMAKE_CXX_KNOWN_FEATURES global properties. See the cmake-compile-features(7) manual for info on compile features ๐.
Added in version 3.2: added MSVC and AppleClang compiler support ๐.
Added in version 3.6: added Intel compiler support.
Changed in version 3.8: the {c,cxx}_std_* meta-features are ignored if requested ๐.
Added in version 3.8: ALLOW_UNKNOWN_COMPILERS and ALLOW_UNKNOWN_COMPILER_VERSIONS cause the module to generate conditions that treat unknown compilers as simply lacking all features. Without these options, the default behavior is to generate a #error for unknown compilers and versions ๐.
Added in version 3.12: BARE_FEATURES will define the compatibility macros with the name used in newer versions of the language standard, so the code can use the new feature name unconditionally โจ.
Feature Test Macros ๐ง
For each compiler, a preprocessor macro is generated matching <PREFIX>_COMPILER_IS_<compiler>, which has the content either 0 or 1 depending on the compiler in use. Preprocessor macros for the compiler version components are generated matching <PREFIX>_COMPILER_VERSION_MAJOR, <PREFIX>_COMPILER_VERSION_MINOR and <PREFIX>_COMPILER_VERSION_PATCH, containing decimal values for the corresponding compiler version components โ if they're defined ๐.
A preprocessor test gets generated based on the compiler version, denoting whether each feature is enabled. A preprocessor macro matching <PREFIX>_COMPILER_<FEATURE> โ where <FEATURE> is the upper-case <feature> name โ is generated to contain the value 0 or 1 depending on whether the compiler in use supports the feature:
write_compiler_detection_header(
FILE climbingstats_compiler_detection.h
PREFIX ClimbingStats
COMPILERS GNU Clang AppleClang MSVC Intel
FEATURES cxx_variadic_templates
)
#if ClimbingStats_COMPILER_CXX_VARIADIC_TEMPLATES
template<typename... T>
void someInterface(T t...) { /* ... */ }
#else
// Compatibility versions
template<typename T1>
void someInterface(T1 t1) { /* ... */ }
template<typename T1, typename T2>
void someInterface(T1 t1, T2 t2) { /* ... */ }
template<typename T1, typename T2, typename T3>
void someInterface(T1 t1, T2 t2, T3 t3) { /* ... */ }
#endif
Symbol Macros ๐
Some extra symbol-defines are created for particular features, for use as symbols that may be conditionally defined empty:
class MyClass ClimbingStats_FINAL
{
ClimbingStats_CONSTEXPR int someInterface() { return 42; }
};
The ClimbingStats_FINAL macro will expand to final if the compiler (and its flags) support the cxx_final feature, and the ClimbingStats_CONSTEXPR macro will expand to constexpr if cxx_constexpr is supported ๐ฅ.
If BARE_FEATURES cxx_final was given as an argument, the final keyword will be defined for old compilers too, bestie ๐.
The following features generate corresponding symbol defines, and if they're available as BARE_FEATURES, they get that too:
c_restrictโ define:<PREFIX>_RESTRICT, symbol:restrict, bare: yes โจcxx_constexprโ define:<PREFIX>_CONSTEXPR, symbol:constexpr, bare: yes โจcxx_deleted_functionsโ define:<PREFIX>_DELETED_FUNCTION, symbol:= delete, bare: (nope, blank)cxx_extern_templatesโ define:<PREFIX>_EXTERN_TEMPLATE, symbol:extern, bare: (blank)cxx_finalโ define:<PREFIX>_FINAL, symbol:final, bare: yes โจcxx_noexceptโ define:<PREFIX>_NOEXCEPT, symbol:noexcept, bare: yes โจcxx_noexceptโ define:<PREFIX>_NOEXCEPT_EXPR(X), symbol:noexcept(X), bare: (blank)cxx_overrideโ define:<PREFIX>_OVERRIDE, symbol:override, bare: yes โจ
๐ง Compatibility Implementation Macros
Okay so some of these features are literally built to be wrapped in a macro that has a backward-compat implementation, for when the compiler just doesn't support the feature. No cap.
When the cxx_static_assert feature isn't provided by the compiler, there's a compatibility implementation waiting for you via the <PREFIX>_STATIC_ASSERT(COND) and <PREFIX>_STATIC_ASSERT_MSG(COND, MSG) function-like macros. These macros expand to static_assert where that compiler feature is available, and to a compatibility implementation otherwise. In the first form, the condition is stringified in the message field of static_assert. In the second form, the message MSG is passed to the message field of static_assert, or ignored if you're using the backward compatibility implementation.
The cxx_attribute_deprecated feature provides a macro definition <PREFIX>_DEPRECATED, which expands to either the standard [[deprecated]] attribute or a compiler-specific decorator such as __attribute__((__deprecated__)) used by GNU compilers. ๐
The cxx_alignas feature provides a macro definition <PREFIX>_ALIGNAS which expands to either the standard alignas decorator or a compiler-specific decorator such as __attribute__ ((__aligned__)) used by GNU compilers.
The cxx_alignof feature provides a macro definition <PREFIX>_ALIGNOF which expands to either the standard alignof decorator or a compiler-specific decorator such as __alignof__ used by GNU compilers.
cxx_alignasโ define:<PREFIX>_ALIGNAS, symbol:alignas, bare: (blank)cxx_alignofโ define:<PREFIX>_ALIGNOF, symbol:alignof, bare: (blank)cxx_nullptrโ define:<PREFIX>_NULLPTR, symbol:nullptr, bare: yes โจcxx_static_assertโ define:<PREFIX>_STATIC_ASSERT, symbol:static_assert, bare: (blank)cxx_static_assertโ define:<PREFIX>_STATIC_ASSERT_MSG, symbol:static_assert, bare: (blank)cxx_attribute_deprecatedโ define:<PREFIX>_DEPRECATED, symbol:[[deprecated]], bare: (blank)cxx_attribute_deprecatedโ define:<PREFIX>_DEPRECATED_MSG, symbol:[[deprecated]], bare: (blank)cxx_thread_localโ define:<PREFIX>_THREAD_LOCAL, symbol:thread_local, bare: (blank)
A use-case which arises with such deprecation macros is the deprecation of an entire library. In that case, all public API in the library may be decorated with the <PREFIX>_DEPRECATED macro. This results in very noisy build output when building the library itself, so the macro may be may be defined to empty in that case when building the deprecated library:
add_library(compat_support ${srcs})
target_compile_definitions(compat_support
PRIVATE
CompatSupport_DEPRECATED=
)
๐ Example Usage
Note: This section was migrated from thecmake-compile-features(7)manual since it relies on theWriteCompilerDetectionHeadermodule which is removed by policyCMP0120.
Compile features may be preferred if available, without creating a hard requirement. For example, a library may provide alternative implementations depending on whether the cxx_variadic_templates feature is available:
#if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
template<int I, int... Is>
struct Interface;
template<int I>
struct Interface<I>
{
static int accumulate()
{
return I;
}
};
template<int I, int... Is>
struct Interface
{
static int accumulate()
{
return I + Interface<Is...>::accumulate();
}
};
#else
template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
struct Interface
{
static int accumulate() { return I1 + I2 + I3 + I4; }
};
#endif
Such an interface depends on using the correct preprocessor defines for the compiler features. CMake can generate a header file containing such defines using the WriteCompilerDetectionHeader module. The module contains the write_compiler_detection_header function which accepts parameters to control the content of the generated header file:
write_compiler_detection_header(
FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
PREFIX Foo
COMPILERS GNU
FEATURES
cxx_variadic_templates
)
Such a header file may be used internally in the source code of a project, and it may be installed and used in the interface of library code. ๐ซถ
For each feature listed in FEATURES, a preprocessor definition is created in the header file, and defined to either 1 or 0.
Additionally, some features call for additional defines, such as the cxx_final and cxx_override features. Rather than being used in #ifdef code, the final keyword is abstracted by a symbol which is defined to either final, a compiler-specific equivalent, or to empty. That way, C++ code can be written to unconditionally use the symbol, and compiler support determines what it is expanded to:
struct Interface {
virtual void Execute() = 0;
};
struct Concrete Foo_FINAL {
void Execute() Foo_OVERRIDE;
};
In this case, Foo_FINAL will expand to final if the compiler supports the keyword, or to empty otherwise. Iconic behaviour honestly.
In this use-case, the project code may wish to enable a particular language standard if available from the compiler. The CXX_STANDARD target property may be set to the desired language standard for a particular target, and the CMAKE_CXX_STANDARD variable may be set to influence all following targets:
write_compiler_detection_header(
FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
PREFIX Foo
COMPILERS GNU
FEATURES
cxx_final cxx_override
)
# Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
# which will expand to 'final' if the compiler supports the requested
# CXX_STANDARD.
add_library(foo foo.cpp)
set_property(TARGET foo PROPERTY CXX_STANDARD 11)
# Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
# which will expand to 'final' if the compiler supports the feature,
# even though CXX_STANDARD is not set explicitly. The requirement of
# cxx_constexpr causes CMake to set CXX_STANDARD internally, which
# affects the compile flags.
add_library(foo_impl foo_impl.cpp)
target_compile_features(foo_impl PRIVATE cxx_constexpr)
okay so here's the tea โ โ write_compiler_detection_header also whips up compatibility code for other features that already have standard equivalents. Like, cxx_static_assert gets emulated with a template and then abstracted via the <PREFIX>_STATIC_ASSERT and <PREFIX>_STATIC_ASSERT_MSG function-macros. cute, right? ๐
๐ Deprecated Find Modules ๐
FindBoost
Changed in version 3.30: This module is available only if policyCMP0167is not set toNEW. Port projects to upstream Boost'sBoostConfig.cmakepackage configuration file, for whichfind_package(Boost)now searches.
Find Boost include dirs and libraries ๐ฆ
You use this module by invoking find_package() with the form:
find_package(Boost
[version] [EXACT] # Minimum or EXACT version e.g. 1.67.0
[REQUIRED] # Fail with error if Boost is not found
[COMPONENTS <libs>...] # Boost libraries by their canonical name
# e.g. "date_time" for "libboost_date_time"
[OPTIONAL_COMPONENTS <libs>...]
# Optional Boost libraries by their canonical name)
) # e.g. "date_time" for "libboost_date_time"
So this module finds headers and requested component libraries OR a CMake package configuration file provided by a "Boost CMake" build. For the latter case, skip ahead to the Boost CMake section below โจ
- Added in version 3.7:
bzip2andzlibcomponents (Windows only). - Added in version 3.11: The
OPTIONAL_COMPONENTSoption. - Added in version 3.13:
stacktrace_*components. - Added in version 3.19:
bzip2andzlibcomponents on all platforms.
โจ Result Variables โจ
This module defines the following variables, bestie โ memorize the vibes:
Boost_FOUNDโ Boolean indicating whether headers and requested libraries were found. ๐ฏBoost_INCLUDE_DIRSโ Boost include directories.Boost_LIBRARY_DIRSโ Link directories for Boost libraries.Boost_LIBRARIESโ Boost component libraries to be linked.Boost_<COMPONENT>_FOUNDโ Boolean indicating whether the component<COMPONENT>was found (<COMPONENT>name is upper-case, iykyk).Boost_<COMPONENT>_LIBRARYโ Libraries to link for component<COMPONENT>(may includetarget_link_libraries()debug/optimizedkeywords).Boost_VERSION_MACROโBOOST_VERSIONvalue fromboost/version.hpp.Boost_VERSION_STRINGโ Boost version number inX.Y.Zformat.Boost_VERSIONโ Boost version number inX.Y.Zformat (same asBoost_VERSION_STRING).
Changed in version 3.15: In previous CMake versions, this variable used the raw version string from the Boost header (same asBoost_VERSION_MACRO). See policyCMP0093. ๐ญ
Boost_LIB_VERSIONโ Version string appended to library filenames.Boost_VERSION_MAJOR,Boost_MAJOR_VERSIONโ Boost major version number (XinX.Y.Z).Boost_VERSION_MINOR,Boost_MINOR_VERSIONโ Boost minor version number (YinX.Y.Z).Boost_VERSION_PATCH,Boost_SUBMINOR_VERSIONโ Boost subminor version number (ZinX.Y.Z).Boost_VERSION_COUNTโ Amount of version components (3).Boost_LIB_DIAGNOSTIC_DEFINITIONS(Windows-specific) โ Pass toadd_definitions()to have diagnostic information about Boost's automatic linking displayed during compilation. ๐ฉบ
Added in version 3.15: The Boost_VERSION_<PART> variables.
๐ Cache Variables ๐
Search results get saved persistently in CMake cache entries, no cap:
Boost_INCLUDE_DIRโ Directory containing Boost headers.Boost_LIBRARY_DIR_RELEASEโ Directory containing release Boost libraries.Boost_LIBRARY_DIR_DEBUGโ Directory containing debug Boost libraries.Boost_<COMPONENT>_LIBRARY_DEBUGโ Component<COMPONENT>library debug variant.Boost_<COMPONENT>_LIBRARY_RELEASEโ Component<COMPONENT>library release variant.
Added in version 3.3: Per-configuration variables Boost_LIBRARY_DIR_RELEASE and Boost_LIBRARY_DIR_DEBUG. ๐ซถ
๐ธ Hints ๐ธ
This module reads hints about search locations from these variables:
BOOST_ROOT,BOOSTROOTโ Preferred installation prefix.BOOST_INCLUDEDIRโ Preferred include directory e.g.<prefix>/include.BOOST_LIBRARYDIRโ Preferred library directory e.g.<prefix>/lib.Boost_NO_SYSTEM_PATHSโ Set toONto disable searching in locations not specified by these hint variables. Default isOFF.Boost_ADDITIONAL_VERSIONSโ List of Boost versions not known to this module. (Boost install locations may contain the version.)
Users may set these hints or results as CACHE entries. Projects should not read these entries directly but instead use the above result variables. Note that some hint names start in upper-case BOOST โ yes, it's giving inconsistent, but that's the deal ๐. One may specify these as environment variables if they are not specified as CMake variables or cache entries.
This module first searches for the Boost header files using the above hint variables (excluding BOOST_LIBRARYDIR) and saves the result in Boost_INCLUDE_DIR. Then it searches for requested component libraries using the above hints (excluding BOOST_INCLUDEDIR and Boost_ADDITIONAL_VERSIONS), lib directories near Boost_INCLUDE_DIR, and the library name configuration settings below. It saves the library directories in Boost_LIBRARY_DIR_DEBUG and Boost_LIBRARY_DIR_RELEASE and individual library locations in Boost_<COMPONENT>_LIBRARY_DEBUG and Boost_<COMPONENT>_LIBRARY_RELEASE. When one changes settings used by previous searches in the same build tree (excluding environment variables) this module discards previous search results affected by the changes and searches again. ๐
๐ Imported Targets ๐
Added in version 3.5.
This module provides the following Imported Targets:
Boost::boostโ Target for header-only dependencies. (Boost include directory).Boost::headersโ Added in version 3.15: Alias forBoost::boost.Boost::<component>โ Target for specific component dependency (shared or static library);<component>name is lower-case.Boost::diagnostic_definitionsโ Interface target to enable diagnostic information about Boost's automatic linking during compilation (adds-DBOOST_LIB_DIAGNOSTIC).Boost::disable_autolinkingโ Interface target to disable automatic linking with MSVC (adds-DBOOST_ALL_NO_LIB).Boost::dynamic_linkingโ Interface target to enable dynamic linking with MSVC (adds-DBOOST_ALL_DYN_LINK).
Implicit dependencies such as Boost::filesystem requiring Boost::system will be automatically detected and satisfied, even if system is not specified when using find_package() and even if Boost::system is not added to target_link_libraries(). And if you're using Boost::thread, then Threads::Threads gets added automatically too. main character energy tbh ๐ฅ
It is important to note that the imported targets behave differently than variables created by this module: multiple calls to find_package(Boost) in the same directory or sub-directories with different options (e.g. static or shared) will not override the values of the targets created by the first call. ๐
๐ฆ Other Variables ๐ฆ
Boost libraries come in so many variants encoded in their file name. Users or projects may tell this module which variant to find by setting these variables:
Boost_USE_DEBUG_LIBSโ Added in version 3.10. Set toONorOFFto specify whether to search and use the debug libraries. Default isON.Boost_USE_RELEASE_LIBSโ Added in version 3.10. Set toONorOFFto specify whether to search and use the release libraries. Default isON.Boost_USE_MULTITHREADEDโ Set toOFFto use the non-multithreaded libraries (mttag). Default isON.Boost_USE_STATIC_LIBSโ Set toONto force the use of the static libraries. Default isOFF.Boost_USE_STATIC_RUNTIMEโ Set toONorOFFto specify whether to use libraries linked statically to the C++ runtime (stag). Default is platform dependent.Boost_USE_DEBUG_RUNTIMEโ Set toONorOFFto specify whether to use libraries linked to the MS debug C++ runtime (gtag). Default isON.Boost_USE_DEBUG_PYTHONโ Set toONto use libraries compiled with a debug Python build (ytag). Default isOFF.Boost_USE_STLPORTโ Set toONto use libraries compiled with STLPort (ptag). Default isOFF.Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMSโ Set toONto use libraries compiled with STLPort deprecated "native iostreams" (ntag). Default isOFF.Boost_COMPILERโ Set to the compiler-specific library suffix (e.g.-gcc43). Default is auto-computed for the C++ compiler in use.
Changed in version 3.9: A list may be used if multiple compatible suffixes should be tested for, in decreasing order of preference. ๐
Boost_LIB_PREFIXโ Added in version 3.18. Set to the platform-specific library name prefix (e.g.lib) used by Boost static libs. This is needed only on platforms where CMake does not know the prefix by default.Boost_ARCHITECTUREโ Added in version 3.13. Set to the architecture-specific library suffix (e.g.-x64). Default is auto-computed for the C++ compiler in use.Boost_THREADAPIโ Suffix for thread component library name, such aspthreadorwin32. Names with and without this suffix will both be tried. โญBoost_NAMESPACEโ the alternate namespace you build boost with. Like, if you set it tomyboost, it's gonna go hunting formyboost_threadinstead ofboost_thread. Slay, custom namespace.
Other variables you can set to boss this module around:
Boost_DEBUGโ set toONand FindBoost goes full narrator mode with debug output. Pls pls pls turn this on before you file a bug report โ it makes everything so much easier, bestie.Boost_REALPATHโ set toONto resolve symlinks on the discovered libraries, which helps with packaging. Like, the"system"component library might resolve to/usr/lib/libboost_system.so.1.67.0instead of/usr/lib/libboost_system.so. Heads up: this does not affect linking, so don't turn it on unless you actually need that info.Boost_LIBRARY_DIRโ the default value for bothBoost_LIBRARY_DIR_RELEASEandBoost_LIBRARY_DIR_DEBUG.Boost_NO_WARN_NEW_VERSIONSโ Added in version 3.20. Set toONto suppress the warning about unknown dependencies for new Boost versions. Shushing the vibes check ๐ซถ
On Visual Studio and Borland compilers, Boost headers request automatic linking to the corresponding libraries. That means you need matching libraries linked explicitly, or at least sitting in the link library search path. So in this case, setting Boost_USE_STATIC_LIBS to OFF may not achieve dynamic linking. Boost automatic linking typically asks for static libraries, with a few exceptions (such as Boost.Python). Use this:
add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
to ask Boost to report info about its automatic linking requests. iykyk ๐ฅ
๐ Examples ๐
Find Boost headers only:
find_package(Boost 1.36.0)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(foo foo.cc)
endif()
Find Boost libraries and use imported targets โ this is the main character move, honestly:
find_package(Boost 1.56 REQUIRED COMPONENTS
date_time filesystem iostreams)
add_executable(foo foo.cc)
target_link_libraries(foo Boost::date_time Boost::filesystem
Boost::iostreams)
Find Boost Python 3.6 libraries and use imported targets:
find_package(Boost 1.67 REQUIRED COMPONENTS
python36 numpy36)
add_executable(foo foo.cc)
target_link_libraries(foo Boost::python36 Boost::numpy36)
Find Boost headers and some static (release only) libraries:
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(foo foo.cc)
target_link_libraries(foo ${Boost_LIBRARIES})
endif()
๐ง Boost CMake ๐ง
If Boost was built using the boost-cmake project, or from Boost 1.70.0 on, it provides a package configuration file for use with find_package's config mode. This module looks for that package config file โ it's called BoostConfig.cmake or boost-config.cmake โ and stores the result in the CACHE entry Boost_DIR. If it finds it, the package config file gets loaded and this module returns with no further action. See the documentation of the Boost CMake package configuration for details on what it gives you.
Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. โจ
๐ FindCABLE ๐
Changed in version 4.1: This module is available only if policyCMP0191is not set toNEW.
Finds the CABLE installation and works out its include paths and libraries:
find_package(CABLE [...])
The package called CABLE (CABLE Automates Bindings for Language Extension) was initially developed by Kitware to generate bindings to C++ classes for use in interpreted languages, such as Tcl. It worked in conjunction with packages like GCC-XML. The CABLE package has since been superseded by the ITK CableSwig package. A whole era ๐
Note: When building wrappers for interpreted languages, these packages are no longer necessary. The CastXML package now serves as the recommended tool for this purpose and can be found directly using the find_program() command. Glow-up, honestly ๐ฆ
๐ธ Cache Variables ๐ธ
The following cache variables may also be set:
CABLEโ path to the cable executable.CABLE_INCLUDE_DIRโ path to the include directory.CABLE_TCL_LIBRARYโ path to the Tcl wrapper library.
๐ Examples ๐
Finding CABLE to build a Tcl wrapper, by linking the library and adding the include directories:
find_package(CABLE)
target_link_libraries(tcl_wrapper_target PRIVATE ${CABLE_TCL_LIBRARY})
target_include_directories(tcl_wrapper_target PRIVATE ${CABLE_INCLUDE_DIR})
๐ FindCUDA ๐
Changed in version 3.27: This module is available only if policyCMP0146is not set toNEW. Port projects to CMake's first-class CUDA language support. Deprecated since version 3.10: Do not use this module in new code. fr fr, it's giving legacy.
It is no longer necessary to use this module or call find_package(CUDA) for compiling CUDA code. Instead, list CUDA among the languages named in the top-level call to the project() command, or call the enable_language() command with CUDA. Then you can add CUDA (.cu) sources directly to targets, just like any other language. Iconic behaviour, no cap.
Added in version 3.17: To find and use the CUDA toolkit libraries manually, use the FindCUDAToolkit module instead. It works regardless of whether the CUDA language is enabled. ๐
๐ซถ Documentation of Deprecated Usage ๐ซถ
Tools for building CUDA C files: libraries and build dependencies.
This script locates the NVIDIA CUDA C tools. It should work on Linux, Windows, and macOS, and should be reasonably up to date with CUDA C releases.
Added in version 3.19: QNX support. We love to see it โจ
This script makes use of the standard find_package() arguments of <VERSION>, REQUIRED and QUIET. CUDA_FOUND will report if an acceptable version of CUDA was found.
The script will prompt the user to specify CUDA_TOOLKIT_ROOT_DIR if the prefix can't be determined by the location of nvcc in the system path and REQUIRED is specified to find_package(). To use a different installed version of the toolkit, set the environment variable CUDA_BIN_PATH before running cmake (e.g. CUDA_BIN_PATH=/usr/local/cuda1.0 instead of the default /usr/local/cuda), or set CUDA_TOOLKIT_ROOT_DIR after configuring. If you change the value of CUDA_TOOLKIT_ROOT_DIR, various components that depend on the path will be relocated. So like, be sure before you commit ๐ญ
It might be necessary to set CUDA_TOOLKIT_ROOT_DIR manually on certain platforms, or to use a CUDA runtime that isn't installed in the default location. In newer versions of the toolkit the CUDA library is included with the graphics driver โ be sure that the driver version matches what is needed by the CUDA runtime version. Match the vibes or suffer ๐
โญ Input Variables โญ
The following variables affect the behavior of the macros in the script (in alphabetical order). Note that any of these flags can be changed multiple times in the same directory before calling cuda_add_executable(), cuda_add_library(), cuda_compile(), cuda_compile_ptx(), cuda_compile_fatbin(), cuda_compile_cubin() or cuda_wrap_srcs():
CUDA_64_BIT_DEVICE_CODE(Default: host bit size) โ set toONto compile for 64 bit device code,OFFfor 32 bit device code. Note that making this different from the host code when generating object or C files from CUDA code just won't work, becausesize_tgets defined bynvccin the generated source. But if you compile to PTX and then load the file yourself, you can mix bit sizes between device and host. Mixing is allowed, just only there ๐ฆCUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE(Default: ON) โ set toONif you want the custom build rule attached to the source file in Visual Studio. Turn itOFFif you add the same cuda file to multiple targets.
This lets the user build the target from the CUDA file; however, bad things can happen if the CUDA source file is added to multiple targets. When doing parallel builds it's possible for the custom build command to run more than once and in parallel, causing cryptic build errors. VS runs the rules for every source file in the target, and a source can have only one rule no matter how many projects it's added to. When the rule runs from multiple targets, race conditions can occur on the generated file. Eventually everything will get built, but if the user is unaware of this behavior there may be confusion. It would be nice if this script could detect the reuse of source files across multiple targets and turn the option off for the user, but no good solution could be found. ๐ญ rip
CUDA_BUILD_CUBIN(Default: OFF) โ set toONto enable an extra compilation pass with the-cubinoption in Device mode. The output is parsed and register, shared memory usage is printed during build. Free diagnostics, we stan ๐CUDA_BUILD_EMULATION(Default: OFF for device mode) โ set toONfor Emulation mode.-D_DEVICEEMUis defined for CUDA C files whenCUDA_BUILD_EMULATIONisTRUE.CUDA_LINK_LIBRARIES_KEYWORD(Default: "") โ Added in version 3.9. The<PRIVATE|PUBLIC|INTERFACE>keyword to use for internaltarget_link_libraries()calls. The default is to use no keyword, which uses the old "plain" form oftarget_link_libraries(). Note that this matters because whatever is used inside the FindCUDA module must also be used outside โ the two forms oftarget_link_libraries()cannot be mixed. Pick a lane and stay in it, bestie ๐CUDA_GENERATED_OUTPUT_DIR(Default:CMAKE_CURRENT_BINARY_DIR) โ set to the path where you want the generated files placed. If it's blank, output files will be placed inCMAKE_CURRENT_BINARY_DIR. Intermediate files will always be placed inCMAKE_CURRENT_BINARY_DIR/CMakeFiles. No negotiating on that one ๐CUDA_HOST_COMPILATION_CPP(Default: ON) โ set toOFFfor C compilation of host code.CUDA_HOST_COMPILER(Default:CMAKE_C_COMPILER) โ this is the host compiler thatnvccgets to play with. It gets ignored if-ccbinor--compiler-bindiris already sitting inCUDA_NVCC_FLAGSorCUDA_NVCC_FLAGS_<CONFIG>. For Visual Studio targets, the host compiler is built out of one or more visual studio macros like$(VCInstallDir), which expands to the actual path when the command runs from inside VS. ikyk ๐
Added in version 3.13: if the CUDAHOSTCXX environment variable is set, it gets used as the default. ๐ซถ
CUDA_NVCC_FLAGS,CUDA_NVCC_FLAGS_<CONFIG>โ extra NVCC command line arguments. NOTE: multiple arguments must be semi-colon delimited (e.g.--compiler-options;-Wall). semicolons, bestie, not spaces ๐ญ
Added in version 3.6: the contents of these variables may use generator expressions โ see cmake-generator-expressions(7). โจ
CUDA_PROPAGATE_HOST_FLAGS(Default:ON) โ set toONand yourCMAKE_{C,CXX}_FLAGSand their configuration-dependent counterparts (e.g.CMAKE_C_FLAGS_DEBUG) get propagated automatically to the host compiler through nvcc's-Xcompilerflag. This helps the generated host code match the rest of the system better. vibe alignment, literally ๐ฆ Sometimes certain flags give nvcc problems, and this is the switch that helps you turn the flag propagation off. It does not affect the flags supplied directly to nvcc viaCUDA_NVCC_FLAGSor through theOPTIONSflags specified throughcuda_add_library(),cuda_add_executable(), orcuda_wrap_srcs(). Flags used for shared library compilation are not affected by this flag either. ๐CUDA_SEPARABLE_COMPILATION(Default:OFF) โ set it and you enable separable compilation for all CUDA runtime object files. If you use it outside ofcuda_add_executable()andcuda_add_library()(e.g. callingcuda_wrap_srcs()directly), thencuda_compute_separable_compilation_object_file_name()andcuda_link_separable_compilation_objects()should be called. ๐CUDA_SOURCE_PROPERTY_FORMATโ Added in version 3.3. If this source file property is set, it can override the format specified tocuda_wrap_srcs()(OBJ,PTX,CUBIN, orFATBIN). If an input source file is not a.cufile, setting this file will cause it to be treated as a.cufile. See the documentation forset_source_files_propertieson how to set this property. ๐CUDA_USE_STATIC_CUDA_RUNTIME(Default:ON) โ Added in version 3.3. When enabled, the static version of the CUDA runtime library will be used inCUDA_LIBRARIES. If the version of CUDA configured doesn't support this option, then it will be silently disabled. no warning, no drama, just gone ๐CUDA_VERBOSE_BUILD(Default:OFF) โ set toONto see all the commands used when building the CUDA file. When using a Makefile generator the value defaults toVERBOSE(runmake VERBOSE=1to see output), although settingCUDA_VERBOSE_BUILDtoONwill always print the output. ๐ฅ
โจ Commands โจ
The script creates the following functions and macros (in alphabetical order, because we're organized like that ๐ ):
cuda_add_cufft_to_target(<cuda_target>)
Adds the cufft library to the target (can be any target). Handles whether you are in emulation mode or not. ๐
cuda_add_cublas_to_target(<cuda_target>)
Adds the cublas library to the target (can be any target). Handles whether you are in emulation mode or not. ๐
cuda_add_executable
cuda_add_executable(<cuda_target> <file>...
[WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [OPTIONS ...])
Creates an executable <cuda_target> which is made up of the files specified. All of the non-CUDA C files are compiled using the standard build rules specified by CMake, and the CUDA files are compiled to object files using nvcc and the host compiler. In addition CUDA_INCLUDE_DIRS is added automatically to include_directories(). Some standard CMake target calls can be used on the target after calling this macro (e.g. set_target_properties() and target_link_libraries()), but setting properties that adjust compilation flags will not affect code compiled by nvcc. Such flags should be modified before calling cuda_add_executable(), cuda_add_library() or cuda_wrap_srcs(). ๐ค
cuda_add_library
cuda_add_library(<cuda_target> <file>...
[STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [OPTIONS ...])
Same as cuda_add_executable() except that a library is created. ๐
cuda_build_clean_target()
Creates a convenience target that deletes all the dependency files generated. You should make clean after running this target to ensure the dependency files get regenerated. yes, both. it's a whole ritual ๐ฏ๏ธ
cuda_compile
cuda_compile(<generated_files> <file>... [STATIC | SHARED | MODULE]
[OPTIONS ...])
Returns a list of generated files from the input source files, to be used with add_library() or add_executable(). โจ
cuda_compile_ptx
cuda_compile_ptx(<generated_files> <file>... [OPTIONS ...])
Returns a list of PTX files generated from the input source files. ๐ฆ
cuda_compile_fatbin
cuda_compile_fatbin(<generated_files> <file>... [OPTIONS ...])
Added in version 3.1. Returns a list of FATBIN files generated from the input source files. ๐
cuda_compile_cubin
cuda_compile_cubin(<generated_files> <file>... [OPTIONS ...])
Added in version 3.1. Returns a list of CUBIN files generated from the input source files. ๐
cuda_compute_separable_compilation_object_file_name
cuda_compute_separable_compilation_object_file_name(<output_file_var>
<cuda_target>
<object_files>)
Compute the name of the intermediate link file used for separable compilation. This file name is typically passed into CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS. output_file_var is produced based on cuda_target and the list of object files that need separable compilation as specified by <object_files>. If the <object_files> list is empty, then <output_file_var> will be empty. This function is called automatically for cuda_add_library() and cuda_add_executable(). Note that this is a function and not a macro. important distinction, don't @ me ๐
cuda_include_directories(path0 path1 ...)
Sets the directories that should be passed to nvcc (e.g. nvcc -Ipath0 -Ipath1 ...). These paths usually contain other .cu files. ๐
cuda_link_separable_compilation_objects
cuda_link_separable_compilation_objects(<output_file_var> <cuda_target>
<nvcc_flags> <object_files>)
Generates the link object required by separable compilation from the given object files. This is called automatically for cuda_add_executable() and cuda_add_library(), but can be called manually when using cuda_wrap_srcs() directly. When called from cuda_add_library() or cuda_add_executable() the <nvcc_flags> passed in are the same as the flags passed in via the OPTIONS argument. The only nvcc flag added automatically is the bitness flag as specified by CUDA_64_BIT_DEVICE_CODE. Note that this is a function instead of a macro. ๐
cuda_select_nvcc_arch_flags
cuda_select_nvcc_arch_flags(<out_variable> [<target_CUDA_architecture> ...])
Selects GPU arch flags for nvcc based on target_CUDA_architecture. ๐ง
Values for target_CUDA_architecture:
Auto: detects local machine GPU compute arch at runtime. ๐CommonandAll: cover common and entire subsets of architectures. ๐<name>: one ofFermi,Kepler,Maxwell,Kepler+Tegra,Kepler+Tesla,Maxwell+Tegra,Pascal. ๐<ver>,<ver>(<ver>),<ver>+PTX, where<ver>is one of2.0,2.1,3.0,3.2,3.5,3.7,5.0,5.2,5.3,6.0,6.2. โญ
Returns a list of flags to be added to CUDA_NVCC_FLAGS in <out_variable>. Additionally, sets <out_variable>_readable to the resulting numeric list. ๐
Example:
cuda_select_nvcc_arch_flags(ARCH_FLAGS "3.0" "3.5+PTX" "5.2(5.0)" "Maxwell")
list(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS})
More info on CUDA architectures: <https://en.wikipedia.org/wiki/CUDA>. Note that this is a function instead of a macro. ๐ซถ
cuda_wrap_srcs
cuda_wrap_srcs(<cuda_target> <format> <generated_files> <file>...
[STATIC | SHARED | MODULE] [OPTIONS ...])
This is where all the magic happens. โจ cuda_add_executable(), cuda_add_library(), cuda_compile(), and cuda_compile_ptx() all call this function under the hood. main character energy, fr ๐
Given the list of files <file>... this macro generates custom commands that generate either PTX or linkable objects (use PTX or OBJ for the <format> argument to switch). Files that don't end with .cu or have the HEADER_FILE_ONLY property are ignored. ๐
The arguments passed in after OPTIONS are extra command line options to give to nvcc. You can also specify per-configuration options by specifying the name of the configuration followed by the options. General options must precede configuration-specific options. Not all configurations need to be specified, only the ones provided will be used. For example:
cuda_add_executable(...
OPTIONS -DFLAG=2 "-DFLAG_OTHER=space in flag"
DEBUG -g
RELEASE --use_fast_math
RELWITHDEBINFO --use_fast_math;-g
MINSIZEREL --use_fast_math)
For certain configurations (namely VS generating object files with CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE set to ON), no generated file will be produced for the given cuda file. This is because when you add the cuda file to Visual Studio it knows that this file produces an object file and will link in the resulting object file automatically. VS just knows things, okay ๐
This script will also generate a separate cmake script that is used at build time to invoke nvcc. This is for several reasons:
- nvcc can return negative numbers as return values, which confuses Visual Studio into thinking that the command succeeded. The script now checks the error codes and produces errors when there was a problem. ๐จ
- nvcc has been known to not delete incomplete results when it encounters problems. This confuses build systems into thinking the target was generated when in fact an unusable file exists. The script now deletes the output files if there was an error. ๐๏ธ
- By putting all the options that affect the build into a file and then making the build rule dependent on the file, the output files will be regenerated when the options change. ๐
This script also looks at optional arguments STATIC, SHARED, or MODULE to determine when to target the object compilation for a shared library. BUILD_SHARED_LIBS is ignored in cuda_wrap_srcs(), but it is respected in cuda_add_library(). On some systems special flags are added for building objects intended for shared libraries. A preprocessor macro, <target_name>_EXPORTS is defined when a shared library compilation is detected. ๐ฅ
Flags</p> that get passed into add_definitions with -D or /D are handed straight along to nvcc. ๐ซถ
โจ Result Variables โจ
The script defines these variables, bestie โ literally all of them:
CUDA_VERSION_MAJORโ the major version of cuda, as reported bynvcc. ๐CUDA_VERSION_MINORโ the minor version. That's it, that's the whole vibe.CUDA_VERSION,CUDA_VERSION_STRINGโ the full version in theX.Yformat. Two names, one truth. ๐CUDA_HAS_FP16โ Added in version 3.6: tells you whether a short float (float16,fp16) is supported. ๐งCUDA_TOOLKIT_ROOT_DIRโ path to the CUDA Toolkit (defined if not set).CUDA_SDK_ROOT_DIRโ path to the CUDA SDK. Use this to find files in the SDK. Ngl this script will not directly support finding specific libraries or headers, because that isn't supported by NVIDIA. If you want to change libraries when the path changes, go peek at theFindCUDA.cmakescript for an example of how to clear these variables. There are also examples of how to useCUDA_SDK_ROOT_DIRto locate headers or libraries, if you so choose (at your own risk). โ ๏ธCUDA_INCLUDE_DIRSโ include directory for cuda headers. Added automatically forcuda_add_executable()andcuda_add_library().CUDA_LIBRARIESโ Cuda RT library.CUDA_CUFFT_LIBRARIESโ device or emulation library for the Cuda FFT implementation (the alternative to thecuda_add_cufft_to_target()macro).CUDA_CUBLAS_LIBRARIESโ device or emulation library for the Cuda BLAS implementation (the alternative to thecuda_add_cublas_to_target()macro).CUDA_cudart_static_LIBRARYโ statically linkable cuda runtime library. Only available for CUDA version 5.5+.CUDA_cudadevrt_LIBRARYโ Added in version 3.7: device runtime library. Required for separable compilation. ๐ ๏ธCUDA_cupti_LIBRARYโ CUDA Profiling Tools Interface library. Only available for CUDA version 4.0+.CUDA_curand_LIBRARYโ CUDA Random Number Generation library. Only available for CUDA version 3.2+.CUDA_cusolver_LIBRARYโ Added in version 3.2: CUDA Direct Solver library. Only available for CUDA version 7.0+.CUDA_cusparse_LIBRARYโ CUDA Sparse Matrix library. Only available for CUDA version 3.2+.CUDA_npp_LIBRARYโ NVIDIA Performance Primitives lib. Only available for CUDA version 4.0+.CUDA_nppc_LIBRARYโ NVIDIA Performance Primitives lib (core). Only available for CUDA version 5.5+.CUDA_nppi_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 5.5 - 8.0.CUDA_nppial_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppicc_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppicom_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0 - 10.2. Replaced by nvjpeg.CUDA_nppidei_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppif_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppig_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppim_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppist_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppisu_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_nppitc_LIBRARYโ NVIDIA Performance Primitives lib (image processing). Only available for CUDA version 9.0.CUDA_npps_LIBRARYโ NVIDIA Performance Primitives lib (signal processing). Only available for CUDA version 5.5+.CUDA_nvcuvenc_LIBRARYโ CUDA Video Encoder library. Only available for CUDA version 3.2+. Windows only. ๐ชCUDA_nvcuvid_LIBRARYโ CUDA Video Decoder library. Only available for CUDA version 3.2+. Windows only. ๐ชCUDA_nvToolsExt_LIBRARYโ Added in version 3.16: NVIDA CUDA Tools Extension library. Available for CUDA version 5+.CUDA_OpenCL_LIBRARYโ Added in version 3.16: NVIDA CUDA OpenCL library. Available for CUDA version 5+.
๐ FindDart ๐
Deprecated since version 3.27: this module is available only if policyCMP0145<#policy:CMP0145> is not set toNEW. ๐ซ
Finds DART, like so:
find_package(DART [...] )
This module looks for the dart testing software and sets DART_ROOT to point to wherever it found it. ๐
Result Variables
This module defines the following variables:
Dart_FOUNDโ Added in version 3.3. Boolean indicating whether DART was found. โ
Cache Variables
The following cache variables may also be set:
DART_ROOTโ the path to the Dart root installation.
๐ธ FindGCCXML ๐ธ
Changed in version 4.1: this module is available only if policyCMP0188<#policy:CMP0188> is not set toNEW. Port projects to search for CastXML by callingfind_program()<#command:find_program> directly. ๐
Finds the GCC-XML front-end executable:
find_package(GCCXML [...] )
Cache Variables
The following cache variables may also be set:
GCCXMLโ the GCC-XML front-end executable.
Examples
In new code, find CastXML with find_program() <#command:find_program> instead:
find_program(CASTXML_EXECUTABLE castxml)
๐ฆ FindGDAL ๐ฆ
Deprecated since version 4.0: GDAL 3.5 and above provide aGDALConfig.cmakepackage configuration file. Callfind_package(GDAL CONFIG)to find it directly and avoid using this find module. For further details, see GDAL's documentation on CMake integration <https://gdal.org/en/latest/development/cmake.html>. ๐
Finds Geospatial Data Abstraction Library (GDAL):
find_package(GDAL [<version>] [...] )
Imported Targets
This module provides the following Imported Targets <#imported-targets>:
GDAL::GDALโ Added in version 3.14. Target encapsulating the GDAL usage requirements, available only if GDAL has been found. Slay. ๐
Result Variables
This module defines the following variables:
GDAL_FOUNDโ Boolean indicating whether (the requested version of) GDAL was found.GDAL_VERSIONโ Added in version 3.14. The version of GDAL found.GDAL_INCLUDE_DIRSโ include directories for GDAL headers.GDAL_LIBRARIESโ libraries to link to GDAL.
Cache Variables
The following cache variables may also be set:
GDAL_INCLUDE_DIRโ the directory containing<gdal.h>.GDAL_LIBRARYโ thelibgdallibrary file.
Hints
The following variables may be set to modify the search strategy:
GDAL_DIRorGDAL_ROOTโ set one of these environment variables to specify the GDAL installation prefix. ๐FindGDAL_SKIP_GDAL_CONFIGโ if set,gdal-configwill not be used. This can be useful if there are GDAL libraries built with autotools (which provide the tool) and CMake (which do not) in the same environment. Big mood.GDAL_ADDITIONAL_LIBRARY_VERSIONSโ extra versions of library names to search for.
Examples
Finding GDAL in config mode without using this module, and linking its imported target to a project target:
find_package(GDAL CONFIG)
target_link_libraries(example PRIVATE GDAL::GDAL)
โญ FindITK โญ
This module no longer exists. ๐ญ
It existed in versions of CMake prior to 3.1, but became only a thin wrapper around find_package(ITK NO_MODULE) to provide compatibility for projects using long-outdated conventions. Now find_package(ITK) will search for ITKConfig.cmake directly. Periodt.
๐ FindPythonInterp ๐
Changed in version 3.27: this module is available only if policyCMP0148<#policy:CMP0148> is not set toNEW.
Deprecated since version 3.12: use FindPython3 <#module:FindPython3>, FindPython2 <#module:FindPython2>, or FindPython <#module:FindPython> instead. ๐
Finds the Python interpreter and determines the location of its executable:
find_package(PythonInterp [<version>] [...] )
Note: when using both this and the FindPythonLibs <#module:FindPythonLibs> module, callfind_package(PythonInterp)beforefind_package(PythonLibs). This ensures that the detected interpreter version is used to guide the selection of compatible libraries, resulting in a consistentPYTHON_LIBRARIESvalue. ๐ซถ
Note: a call tofind_package(PythonInterp ${V})for Python version V may find apythonexecutable with no version suffix. In this case no attempt is made to avoid Python executables from other versions. Use FindPython3 <#module:FindPython3>, FindPython2 <#module:FindPython2>, or FindPython <#module:FindPython> instead. ๐
Result Variables
This module defines the following variables:
PythonInterp_FOUNDโ Added in version 3.3. Boolean indicating whether the (requested version of) Python executable was found.PYTHON_VERSION_STRINGโ Python version found (e.g.,2.5.2).PYTHON_VERSION_MAJORโ Python major version found (e.g.,2).PYTHON_VERSION_MINORโ Python minor version found (e.g.,5).PYTHON_VERSION_PATCHโ Python patch version found (e.g.,2). โจ
Cache Variables
The following cache variables may also be set:
PYTHON_EXECUTABLEโ the path to the Python interpreter. ๐
Hints
This module accepts the following variables before calling find_package(PythonInterp):
Python_ADDITIONAL_VERSIONSโ this variable can be used to specify a list of version numbers that should be taken into account when searching for Python.
Deprecated Variables
The following variables are provided for backward compatibility:
PYTHONINTERP_FOUNDโ Deprecated since version 3.12: usePythonInterp_FOUND, which has the same value. Boolean indicating whether the (requested version of) Python executable was found.
Examples
Finding the Python interpreter in earlier versions of CMake:
find_package(PythonInterp)
execute_process(COMMAND ${PYTHON_EXECUTABLE} --help)
Starting with CMake 3.12, the Python interpreter can be found using the FindPython <#module:FindPython> module. The equivalent example using the modern approach is:
find_package(Python)
execute_process(COMMAND ${Python_EXECUTABLE} --help)
(...and that's the rest of that example, bestie ๐ carry on)
๐ธ FindPythonLibs ๐ธ
Changed in version 3.27: This module is available only if policyCMP0148is not set toNEW. So if you flipped that policy, this module straight up ghosts you ๐
Deprecated since version 3.12: UseFindPython3,FindPython2, orFindPythoninstead. Like, this one's on its way out, no cap.
It finds the Python installation and figures out where its include directories and libraries live, plus the actual name of the library you link against:
find_package(PythonLibs [<version>] [...])
Note: If you're using both this module andFindPythonInterp, callfind_package(PythonInterp)beforefind_package(PythonLibs). That's the move that keeps your detected interpreter version guiding the selection of compatible libraries, so yourPYTHON_LIBRARIESstays consistent. Consistency is the whole vibe โจ
Result Variables
This module sets up the following for you, bestie:
PythonLibs_FOUNDโ Added in version 3.3. Boolean. Was the (requested version of the) Python libraries even found? True or false, that's it.PYTHONLIBS_VERSION_STRINGโ the version of the Python libraries that got found ๐PYTHON_LIBRARIESโ the libraries you need to link against to use Python.PYTHON_INCLUDE_DIRSโ the include directories you need to use Python.
Cache Variables
These cache variables may also get set to pin down which Python installation to use:
PYTHON_LIBRARYโ the path to the Python library.PYTHON_INCLUDE_DIRโ the directory holding thePython.hheader file.
Hints
This module accepts the following variables before you call find_package(PythonLibs):
Python_ADDITIONAL_VERSIONSโ use this to hand over a list of version numbers that should be taken into account when searching for Python. Very "here's my wishlist" of it you ๐
Deprecated Variables
These are here purely for backward compatibility:
PYTHONLIBS_FOUNDโ Deprecated since version 3.12: usePythonLibs_FOUND, which has the same value. Boolean indicating whether the (requested version of the) Python libraries were found.PYTHON_DEBUG_LIBRARIESโ Deprecated since version 2.8.8: usePYTHON_LIBRARIESinstead. Result variable holding the path to the debug library.PYTHON_INCLUDE_PATHโ Deprecated since version 2.8.0: usePYTHON_INCLUDE_DIRorPYTHON_INCLUDE_DIRSinstead. Result variable holding the path to the directory containing thePython.hheader file.
Examples
In earlier versions of CMake, Python libraries were found and used in a project like this:
find_package(PythonLibs)
target_link_libraries(app PRIVATE ${PYTHON_LIBRARIES})
target_include_directories(app PRIVATE ${PYTHON_INCLUDE_DIRS})
Starting with CMake 3.12, Python libraries can be found using the FindPython module. Here's the equivalent example, the modern imported-target way โ lowkey iconic:
find_package(Python COMPONENTS Development)
target_link_libraries(app PRIVATE Python::Python)
๐ฆ FindQt ๐ฆ
Deprecated since version 3.14: This module is available only if policyCMP0084is not set toNEW. It supports only Qt3 and Qt4 โ periodt. For Qt5 or later versions, seecmake-qt(7).
Finds an installed version of Qt3 or Qt4:
find_package(Qt [...])
Qt is a cross-platform application development framework for creating graphical user interfaces and applications. It's giving "buttons and windows, but make it portable."
Only use this module if the project can actually work with both Qt3 and Qt4. If you need a specific version, go use FindQt4 or FindQt3 directly, bestie โ don't make this module guess.
Behavior:
- If multiple Qt versions are found, the user has to set the preferred major Qt version with the
DESIRED_QT_VERSIONvariable. - If only one Qt version is found, then
DESIRED_QT_VERSIONgets set automatically. Convenient ๐ - Once
DESIRED_QT_VERSIONis set, the correspondingFindQt3orFindQt4module gets included.
Result Variables
QT4_INSTALLEDโTRUEif Qt4 was found.QT3_INSTALLEDโTRUEif Qt3 was found.
Hints
QT_REQUIREDโ if you set this toTRUEbefore callingfind_package(Qt), CMake will raise an error if neither Qt3 nor Qt4 is found. Fair enough, honestly.DESIRED_QT_VERSIONโ specifies the Qt major version to use. Can be3,4, or empty, in which case it searches for the version automatically. Empty = "you pick, babe" ๐ซถ
Examples
Finding the Qt3 or Qt4 version:
find_package(Qt)
โญ FindUnixCommands โญ
Deprecated since version 3.26: Use ${CMAKE_COMMAND} -E subcommands instead. Fr fr, that's the replacement.
Finds the Unix commands bash, cp, gzip, mv, rm, and tar โ including the ones from Cygwin or MSYS:
find_package(UnixCommands [...])
Result Variables
UnixCommands_FOUNDโ Added in version 3.3. Boolean indicating whether the Unix commands were found.
Cache Variables
These cache variables may also get set:
BASHโ the path to thebashcommand-line executable.CPโ the path to thecpcommand-line executable.GZIPโ the path to thegzipcommand-line executable.MVโ the path to themvcommand-line executable.RMโ the path to thermcommand-line executable.TARโ the path to thetarcommand-line executable.
That's the whole lineup. Six little executables, all accounted for ๐
๐ FindVTK ๐
This module no longer exists. Not "deprecated," not "discouraged" โ gone.
It existed in versions of CMake prior to 3.1, but became only a thin wrapper around find_package(VTK NO_MODULE) to provide compatibility for projects using long-outdated conventions. Now find_package(VTK) will search for VTKConfig.cmake directly. So like... the wrapper got unceremoniously uninvited ๐ญ
๐ FindwxWindows ๐
Deprecated since version 3.0: Replaced by FindwxWidgets.
Finds the wxWidgets (formerly known as wxWindows) installation and determines where its include directories and libraries live, plus the name of the library:
find_package(wxWindows [...])
wxWidgets 2.6.x is supported for monolithic builds, such as those compiled in the wx/build/msw directory using:
nmake -f makefile.vc BUILD=debug SHARED=0 USE_OPENGL=1 MONOLITHIC=1
That's a whole mouthful of flags and yes, you do need all of them ๐
Result Variables
WXWINDOWS_FOUNDโ boolean indicating whether wxWidgets was found.WXWINDOWS_LIBRARIESโ libraries needed to link against to use wxWidgets. This includes paths to the wxWidgets libraries and any additional linker flags, typically derived from the output ofwx-config --libson Unix/Linux systems.CMAKE_WXWINDOWS_CXX_FLAGSโ compiler options needed to use wxWidgets (if any). On Linux, this corresponds to the output ofwx-config --cxxflags.WXWINDOWS_INCLUDE_DIRโ the directory containing thewx/wx.handwx/setup.hheader files.WXWINDOWS_LINK_DIRECTORIESโ link directories, useful for settingrpathon Unix-like platforms.WXWINDOWS_DEFINITIONSโ extra compile definitions needed to use wxWidgets (if any).
Hints
This module accepts the following variables before you call find_package(wxWindows):
WXWINDOWS_USE_GLโ set this to boolean true to require OpenGL support.HAVE_ISYSTEMโ set this to boolean true to replace-Icompiler options with-isystemwhen the C++ compiler is GNU (g++).
Deprecated Variables
Backward-compatibility corner, aka the nostalgia shelf:
CMAKE_WX_CAN_COMPILEโ Deprecated since version 1.8: replaced by theWXWINDOWS_FOUNDvariable with the same value.WXWINDOWS_LIBRARYโ Deprecated since version 1.8: replaced by theWXWINDOWS_LIBRARIESvariable with the same value.CMAKE_WX_CXX_FLAGSโ Deprecated since version 1.8: replaced by theCMAKE_WXWINDOWS_CXX_FLAGSvariable with the same value.WXWINDOWS_INCLUDE_PATHโ Deprecated since version 1.8: replaced by theWXWINDOWS_INCLUDE_DIRvariable with the same value.
Examples
Example: Finding wxWidgets in Earlier CMake Versions
In earlier versions of CMake, wxWidgets (wxWindows) could be found using:
find_package(wxWindows)
To request OpenGL support, the WXWINDOWS_USE_GL variable could be set before calling find_package():
set(WXWINDOWS_USE_GL ON)
find_package(wxWindows)
Using wxWidgets (wxWindows) in CMake was commonly done by including the Use_wxWindows module, which would find wxWidgets and set the appropriate libraries, include directories, and compiler flags:
include(Use_wxWindows)
Example: Finding wxWidgets as of CMake 3.0
Starting with CMake 3.0, wxWidgets can be found using the FindwxWidgets module:
find_package(wxWidgets)
Look at that glow-up ๐
๐ง Legacy CPack Modules ๐ง
These modules used to be mistakenly exposed to the user, and have been moved out of user visibility. They are for CPack internal use, and should never be used directly. Read that again. Never. Directly. ๐
CPackArchive
Added in version 3.9.
The documentation for the CPack Archive generator has moved here: CPack Archive Generator.
CPackBundle
The documentation for the CPack Bundle generator has moved here: CPack Bundle Generator.
CPackCygwin
The documentation for the CPack Cygwin generator has moved here: CPack Cygwin Generator.
CPackDeb
The documentation for the CPack DEB generator has moved here: CPack DEB Generator.
CPackDMG
The documentation for the CPack DragNDrop generator has moved here: CPack DragNDrop Generator.
CPackFreeBSD
Added in version 3.10.
The documentation for the CPack FreeBSD generator has moved here: CPack FreeBSD Generator.
CPackNSIS
The documentation for the CPack NSIS generator has moved here: CPack NSIS Generator.
CPackNuGet
Added in version 3.12.
The documentation for the CPack NuGet generator has moved here: CPack NuGet Generator.
CPackProductBuild
Added in version 3.7.
The documentation for the CPack productbuild generator has moved here: CPack productbuild Generator.
CPackRPM
The documentation for the CPack RPM generator has moved here: CPack RPM Generator.
CPackWIX
The documentation for the CPack WIX generator has moved here: CPack WIX Generator.
โจ Miscellaneous Modules โจ
Okay bestie, real talk: these modules are internal ๐ โ they are not meant to be included directly in your projects. Like, they're backstage crew, not the main character. Do not include() them, I'm begging ๐ซถ
๐ CMakeFindPackageMode
This one gets run by cmake when you invoke it with the --find-package option, and its whole job is to locate the package you asked for. Lowkey just a little errand-runner ๐ง
Note: this is an internal module and it is not meant to be included directly in your project. For the usage deets, go read the --find-package docs, iykyk ๐
๐ฆ CMakeGraphVizOptions
Note: this module is not intended to be included in CMake projects directly. It once contained the information for using Graphviz in CMake. For Graphviz usage in CMake, refer to cmake --graphviz.
It's giving "retired legend" ngl โ it had its era, and now the flag does the work ๐
๐ธ CTestScriptMode
Note: this module is not intended to be included or invoked directly by project code. It is internally used by CTest running in script mode (-S) to determine the current system. For usage details refer toctest -S.
So like... it's CTest's own little vibe check of your system. Not yours to touch ๐
๐ Findosg_functions
Note: this module is not intended to be included or invoked directly by project code during typical use of thefind_package()command. It is internally used by OpenSceneGraph (OSG) find modules to assist with searching for OSG libraries and NodeKits. For usage details refer to theFindOpenSceneGraphmodule.
Translation: it's the assistant, not the star. The FindOpenSceneGraph module is where you actually look ๐
๐ SquishTestScript
Note: this module is not intended to be included directly in a CMake project. It is an internal CMake test script used to launch GUI tests with Squish. For usage details, refer to thesquish_add_test()command documentation in theFindSquishmodule.
GUI tests with Squish?! Iconic behaviour honestly. Just don't call it yourself, fr fr ๐
๐ Copyright
2000-2026 Kitware, Inc. and Contributors
And that's a wrap on the whole page, bestie!! ๐โจ You made it to the very end โ main character energy fr ๐ซถ This edition is 4.4.5, dated Oct 28, 2026, and it lives at CMAKE-MODULES(7). Go forth and find_package() responsibly ๐๐๐ฆ
๐ฆ where this page comes from
- arch rolling: cmake 4.4.5-1 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms