CMAKE-VARIABLES(7)
okay so welcome to cmake-variables(7) — the CMake Variables Reference, bestie. This is the page that documents variables that are provided by CMake or have meaning to CMake when set by project code. 💅
if you want the general tea on variables, see the Variables section in the cmake-language manual. ✨
⚠️ Note: CMake reserves identifiers that: - begin withCMAKE_(upper-, lower-, or mixed-case), or - begin with_CMAKE_(upper-, lower-, or mixed-case), or - begin with_followed by the name of any CMake Command fromcmake-commands(7).
🔎 VARIABLES THAT PROVIDE INFORMATION 🔎
💖 CMAKE_AR
Name of archiving tool for static libraries.
This specifies the name of the program that creates archive or static libraries. iconic.
🎀 CMAKE_ARGC
Number of command line arguments passed to CMake in script mode.
When run in -P script mode, CMake sets this variable to the number of command line arguments. See also CMAKE_ARGV0, 1, 2, ... 👑
🦋 CMAKE_ARGV0
Command line argument passed to CMake in script mode.
When run in -P script mode, CMake sets this variable to the first command line argument. It then also sets CMAKE_ARGV1, CMAKE_ARGV2, ... and so on, up to the number of command line arguments given. See also CMAKE_ARGC. ✨
🌸 CMAKE_BINARY_DIR
The path to the top level of the build tree.
This is the full path to the top level of the current CMake build tree. For an in-source build, this would be the same as CMAKE_SOURCE_DIR.
When run in cmake -P script mode, CMake sets the variables CMAKE_BINARY_DIR, CMAKE_SOURCE_DIR, CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR to the current working directory.
💀 Modifying CMAKE_BINARY_DIR has undefined behavior. do not do it, bestie.
🧚 CMAKE_BUILD_TOOL
This variable exists only for backwards compatibility. It contains the same value as CMAKE_MAKE_PROGRAM. Use that variable instead. periodt.
🍓 CMAKE_CACHE_MAJOR_VERSION
Major version of CMake used to create the CMakeCache.txt file.
This stores the major version of CMake used to write a CMake cache file. It is only different when a different version of CMake is run on a previously created cache file.
🍓 CMAKE_CACHE_MINOR_VERSION
Minor version of CMake used to create the CMakeCache.txt file.
This stores the minor version of CMake used to write a CMake cache file. It is only different when a different version of CMake is run on a previously created cache file.
🍓 CMAKE_CACHE_PATCH_VERSION
Patch version of CMake used to create the CMakeCache.txt file.
This stores the patch version of CMake used to write a CMake cache file. It is only different when a different version of CMake is run on a previously created cache file.
🫶 CMAKE_CACHEFILE_DIR
This variable is used internally by CMake, and may not be set during the first configuration of a build tree. When it is set, it has the same value as CMAKE_BINARY_DIR. Use that variable instead. lowkey just use the other one.
🔥 CMAKE_COMMAND
The full path to the cmake(1) executable.
This is the full path to the CMake executable cmake(1) which is useful from custom commands that want to use the cmake -E option for portable system commands. (e.g. /usr/local/bin/cmake) 👑
🌈 CMAKE_CPACK_COMMAND
Added in version 3.13.
Full path to cpack(1) command installed with CMake.
This is the full path to the CPack executable cpack(1) that can be used for custom commands or tests to invoke CPack commands. iconic behavior.
🦋 CMAKE_CROSSCOMPILING
This variable is set by CMake to indicate whether it is cross compiling, but note limitations discussed below.
This variable will be set to true by CMake if the CMAKE_SYSTEM_NAME variable has been set manually (i.e. in a toolchain file or as a cache entry from the cmake command line). In most cases, manually setting CMAKE_SYSTEM_NAME will only be done when cross compiling since, if not manually set, it will be given the same value as CMAKE_HOST_SYSTEM_NAME, which is correct for the non-cross-compiling case. In the event that CMAKE_SYSTEM_NAME is manually set to the same value as CMAKE_HOST_SYSTEM_NAME, then CMAKE_CROSSCOMPILING will still be set to true.
Another case to be aware of is that builds targeting Apple platforms other than macOS are handled differently to other cross compiling scenarios. Rather than relying on CMAKE_SYSTEM_NAME to select the target platform, Apple device builds use CMAKE_OSX_SYSROOT to select the appropriate SDK, which indirectly determines the target platform. Furthermore, when using the Xcode generator, developers can switch between device and simulator builds at build time rather than having a single choice at configure time, so the concept of whether the build is cross compiling or not is more complex. Therefore, the use of CMAKE_CROSSCOMPILING is not recommended for projects targeting Apple devices. no cap, that's the whole warning. 🫶
💜 CMAKE_CROSSCOMPILING_EMULATOR
Added in version 3.3.
This variable is only used when CMAKE_CROSSCOMPILING is on. It should point to a command on the host system that can run executable built for the target system.
Added in version 3.15: If this variable contains a semicolon-separated list, then the first value is the command and remaining values are its arguments.
Added in version 3.28: This variable can be initialized via an CMAKE_CROSSCOMPILING_EMULATOR environment variable.
The command will be used to run try_run() generated executables, which avoids manual population of the TryRunResults.cmake file.
This variable is also used as the default value for the CROSSCOMPILING_EMULATOR target property of executables. However, while generator expressions are supported by the target property (since CMake 3.29), they are not supported by this variable's try_run() functionality. important!! ✨
💖 CMAKE_CTEST_COMMAND
Full path to ctest(1) command installed with CMake.
This is the full path to the CTest executable ctest(1) that can be used for custom commands or tests to invoke CTest commands.
🎀 CMAKE_CURRENT_BINARY_DIR
The path to the binary directory currently being processed.
This is the full path to the build directory that is currently being processed by cmake. Each directory added by add_subdirectory() will create a binary directory in the build tree, and as it is being processed this variable will be set. For in-source builds this is the current source directory being processed.
When run in cmake -P script mode, CMake sets the variables CMAKE_BINARY_DIR, CMAKE_SOURCE_DIR, CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR to the current working directory.
💀 Modifying CMAKE_CURRENT_BINARY_DIR has undefined behavior. seriously, don't.
🌟 CMAKE_CURRENT_FUNCTION
Added in version 3.17.
When executing code inside a function(), this variable contains the name of the current function. It can be useful for diagnostic or debug messages.
See also CMAKE_CURRENT_FUNCTION_LIST_DIR, CMAKE_CURRENT_FUNCTION_LIST_FILE and CMAKE_CURRENT_FUNCTION_LIST_LINE.
🌟 CMAKE_CURRENT_FUNCTION_LIST_DIR
Added in version 3.17.
When executing code inside a function(), this variable contains the full directory of the listfile that defined the current function.
It is quite common practice in CMake for modules to use some additional files, such as templates to be copied in after substituting CMake variables. In such cases, a function needs to know where to locate those files in a way that doesn't depend on where the function is called. Without CMAKE_CURRENT_FUNCTION_LIST_DIR, the code to do that would typically use the following pattern:
set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
function(foo)
configure_file(
"${_THIS_MODULE_BASE_DIR}/some.template.in"
some.output
)
endfunction()
Using CMAKE_CURRENT_FUNCTION_LIST_DIR inside the function instead eliminates the need for the extra variable which would otherwise be visible outside the function's scope. The above example can be written in the more concise and more robust form:
function(foo)
configure_file(
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/some.template.in"
some.output
)
endfunction()
See also CMAKE_CURRENT_FUNCTION, CMAKE_CURRENT_FUNCTION_LIST_FILE, CMAKE_CURRENT_FUNCTION_LIST_LINE and CMAKE_CURRENT_LIST_DIR. slay. 💅
🌟 CMAKE_CURRENT_FUNCTION_LIST_FILE
Added in version 3.17.
When executing code inside a function(), this variable contains the full path to the listfile that defined the current function.
See also CMAKE_CURRENT_FUNCTION, CMAKE_CURRENT_FUNCTION_LIST_DIR, CMAKE_CURRENT_FUNCTION_LIST_LINE and CMAKE_CURRENT_LIST_FILE.
🌟 CMAKE_CURRENT_FUNCTION_LIST_LINE
Added in version 3.17.
When executing code inside a function(), this variable contains the line number in the listfile where the current function was defined.
See also CMAKE_CURRENT_FUNCTION, CMAKE_CURRENT_FUNCTION_LIST_DIR, CMAKE_CURRENT_FUNCTION_LIST_FILE and CMAKE_CURRENT_LIST_LINE.
🦋 CMAKE_CURRENT_LIST_DIR
Full directory of the listfile currently being processed. that's literally it, bestie. ✨
...so like, as CMake chews through the listfiles in your project, this variable is always gonna be the directory where the listfile currently being processed (CMAKE_CURRENT_LIST_FILE) lives. 💅 The value has dynamic scope — when CMake starts running commands in a source file it sets this to that file's directory, and when it's done with that file it puts the previous value back. So inside a macro or function, the value is the directory of the file invoking the bottom-most entry on the call stack — not the directory of the file where the macro/function is defined. iykyk 😭
See also CMAKE_CURRENT_LIST_FILE and CMAKE_CURRENT_FUNCTION_LIST_DIR. 🫶
CMAKE_CURRENT_LIST_FILE
Full path to the listfile currently being processed. 🎀
As CMake processes the listfiles in your project, this one is always set to the file currently being processed. The value has dynamic scope — when CMake starts processing commands in a source file it sets this variable to the location of the file, and when it finishes with that file it restores the previous value. So inside a macro or function, the value is the file invoking the bottom-most entry on the call stack, not the file containing the macro or function definition. literally the same energy as the one above ✨
See also CMAKE_PARENT_LIST_FILE and CMAKE_CURRENT_FUNCTION_LIST_FILE.
CMAKE_CURRENT_LIST_LINE
The line number of the current file being processed. 🔥
It's the line number of the file that cmake is, like, currently processing.
Heads up bestie: if CMake is currently processing deferred calls scheduled by the cmake_language(DEFER) command, this variable evaluates to DEFERRED instead of an actual line number. 👑
See also CMAKE_CURRENT_FUNCTION_LIST_LINE.
CMAKE_CURRENT_SOURCE_DIR
The path to the source directory currently being processed. 🌸
Full path to the source directory that cmake is processing right now.
When you run in cmake -P script mode, CMake sets CMAKE_BINARY_DIR, CMAKE_SOURCE_DIR, CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR all to the current working directory. 🦋
Modifying CMAKE_CURRENT_SOURCE_DIR has undefined behavior. don't do it, bestie, I'm begging 😭
CMAKE_CXX_STDLIB_MODULES_JSON
Added in version 4.2.
You can use this variable to set the path to a metadata file so CMake knows how the import std target for the active CXX compiler should be constructed. 🧚
Only use this when the compiler genuinely can't discover the relevant module metadata file on its own — like, it needs the assist. 💅
CMAKE_DEBUG_TARGET_PROPERTIES
Turns on tracing output for target properties. 🔍
Populate this variable with a list of properties and you'll get debug output when those target properties get evaluated. Currently it can only be used when evaluating these target properties:
AUTOUIC_OPTIONSCOMPILE_DEFINITIONSCOMPILE_FEATURESCOMPILE_OPTIONSINCLUDE_DIRECTORIESLINK_DIRECTORIESLINK_OPTIONSPOSITION_INDEPENDENT_CODESOURCES
…and any other property listed in COMPATIBLE_INTERFACE_STRING plus the other COMPATIBLE_INTERFACE_ properties. It prints an origin for each entry in the target property. Default is unset. 🎀
CMAKE_DIRECTORY_LABELS
Added in version 3.10.
Specify labels for the current directory. ✨
This is used to initialize the LABELS directory property.
CMAKE_DL_LIBS
This variable holds the name of the dynamic loading library, or a whole list of system libraries you need in order to use the dlopen() and dlclose() functions. 🫶
A few examples of the values this gets set to:
dl— on most Unix-like systems.-lld— on AIX, prior to CMake 4.2.dld— on HP-UX.""— empty string value, or not set at all, on systems that havedl*()functions either in the default library that's implicitly linked (like BSD-like systems, Haiku, macOS, SunOS, etc.), or on systems that just don't provide these functions (looking at you, Windows). 💀
Examples
Example: Linking Dynamic Loading Library
Using this variable in a project that uses dynamic loading functionality:
target_link_libraries(example PRIVATE ${CMAKE_DL_LIBS})
Example: Checking Symbols
Checking for symbols with the dynamic loading library linked during the check:
include(CheckSymbolExists)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN)
cmake_pop_check_state()
CMAKE_DOTNET_SDK
Added in version 3.23.
Default value for the DOTNET_SDK property of targets. 🎯
This variable initializes the DOTNET_SDK property on all targets. Peep that target property for the extra details.
CMAKE_DOTNET_TARGET_FRAMEWORK
Added in version 3.17.
Default value for the DOTNET_TARGET_FRAMEWORK property of targets. 💜
This variable initializes the DOTNET_TARGET_FRAMEWORK property on all targets. See that target property for more info.
Setting CMAKE_DOTNET_TARGET_FRAMEWORK may be necessary when you're working with C# and newer .NET framework versions, so you avoid referencing errors with the ALL_BUILD CMake target. 😭
This variable is only evaluated for Visual Studio Generators — VS 2010 and above.
CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
Added in version 3.12.
Default value for the DOTNET_TARGET_FRAMEWORK_VERSION property of targets. 🌈
This variable initializes the DOTNET_TARGET_FRAMEWORK_VERSION property on all targets. See that target property for extra info. And when it's set, CMAKE_DOTNET_TARGET_FRAMEWORK takes precedence over this variable — check that variable or the associated target property DOTNET_TARGET_FRAMEWORK for more. 👑
Setting CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION may be necessary when working with C# and newer .NET framework versions to dodge referencing errors with the ALL_BUILD CMake target.
This variable is only evaluated for Visual Studio Generators — VS 2010 and above. periodt. 💅
CMAKE_EDIT_COMMAND
Full path to cmake-gui(1) or ccmake(1). 🎀
It's defined only for Makefile Generators and Ninja Generators, and only when you're not using any Extra Generators.
So yeah — it's the full path to the CMake executable that can graphically edit the cache. Like cmake-gui(1) or ccmake(1). iconic ✨
CMAKE_EXECUTABLE_SUFFIX
The suffix for executables on the target platform. 🦋
The suffix to slap on the end of an executable filename, if there is one — .exe on Windows.
CMAKE_EXECUTABLE_SUFFIX_<LANG> overrides this for language <LANG>.
See the CMAKE_HOST_EXECUTABLE_SUFFIX variable for the executable suffix on the host platform. 💫
CMAKE_EXECUTABLE_SUFFIX_<LANG>
The suffix to use at the end of an executable filename for <LANG> compiler target architecture, if any. 🌸
It overrides CMAKE_EXECUTABLE_SUFFIX for language <LANG>.
CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
Extra suffixes for shared libraries. 🎁
These are extensions for shared libraries other than the one specified by CMAKE_SHARED_LIBRARY_SUFFIX, if there are any. CMake uses this to recognize external shared library files while it's analyzing the libraries linked by a target. 🔍
CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE
Added in version 4.2.
Enables FASTBuild's AllowResponseFile option. ✨
See the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html for more info.
CMAKE_FASTBUILD_CACHE_PATH
Added in version 4.2.
Specifies the directory for the FASTBuild artifact cache in the generated file. 🗂️
If it's not set, FASTBuild will use the FASTBUILD_CACHE_PATH environment variable at build time.
See the FASTBuild caching documentation at https://www.fastbuild.org/docs/features/caching.html for more. 💅
CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV
Added in version 4.2.
Controls capturing of the system environment into fbuild.bff. 🫶
Setting it to OFF makes the invocation of all tools (compilers and other external processes) hermetic.
⚠️ Setting this variable toOFFcan break MSVC toolchains that rely on environment variables such asINCLUDEorLIBunless those are manually configured elsewhere. no cap, be careful 😭
Defaults to ON.
CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG
Added in version 4.2.
Enables FASTBuild's ClangGCCUpdateXLanguageArg option. 🔥
See the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html for more info.
CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES
Added in version 4.2.
Enables FASTBuild's ClangRewriteIncludes option. 🦋
See the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html for more info.
CMAKE_FASTBUILD_COMPILER_EXTRA_FILES
Added in version 4.2.
Specifies a semicolon-separated list of additional files (usually DLLs) to include in the FASTBuild Compiler() node. 📦
See the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html for more info.
CMAKE_FASTBUILD_ENV_OVERRIDES
Added in version 4.2.
Lets you override environment variables in the captured environment written to fbuild.bff. 🌈
Specify a CMake-style list of key=value pairs — those values override the corresponding variables in the environment block that FASTBuild uses while executing tools (e.g., compilers, linkers, resource compilers, etc.). 💜
Lowkey this one matters a lot, because if your tools keep grabbing the wrong binary, you can just hand them a whole fake PATH and watch the chaos stop. Fr fr.
set(CMAKE_FASTBUILD_ENV_OVERRIDES
"PATH=C:/MyTools/bin"
"TMP=C:/temp"
"MY_CUSTOM_VAR=some_value"
)
Note: this only affects the environment seen by FASTBuild-generated rules. It does not modify the environment in which CMake itself runs. So no, it's not a sneaky way to change your own shell — it's strictly a glow-up for the generated rules.
Defaults to empty (no overrides).
CMAKE_FASTBUILD_FORCE_RESPONSE_FILE
Added in version 4.2.
Turns on FASTBuild's ForceResponseFile option. That's it, that's the whole vibe.
For the deets, go read the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html.
CMAKE_FASTBUILD_IDE_ARGS
Added in version 4.2.
This is literally "what command-line arguments do we pass when invoking fbuild from IDE projects?" Set it and it's yours.
If you don't set it, these are the args that get used:
-ide -cache -summary -dist
Example of being extra:
set(CMAKE_FASTBUILD_IDE_ARGS "-ide -cache -summary -dist -clean")
CMAKE_FASTBUILD_SOURCE_MAPPING
Added in version 4.2.
Sets FASTBuild's SourceMapping_Experimental option. Experimental behavior, iconic variable name.
set(CMAKE_FASTBUILD_SOURCE_MAPPING "/another/root")
Again, the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html is where you get the full lore.
CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT
Added in version 4.2.
Okay so by default, custom commands that declare only BYPRODUCTS will always run unconditionally. Like, every single time. No vibe check, no "did anything change?" — just go. But if you set this variable, FASTBuild will rerun the command only when its inputs have changed or the byproduct file is missing. Which is the behavior you actually want like 90% of the time ngl.
Note: when this variable isOFF(the default!),BYPRODUCTSare treated similarly to how Ninja handles them — as opaque side effects — and the generator emitsExecAlwaysnodes to make sure they always run. So they always run. Yes. That's the whole point of the note.
Defaults to OFF.
CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS
Added in version 4.2.
Enables FASTBuild's UseDeterministicPaths_Experimental option. Deterministic paths are such a slay.
More info in the FASTBuild Compiler() documentation: https://www.fastbuild.org/docs/functions/compiler.html.
CMAKE_FASTBUILD_USE_LIGHTCACHE
Added in version 4.2.
Enables FASTBuild's light caching mode, which speeds up cache lookups by parsing source files directly instead of invoking the compiler preprocessor. Basically it skips the whole "ask the compiler politely" step and just reads the vibe of the file itself. Faster. Chef's kiss.
See the FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html.
CMAKE_FASTBUILD_USE_RELATIVE_PATHS
Added in version 4.2.
Enables FASTBuild's UseRelativePaths_Experimental option.
The FASTBuild Compiler() documentation at https://www.fastbuild.org/docs/functions/compiler.html has the details, bestie.
CMAKE_FASTBUILD_VERBOSE_GENERATOR
Added in version 4.2.
Enables verbose logging while FASTBuild files are being generated. Turn it on when you want to see everything 😭
Initialized by the CMAKE_FASTBUILD_VERBOSE_GENERATOR environment variable.
Defaults to OFF.
CMAKE_FIND_DEBUG_MODE
Added in version 3.17.
This one prints extra find-call information to standard error for the following commands:
find_program()find_library()find_file()find_path()find_package()
The output is designed for human consumption, not for parsing. So like, read it with your eyeballs, don't pipe it into a script. Enabling this variable is equivalent to using cmake --debug-find with the added ability to enable debugging for a subset of find calls. Targeted debugging? We love to see it.
set(CMAKE_FIND_DEBUG_MODE TRUE)
find_program(...)
set(CMAKE_FIND_DEBUG_MODE FALSE)
Default is unset.
CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG
Added in version 4.1.
So these commands will report configure log events when they experience a transition between found and not-found states, or when the result is first defined:
find_program()find_library()find_file()find_path()find_package()
The CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG boolean variable suppresses those implicit events from the configure log when you set it to a true value. It's giving "mute the notifications" energy.
set(CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG TRUE)
find_program(...)
set(CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG FALSE)
Default is unset.
CMAKE_FIND_PACKAGE_NAME
Added in version 3.1.1.
Defined by the find_package() command while it's loading a find module, to record the caller-specified package name. So it's the "who even asked for this?" record. Check the command documentation for details.
CMAKE_FIND_PACKAGE_REDIRECTS_DIR
Added in version 3.24.
This is a read-only variable, bestie, so don't get any ideas about setting it. It specifies a directory that the find_package() command will check first, before searching anywhere else for a module or config package file. And listen: a config package file in this directory will always be found in preference to any other Find module file or config package file. Always. Main character directory behavior.
The primary purpose of this variable is to facilitate integration between find_package() and FetchContent_MakeAvailable(). That latter command may create files in the CMAKE_FIND_PACKAGE_REDIRECTS_DIR directory when it populates a dependency. This lets subsequent calls to find_package() for the same dependency reuse the already-populated contents instead of trying to satisfy the dependency from somewhere external to the build. Projects may also want to write files into this directory in some situations — see "Integrating With find_package()" in the FetchContent docs for examples.
The directory that CMAKE_FIND_PACKAGE_REDIRECTS_DIR points to will always be erased and recreated empty at the start of every CMake run. So any files you write into it during a CMake run will be gone the next time CMake configures the project. Gone. Deleted. Not coming back. 😭 Plan accordingly.
CMAKE_FIND_PACKAGE_REDIRECTS_DIR is only set in CMake project mode. It is not set when CMake is run in script mode (i.e. cmake -P).
CMAKE_FIND_PACKAGE_SORT_DIRECTION
Added in version 3.7.
Changed in version 4.2: the default sort direction has changed from DEC to ASC.
This is the sorting direction used by CMAKE_FIND_PACKAGE_SORT_ORDER. It can assume one of the following values:
ASC— ordering is done in ascending mode. The lowest folder found will be tested first.DEC— default. Ordering is done in descending mode. The highest folder found will be tested first.
IfCMAKE_FIND_PACKAGE_SORT_ORDERis set toNONE, this variable has no effect. Zero. None. It's just sitting there looking pretty.
CMAKE_FIND_PACKAGE_SORT_ORDER
Added in version 3.7.
Changed in version 4.2: the default sort order has changed from NONE to NATURAL.
This is the default order for sorting directories that match a search path containing a glob expression found using find_package(). It can assume one of the following values:
NONE— no attempt is done to sort directories. The first valid package found will be selected. First come, first served.NAME— sort directories lexicographically before searching.NATURAL— default. Sort directories using natural order (seestrverscmp(3)manual), i.e. such that contiguous digits are compared as whole numbers.
Natural sorting is employed by default to return the highest version when multiple versions of the same library are available to be found by find_package(). Obsessed honestly. For example, suppose the following libraries have package configuration files on disk, in a directory of the same name, with all such directories residing in the same parent directory:
libX-1.1.0libX-1.2.9libX-1.2.10
The default order of NATURAL will select the one with the highest version number, i.e. libX-1.2.10. (And yes, that's the correct answer — lexicographic sorting would've fumbled this so bad and picked libX-1.2.9.)
The sort direction can be controlled using the CMAKE_FIND_PACKAGE_SORT_DIRECTION variable (by default descending, i.e. libX-1.2 will be tested before libX-1.0 and lib-B will be tested before lib-A).
CMAKE_FIND_REQUIRED
Added in version 4.1.
If enabled, the following commands are treated as having the REQUIRED keyword unless they're provided with the OPTIONAL keyword:
find_package()find_program()find_library()find_path()find_file()
When find_package() loads a Find<PackageName>.cmake or <PackageName>Config.cmake module, the CMAKE_FIND_REQUIRED variable is automatically unset within it to restore the default behavior for nested find operations. The module is free to set the CMAKE_FIND_REQUIRED variable itself to opt-in to the behavior. Consent-based inheritance, we respect that.
Heads up: enabling this variable breaks some commonly used patterns. Multiple calls to find_package() are sometimes used to obtain a different search order to the default. So like, this is powerful but it will mess with your existing setup. Not a drill.
See also the CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> variable for making a find_package() call REQUIRED, and for additional information on how enabling these variables can break commonly used patterns.
CMAKE_GENERATOR
The generator used to build the project. See cmake-generators(7).
Basically: the name of the generator that is being used to generate the build files. (e.g. Unix Makefiles, Ninja, etc.) — you know, the whole "who's doing the actual building" question.
The value of this variable should never be modified by project code. Like ever. A generator may be selected via thecmake -Goption, interactively incmake-gui(1), or via theCMAKE_GENERATORenvironment variable. Those are the doors. Use them.
CMAKE_GENERATOR_INSTANCE
Added in version 3.11.
Generator-specific instance specification provided by the user.
Some CMake generators support selection of an instance of the native build system when multiple instances are available. If the user specifies an instance (e.g. by setting this cache entry or via the CMAKE_GENERATOR_INSTANCE environment variable), or after a default instance is chosen when a build tree is first configured, the value will be available in this variable. Slay.
The value of this variable should never be modified by project code, okay? Like, hands off. 🙅♀️ A toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable may initialize CMAKE_GENERATOR_INSTANCE as a cache entry. But once a given build tree has been initialized with a particular value for this variable, changing the value has undefined behavior — and undefined behavior is not the vibe. 💀
Instance specification is supported only on specific generators. (Not all of them, bestie. Some generators just don't get the aux cord. 😭)
💻 Visual Studio Instance Selection
So the Visual Studio Generators support instance specification for Visual Studio 2017 and above ✨. The CMAKE_GENERATOR_INSTANCE variable may be set as a cache entry selecting an instance of Visual Studio via one of these forms:
locationlocation[,key=value]*key=value[,key=value]*
The location specifies the absolute path to the top-level directory of the VS installation. 📁
The key=value pairs form a comma-separated list of options to specify details of the instance selection. Supported pairs are:
version=<major>.<minor>.<date>.<build>— Added in version 3.23. Specify the 4-component VS Build Version, a.k.a. Build Number.
The components are:
<major>.<minor>— The VS major and minor version numbers. These are the same as the release version numbers.<date>— A build date in the formatMMMDD, whereMMMis a month index since an epoch used by Microsoft, andDDis a day in that month.<build>— A build index on the day represented by<date>.
The build number is reported by vswhere as installationVersion. For example, VS 16.11.10 has build number 16.11.32126.315. 🔥
Added in version 3.23: A portable VS instance, which is not known to the Visual Studio Installer, may be specified by providing both location and version=. 👑
If the value of CMAKE_GENERATOR_INSTANCE is not specified explicitly by the user or a toolchain file, CMake queries the Visual Studio Installer to locate VS instances, chooses one, and sets the variable as a cache entry to hold the value persistently. If an environment variable of the form VS##0COMNTOOLS, where ## the Visual Studio major version number, is set and points to the Common7/Tools directory within one of the VS instances, that instance will be used. Otherwise, if more than one VS instance is installed we do not define which one is chosen by default. 🙈 (So if your build picks the wrong one, that's just... the mystery of it.)
The VS version build number of the selected VS instance is provided in the CMAKE_VS_VERSION_BUILD_NUMBER variable. 📌
🎯 CMAKE_GENERATOR_PLATFORM
Added in version 3.1.
Generator-specific target platform specification provided by user. 💅
Some CMake generators support a target platform name to be given to the native build system to choose a compiler toolchain. If the user specifies a platform name (e.g. via the cmake -A option or via the CMAKE_GENERATOR_PLATFORM environment variable) the value will be available in this variable.
The value of this variable should never be modified by project code. 🚫 A toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable may initialize CMAKE_GENERATOR_PLATFORM. Once a given build tree has been initialized with a particular value for this variable, changing the value has undefined behavior. (Yeah, again. Y'all know the drill by now. 😭)
Platform specification is supported only on specific generators:
- For Visual Studio Generators with VS 2005 and above this specifies the target architecture.
- For
Green Hills MULTIthis specifies the target architecture.
See native build system documentation for allowed platform names. 📖
🪟 Visual Studio Platform Selection
The Visual Studio Generators support platform specification using one of these forms:
platformplatform[,key=value]*key=value[,key=value]*
The platform specifies the target platform (VS target architecture), such as x64, ARM64, or Win32. The selected platform name is provided in the CMAKE_VS_PLATFORM_NAME variable. 🌸
The key=value pairs form a comma-separated list of options to specify generator-specific details of the platform selection. Supported pairs are:
version=<version>— Added in version 3.27. Specify the Windows SDK version to use. This is supported by VS 2015 and above when targeting Windows or Windows Store. CMake will set theCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSIONvariable to the selected SDK version.
The <version> may be one of:
10.0— Specify that any10.0SDK version may be used, and let Visual Studio pick one. This is supported by VS 2019 and above.10.0.<build>.<increment>— Specify the exact 4-component SDK version, e.g.,10.0.19041.0. The specified version of the SDK must be installed. It may not exceed the value ofCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM, if that variable is set.8.1— Specify the8.1SDK version. This is always supported by VS 2015. On VS 2017 and above the8.1SDK must be installed.
If the version field is not specified, CMake selects a version as described in the CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION variable documentation. 🫶
🛠️ CMAKE_GENERATOR_TOOLSET
Native build system toolset specification provided by user.
Some CMake generators support a toolset specification to tell the native build system how to choose a compiler. If the user specifies a toolset (e.g. via the cmake -T option or via the CMAKE_GENERATOR_TOOLSET environment variable) the value will be available in this variable.
The value of this variable should never be modified by project code. ✋ A toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable may initialize CMAKE_GENERATOR_TOOLSET. Once a given build tree has been initialized with a particular value for this variable, changing the value has undefined behavior.
Toolset specification is supported only on specific generators:
- Visual Studio Generators for VS 2010 and above
- The
Xcodegenerator for Xcode 3.0 and above - The
Green Hills MULTIgenerator
See native build system documentation for allowed toolset names. 🌈
🧰 Visual Studio Toolset Selection
The Visual Studio Generators support toolset specification using one of these forms:
toolsettoolset[,key=value]*key=value[,key=value]*
The toolset specifies the toolset name. The selected toolset name is provided in the CMAKE_VS_PLATFORM_TOOLSET variable. ✨
The key=value pairs form a comma-separated list of options to specify generator-specific details of the toolset selection. Supported pairs are:
cuda=<version>|<path>— Specify the CUDA toolkit version to use or the path to a standalone CUDA toolkit directory. Supported by VS 2010 and above. The version can only be used with the CUDA toolkit VS integration globally installed. See theCMAKE_VS_PLATFORM_TOOLSET_CUDAandCMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIRvariables.fortran=<compiler>— Added in version 3.29. Specify the Fortran compiler to use, among those that have the required Visual Studio Integration feature installed. The value may be one of:ifort— Intel classic Fortran compiler.ifx— Intel oneAPI Fortran compiler.
See the CMAKE_VS_PLATFORM_TOOLSET_FORTRAN variable.
host=<arch>— Specify the host tools architecture asx64orx86. Supported by VS 2013 and above. See theCMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTUREvariable.version=<version>— Specify the toolset version to use. Supported by VS 2017 and above with the specified toolset installed. See theCMAKE_VS_PLATFORM_TOOLSET_VERSIONvariable.VCTargetsPath=<path>— Specify an alternativeVCTargetsPathvalue for Visual Studio project files. This allows use of VS platform extension configuration files (.propsand.targets) that are not installed with VS.
⚠️ Visual Studio Toolset Customization
Okay bestie, real talk: these are unstable interfaces with no compatibility guarantees because they hook into undocumented internal CMake implementation details. 😬 Institutions may use these to internally maintain support for non-public Visual Studio platforms and toolsets, but must accept responsibility to make updates as changes are made to CMake. (You break it, you bought it energy fr fr.)
Additional key=value pairs are available:
customFlagTableDir=<path>— Added in version 3.21. Specify the absolute path to a directory from which to load custom flag tables stored as JSON documents with file names of the form<platform>_<toolset>_<tool>.jsonor<platform>_<tool>.json, where<platform>is theCMAKE_VS_PLATFORM_NAME,<toolset>is theCMAKE_VS_PLATFORM_TOOLSET, and<tool>is the tool for which the flag table is meant. This naming pattern is an internal CMake implementation detail. The<tool>names are undocumented. The format of the.jsonflag table files is undocumented. 💀 (Yes. Both. Undocumented. Don't come for me.)
📚 CMAKE_IMPORT_LIBRARY_PREFIX
The prefix for import libraries that you link to.
The prefix to use for the name of an import library if used on this platform.
CMAKE_IMPORT_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>. 💖
📚 CMAKE_IMPORT_LIBRARY_SUFFIX
The suffix for import libraries that you link to.
The suffix to use for the end of an import library filename if used on this platform.
CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>. 🎀
CMAKE_JOB_POOL_COMPILE
Okay so this one is a little default-setter 💅 — it's the value used to initialize the JOB_POOL_COMPILE property on all the targets. That's literally every target, bestie, no exceptions. If you want the whole tea on what that property actually does, go read JOB_POOL_COMPILE. 🫶
CMAKE_JOB_POOL_LINK
Same vibe, different pool: this initializes the JOB_POOL_LINK property on all the targets. Additional info lives over at JOB_POOL_LINK, go sip. ✨
CMAKE_JOB_POOL_PRECOMPILE_HEADER
Added in version 3.17.
Precompiled headers getting their own job pool era 🎀 — this variable initializes the JOB_POOL_PRECOMPILE_HEADER property on all the targets. See JOB_POOL_PRECOMPILE_HEADER for the full story.
CMAKE_JOB_POOLS
Added in version 3.11.
Backup-plan energy: if the JOB_POOLS global property is not set, then the value of this variable is used in its place. That's it, that's the whole job. See JOB_POOLS for additional information. 💖
CMAKE_<LANG>_COMPILER_AR
Added in version 3.9.
It's a wrapper around ar that adds the appropriate --plugin option for the compiler. Lowkey iconic, does the fiddly bit for you. 🧚
See also CMAKE_AR.
CMAKE_<LANG>_COMPILER_ARCHITECTURE_ID
Added in version 3.10.
A [list](cmake-language-lists) of identifiers telling you the target architecture(s) of the compiler for language <LANG>. 🦋
Typically the list has exactly one entry — unless CMAKE_OSX_ARCHITECTURES lists multiple architectures, in which case it can be more. A whole lil squad of architectures.
The possible values for each platform are documented in the sections below, so keep scrolling babes. 👑
Apple Platforms
Added in version 4.1.
These identifiers are used when CMAKE_<LANG>_COMPILER targets an Apple platform (__APPLE__ is defined). 🍎
arm64— ARM 64-bitarm64e— ARM 64-bit with Pointer Authentication (PACs)arm64_32— ARM 64-bit with 32-bit pointers (watchOS)armv5,armv6,armv7,armv7k,armv7s— ARM 32-biti386,i486,i586,i686— Intel 32-bitppc— PowerPC 32-bitx86_64— Intel 64-bit
UNIX Platforms
Added in version 4.1.
These identifiers are used when CMAKE_<LANG>_COMPILER targets a UNIX platform.
aarch64— ARM 64-bitalpha— DEC Alphaarmv5,armv6,armv7— ARM 32-biti386,i486,i586,i686— Intel 32-bitia64— Itanium 64-bitloongarch32— LoongArch 32-bitloongarch64— LoongArch 64-bitm68k— Motorola 68000mips— MIPS 32-bit big-endianmipsel— MIPS 32-bit little-endianmips64— MIPS 64-bit big-endianmips64el— MIPS 64-bit little-endianparisc— PA-RISC 32-bitparisc64— PA-RISC 64-bitppc— PowerPC 32-bit big-endianppcle— PowerPC 32-bit little-endianppc64— PowerPC 64-bit big-endianppc64le— PowerPC 64-bit little-endianriscv32— RISC-V 32-bitriscv64— RISC-V 64-bits390,s390x— IBM Zsparc— SPARC 32-bitsparcv9— SPARC 64-bitsw_64— Sunwaywasm32— WebAssembly (Emscripten) 32-bitwasm64— WebAssembly (Emscripten) 64-bitx86_64— Intel 64-bit
Windows Platforms with GNU ABI (MinGW)
Added in version 4.1.
These identifiers are used when CMAKE_<LANG>_COMPILER targets Windows with a GNU ABI (_WIN32 and __MINGW32__ are defined). 🪟
aarch64— ARM 64-bitarmv7— ARM 32-biti386,i486,i586,i686— Intel 32-bitx86_64— Intel 64-bit
Windows Platforms with MSVC ABI
Added in version 3.10.
These identifiers are used when CMAKE_<LANG>_COMPILER targets Windows with a MSVC ABI (_WIN32 and _MSC_VER are defined).
ARM64— ARM 64-bitARM64EC— ARM 64-bit Emulation-CompatibleARMV4I,ARMV5I,ARMV7— ARM 32-bitIA64— Itanium 64-bitMIPS— MIPSSHx,SH3,SH3DSP,SH4,SH5— SuperHx64— Intel 64-bitX86— Intel 32-bit
Windows Platforms with Watcom ABI
Added in version 3.10.
These identifiers are used when CMAKE_<LANG>_COMPILER_ID is OpenWatcom or Watcom.
I86— Intel 16-bitX86— Intel 32-bit
Green Hills MULTI Platforms
Added in version 3.14.
These identifiers are used when CMAKE_<LANG>_COMPILER_ID is GHS.
ARM— ARM 32-bitPPC— PowerPC 32-bitPPC64— PowerPC 64-bitx64— Intel 64-bitX86— Intel 32-bit
IAR Platforms
Added in version 3.10.
These identifiers are used when CMAKE_<LANG>_COMPILER_ID is IAR. 🌸
8051— Intel 8051-compatible 8-bitARM— ARM 32-/64-bitAVR— Microchip AVR 8-bitMSP430— Texas Instruments MSP430 16-bitRH850— Renesas Electronics RH850 32-bitRISCV— RISC-V 32-/64-bitRL78— Renesas Electronics RL78 16-bitRX— Renesas Electronics RX 32-bitSTM8— STMicroelectronics STM8 8-bitV850— Renesas Electronics V850 32-bit
Renesas Compiler Platforms
Added in version 4.1.
These identifiers are used when CMAKE_<LANG>_COMPILER_ID is Renesas.
RH850— Renesas Electronics RH850RL78— Renesas Electronics RL78RX— Renesas Electronics RX
TASKING Platforms
Added in version 3.25.
These identifiers are used when CMAKE_<LANG>_COMPILER_ID is Tasking.
8051ARCARMMCSPCPTriCore
Texas Instruments Platforms
Added in version 3.19.
These identifiers are used when CMAKE_<LANG>_COMPILER_ID is TI.
ARMBlackfinMSP430SHARCTMS320C28xTMS320C6x
CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT
Added in version 3.14.
The identification string of the compiler frontend variant. 😭 This one needs a sec to explain, okay?
Some compilers have multiple, different frontends for accepting command line options. Example time: Clang originally only had a frontend compatible with the GNU compiler, but since its port to Windows (Clang-Cl) it now also supports a frontend compatible with MSVC. So when CMake detects such a compiler, it sets this variable to what would have been the CMAKE_<LANG>_COMPILER_ID for the compiler whose frontend it resembles. 🎀
Note: In other words, this variable describes what command line options and language extensions the compiler frontend expects.
Changed in version 3.26: This variable is set for GNU, MSVC, and AppleClang compilers that have only one frontend variant. (Yes, even the single-frontend girlies get it now. 💅)
CMAKE_<LANG>_COMPILER_LINKER
Added in version 3.29.
The full path to the linker for LANG. 🦋 This is the command that will be used as the <LANG> linker.
Real talk though: this variable is not guaranteed to be defined for all linkers or languages. So maybe check before you build your whole personality on it.
Note: This variable is read-only. It must not be set by the user. If you want to pick a specific linker, use theCMAKE_LINKER_TYPEvariable or theLINKER_TYPEtarget property. Don't fight the variable, bestie. ✨
CMAKE_<LANG>_COMPILER_LINKER_FRONTEND_VARIANT
Added in version 3.29.
Identification string of the linker frontend variant.
Same situation as the compiler one but for linkers, and it's giving déjà vu: some linkers have multiple, different frontends for accepting command line options. For example, LLVM LLD originally only had a frontend compatible with the GNU compiler, but since its port to Windows (lld-link), it now also supports a frontend compatible with MSVC. When CMake detects such a linker, it sets this variable to what would have been the CMAKE_<LANG>_COMPILER_LINKER_ID for the linker whose frontend it resembles. 🔥
Note: In other words, this variable describes what command line options and language extensions the linker frontend expects.
CMAKE_<LANG>_COMPILER_LINKER_ID
Added in version 3.29.
Linker identification string. 🫶
A short string unique to the linker vendor. Possible values include:
AIX— AIX system linkerAppleClang— Apple ClangLLD— LLVM LLD (https://lld.llvm.org)GNU— GNU Binutils - ld linker (https://sourceware.org/binutils) (also known as bfd)GNUgold— GNU Binutils - gold linker (https://sourceware.org/binutils)MSVC— Microsoft Visual Studio (https://visualstudio.microsoft.com)MOLD— mold: A Modern Linker (https://github.com/rui314/mold), or on Apple the sold (https://github.com/bluewhalesystems/sold) linkerSolaris— SunOS system linkerWILD— wild (https://github.com/wild-linker/wild) linkerOpenWatcom— OpenWatcom wlink (https://www.openwatcom.com/) linker
Quick heads-up bestie: this variable is not guaranteed to be defined for all linkers or languages. So like, vibe check it before you rely on it. 🙈
🧚 CMAKE_<LANG>_COMPILER_LINKER_VERSION
✨ Added in version 3.29.
Linker version string, periodt.
Format is major[.minor[.patch[.tweak]]] — yes, those brackets are nested like that, don't @ me.
Same caveat as above: this variable is not guaranteed to be defined for all linkers or languages. 😭
🎀 CMAKE_<LANG>_COMPILER_RANLIB
✨ Added in version 3.9.
A wrapper around ranlib that adds the appropriate --plugin option for the compiler. It's giving "middleman but make it useful." 💅
See also CMAKE_RANLIB.
💀 CMAKE_<LANG>_DEVICE_LINK_MODE
✨ Added in version 4.0.
Defines how the device link step is done. The possible values are:
DRIVER— the compiler is used as driver for the device link step.LINKER— the linker is used directly for the device link step.
This variable is read-only. Setting it is undefined behavior — like, do not touch, bestie, I'm so serious. ⚠️
🌸 CMAKE_<LANG>_LINK_LIBRARY_SUFFIX
✨ Added in version 3.16.
Language-specific suffix for libraries that you link to.
Specifically, the suffix to use for the end of a library filename — .lib on Windows. Slay. 🪟
🦋 CMAKE_<LANG>_LINK_MODE
✨ Added in version 4.0.
Defines how the link step is done. The possible values are:
DRIVER— the compiler is used as driver for the link step.LINKER— the linker is used directly for the link step.
This variable is read-only. Setting it is undefined behavior — no cap, leave it alone. 🛑
See Also
- The
CMAKE_<LANG>_USING_LINKER_<TYPE>variable.
💜 CMAKE_LINK_LIBRARY_SUFFIX
The suffix for libraries that you link to.
It's the suffix to use for the end of a library filename — .lib on Windows. (Yes, it's basically the non-language-specific twin of the one above, iconic.) ✨
🔥 CMAKE_LINK_SEARCH_END_STATIC
✨ Added in version 3.4.
Ends a link line such that static system libraries are used.
Okay so some linkers support switches such as -Bstatic and -Bdynamic to determine whether to use static or shared libraries for -lXXX options. CMake uses these options to set the link type for libraries whose full paths are not known or (in some cases) are in implicit link directories for the platform.
By default CMake adds an option at the end of the library list (if necessary) to set the linker search type back to its starting type. This property switches the final linker search type to -Bstatic regardless of how it started.
This variable is used to initialize the target property LINK_SEARCH_END_STATIC for all targets. If set, its value is also used by the try_compile() command.
See also CMAKE_LINK_SEARCH_START_STATIC.
🌈 CMAKE_LINK_SEARCH_START_STATIC
✨ Added in version 3.4.
Assumes the linker looks for static libraries by default.
Same lore as above: some linkers support switches such as -Bstatic and -Bdynamic to determine whether to use static or shared libraries for -lXXX options. CMake uses these options to set the link type for libraries whose full paths are not known or (in some cases) are in implicit link directories for the platform.
By default the linker search type is assumed to be -Bdynamic at the beginning of the library list. This property switches the assumption to -Bstatic. It is intended for use when linking an executable statically (e.g. with the GNU -static option).
This variable is used to initialize the target property LINK_SEARCH_START_STATIC for all targets. If set, its value is also used by the try_compile() command.
See also CMAKE_LINK_SEARCH_END_STATIC.
🍓 CMAKE_LIST_FILE_NAME
✨ Added in version 4.0.
The name of the CMake project files. This determines the top-level file processed when CMake is configured, and the file processed by add_subdirectory().
By default, this is CMakeLists.txt. If set to anything else, CMakeLists.txt will be used as a fallback whenever the specified file cannot be found within a project subdirectory.
This variable reports the value set via the cmake --project-file option. The value of this variable should never be set directly by projects or users. Nope. Not yours to touch. 🙅♀️
Warning: The use of alternate project file names is intended for temporary use by developers during an incremental transition and not for publication of a final product. CMake will always emit a warning when the project file is anything other than CMakeLists.txt. You've been warned, bestie. 💛
👑 CMAKE_MAJOR_VERSION
First version number component of the CMAKE_VERSION variable. That's it, that's the whole thing — tiny but mighty. ⭐
🔨 CMAKE_MAKE_PROGRAM
The tool that can launch the native build system. The value may be the full path to an executable, or just the tool name if it is expected to be in the PATH.
The tool selected depends on the CMAKE_GENERATOR used to configure the project:
- The Makefile Generators set this to
make,gmake, or a generator-specific tool (e.g.nmakefor NMake Makefiles).
These generators store CMAKE_MAKE_PROGRAM in the CMake cache so that it may be edited by the user.
- The Ninja generator sets this to
ninja.
This generator stores CMAKE_MAKE_PROGRAM in the CMake cache so that it may be edited by the user.
- The Xcode generator sets this to
xcodebuild.
This generator prefers to look up the build tool at build time rather than to store CMAKE_MAKE_PROGRAM in the CMake cache ahead of time. This is because xcodebuild is easy to find.
For compatibility with versions of CMake prior to 3.2, if a user or project explicitly adds CMAKE_MAKE_PROGRAM to the CMake cache then CMake will use the specified value.
- The Visual Studio Generators set this to the full path to
MSBuild.exeordevenv.com. (See also variablesCMAKE_VS_MSBUILD_COMMANDandCMAKE_VS_DEVENV_COMMAND.)
These generators prefer to look up the build tool at build time rather than to store CMAKE_MAKE_PROGRAM in the CMake cache ahead of time. This is because the tools are version-specific and can be located using the Visual Studio Installer. It is also necessary because the proper build tool may depend on the project content (e.g. the Intel Fortran plugin to Visual Studio requires devenv.com to build its .vfproj project files even though MSBuild.exe is normally preferred to support the CMAKE_GENERATOR_TOOLSET).
For compatibility with versions of CMake prior to 3.0, if a user or project explicitly adds CMAKE_MAKE_PROGRAM to the CMake cache then CMake will use the specified value if possible.
- The Green Hills MULTI generator sets this to the full path to
gbuild.exe(Windows) orgbuild(Linux) based upon the toolset being used.
Once the generator has initialized a particular value for this variable, changing the value has undefined behavior. ⚠️
The CMAKE_MAKE_PROGRAM variable is set for use by project code. The value is also used by the cmake --build and ctest --build-and-test tools to launch the native build process. 🚀
🧚 CMAKE_MATCH_COUNT
✨ Added in version 3.2.
The number of matches with the last regular expression. Regex girlies, this one's for you. 💖
When a regular expression match happens, CMake fills in the CMAKE_MATCH_<n> variables with the match contents. And the CMAKE_MATCH_COUNT variable holds the number of match expressions when these get filled in. cute little duo, honestly 🫶
🎯 CMAKE_MATCH_<n>
Capture group n matched by the last regular expression — for groups 0 through 9. Group 0 is the entire match, and groups 1 through 9 are the subexpressions captured by () syntax. bestie this is literally just regex muscle memory but in variable form 💅
When a regular expression match is used, CMake fills in CMAKE_MATCH_<n> variables with the match contents. The CMAKE_MATCH_COUNT variable holds the number of match expressions when these are filled.
📌 CMAKE_MINIMUM_REQUIRED_VERSION
The <min> version of CMake given to the most recent call to the cmake_minimum_required(VERSION) command in the current variable scope or any parent variable scope. it's giving "who's your daddy" but for version numbers 😭
🔢 CMAKE_MINOR_VERSION
Second version number component of the CMAKE_VERSION variable. tiny but mighty 🤏
🧾 CMAKE_NETRC
Added in version 3.11.
This variable is used to initialize the NETRC option for the file(DOWNLOAD) and file(UPLOAD) commands. See those commands for additional information. go read them, they're right there ✨
This variable is also used by the ExternalProject and FetchContent modules for internal calls to file(DOWNLOAD).
The local option takes precedence over this variable. so if you set both, the local one wins — no cap 👑
📁 CMAKE_NETRC_FILE
Added in version 3.11.
This variable is used to initialize the NETRC_FILE option for the file(DOWNLOAD) and file(UPLOAD) commands. See those commands for additional information.
This variable is also used by the ExternalProject and FetchContent modules for internal calls to file(DOWNLOAD).
The local option takes precedence over this variable. same deal, local option eats this variable for breakfast 🍓
🔍 CMAKE_OBJDUMP
Path to the objdump executable on the host system. This tool, typically part of the Binutils collection on Unix-like systems, provides information about compiled object files. it's the "what's actually inside this binary" girly 🔬
This cache variable may be populated by CMake when project languages are enabled using the project() or enable_language() commands.
See Also
- The
file(GET_RUNTIME_DEPENDENCIES)command provides a more general way to get information from runtime binaries. lowkey the glow-up version of this 🦋 - The
CPACK_OBJDUMP_EXECUTABLEvariable.
🪆 CMAKE_PARENT_LIST_FILE
Full path to the CMake file that included the current one.
While processing a CMake file loaded by include() or find_package() this variable contains the full path to the file including it.
While processing a CMakeLists.txt file, even in subdirectories, this variable is not defined. See policy CMP0198.
While processing a cmake -P script, this variable is not defined in the outermost script.
See also CMAKE_CURRENT_LIST_FILE.
ok so the ✨plot twist✨ here: in a normal CMakeLists.txt this thing just ghosts you. it's not defined. don't come for me, that's what the page says 😭
🔢 CMAKE_PATCH_VERSION
Third version number component of the CMAKE_VERSION variable. the final boss of the version triple 💀
🧬 CMAKE_PROJECT_COMPAT_VERSION
Added in version 4.3.
The compatibility version of the top level project.
This variable holds the compatibility version of the project as specified in the top level CMakeLists.txt file by a project() command. In the event that the top level CMakeLists.txt contains multiple project() calls, the most recently called one from that top level CMakeLists.txt will determine the value that CMAKE_PROJECT_COMPAT_VERSION contains. For example, consider the following top level CMakeLists.txt:
cmake_minimum_required(VERSION 4.3)
project(First VERSION 9.0 COMPAT_VERSION 1.2.3)
project(Second VERSION 9.0 COMPAT_VERSION 3.4.5)
add_subdirectory(sub)
project(Third VERSION 9.0 COMPAT_VERSION 6.7.8)
And sub/CMakeLists.txt with the following contents:
project(SubProj VERSION 2.0 COMPAT_VERSION 1.0)
message("CMAKE_PROJECT_COMPAT_VERSION = ${CMAKE_PROJECT_COMPAT_VERSION}")
The most recently seen project() command from the top level CMakeLists.txt would be project(Second ...), so this will print:
CMAKE_PROJECT_COMPAT_VERSION = 3.4.5
To obtain the version from the most recent call to project() in the current directory scope or above, see the PROJECT_COMPAT_VERSION variable. iykyk — top level only, bestie, the sub one does NOT count 🙈
📝 CMAKE_PROJECT_DESCRIPTION
Added in version 3.9.
The description of the top level project.
This variable holds the description of the project as specified in the top level CMakeLists.txt file by a project() command. In the event that the top level CMakeLists.txt contains multiple project() calls, the most recently called one from that top level CMakeLists.txt will determine the value that CMAKE_PROJECT_DESCRIPTION contains. For example, consider the following top level CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(First DESCRIPTION "I am First")
project(Second DESCRIPTION "I am Second")
add_subdirectory(sub)
project(Third DESCRIPTION "I am Third")
And sub/CMakeLists.txt with the following contents:
project(SubProj DESCRIPTION "I am SubProj")
message("CMAKE_PROJECT_DESCRIPTION = ${CMAKE_PROJECT_DESCRIPTION}")
The most recently seen project() command from the top level CMakeLists.txt would be project(Second ...), so this will print:
CMAKE_PROJECT_DESCRIPTION = I am Second
To obtain the description from the most recent call to project() in the current directory scope or above, see the PROJECT_DESCRIPTION variable. notice how it says "I am Second" and NOT "I am SubProj" — the subdirectory project is literally not even in the running 💀✨
🌐 CMAKE_PROJECT_HOMEPAGE_URL
Added in version 3.12.
The homepage URL of the top level project.
This variable holds the homepage URL of the project as specified in the top level CMakeLists.txt file by a project() command. In the event that the top level CMakeLists.txt contains multiple project() calls, the most recently called one from that top level CMakeLists.txt will determine the value that CMAKE_PROJECT_HOMEPAGE_URL contains. For example, consider the following top level CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(First HOMEPAGE_URL "https://first.example.com")
project(Second HOMEPAGE_URL "https://second.example.com")
add_subdirectory(sub)
project(Third HOMEPAGE_URL "https://third.example.com")
And sub/CMakeLists.txt with the following contents:
project(SubProj HOMEPAGE_URL "https://subproj.example.com")
message("CMAKE_PROJECT_HOMEPAGE_URL = ${CMAKE_PROJECT_HOMEPAGE_URL}")
The most recently seen project() command from the top level CMakeLists.txt would be project(Second ...), so this will print:
CMAKE_PROJECT_HOMEPAGE_URL = https://second.example.com
To obtain the homepage URL from the most recent call to project() in the current directory scope or above, see the PROJECT_HOMEPAGE_URL variable. again: top level energy only 👑
👑 CMAKE_PROJECT_NAME
The name of the top level project.
This variable holds the name of the project as specified in the top level CMakeLists.txt file by a project() command. In the event that the top level CMakeLists.txt contains multiple project() calls, the most recently called one from that top level CMakeLists.txt will determine the name that CMAKE_PROJECT_NAME contains. For example, consider the following top level CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(First)
project(Second)
add_subdirectory(sub)
project(Third)
And sub/CMakeLists.txt with the following contents:
project(SubProj)
message("CMAKE_PROJECT_NAME = ${CMAKE_PROJECT_NAME}")
The most recently seen project() command from the top level CMakeLists.txt would be project(Second), so this will print:
CMAKE_PROJECT_NAME = Second
To obtain the name from the most recent call to project() in the current directory scope or above, see the PROJECT_NAME variable. fr fr the main character of your whole build is this one 🌟
⚖️ CMAKE_PROJECT_SPDX_LICENSE
Added in version 4.3.
The license(s) of the top level project.
This variable holds the license expression of the project as specified in the top level CMakeLists.txt file by a project() command. In the event that the top level CMakeLists.txt contains multiple project() calls, the most recently called one from that top level CMakeLists.txt will determine the value that CMAKE_PROJECT_SPDX_LICENSE contains. For example, consider the following top level CMakeLists.txt:
cmake_minimum_required(VERSION 4.3)
project(First SPDX_LICENSE "BSD-3-Clause")
project(Second SPDX_LICENSE "BSD-3-Clause AND CC-BY-SA-4.0")
add_subdirectory(sub)
project(Third SPDX_LICENSE "BSD-3-Clause AND CC0-1.0")
And sub/CMakeLists.txt with the following contents:
project(SubProj SPDX_LICENSE Apache-2.0)
message("CMAKE_PROJECT_SPDX_LICENSE = ${CMAKE_PROJECT_SPDX_LICENSE}")
The most recently seen project() command from the top level CMakeLists.txt would be project(Second ...), so this will print:
CMAKE_PROJECT_SPDX_LICENSE = BSD-3-Clause AND CC-BY-SA-4.0
To obtain the version from the most recent call to project() in the current directory scope or above, see the PROJECT_SPDX_LICENSE variable.
ok yes the page says "version" in that last line for a license variable 💀 that's literally what it says, I'm not fixing it, I'm just reporting it 🫡
🔖 CMAKE_PROJECT_VERSION
Added in version 3.12.
The version of the top level project.
This variable holds the version of the project as specified in the top level CMakeLists.txt file by a project() command. In the event that the top level CMakeLists.txt contains multiple project() calls, the most recently called one from that top level CMakeLists.txt will determine the value that CMAKE_PROJECT_VERSION contains. For example, consider the following top level CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(First VERSION 1.2.3)
project(Second VERSION 3.4.5)
add_subdirectory(sub)
project(Third VERSION 6.7.8)
And sub/CMakeLists.txt with the following contents:
project(SubProj VERSION 1)
message("CMAKE_PROJECT_VERSION = ${CMAKE_PROJECT_VERSION}")
The most recently seen project() command from the top level CMakeLists.txt would be project(Second ...), so this will print:
CMAKE_PROJECT_VERSION = 3.4.5
and that's the vibe: 3.4.5, not 1, not 6.7.8 — Most Recent Top Level Call ate and left no crumbs 🍽️✨
To grab the version from the most recent call to project() in the current directory scope or above, peek at the PROJECT_VERSION variable instead. 💖
CMAKE_PROJECT_VERSION_MAJOR
Added in version 3.12.
The major version of the top level project. 👑
This one holds the major version of the project exactly as the top level CMakeLists.txt file spelled it out in a project() command. And if there's more than one project() call floating around your sources? The CMAKE_PROJECT_VERSION docs have the whole behavior breakdown for you, bestie. 💅
CMAKE_PROJECT_VERSION_MINOR
Added in version 3.12.
The minor version of the top level project.
Same deal — this holds the minor version of the project as specified in the top level CMakeLists.txt file by a project() command. Multiple project() commands in the sources? Run, don't walk, to the CMAKE_PROJECT_VERSION documentation for how that shakes out. 🦋
CMAKE_PROJECT_VERSION_PATCH
Added in version 3.12.
The patch version of the top level project.
Holds the patch version of the project as specified in the top level CMakeLists.txt file by a project() command. Yes, again: if there are multiple project() commands in the sources, please see the CMAKE_PROJECT_VERSION documentation. It's giving consistency, and we love her. 🌸
CMAKE_PROJECT_VERSION_TWEAK
Added in version 3.12.
The tweak version of the top level project.
This variable holds the tweak version of the project as specified in the top level CMakeLists.txt file by a project() command. And you already know — multiple project() commands used in the sources? See CMAKE_PROJECT_VERSION docs. Periodt. ✨
CMAKE_RANLIB
Name of the randomizing tool for static libraries.
This specifies the name of the program that randomizes libraries on UNIX. It's not used on Windows — but it may still be present there, lurking. 🙈
CMAKE_ROOT
The install directory for running cmake.
This is the install root for the running CMake, and the Modules directory lives right here. Also, this is literally the format people use it in all the time:
${CMAKE_ROOT}/Modules
CMAKE_RULE_MESSAGES
Added in version 3.13.
Specifies whether to report a message for each make rule. 🎀
If it's set in the cache, it gets used to initialize the value of the RULE_MESSAGES global property. Users can disable the option in their local build tree to turn off the granular messages and just report as each target completes, in Makefile builds. Iconic level of control, honestly.
CMAKE_SCRIPT_MODE_FILE
Full path to the cmake -P script file currently being processed.
When you run in cmake -P script mode, CMake sets this variable to the full path of the script file. When you run it to configure a CMakeLists.txt file instead? This variable is not set. Vibe check: script mode only. 💀
See Also
- The
CMAKE_ROLEglobal property provides the current running mode. 🫶
CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX
Added in version 3.31.
The suffix for archived shared libraries that you link to.
So this is the suffix you use for the end of an archive containing a shared library — and it's .a on AIX. 💅
CMAKE_SHARED_LIBRARY_PREFIX
The prefix for shared libraries that you link to.
The prefix to use for the name of a shared library. On UNIX, that's lib. 🍓
CMAKE_SHARED_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_SHARED_LIBRARY_SUFFIX
The suffix for shared libraries that you link to.
The suffix to use at the end of a shared library filename — .dll on Windows. 🔥
CMAKE_SHARED_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_SHARED_MODULE_PREFIX
The prefix for loadable modules that you link to.
The prefix to use for the name of a loadable module on this platform. 🦋
CMAKE_SHARED_MODULE_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_SHARED_MODULE_SUFFIX
The suffix for shared libraries that you link to.
The suffix to use at the end of a loadable module filename on this platform. 🌈
CMAKE_SHARED_MODULE_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_SIZEOF_VOID_P
The size of a void pointer. 🎯
This is set to the size of a pointer on the target machine, and it gets determined when a compiled language is enabled. And here's the slay detail: if a 64-bit size is found, then the library search path gets modified to look for 64-bit libraries first. Highkey important.
CMAKE_SKIP_INSTALL_RULES
Whether to disable generation of installation rules.
If it's TRUE, CMake will neither generate installation rules nor generate cmake_install.cmake files. And this variable is FALSE by default. Ngl, that default matters. 💜
CMAKE_SKIP_RPATH
If true, do not add run time path information. 😭
If this is set to TRUE, then the rpath information is not added to compiled executables. The default is to add rpath information if the platform supports it — which is what lets you easily run straight from the build tree. Obsessed with that convenience, fr fr.
Wanna omit RPATH in the install step but not the build step? UseCMAKE_SKIP_INSTALL_RPATHinstead. Wanna omit RPATH in the build step? UseCMAKE_SKIP_BUILD_RPATH. Don't mix them up, bestie. 🫶
For more info on RPATH handling, see the INSTALL_RPATH and BUILD_RPATH target properties. ✨
CMAKE_SOURCE_DIR
The path to the top level of the source tree. 👑
This is the full path to the top level of the current CMake source tree. For an in-source build, this would be the same as CMAKE_BINARY_DIR. No cap.
When you run in cmake -P script mode, CMake sets the variables CMAKE_BINARY_DIR, CMAKE_SOURCE_DIR, CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR to the current working directory. 🌀
Modifying CMAKE_SOURCE_DIR has undefined behavior. Like, do not. I'm so serious.
CMAKE_STATIC_LIBRARY_PREFIX
The prefix for static libraries that you link to.
The prefix to use for the name of a static library — lib on UNIX. 🌸
CMAKE_STATIC_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_STATIC_LIBRARY_SUFFIX
The suffix for static libraries that you link to.
The suffix to use at the end of a static library filename — .lib on Windows. 💖
CMAKE_STATIC_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_Swift_COMPILATION_MODE
Added in version 3.29.
Specifies how Swift compiles a target. This variable is used to initialize the Swift_COMPILATION_MODE property on targets as they are created. 🧚
The allowed values are:
incremental— Compiles each Swift source in the module separately, which results in better parallelism in the build. The compiler emits additional information into the build directory, improving rebuild performance when small changes are made to the source between rebuilds. This is the best option to use while iterating on changes in a project. 🔥wholemodule— Whole-module optimizations are the slowest to compile, but they result in the most optimized library. The entire context is loaded into one instance of the compiler, so there's no parallelism across source files in the module. 💀singlefile— Compiles each source in a Swift module separately, giving better parallelism. Unlike the incremental build mode, no additional information is emitted by the compiler during the build, so rebuilding after making small changes to the source file will not run faster. Use this option sparingly, preferring incremental builds — unless you're working around a compiler bug. 🐛
Use generator expressions to support per-configuration specification. For example, this code:
set(CMAKE_Swift_COMPILATION_MODE
"$<IF:$<CONFIG:Release>,wholemodule,incremental>")
sets the default Swift compilation mode to wholemodule when building a release configuration, and to incremental in other configurations. Slay. ✨
If this variable is not set, then the Swift_COMPILATION_MODE target property will not be set automatically. And if that property is unset, CMake uses the default value incremental to build the Swift source files. Default behavior, we stan.
Note: This property only has effect when policyCMP0157is set toNEWprior to the firstproject()orenable_language()command that enables the Swift language. Timing is everything, bestie. ⏰
CMAKE_Swift_MODULE_DIRECTORY
Added in version 3.15.
Swift module output directory.
This variable is used to initialize the Swift_MODULE_DIRECTORY property on all the targets. See the target property for additional information. 🦋
CMAKE_Swift_NUM_THREADS
Added in version 3.15.1.
Number of threads for parallel compilation of Swift targets. ⚡
This variable controls the number of parallel jobs that the swift driver creates for building targets. If it's not specified, it defaults to the number of logical CPUs on the host. Actually so convenient.
CMAKE_Swift_SEPARATE_MODULE_EMISSION
Added in version 4.4.
Specifies whether Swift targets emit .swiftmodule from a dedicated build edge. This variable is used to initialize the Swift_SEPARATE_MODULE_EMISSION property on targets as they are created. 🎀
When set to ON, importable Swift targets built by Ninja Generators produce the .swiftmodule from a separate -emit-module build edge, which lets downstream Swift targets compile in parallel with upstream object compilation. Parallelism? We love to see it. 🌈
If this variable is not set, separate module emission is enabled by default in targets that do not set Swift_SEPARATE_MODULE_EMISSION. See policy CMP0215.
Note: Separate module emission takes effect only when policyCMP0157is set toNEWprior to the firstproject()orenable_language()command that enables the Swift language. Same energy as before — order of operations is the whole game. 💅
CMAKE_TEST_BUILD_DEPENDS
Added in version 4.4.
Enables test_prep/<name> build targets for tests added by add_test() when using the Ninja Generators. 👑
When this variable is set to a true value, CMake generates a test_prep/<name> target for each eligible test and a test_prep/all target for all such tests. Building these targets ensures the test executable, the targets referenced by test command generator expressions, and explicit BUILD_DEPENDS entries are up-to-date before the test runs. Chef's kiss — no more flaky "wait, was it built?" moments. 🫶
Tests whose names aren't valid target names get left out of this whole situation, no cap. And if multiple tests in different directories share the same name, their dependencies get merged into a single test_prep/<name> target. Teamwork! 🫶
🧪 CMAKE_TEST_LAUNCHER ✨
<span class="mint">Added in version 3.29.</span>
Okay so this one is literally the plug for launching your tests 💅 It's the variable that initializes the TEST_LAUNCHER target property on executable targets as they're created. What's it for? Specifying a launcher for running the tests that add_test() sets up, where those tests run an executable target. Iconic behavior.
And if this variable holds a semicolon-separated list, then heads up: the first value is the command, and the remaining values are its arguments. First one drives, everybody else rides along 🚗
You can also initialize this bad girl via a CMAKE_TEST_LAUNCHER environment variable. Slay.
🛠️ CMAKE_TOOLCHAIN_FILE 🔧
Path to the toolchain file you supply to cmake(1).
So when you're cross-compiling with CMake, you specify this on the command line. It's the path to a file that gets read <span class="hotpink">early</span> in the CMake run, and it specifies locations for compilers and toolchain utilities, plus other target platform and compiler related info. Basically the whole vibe of "what machine are we even building for" lives here 🌀
Relative paths are allowed, and they're interpreted <span class="yellow">first</span> as relative to the build directory, and if that's a no-find, relative to the source directory. Two chances, queen 👑
This one is initialized by the CMAKE_TOOLCHAIN_FILE environment variable if that's set when a new build tree is first created. Very "first impression matters" of it.
Also peep CMAKE_PROJECT_TOP_LEVEL_INCLUDES if you need to set other things that aren't directly related to the toolchain. Different department, same building 🏢
🎀 CMAKE_TWEAK_VERSION 💅
Defined to 0 for compatibility with code written for older CMake versions that may have defined higher values. It's giving "we retired the position but kept the desk" 😭
Note: In CMake versions 2.8.2 through 2.8.12, this variable holds the <span class="purple">fourth</span> version number component of theCMAKE_VERSIONvariable. So old code out here expecting a number is gonna get a0and honestly? That's on them.
📢 CMAKE_VERBOSE_MAKEFILE 🔊
Enable verbose output from Makefile builds. Yes bestie, we're turning the volume UP 📣
This variable is a cache entry initialized (to FALSE) by the project() command. Users may enable the option in their local build tree to get more verbose output from Makefile builds — and it shows <span class="hotpink">each command line as it's launched</span>. Every single one. No secrets in this house 🙈
🏷️ CMAKE_VERSION 🌈
The CMake version string, made of three non-negative integer components separated by ., possibly followed by - and other information. The first two components represent the feature level, and the third component represents either a bug-fix level or a development date. Knowing which is which is the whole game, iykyk 👀
Release versions and release candidate versions of CMake use the format:
<major>.<minor>.<patch>[-rc<n>]
where the <patch> component is less than 20000000. (Big number, but not that big. Number lore 📚)
Development versions of CMake use the format:
<major>.<minor>.<date>[-<id>]
where the <date> component is of format CCYYMMDD and <id> may contain arbitrary text. This represents development as of a particular date following the <major>.<minor> feature release. It's a timestamp, it's a vibe check, it's both 💫
Individual component values are also available in variables, because sometimes you just want one fry instead of the whole bag:
CMAKE_MAJOR_VERSIONCMAKE_MINOR_VERSIONCMAKE_PATCH_VERSIONCMAKE_TWEAK_VERSION
Use the if() command's VERSION_LESS, VERSION_GREATER, VERSION_EQUAL, VERSION_LESS_EQUAL, or VERSION_GREATER_EQUAL operators to compare version string values against CMAKE_VERSION using a component-wise test. That's the correct way, bestie, please don't freelance ✋
⚠️ Version component values may be10or larger, so <span class="red">do not</span> attempt to compare version strings as floating-point numbers. Fr fr.1.10is not1.1and floating-point will betray you. It always does 💀
Note: CMake versions 2.8.2 through 2.8.12 used <span class="purple">three</span> components for the feature level. Release versions represented the bug-fix level in a fourth component, i.e.<major>.<minor>.<patch>[.<tweak>][-rc<n>]. Development versions represented the development date in the fourth component, i.e.<major>.<minor>.<patch>.<date>[-<id>]. CMake versions prior to 2.8.2 used three components for the feature level and had <span class="purple">no</span> bug-fix component. Release versions used an even-valued second component, i.e.<major>.<even-minor>.<patch>[-rc<n>]. Development versions used an odd-valued second component with the development date as the third component, i.e.<major>.<odd-minor>.<date>. Even = stable, odd = chaotic era. Love that for them 🎢 TheCMAKE_VERSIONvariable is defined by CMake 2.6.3 and higher. Earlier versions defined only the individual component variables. Ancient history, but we respect the ancestors 🫡
💻 CMAKE_VS_DEVENV_COMMAND 🖥️
The Visual Studio Generators set this variable to the devenv.com command installed with the corresponding Visual Studio version.
And listen — this variable is <span class="red">not</span> defined by other generators, even if devenv.com happens to be installed on the computer. Like, it's there, but it's not yours. Gatekeeping, honestly 🚪
See also the CMAKE_VS_MSBUILD_COMMAND and CMAKE_MAKE_PROGRAM variables. The whole friend group 🫶
🏗️ CMAKE_VS_MSBUILD_COMMAND ⚙️
The Visual Studio Generators set this variable to the MSBuild.exe command installed with the corresponding Visual Studio version.
Same deal as above: this variable is <span class="red">not</span> defined by other generators even if MSBuild.exe is installed on the computer. Presence ≠ permission, periodt 💅
See also the CMAKE_VS_DEVENV_COMMAND and CMAKE_MAKE_PROGRAM variables.
🎮 CMAKE_VS_NsightTegra_VERSION 🕹️
<span class="mint">Added in version 3.1.</span>
When you're using the Visual Studio Generators with the CMAKE_SYSTEM_NAME variable set to Android, this variable contains the version number of the installed NVIDIA Nsight Tegra Visual Studio Edition. Very niche, very specific, very much her own lane 🧚
📦 CMAKE_VS_NUGET_PACKAGE_RESTORE 🍓
<span class="mint">Added in version 3.23.</span>
When using the Visual Studio Generators, this cache variable controls if msbuild should automatically attempt to restore NuGet packages prior to a build. NuGet packages can be defined using the VS_PACKAGE_REFERENCES property on a target. And if no package references are defined, this setting will do <span class="purple">nothing</span>. Zero. Zilch. It's a togglesona with nothing to toggle 😭
The command line option --resolve-package-references can be used alternatively to control the resolve behavior globally — and heads up, <span class="hotpink">this option takes precedence over the cache variable</span>. Command line stays winning 👑
⚠️ Targets that use the DOTNET_SDK are <span class="red">required</span> to run a restore before building. Disabling this option may cause the build to fail in such projects. Not a drill, bestie — leave it on unless you know exactly what you're doing 🙏
This setting is stored as a cache entry. Default value is ON.
See also the VS_PACKAGE_REFERENCES property.
🏢 CMAKE_VS_PLATFORM_NAME 🏙️
<span class="mint">Added in version 3.1.</span>
Visual Studio target platform name used by the current generator.
VS 8 and above allow project files to specify a target platform, and CMake provides the name of the chosen platform right here in this variable. It's giving "we already picked, you're welcome" 💁♀️
See the CMAKE_GENERATOR_PLATFORM variable for details. And see also the CMAKE_VS_PLATFORM_NAME_DEFAULT variable.
🌱 CMAKE_VS_PLATFORM_NAME_DEFAULT 🌸
<span class="mint">Added in version 3.14.3.</span>
This is the <span class="cyan">default</span> for the Visual Studio target platform name for the current generator — computed without considering the value of the CMAKE_GENERATOR_PLATFORM variable. It's the "what would you have picked if nobody told you what to pick" answer 🧠
- For the Visual Studio Generators for VS 2017 and below, this is always
Win32. - For VS 2019 and above, this is based on the host platform.
See also the CMAKE_VS_PLATFORM_NAME variable — that's the one that does consider what you asked for. Two different girls, two different jobs 👯
🧰 CMAKE_VS_PLATFORM_TOOLSET 🔨
Visual Studio Platform Toolset name.
VS 10 and above use MSBuild under the hood and support multiple compiler toolchains. CMake may specify a toolset explicitly, such as v110 for VS 11, or Windows7.1SDK for 64-bit support in VS 10 Express. And CMake provides the name of the chosen toolset right here in this variable. Pick a lane, any lane 🛤️
See the CMAKE_GENERATOR_TOOLSET variable for details.
🟩 CMAKE_VS_PLATFORM_TOOLSET_CUDA ⚡
<span class="mint">Added in version 3.9.</span>
NVIDIA CUDA Toolkit version whose Visual Studio toolset to use. We're going GPU mode, bestie 🚀
The Visual Studio Generators for VS 2010 and above support using a CUDA toolset provided by a CUDA Toolkit. The toolset version number may be specified by a field in CMAKE_GENERATOR_TOOLSET of the form cuda=8.0. Or it gets automatically detected if a path to a standalone CUDA directory is specified in the form cuda=C:\path\to\cuda. If none is specified, CMake will choose a default version — it's got good taste, trust 🤌
CMake provides the selected CUDA toolset version in this variable. The value may be <span class="purple">empty</span> if no CUDA Toolkit with Visual Studio integration is installed. Sad but valid 💔
📁 CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR 🗂️
<span class="mint">Added in version 3.16.</span>
Path to a standalone NVIDIA CUDA Toolkit (eg. extracted from installer). The suitcase version, not the installed-in-the-system version 🧳
The Visual Studio Generators for VS 2010 and above support using a standalone (non-installed) NVIDIA CUDA toolkit. The path may be specified by a field in CMAKE_GENERATOR_TOOLSET of the form cuda=C:\path\to\cuda.
And the rules, because there are always rules:
- The given directory must at least contain the
nvcccompiler in path.\bin - and must provide Visual Studio integration files in path
.\extras\visual_studio_integration\MSBuildExtensions\
One can create a standalone CUDA toolkit directory by either opening an installer with 7zip or copying the files that are extracted by the running installer. Hacker-girl behavior, we love it 🕵️♀️
The value may be <span class="purple">empty</span> if no path to a standalone CUDA Toolkit was specified.
🟦 CMAKE_VS_PLATFORM_TOOLSET_FORTRAN 🧮
<span class="mint">Added in version 3.29.</span>
Fortran compiler to be used by Visual Studio projects. Yes, Fortran. She's still here and she's thriving, show some respect 👑📼
The Visual Studio Generators support selecting among Fortran compilers that have the required Visual Studio Integration feature installed. The compiler may be specified by a field in CMAKE_GENERATOR_TOOLSET of the form fortran=.... CMake provides the selected Fortran compiler in this variable.
If the field was not specified, the default depends on the generator:
- On Visual Studio 18 2026 and above, the default is
ifx. - On older Visual Studio Generators, the default is <span class="purple">empty</span>, which the Intel Visual Studio Integration interprets as equivalent to
ifort.
So "empty" here is not nothing, it's a secret message that means ifort. Communication is wild 😭💌
🧬 CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE 🖲️
<span class="mint">Added in version 3.8.</span>
Visual Studio preferred tool architecture. That's it, that's the whole sentence — short and mysterious and honestly kind of iconic for it ✨
...so the Visual Studio generators for VS 2013 and up let you pick a 32-bit or 64-bit host toolchain by dropping a host=x86 or host=x64 value into the CMAKE_GENERATOR_TOOLSET option. And CMake hands you back whichever toolchain architecture preference got selected in this variable — it'll be x86, x64, ARM64, or just empty. 💅
CMAKE_VS_PLATFORM_TOOLSET_VERSION
✨ Added in version 3.12.
It's giving… the Visual Studio Platform Toolset version. 🎀
The Visual Studio generators for VS 2017 and above are cool with you selecting minor versions of the same toolset. You specify the version number with a version=14.11-shaped field inside CMAKE_GENERATOR_TOOLSET. If you don't specify one, CMake picks a default toolset for you. And lowkey the value can be empty if no minor version was selected and the default is what's being used.
If the value isn't empty, it's the version number that MSBuild uses in its Microsoft.VCToolsVersion.*.props file names.
🌸 Added in version 3.19.7: VS 16.9's toolset can also be specified as14.28.16.9, because VS 16.10 uses the file nameMicrosoft.VCToolsVersion.14.28.16.9.props.
Three-Component MSVC Toolset Versions
✨ Added in version 3.19.7.
Okay so the version= field can take a three-component toolset version like 14.28.29910, and CMake will convert it to the name MSBuild uses for Microsoft.VCToolsVersion.*.props files. This is genuinely so useful for telling apart VS 16.8's 14.28.29333 toolset from VS 16.9's 14.28.29910 toolset — they're siblings, not twins, bestie. It also matches vcvarsall's -vcvars_ver= behavior. 👑
CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER
✨ Added in version 3.22.
Visual Studio target framework identifier, no cap.
Sometimes the Visual Studio generators will use an explicit value for the MSBuild TargetFrameworkIdentifier setting in .csproj files. CMake gives you the chosen value right here in this variable. 🫶
See also CMAKE_VS_TARGET_FRAMEWORK_VERSION and CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.
CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION
✨ Added in version 3.22.
Visual Studio target framework targets version — yes it's a different variable, don't @ me. 💀
In some cases the Visual Studio generators may use an explicit value for the MSBuild TargetFrameworkTargetsVersion setting in .csproj files, and CMake provides the chosen value in this variable.
See also CMAKE_VS_TARGET_FRAMEWORK_VERSION and CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER.
CMAKE_VS_TARGET_FRAMEWORK_VERSION
✨ Added in version 3.22.
Visual Studio target framework version. The third of the trio 🎀
In some cases, the Visual Studio generators may use an explicit value for the MSBuild TargetFrameworkVersion setting in .csproj files. CMake provides the chosen value in this variable.
Check out the CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION variable and the DOTNET_TARGET_FRAMEWORK_VERSION target property to specify custom TargetFrameworkVersion values for project targets.
See also CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER and CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.
CMAKE_VS_USE_DEBUG_LIBRARIES
✨ Added in version 3.30.
Tells the Visual Studio generators which configurations count as debug configurations. This is the puppet master behind the UseDebugLibraries setting in each configuration of a .vcxproj file. 🧚
The "Use Debug Libraries" setting in Visual Studio projects, despite its very specific-sounding name, is actually a general-purpose indicator of what configurations are considered debug configurations. In standalone projects it may affect MSBuild's default selection of MSVC runtime library, optimization flags, runtime checks, and similar settings. In CMake projects those settings are typically generated explicitly based on the project's specification — like, the MSVC runtime library is controlled by CMAKE_MSVC_RUNTIME_LIBRARY. But the UseDebugLibraries indicator is still useful for reference by both humans and tools, and it may also affect the behavior of platform-specific SDKs. 💅
Set CMAKE_VS_USE_DEBUG_LIBRARIES to a true or false value to indicate whether each configuration is considered a debug configuration. The value can also be the empty string (""), in which case no UseDebugLibraries gets added explicitly by CMake and MSBuild just uses its default value, false.
Use generator expressions for per-configuration specification. For example, this code:
set(CMAKE_VS_USE_DEBUG_LIBRARIES "$<CONFIG:Debug,Custom>")
indicates that all following targets consider their Debug and Custom configurations to be debug configurations, and their other configurations to be non-debug configurations. Slay. ✨
This variable is used to initialize the VS_USE_DEBUG_LIBRARIES property on all targets as they're created. It's also propagated by calls to the try_compile() command into its test project.
If this variable is not set, then the VS_USE_DEBUG_LIBRARIES property will not be set automatically. And if that property isn't set, CMake generates UseDebugLibraries using heuristics to figure out which configurations are debug configurations. See policy CMP0162.
CMAKE_VS_VERSION_BUILD_NUMBER
✨ Added in version 3.26.
Visual Studio version. 👑
The Visual Studio generators for VS 2017 and above set this variable to the Visual Studio version build number in the format <major>.<minor>.<date>.<build>.
The components are:
<major>.<minor>— the VS major and minor version numbers. These are the same as the release version numbers.<date>— a build date in the formatMMMDD, whereMMMis a month index since an epoch used by Microsoft, andDDis a day in that month.<build>— a build index on the day represented by<date>.
The build number is reported by vswhere as installationVersion. For example, VS 16.11.10 has build number 16.11.32126.315. 🔥
See also the CMAKE_GENERATOR_INSTANCE variable.
CMAKE_VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
✨ Added in version 3.27.
Tells the Visual Studio generators to use the Windows Target Platform Minimum Version you give it. 🎀
This variable is used to initialize the VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION property on all targets when they're created. See that target property for the extra deets.
CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
✨ Added in version 3.4.
Visual Studio Windows Target Platform Version, bestie.
When you're targeting Windows 10 and above, the Visual Studio generators for VS 2015 and above support specifying a Windows SDK version:
- If
CMAKE_GENERATOR_PLATFORMspecifies aversion=field, as documented by Visual Studio Platform Selection, that SDK version is selected. - Otherwise, if the
WindowsSDKVersionenvironment variable is set to an available SDK version, that version is selected. This is intended for use in environments established byvcvarsall.bator similar scripts.- ✨ Added in version 3.27: This is enabled by policy
CMP0149.
- ✨ Added in version 3.27: This is enabled by policy
- Otherwise, if
CMAKE_SYSTEM_VERSIONis set to an available SDK version, that version is selected.- 🦋 Changed in version 3.27: This is disabled by policy
CMP0149.
- 🦋 Changed in version 3.27: This is disabled by policy
- Otherwise, CMake uses the latest Windows SDK version available.
The chosen Windows target version number is provided in CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION. And if no Windows 10 SDK is available, this value will be empty. 😭
You can 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 Include/10.0.* directories.
See also CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM.
CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM
✨ Added in version 3.19.
Override the Windows 10 SDK Maximum Version for VS 2015 and beyond. 🌈
The CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM variable may be set to a false value (e.g. OFF, FALSE, or 0) or the SDK version to use as the maximum (e.g. 10.0.14393.0). If unset, the default depends on which version of Visual Studio is targeted by the current generator.
This can be used to exclude Windows SDK versions from consideration for CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION. 💜
CMAKE_WINDOWS_KMDF_VERSION
✨ Added in version 3.31.
Specify the Kernel-Mode Drive Framework target version. 🎀
A toolchain file that sets CMAKE_SYSTEM_NAME to WindowsKernelModeDriver must also set CMAKE_WINDOWS_KMDF_VERSION to specify the KMDF target version. No skipping, bestie — both or nothing.
CMAKE_XCODE_BUILD_SYSTEM
✨ Added in version 3.19.
Xcode build system selection, let's gooo. 🍓
The Xcode generator defines this variable to indicate which variant of the Xcode build system will be used. The value is the version of Xcode in which the corresponding build system first became mature enough for use by CMake. The possible values are:
1— the original Xcode build system. This is the default when using Xcode 11.x or below and is supported up to Xcode 13.x.12— the Xcode "new build system" introduced by Xcode 10. It became mature enough for use by CMake in Xcode 12. This is the default when using Xcode 12.x or above.
⭐ The CMAKE_XCODE_BUILD_SYSTEM variable is informational and should not be modified by project code. See the Toolset and Build System Selection documentation section to select the Xcode build system.
CMAKE_XCODE_PLATFORM_TOOLSET
Xcode compiler selection.
Okay so Xcode lets you pick a compiler from one of the installed toolsets — and CMake hands you the name of whichever toolset got chosen in this variable, but only if one was explicitly selected (like via the cmake -T option). cute, right? 💅
<PROJECT-NAME>_BINARY_DIR
Top-level binary directory for the project whose name you used. ✨
So a variable gets created using the exact name you passed to project(), and its value is that project's binary directory. Lowkey the moment when add_subdirectory() is gluing a bunch of projects together and you're like "wait, where did that one build again?" — this is your girl. 🫶
<PROJECT-NAME>_COMPAT_VERSION
Added in version 4.3. 🎀
Whatever value you gave to the COMPAT_VERSION option on the most recent call to project() with the project name <PROJECT-NAME> — if you gave one at all, that is.
<PROJECT-NAME>_DESCRIPTION
Added in version 3.12. 🌸
The value you handed to the DESCRIPTION option of the most recent project() call with project name <PROJECT-NAME>, if any.
<PROJECT-NAME>_HOMEPAGE_URL
Added in version 3.12. 🦋
The value you handed to the HOMEPAGE_URL option of the most recent project() call with project name <PROJECT-NAME>, if any.
<PROJECT-NAME>_IS_TOP_LEVEL
Added in version 3.21. ⭐
A boolean variable — classic true/false vibe check — telling you whether the named project was called in a top-level CMakeLists.txt file. 👑
Want the value from the most recentproject()call in the current directory scope or above instead? That's thePROJECT_IS_TOP_LEVELvariable. different girl, different job 💅
The value is true in:
- the top-level directory of the project
- the top-level directory of an external project added by
ExternalProject - a directory added by
add_subdirectory()that does not also contain aproject()call - a directory added by
FetchContent_MakeAvailable(), if the fetched content doesn't contain aproject()call
The value is false in:
- a directory added by
add_subdirectory()that also contains aproject()call - a directory added by
FetchContent_MakeAvailable(), if the fetched content does contain aproject()call
<PROJECT-NAME>_SOURCE_DIR
Top-level source directory for the named project. 🗂️
A variable is created with the name used in the project() command, and it holds the source directory for that project. Same deal as the binary one — chef's kiss when add_subdirectory() is linking multiple projects together and you need to know where a project actually lives.
<PROJECT-NAME>_SPDX_LICENSE
Added in version 4.3. 🎀
The value given to the SPDX_LICENSE option of the most recent call to project() with project name <PROJECT-NAME>, if any.
<PROJECT-NAME>_VERSION
The value you gave to the VERSION option of the most recent call to project() with project name <PROJECT-NAME>, if any. 🔥
Also peep the component-wise version variables: <PROJECT-NAME>_VERSION_MAJOR, <PROJECT-NAME>_VERSION_MINOR, <PROJECT-NAME>_VERSION_PATCH, and <PROJECT-NAME>_VERSION_TWEAK.
<PROJECT-NAME>_VERSION_MAJOR
First version number component of the <PROJECT-NAME>_VERSION variable, as set by the project() command. 1️⃣
<PROJECT-NAME>_VERSION_MINOR
Second version number component of the <PROJECT-NAME>_VERSION variable, as set by the project() command. 2️⃣
<PROJECT-NAME>_VERSION_PATCH
Third version number component of the <PROJECT-NAME>_VERSION variable, as set by the project() command. 3️⃣
<PROJECT-NAME>_VERSION_TWEAK
Fourth version number component of the <PROJECT-NAME>_VERSION variable, as set by the project() command. 4️⃣
PROJECT_BINARY_DIR
Full path to the build directory for the project. 🏗️
Specifically: the binary directory of the most recent project() command.
PROJECT_COMPAT_VERSION
Added in version 4.3. 🌈
The value given to the COMPAT_VERSION option of the most recent call to project(), if any. Want the compatibility version of the top level project instead? Go see the CMAKE_PROJECT_COMPAT_VERSION variable. ✨
PROJECT_DESCRIPTION
Added in version 3.9. 💜
Short project description given to the project command. 📝
This is the description from the most recently called project() command in the current directory scope or above. For the top level project's description, the variable you want is CMAKE_PROJECT_DESCRIPTION.
PROJECT_HOMEPAGE_URL
Added in version 3.12. 🔗
The homepage URL of the project. 🌐
This is the homepage URL given to the most recently called project() command in the current directory scope or above. Need the top level project's homepage URL? That's CMAKE_PROJECT_HOMEPAGE_URL.
PROJECT_IS_TOP_LEVEL
Added in version 3.21. 👑
A boolean variable that tells you whether the most recently called project() command in the current scope or above happened in the top level CMakeLists.txt file.
Why do you care? Because some modules should only get included as part of the top level CMakeLists.txt — otherwise they cause unintended side effects in your build tree 😭 — and this variable is literally the switch you use to conditionally run that code. Classic example: the CTest module, which creates targets and options:
project(MyProject)
...
if(PROJECT_IS_TOP_LEVEL)
include(CTest)
endif()
The value is true in:
- the top-level directory of the project
- the top-level directory of an external project added by
ExternalProject - a directory added by
add_subdirectory()that does not also contain aproject()call - a directory added by
FetchContent_MakeAvailable(), if the fetched content doesn't contain aproject()call
The value is false in:
- a directory added by
add_subdirectory()that also contains aproject()call - a directory added by
FetchContent_MakeAvailable(), if the fetched content does contain aproject()call
PROJECT_NAME
Name of the project given to the project command. 🏷️
This is the name from the most recently called project() command in the current directory scope or above. Want the top level project's name? That's CMAKE_PROJECT_NAME, bestie.
PROJECT_SOURCE_DIR
This one is the source directory of the last project() call made in the current directory scope or one of its parents. 📁
Heads up fr fr: it is not affected byproject()calls made inside a child directory scope — i.e. from within anadd_subdirectory()call made from the current scope. so don't get it twisted 💅
PROJECT_SPDX_LICENSE
Added in version 4.3. 🎀
The value given to the SPDX_LICENSE option of the most recent call to project(), if any. For the top level project's one, see the CMAKE_PROJECT_SPDX_LICENSE variable.
PROJECT_VERSION
The value given to the VERSION option of the most recent call to project(), if any. 🔥
Also check the component-wise version variables PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR, PROJECT_VERSION_PATCH, and PROJECT_VERSION_TWEAK.
PROJECT_VERSION_MAJOR
First version number component of the PROJECT_VERSION variable, as set by the project() command. 1️⃣
PROJECT_VERSION_MINOR
Second version number component of the PROJECT_VERSION variable, as set by the project() command. 2️⃣
PROJECT_VERSION_PATCH
Third version number component of the PROJECT_VERSION variable, as set by the project() command. 3️⃣
PROJECT_VERSION_TWEAK
Fourth version number component of the PROJECT_VERSION variable, as set by the project() command. 4️⃣
⚡ VARIABLES THAT CHANGE BEHAVIOR ⚡
BUILD_SHARED_LIBS
Tells add_library() to default to SHARED libraries instead of STATIC ones when you call it with no explicit library type. 🎚️
Every add_library() call that doesn't specify a library type checks the current value of BUILD_SHARED_LIBS. If it's true, the default type is SHARED. Otherwise the default is STATIC. simple as that ✨
So like, this code:
add_library(example ${sources})
behaves exactly as if you'd written:
if(BUILD_SHARED_LIBS)
add_library(example SHARED ${sources})
else()
add_library(example STATIC ${sources})
endif()
CMake does not define BUILD_SHARED_LIBS by default — but projects often create a cache entry for it with the option() command:
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
That gives users a switch they can control, e.g. with cmake -D. 🫶
⚠️ If you're adding that option to your project, do it in the top levelCMakeLists.txtfile, before anyadd_library()calls. And note this: if you bring external dependencies directly into the build — like withFetchContentor a directadd_subdirectory()call — and one of those dependencies has such a call tooption(BUILD_SHARED_LIBS ...), then the top level project must also calloption(BUILD_SHARED_LIBS ...)before bringing in its dependencies. Failure to do so can lead to different behavior between the first and subsequent CMake runs. 😭 not the first-run-works-second-run-explodes pipeline
BUILD_TESTING
Controls whether the CTest module invokes enable_testing(). 🧪
Like literally, the CTest module? When it's loaded via include(CTest), it runs code that looks exactly like this:
option(BUILD_TESTING "..." ON)
if (BUILD_TESTING)
# ...
enable_testing()
# ...
endif()
So what that does is it creates a BUILD_TESTING option, and that option is the whole vibe check for whether the enable_testing() command gets invoked to turn on generation of tests you can run with ctest(1). And if you wanna actually create tests? Go see the add_test() command, bestie. 🧪
Note: pls callinclude(CTest)in the top-level source directory, becausectest(1)expects to find a test file in the top-level build directory. Don't make it go looking, it will not slay. 💅
CMAKE_ABSOLUTE_DESTINATION_FILES
A list of files that have been installed using an ABSOLUTE DESTINATION path. That's it, that's the list. 🎀
This variable is defined by the CMake-generated cmake_install.cmake scripts. Programs or scripts that source those install scripts can use it read-only (so no touching, only looking 👀). Some CPack generators use it — e.g. RPM.
CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
Added in version 3.27.
This one's a yes/no on whether DEPENDS_EXPLICIT_ONLY should be on by default inside add_custom_command().
It affects the default behavior of the add_custom_command() command. Setting this variable to ON is literally equivalent to using the DEPENDS_EXPLICIT_ONLY option in all the uses of that command. All of them. Periodt. ✨
Also see CMAKE_OPTIMIZE_DEPENDENCIES.
CMAKE_APPBUNDLE_PATH
A semicolon-separated list of directories that specifies a search path for macOS application bundles, used by the find_program() and find_package() commands. 🍎
There's also an environment variable CMAKE_APPBUNDLE_PATH, which gets used as an additional list of search directories. So it's not either/or, it's both, iykyk.
CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
Added in version 4.2.
This is a string cache variable that specifies the strategy to use for autogen target intermediate directories and everything inside them. The supported values are:
FULL— intermediate directories get named based on a<TARGET_NAME>_autogen.dirand<TARGET_NAME>_autogenpattern (with some slight deviations and sanitizations applied in various places). Object file names are based on the filename of the source file being compiled.SHORT— intermediate directories get named from a hash of the target name and the build directory location, plus an/autogensubdirectory. This one may help with projects that generate long paths in the build directory, so you can build in directories that aren't near a root path. 🦋
When it's unset, or when the named strategy isn't supported, the FULL strategy gets used.
Note: this only works as a cache variable, not a locally-scoped variable. Don't try to be cute.
This is supported by the following generators:
- Ninja Generators
- Makefile Generators
- Visual Studio Generators
Note: not all generators support all strategies, and paths may differ between generators. So like, don't @ me.
CMAKE_BUILD_TYPE
Specifies the build type on single-configuration generators (e.g. Makefile Generators or Ninja). Typical values include Debug, Release, RelWithDebInfo and MinSizeRel, but you can also define custom build types if you're feeling main character energy. 👑
This variable is initialized by the first project() or enable_language() command called in a project, when a new build tree is first created. If the CMAKE_BUILD_TYPE environment variable is set, its value gets used. Otherwise, a toolchain-specific default is chosen when a language is enabled. That default is often an empty string — but ngl, that's usually not desirable, and one of the other standard build types is usually way more appropriate. 😭
Depending on the situation, the value of this variable may be treated case-sensitively or case-insensitively. See Build Configurations for the discussion of this and other related topics.
For multi-config generators, go see CMAKE_CONFIGURATION_TYPES.
CMAKE_CLANG_VFS_OVERLAY
Added in version 3.19.
When you're cross compiling for windows with clang-cl, this variable can be an absolute path pointing to a clang virtual file system yaml file — and that enables clang-cl to resolve windows header names on a case sensitive file system. Iconic problem-solving fr fr. 🧚
CMAKE_CODEBLOCKS_COMPILER_ID
Added in version 3.11.
Changes the compiler id in the generated CodeBlocks project files.
CodeBlocks uses its own compiler id string, which differs from CMAKE_<LANG>_COMPILER_ID. If you leave this variable empty, CMake tries to recognize the CodeBlocks compiler id automatically. Otherwise, the string you specified gets used in the CodeBlocks project file. Wanna know what's valid? See the CodeBlocks documentation for valid compiler id strings. 📝
Other IDEs like QtCreator that also use the CodeBlocks generator may just ignore this setting entirely — rude, but okay.
CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
Added in version 3.10.
Changes the way the CodeBlocks generator creates project files.
If this variable evaluates to ON, the generator excludes from the project file any files that are located outside the project root. Bye bestie, you're not in this clique. ✌️
CMAKE_CODELITE_USE_TARGETS
Added in version 3.7.
Changes the way the CodeLite generator creates projectfiles. (Yes, projectfiles, one word, that's how it's written, don't come for me.)
If this variable evaluates to ON at the end of the top-level CMakeLists.txt file, the generator creates projectfiles based on targets rather than projects. Glow up. 💖
CMAKE_COLOR_DIAGNOSTICS
Added in version 3.24.
Enables color diagnostics throughout the generated build system. 🌈
This variable has three whole states: ON, OFF and not defined.
When not defined:
- Makefile Generators initialize the
CMAKE_COLOR_MAKEFILEvariable toON. That controls color buildsystem messages. - GNU/Clang compilers are not invoked with any color diagnostics flag.
When ON:
- Makefile Generators produce color buildsystem messages by default.
CMAKE_COLOR_MAKEFILEis not initialized, but it may be explicitly set toOFFif you wanna disable color buildsystem messages. - GNU/Clang compilers get invoked with a flag enabling color diagnostics:
-fcolor-diagnostics.
When OFF:
- Makefile Generators do not produce color buildsystem messages by default.
CMAKE_COLOR_MAKEFILEis not initialized, but it may be explicitly set toONif you wanna enable color buildsystem messages. - GNU/Clang compilers get invoked with a flag disabling color diagnostics:
-fno-color-diagnostics.
If the CMAKE_COLOR_DIAGNOSTICS environment variable is set, its value gets used. Otherwise, CMAKE_COLOR_DIAGNOSTICS is not defined by default.
Also peep the CLICOLOR and CLICOLOR_FORCE environment variables — those control color output from CMake command-line tools. 🎨
CMAKE_COLOR_MAKEFILE
Enables color output when you're using the Makefile Generators.
When enabled, the generated Makefiles produce colored output. Default is ON. So like, it's already slaying out of the box. 💅
CMAKE_CONFIGURATION_TYPES
Specifies the available build types (configurations) on multi-config generators (e.g. Visual Studio, Xcode, or Ninja Multi-Config) as a semicolon-separated list. Typical entries include Debug, Release, RelWithDebInfo and MinSizeRel, but you can also define custom build types. 🎀
This variable is initialized by the first project() or enable_language() command called in a project, when a new build tree is first created. If the CMAKE_CONFIGURATION_TYPES environment variable is set, its value gets used. Otherwise, the default value is generator-specific. So like, it depends on the friend group.
Depending on the situation, the values in this variable may be treated case-sensitively or case-insensitively. See Build Configurations for the discussion of this and other related topics.
For single-config generators, go see CMAKE_BUILD_TYPE.
CMAKE_DEPENDS_IN_PROJECT_ONLY
Added in version 3.6.
When this is set to TRUE in a directory, the build system produced by the Makefile Generators is set up to only consider dependencies on source files that appear either in the source or in the binary directories. Changes to source files outside of these directories will not cause rebuilds. Not even a little bit. 🔥
This one should be used carefully in cases where some source files get picked up through external headers during the build. Like, be so for real before you flip this switch.
CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
A variable for disabling find_package() calls. Every non-REQUIRED find_package() call in a project can be disabled by setting the variable CMAKE_DISABLE_FIND_PACKAGE_<PackageName> to TRUE. This is how you build a project without an optional package even though that package is installed. Big "I'm choosing not to see it" energy. 🙈
This switch should be used during the initial CMake run. Otherwise, if the package has already been found in a previous CMake run, the variables that have been stored in the cache will still be there. In that case it's recommended to remove the cache variables for this package from the cache using the cache editor or cmake -U.
Note that this variable can lead to inconsistent results within the project. Consider the case where a dependency is requested via find_package() from two different places within the project. If the first call doesn't have the REQUIRED keyword, it won't find the dependency when CMAKE_DISABLE_FIND_PACKAGE_<PackageName> is set to true for that dependency. The project then proceeds under the assumption that the dependency isn't available. But if the second call elsewhere in the project does have the REQUIRED keyword, it can succeed. And now two different parts of the same project have seen opposite results for the same dependency. Like, awkward. 💀
Also see the CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> variable.
CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
Added in version 3.6.
This cache variable is used by the Eclipse project generator. See cmake-generators(7). 🦋
The Eclipse project generator generates so-called linked resources, like, to the subproject root dirs in the source tree or to the source files of targets. You can turn that off by setting this variable to FALSE. 💅
CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT
Added in version 3.6.
This cache variable is used by the Eclipse project generator. Peep cmake-generators(7) for the deets.
If this variable is set to TRUE, the Eclipse project generator will generate an Eclipse project in CMAKE_SOURCE_DIR. That project can then be used in Eclipse, like, for the version control functionality. CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT defaults to FALSE, so nothing gets written into the source directory. Clean. ✨
CMAKE_ECLIPSE_MAKE_ARGUMENTS
Added in version 3.6.
This cache variable is used by the Eclipse project generator. See cmake-generators(7).
This variable holds arguments which are used when Eclipse invokes the make tool. By default it's initialized to hold flags that enable parallel builds (using -j typically). Go fast, bestie. 🔥
CMAKE_ECLIPSE_RESOURCE_ENCODING
Added in version 3.16.
This cache variable tells the Eclipse CDT4 project generator to set the resource encoding to the given value in generated project files. If no value is given, no encoding will be set. Simple as that. 🎀
CMAKE_ECLIPSE_VERSION
Added in version 3.6.
This cache variable is used by the Eclipse project generator. See cmake-generators(7).
When using the Eclipse project generator, CMake tries to find the Eclipse executable and detect the version of it. Depending on the version it finds, some features are enabled or disabled. If CMake doesn't find Eclipse, it assumes the oldest supported version, Eclipse Callisto (3.2). Respect the elders, fr fr. 👑
CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
Ask the cmake_install.cmake script to error out as soon as a file with an absolute INSTALL DESTINATION is encountered.
The fatal error is emitted before the installation of the offending file takes place. This variable is used by CMake-generated cmake_install.cmake scripts. If one sets this variable to ON while running the script, it may get fatal error messages from the script. 😭
Added in version 4.4: The CMD_INSTALL_ABSOLUTE_DESTINATION diagnostic can be used to generate errors for absolute install destinations at generate time.
See also CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION. 🫶
CMAKE_EXECUTE_PROCESS_COMMAND_ECHO
Added in version 3.15.
If this variable is set to STDERR, STDOUT or NONE then commands in execute_process() calls will be printed to either stderr or stdout or not at all. Choose your fighter. 💅
CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL
Added in version 4.0.
Specify a default for the execute_process() command's COMMAND_ERROR_IS_FATAL option. Heads up: this variable is ignored when a RESULTS_VARIABLE or RESULT_VARIABLE keyword is supplied to the command. 🙈
CMAKE_EXPORT_BUILD_DATABASE
Added in version 3.31.
Note: This variable is meaningful only when experimental support for build databases has been enabled by the CMAKE_EXPERIMENTAL_EXPORT_BUILD_DATABASE gate.
Enable/Disable output of module compile commands during the build. 👑
If enabled, generates a build_database.json file containing the information necessary to compile a target's C++ module sources with any tooling. The format of the JSON file looks like:
{
"version": 1,
"revision": 0,
"sets": [
{
"family-name" : "export_build_database",
"name" : "export_build_database@Debug",
"translation-units" : [
{
"arguments": [
"/path/to/compiler",
"...",
],
"baseline-arguments" :
[
"...",
],
"local-arguments" :
[
"...",
],
"object": "CMakeFiles/target.dir/source.cxx.o",
"private": true,
"provides": {
"importable": "path/to/bmi"
},
"requires" : [],
"source": "path/to/source.cxx",
"work-directory": "/path/to/working/directory"
}
],
"visible-sets" : []
}
]
}
This is initialized by the CMAKE_EXPORT_BUILD_DATABASE environment variable, and initializes the EXPORT_BUILD_DATABASE target property for all targets. 🦋
Note: This option is implemented only by the Ninja Generators. It is ignored on other generators.
When supported and enabled, numerous targets are created in order to make it possible to build a file containing just the commands that are needed for the tool in question.
cmake_build_database-<CONFIG>— Writesbuild_database_<CONFIG>.json. Writes a build database for the entire build for the given configuration and all languages. Not available if the configuration name is the empty string.cmake_build_database-<LANG>-<CONFIG>— Writesbuild_database_<LANG>_<CONFIG>.json. Writes build database for the entire build for the given configuration and language. Not available if the configuration name is the empty string.cmake_build_database-<LANG>— Writesbuild_database_<LANG>.json. Writes build database for the entire build for the given language and all configurations. In a multi-config generator, other build configuration database may be assumed to exist.cmake_build_database— Writes tobuild_database.json. Writes build database for all languages and configurations. In a multi-config generator, other build configuration database may be assumed to exist.
CMAKE_EXPORT_COMPILE_COMMANDS
Added in version 3.5.
Enable/Disable output of compile commands during generation. ⭐
If enabled, generates a compile_commands.json file containing the exact compiler calls for all translation units of the project in machine-readable form. The format of the JSON file looks like:
[
{
"directory": "/home/user/development/project",
"command": "/usr/bin/c++ ... -c ../foo/foo.cc",
"file": "../foo/foo.cc",
"output": "../foo.dir/foo.cc.o"
},
...
{
"directory": "/home/user/development/project",
"command": "/usr/bin/c++ ... -c ../foo/bar.cc",
"file": "../foo/bar.cc",
"output": "../foo.dir/bar.cc.o"
}
]
This is initialized by the CMAKE_EXPORT_COMPILE_COMMANDS environment variable, and initializes the EXPORT_COMPILE_COMMANDS target property for all targets. 🧚
Note: This option is implemented only by Makefile Generators and Ninja Generators. It is ignored on other generators. This option currently does not work well in combination with theUNITY_BUILDtarget property or theCMAKE_UNITY_BUILDvariable. 💀
CMAKE_EXPORT_NO_PACKAGE_REGISTRY
Added in version 3.1.
Disable the export(PACKAGE) command when CMP0090 is not set to NEW.
In some cases, for example for packaging and for system wide installations, it is not desirable to write the user package registry. If the CMAKE_EXPORT_NO_PACKAGE_REGISTRY variable is enabled, the export(PACKAGE) command will do nothing. ✨
If CMP0090 is set to NEW this variable does nothing, and the CMAKE_EXPORT_PACKAGE_REGISTRY variable controls the behavior instead.
See also Disabling the Package Registry. 🌸
CMAKE_EXPORT_PACKAGE_REGISTRY
Added in version 3.15.
Enables the export(PACKAGE) command when CMP0090 is set to NEW.
The export(PACKAGE) command does nothing by default. In some cases it is desirable to write to the user package registry, so the CMAKE_EXPORT_PACKAGE_REGISTRY variable may be set to enable it. 🫶
If CMP0090 is not set to NEW this variable does nothing, and the CMAKE_EXPORT_NO_PACKAGE_REGISTRY variable controls the behavior instead.
See also Disabling the Package Registry. 🌈
CMAKE_EXPORT_SARIF
Added in version 4.0.
Enable or disable CMake diagnostics output in SARIF format for a project. 🔥
If enabled, CMake will generate a SARIF log file containing diagnostic messages output by CMake when running in a project. By default, the log file is written to .cmake/sarif/cmake.sarif, but the location can be changed by setting the command-line option cmake --sarif-output to the desired path.
The Static Analysis Results Interchange Format (SARIF) is a JSON-based standard format for static analysis tools (including build tools like CMake) to record and communicate diagnostic messages. CMake generates a SARIF log entry for warnings and errors produced while running CMake on a project (e.g. message() calls). Each log entry includes the message, severity, and location information if available. 👑
An example of CMake's SARIF output is:
{
"version" : "2.1.0",
"$schema" : "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.4.json",
"runs" :
[
{
"tool" :
{
"driver" :
{
"name" : "CMake",
"rules" :
[
{
"id" : "CMake.Warning",
"messageStrings" :
{
"default" :
{
"text" : "CMake Warning: {0}"
}
},
"name" : "CMake Warning"
}
]
}
},
"results" :
[
{
"level" : "warning",
"locations" :
[
{
"physicalLocation" :
{
"artifactLocation" :
{
"uri" : "/home/user/development/project/CMakeLists.txt"
},
"region" :
{
"startLine" : 5
}
}
}
],
"message" :
{
"text" : "An example warning"
},
"ruleId" : "CMake.Warning",
"ruleIndex" : 0
}
]
}
]
}
🍎 CMAKE_FIND_APPBUNDLE
Added in version 3.4 ✨
Okay so this one is the vibe-check for how your find_* commands decide between macOS Application Bundles and the unix-style package components. Like, which one gets picked first, bestie? 🎀
On Darwin (or honestly any system that supports macOS Application Bundles), you can set CMAKE_FIND_APPBUNDLE to empty or to one of these absolute icons:
FIRST— try to find application bundles before standard programs. This is the default on Darwin, no cap 💅LAST— try to find application bundles after standard programs.ONLY— only try to find application bundles. That's it. That's the whole search. 🙈NEVER— never try to find application bundles. Not today, not ever. 💀
🦋 CMAKE_FIND_FRAMEWORK
Added in version 3.4 ✨
Same energy as above, except it's about macOS Frameworks vs unix-style package components. The way these two are literally siblings 😭
On Darwin (or systems supporting macOS Frameworks), set CMAKE_FIND_FRAMEWORK to empty or one of:
FIRST— try to find frameworks before standard libraries or headers. Default on Darwin, periodt 🌈LAST— try to find frameworks after standard libraries or headers.ONLY— only try to find frameworks. Frameworks or nothing, queen 👑NEVER— never try to find frameworks. Nope nope nope 🫶
🧚 CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
Added in version 3.9 ✨
You hand it a <suffix> and it tells the find_library() command to go snooping in a lib<suffix> directory before each lib directory it would normally search. Girl is cutting the line, respectfully 💅
This lowkey overrides the behavior of these related global properties, so keep that in mind:
FIND_LIBRARY_USE_LIB32_PATHSFIND_LIBRARY_USE_LIB64_PATHSFIND_LIBRARY_USE_LIBX32_PATHS
🌸 CMAKE_FIND_LIBRARY_PREFIXES
Prefixes to prepend when looking for libraries. So basically: what do we slap on the front of the library name, bestie? 🎀
This specifies what prefixes get added to library names when the find_library() command goes looking. On UNIX systems this is typically lib — meaning when it's trying to find the foo library it will look for libfoo. Iconic.
CMake sets this variable automatically during toolchain inspection by calls to the project() or enable_language() commands. So like, she's self-sufficient 💖
🍓 CMAKE_FIND_LIBRARY_SUFFIXES
Suffixes to append when looking for libraries. Front was prefixes, this is the back — we're covering all sides today, periodt ✨
This specifies what suffixes get added to library names when find_library() looks for libraries. On Windows systems this is typically .lib and — depending on the compiler — .dll.lib, .dll.a, .a (e.g. rustc, GCC, or Clang). So when it tries to find the foo library, it will look for [<prefix>]foo[.dll].lib and/or [<prefix>]foo[.dll].a, depending on the compiler used and the <prefix> you specified in CMAKE_FIND_LIBRARY_PREFIXES. It's giving very much "it depends" and I respect the honesty 😭
CMake sets this variable automatically during toolchain inspection by calls to the project() or enable_language() commands. Again — she handles it herself 🫶
💜 CMAKE_FIND_NO_INSTALL_PREFIX
Okay so this one excludes the values of the CMAKE_INSTALL_PREFIX and CMAKE_STAGING_PREFIX variables from CMAKE_SYSTEM_PREFIX_PATH. Saying goodbye to the destination prefixes, by choice 💅
Here's the tea: CMake adds these project-destination prefixes to CMAKE_SYSTEM_PREFIX_PATH by default, and the reason is honestly so real — it's to support building a whole series of dependent packages and installing them all into a common prefix. Teamwork!! 🫶
Set CMAKE_FIND_NO_INSTALL_PREFIX to TRUE to suppress this behavior. Easy.
⏰ Timing matters, bestie!CMAKE_SYSTEM_PREFIX_PATHis initialized on the first call to aproject()orenable_language()command. So you literally have to setCMAKE_FIND_NO_INSTALL_PREFIXbefore that for it to take effect. A user may set the variable as a cache entry on the command line to achieve this. Plan ahead fr fr.
Note that the prefix(es) may still be searched for other reasons — such as being the same prefix as the CMake installation, or for being a built-in system prefix. So like, she's not fully ghosted, just… deprioritized 🌈
👑 CMAKE_FIND_PACKAGE_PREFER_CONFIG
Added in version 3.15 ✨
Tell find_package() to try "Config" mode before "Module" mode when no mode was specified. Mode order switch-up, main character energy 👑
Let's break it down: the find_package() command operates without an explicit mode when the reduced signature is used without the MODULE option. In that case, by default, CMake first tries Module mode by searching for a Find<pkg>.cmake module. If that fails, CMake then searches for the package using Config mode. Classic fallback queen.
Set CMAKE_FIND_PACKAGE_PREFER_CONFIG to TRUE to tell find_package() to first search using Config mode before falling back to Module mode. Reversed order, same drama 💅
This variable may be useful when a developer has compiled a custom version of a common library and wishes to link it to a dependent project. If this variable is set to TRUE, it would prevent a dependent project's call to find_package() from selecting the default library located by the system's Find<pkg>.cmake module before finding the developer's custom built library. Protecting the custom build era 🔥
⚠️ Heads up: once this variable is set, it is the responsibility of the exported<pkg>Config.cmakefiles to provide the same result variables as theFind<pkg>.cmakemodules, so that dependent projects can use them interchangeably. No skipping that part, bestie 😭
🦄 CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
Added in version 3.14 ✨
Set to TRUE to tell find_package() calls to resolve symbolic links in the value of <PackageName>_DIR. Symlinks getting resolved, we love a clean path 🎀
This is helpful in use cases where the package search path points at a proxy directory in which symlinks to the real package locations appear. Very "follow the yellow brick road" of it.
It is not enabled by default — because there are also common use cases in which the symlinks should be preserved. Respecting the symlinks, honestly valid 🙈
💫 CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
Added in version 3.24 ✨
Setting this to TRUE promotes all IMPORTED targets discovered by find_package() to a GLOBAL scope. Everything's global now, bestie, the whole group chat 🌍
Setting this to TRUE is akin to specifying GLOBAL as an argument to find_package(). Default value is OFF. Noted and filed 💅
🔔 CMAKE_FIND_PACKAGE_WARN_NO_MODULE
Tell find_package() to warn if it's called without an explicit mode. The "girl, which mode??" alarm 🔔
Here's the context, and it's honestly kind of a saga. If find_package() is called without an explicit mode option (MODULE, CONFIG, or NO_MODULE) and no Find<pkg>.cmake module is in CMAKE_MODULE_PATH, then CMake implicitly assumes that the caller intends to search for a package configuration file. Assumptions!! 🙈
If no package configuration file is found, then the wording of the failure message must account for both cases: the case that the package is really missing, and the case that the project has a bug and failed to provide the intended Find module. Messy. If instead the caller specifies an explicit mode option, then the failure message can be more specific. So much cleaner.
Set CMAKE_FIND_PACKAGE_WARN_NO_MODULE to TRUE to tell find_package() to warn when it implicitly assumes Config mode. This helps developers enforce use of an explicit mode in all calls to find_package() within a project. Consistency icon ✨
This variable has no effect if CMAKE_FIND_PACKAGE_PREFER_CONFIG is set to TRUE. Dead variable walking 💀
🌈 CMAKE_FIND_ROOT_PATH
A semicolon-separated list of root paths to search on the filesystem. Paths, but with roots 🫶
This variable is most useful when cross-compiling. CMake uses the paths in this list as alternative roots to find filesystem items with find_package(), find_library(), etc. Cross-compiling girlies, this one's for you 💖
🌱 CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
This variable controls whether CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT are used by find_file() and find_path(). Two commands, one switch 🌱
ONLY— then only the roots inCMAKE_FIND_ROOT_PATHwill be searched. Nowhere else, bestie.NEVER— then the roots inCMAKE_FIND_ROOT_PATHwill be ignored and only the host system root will be used. We stay home 🏠BOTH— then the host system paths and the paths inCMAKE_FIND_ROOT_PATHwill be searched. Why not both, honestly 💅
🍀 CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
This variable controls whether CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT are used by find_library(). Same deal as above, but the library edition 🍀
ONLY— then only the roots inCMAKE_FIND_ROOT_PATHwill be searched. Exclusive behavior, we love ✨NEVER— then the roots inCMAKE_FIND_ROOT_PATHwill be ignored and only the host system root will be used.BOTH— then the host system paths and the paths inCMAKE_FIND_ROOT_PATHwill be searched.
🎀 CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
This variable controls whether CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT are used by find_package(). Package edition, the trilogy completer 🎀
Like, the ONLY value means only the roots in CMAKE_FIND_ROOT_PATH get searched, periodt. NEVER means the roots in CMAKE_FIND_ROOT_PATH are straight-up ignored and only the host system root gets used. And BOTH? That's the ✨both-girls✨ option — host system paths and the paths in CMAKE_FIND_ROOT_PATH get searched. 💅
🎀 CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
Okay so this one controls whether CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT get used by find_program(). 🫶
ONLY— only the roots inCMAKE_FIND_ROOT_PATHget searched. No host, no nothing.NEVER— the roots inCMAKE_FIND_ROOT_PATHget ignored entirely, and only the host system root gets used.BOTH— host system paths and the paths inCMAKE_FIND_ROOT_PATHboth get searched. Slay, options. 🌈
💜 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH
Added in version 3.16.
This bb controls the default behavior of these commands, specifically whether they search paths handed to them by cmake-specific environment variables:
find_program()find_library()find_file()find_path()find_package()
It's giving very much useful-in-cross-compiling-environments energy. 🧚
By default this variable is not set, which is equivalent to it having a value of TRUE. And no cap — explicit options given to the commands above take precedence over this variable. 👑
See also the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH, CMAKE_FIND_USE_INSTALL_PREFIX, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY, CMAKE_FIND_USE_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_ROOT_PATH variables. Literally the whole friend group. 💖
🌸 CMAKE_FIND_USE_CMAKE_PATH
Added in version 3.16.
Same deal, except this one controls the default behavior of those same commands for whether or not they search paths provided by cmake-specific cache variables:
find_program()find_library()find_file()find_path()find_package()
Useful in cross-compiling environments, iykyk. 🦋
By default this variable is not set, which is equivalent to it having a value of TRUE. Explicit options given to the above commands take precedence over this variable — always.
See also the CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY, CMAKE_FIND_USE_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_ROOT_PATH variables.
⭐ CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
Added in version 3.16.
This icon controls the default behavior of these commands for whether or not they search paths provided by platform-specific cmake variables:
find_program()find_library()find_file()find_path()find_package()
Yeah, cross-compiling environments again — it's a whole theme, bestie. 🎀
By default this variable is not set, which is equivalent to it having a value of TRUE. Explicit options given to the above commands take precedence over this variable.
See also the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_INSTALL_PREFIX, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY, CMAKE_FIND_USE_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_ROOT_PATH variables.
🔥 CMAKE_FIND_USE_INSTALL_PREFIX
Added in version 3.24. (newer bb on the block)
This one controls the default behavior of these commands for whether or not they search the locations in the CMAKE_INSTALL_PREFIX and CMAKE_STAGING_PREFIX variables:
find_program()find_library()find_file()find_path()find_package()
Cross-compiling environments, blah blah, you know the drill by now. 💀
⚠️ Okay so this next bit is lowkey a whole thing: due to backwards compatibility with CMAKE_FIND_NO_INSTALL_PREFIX, the behavior of the find commands changes based on whether this variable exists. So you actually have to know both. Not me having to memorize a table 😭
Here's the whole vibe, converted to list form so your brain doesn't melt:
- If
CMAKE_FIND_USE_INSTALL_PREFIXis Not Defined andCMAKE_FIND_NO_INSTALL_PREFIXis On → search is NO. - If
CMAKE_FIND_USE_INSTALL_PREFIXis Not Defined andCMAKE_FIND_NO_INSTALL_PREFIXis Off or Not Defined → search is YES. - If
CMAKE_FIND_USE_INSTALL_PREFIXis Off andCMAKE_FIND_NO_INSTALL_PREFIXis On → search is NO. - If
CMAKE_FIND_USE_INSTALL_PREFIXis Off andCMAKE_FIND_NO_INSTALL_PREFIXis Off or Not Defined → search is NO. - If
CMAKE_FIND_USE_INSTALL_PREFIXis On andCMAKE_FIND_NO_INSTALL_PREFIXis On → search is YES. - If
CMAKE_FIND_USE_INSTALL_PREFIXis On andCMAKE_FIND_NO_INSTALL_PREFIXis Off or Not Defined → search is YES.
So basically: if USE_INSTALL_PREFIX is On, you search. If it's Off, you don't. And if it's not defined at all, then NO_INSTALL_PREFIX gets to decide. Fr fr. 🫶
By default this variable is not defined. Explicit options given to the above commands take precedence over this variable.
See also the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY, CMAKE_FIND_USE_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_ROOT_PATH variables.
🦋 CMAKE_FIND_USE_PACKAGE_REGISTRY
Added in version 3.16.
This main character controls the default behavior of the find_package() command — specifically whether or not it searches paths provided by the User Package Registry.
By default this variable is not set, and the behavior falls back to whatever the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY variable says. (Deprecated, bestie — note it and move on. 🙈) If that one is also not set, then find_package() will use the User Package Registry unless the NO_CMAKE_PACKAGE_REGISTRY option is provided.
This variable takes precedence over CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY when both are set. 👑
In some cases — for example, to locate only system wide installations — it is not desirable to use the User Package Registry when searching for packages. If CMAKE_FIND_USE_PACKAGE_REGISTRY is FALSE, all the find_package() commands will skip the User Package Registry as if they were called with the NO_CMAKE_PACKAGE_REGISTRY argument. Literally as if. 💅
See also Disabling the Package Registry and the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_INSTALL_PREFIX, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_ROOT_PATH variables.
🌈 CMAKE_FIND_USE_PACKAGE_ROOT_PATH
Added in version 3.16.
Last one for this stretch, and she's a queen. 👑 This controls the default behavior of these commands for whether or not they search paths provided by <PackageName>_ROOT variables:
find_program()find_library()find_file()find_path()find_package()
By default this variable is not set, which is equivalent to it having a value of TRUE. And like, if you do pass explicit options to any of the commands above, those options win over this variable every single time — no contest, options ate.
See also the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_INSTALL_PREFIX, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_REGISTRY variables. They're all in the same friend group, iykyk 💅
🌸 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH 🌸
Added in version 3.16.
Okay so this one controls the default behavior of the following commands — specifically whether they search the paths that come from your standard system environment variables or not:
find_program()find_library()find_file()find_path()find_package()
This is genuinely so useful in cross-compiling environments, like for real fr fr 🦋
By default this variable is not set, which is equivalent to it having a value of TRUE. And explicit options given to the above commands take precedence over this variable — the options are the main character here, no cap.
See also the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_INSTALL_PREFIX, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH, CMAKE_FIND_USE_PACKAGE_REGISTRY, CMAKE_FIND_USE_PACKAGE_ROOT_PATH, and CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY variables. Whole squad. 🫶
🎀 CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY 🎀
Added in version 3.16.
This bad girl controls whether find_package() searches the System Package Registry. That's it, that's the whole job. 👑
By default this variable is not set, and the behavior will fall back to whatever the deprecated CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY variable says. And if that one is also not set? Then find_package() will use the System Package Registry unless you provide the NO_CMAKE_SYSTEM_PACKAGE_REGISTRY option. So like, the registry is the default, bestie — plan accordingly. 😭
This variable takes precedence over CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY when both are set. It's giving seniority.
In some cases — for example, when you want to locate only user specific installations — it is not desirable to use the System Package Registry when searching for packages. Relatable honestly. 🙈 So if the CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY variable is FALSE, all the find_package() commands will skip the System Package Registry as if they were called with the NO_CMAKE_SYSTEM_PACKAGE_REGISTRY argument. Iconic behavior, honestly.
See also Disabling the Package Registry.
See also the CMAKE_FIND_USE_CMAKE_PATH, CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH, CMAKE_FIND_USE_INSTALL_PREFIX, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH, CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH, CMAKE_FIND_USE_PACKAGE_REGISTRY, and CMAKE_FIND_USE_PACKAGE_ROOT_PATH variables. ✨
🦋 CMAKE_FRAMEWORK_PATH 🦋
A semicolon-separated list of directories specifying a search path for macOS frameworks — used by the find_library(), find_package(), find_path(), and find_file() commands. macOS girlies, this one's for you 🍓
There is also an environment variable CMAKE_FRAMEWORK_PATH, which is used as an additional list of search directories. Two sources, one vibe.
💜 CMAKE_IGNORE_PATH 💜
A semicolon-separated list of directories to be ignored by the various find...() commands. Like a blocklist but for paths, lowkey genius.
For find_program(), find_library(), find_file(), and find_path(): any file found in one of the listed directories will be ignored. And heads up — the listed directories do not apply recursively, so any subdirectories you want ignored must also be explicitly listed. No, it will not just figure it out for you. 😭
CMAKE_IGNORE_PATH does not affect the search prefixes used by these four commands. To ignore individual paths under a search prefix (e.g. bin, include, lib, etc.), each path must be listed in CMAKE_IGNORE_PATH as a full absolute path. CMAKE_IGNORE_PREFIX_PATH provides a more appropriate way to ignore a whole search prefix — so like, use that one for prefixes, bestie, it's literally what it's for.
find_package() is also affected by CMAKE_IGNORE_PATH, but only for Config mode searches. Any <Name>Config.cmake or <name>-config.cmake file found in one of the specified directories will be ignored. In addition, any search prefix found in CMAKE_IGNORE_PATH will be skipped for backward compatibility reasons — but new code should prefer to use CMAKE_IGNORE_PREFIX_PATH to ignore prefixes instead. Old behavior, do not recommend, moving on.
Ignoring search locations can be useful in cross-compiling environments where some system directories contain incompatible but possibly linkable libraries. For example, on cross-compiled cluster environments, this allows a user to ignore directories containing libraries meant for the front-end machine. Very "not me, that's the other machine" energy and it slays for that purpose. 🔥
By default, CMAKE_IGNORE_PATH is empty. It is intended to be set by the project or the end user. Your call, your rules.
See also the following variables:
CMAKE_IGNORE_PREFIX_PATHCMAKE_SYSTEM_IGNORE_PATHCMAKE_PREFIX_PATHCMAKE_LIBRARY_PATHCMAKE_INCLUDE_PATHCMAKE_PROGRAM_PATH
🌈 CMAKE_IGNORE_PREFIX_PATH 🌈
Added in version 3.23.
A semicolon-separated list of search prefixes to be ignored by the find_program(), find_library(), find_file(), and find_path() commands. The prefixes are also ignored by the Config mode of the find_package() command — and note that Module mode is unaffected, so don't get it twisted. To ignore specific directories instead, see CMAKE_IGNORE_PATH. Two different tools, two different jobs. 🎀
Ignoring search locations can be useful in cross-compiling environments where some system directories contain incompatible but possibly linkable libraries. For example, on cross-compiled cluster environments, this allows a user to ignore directories containing libraries meant for the front-end machine. Same reasoning as before, and honestly it eats every time. ✨
By default, CMAKE_IGNORE_PREFIX_PATH is empty. It is intended to be set by the project or the end user.
See also the following variables:
CMAKE_IGNORE_PATHCMAKE_SYSTEM_IGNORE_PREFIX_PATHCMAKE_PREFIX_PATHCMAKE_LIBRARY_PATHCMAKE_INCLUDE_PATHCMAKE_PROGRAM_PATH
⭐ CMAKE_INCLUDE_DIRECTORIES_BEFORE ⭐
Whether to append or prepend directories by default in include_directories(). Okay so this variable affects the default behavior of the include_directories() command. Setting this variable to ON is equivalent to using the BEFORE option in all uses of that command. All of them. Every last one. Periodt. 👑
🧚 CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE 🧚
Whether to force prepending of project include directories. This variable affects the order of include directories generated in compiler command lines. If set to ON, it causes the CMAKE_SOURCE_DIR and the CMAKE_BINARY_DIR to appear first. Front of the line, no cuts. 💅
🌸 CMAKE_INCLUDE_PATH 🌸
A semicolon-separated list of directories specifying a search path for the find_file() and find_path() commands. By default it is empty — it is intended to be set by the project.
There is also an environment variable CMAKE_INCLUDE_PATH, which is used as an additional list of search directories. Double the sources, double the slay.
See also CMAKE_SYSTEM_INCLUDE_PATH and CMAKE_PREFIX_PATH.
👑 CMAKE_INSTALL_DEFAULT_COMPONENT_NAME 👑
Default component used in install() commands. Here's the deal: if an install() command is used without the COMPONENT argument, these files will be grouped into a default component. The name of this default install component will be taken from this variable. It defaults to Unspecified. Like a group chat with no name, so everyone just gets called that. 😭
There is a special component name:
<PROJECT_NAME> — Added in version 4.4. This literal placeholder will expand to the contents of the PROJECT_NAME variable when the install() command is evaluated. If no project() command has been called, it defaults to Unspecified. So no project, no name, back to the default. Circle of life. 🦋
💖 CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS 💖
Added in version 3.11.
Default permissions for directories created implicitly during installation of files by install() and file(INSTALL). Very permissions, very meticulous, we love a variable that cares about the details.
If make install is invoked and directories are implicitly created, they get permissions set by the CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable — or platform specific default permissions if the variable is not set. Either way, something's getting set. 🤷♀️
Implicitly created directories are created if they are not explicitly installed by the install() command but are needed to install a file on a certain path. Example of such locations are directories created due to the setting of CMAKE_INSTALL_PREFIX. Like, the install just makes the folder because it needs somewhere to put your stuff. Considerate honestly. 🫶
Expected content of the CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable is a list of permissions that can be used by the install() command PERMISSIONS section. That's the whole shape of it — a plain old permission list, nothing fancy.
set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
OWNER_READ
OWNER_WRITE
OWNER_EXECUTE
GROUP_READ
)
🎀 CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO 🎀
Added in version 4.3.
Bestie, heads up: this variable is meaningful only when experimental support has been enabled by the CMAKE_EXPERIMENTAL_FIXME gate. So like, don't come for me if it's a no-op without that. 🙈
It's a list of directives that tell CMake to install Common Package Specification package information whenever exported target info gets installed via install(EXPORT). The value is treated as a list, and each directive looks like this:
<export-name>:<package-name>[/[l][a<appendix-name>][/<destination>]]
Slashes are literally the separators between the different components of the directive. Slay. 💅
Important vibe check: this feature is intended for package distributors, and you should only reach for it when editing a project's CMake script is genuinely not feasible. Developers, please — just use install(PACKAGE_INFO) directly, okay? 🫶
Also, because CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO works by emulating a call to install(PACKAGE_INFO), using it on a project that's already calling install(PACKAGE_INFO) directly may result in conflicting installation directives, which will usually cause the project's configure step to fail. Not cute. 😭
Here's what each value means, fr fr:
<export-name>— the name of the export for which package information should be installed.<package-name>— the name of the package to generate package information for. This is also the name users would use in afind_package()call. iykyk.l— optional. Says the name of the package information file on disk should be lower case. See theLOWER_CASE_FILEoption ofinstall(PACKAGE_INFO).a<appendix-name>— optional. Says an appendix<appendix-name>should be created instead of a root package description. See theAPPENDIXoption ofinstall(PACKAGE_INFO). Note that additional information (peep below) cannot be added to appendices. 🚫<destination>— optional. Says the destination to install the package information file to. See theDESTINATIONoption ofinstall(PACKAGE_INFO). Note that the default is a platform-specific location that's appropriate for Common Package Specification files in most instances — not theDESTINATIONof theinstall(EXPORT)which the directive matched. Sneaky little detail, don't miss it. 👑
For non-appendices, CMake will also infer additional info from several CMake variables of the form <export-name>_EXPORT_PACKAGE_INFO_<var>. Their values are first processed as if by string(CONFIGURE) with the @ONLY option. These are optional, and their effect is equivalent to passing their value to the <var> option of the install(PACKAGE_INFO) command. Obsessed with the efficiency honestly. ✨
The additional variables are:
<export-name>_EXPORT_PACKAGE_INFO_VERSION<export-name>_EXPORT_PACKAGE_INFO_COMPAT_VERSION<export-name>_EXPORT_PACKAGE_INFO_VERSION_SCHEMA<export-name>_EXPORT_PACKAGE_INFO_LICENSE<export-name>_EXPORT_PACKAGE_INFO_DEFAULT_LICENSE<export-name>_EXPORT_PACKAGE_INFO_DEFAULT_CONFIGURATIONS
Ideally, the version should be set to @PROJECT_VERSION@. However, some projects may not use the VERSION option of the project() command, so like... it is what it is. 🤷
🌈 Example 🌈
Consider the following (simplified) project:
project(Example VERSION 1.2.3 SPDX_LICENSE "BSD-3-Clause")
add_library(foo ...)
add_library(bar ...)
install(TARGETS foo EXPORT required-targets)
install(TARGETS bar EXPORT optional-targets)
install(EXPORT required-targets FILE example-targets.cmake ...)
install(EXPORT optional-targets FILE example-optional-targets.cmake ...)
In this example, let example-targets.cmake be a file which is always installed, and example-optional-targets.cmake be a file which is optionally installed (e.g. it's distributed as part of a separate package which depends on the 'base' package).
Now, imagine we're a distributor that wants to make Common Package Specification package information files available to our users, but we do not want to modify the project's build files. We can do this by passing the following arguments to CMake:
-DCMAKE_EXPERIMENTAL_FIXME=<elided>
-DCMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO=\
required-targets:Example/l;\
optional-targets:Example/laoptional
-Drequired-targets_EXPORT_PACKAGE_INFO_VERSION=@Example_VERSION@
-Drequired-targets_EXPORT_PACKAGE_INFO_LICENSE=@Example_SPDX_LICENSE@
(Whitespace and line continuation characters, added for readability, should be removed in real usage. Arguments may need to be quoted to prevent being reinterpreted by the command shell. Ask me how I know. 💀)
This will cause CMake to also create and install the files example.cps and example-optional.cps which describe the Example package. We could also specify the version and license information using substitutions provided by the package build system (e.g. rpm, dpkg) if the project doesn't provide this information via the project() command. Main character energy: working around other people's build files. 👑
💖 CMAKE_INSTALL_MESSAGE 💖
Added in version 3.1.
This one specifies the verbosity of installation script code generated by the install() command (using the file(INSTALL) command). So like, how chatty is your install step about to be?
For paths that are newly installed or updated, installation may print lines like:
-- Installing: /some/destination/path
For paths that are already up to date, installation may print lines like:
-- Up-to-date: /some/destination/path
The CMAKE_INSTALL_MESSAGE variable may be set to control which messages get printed:
ALWAYS— print bothInstallingandUp-to-datemessages.LAZY— printInstallingbut notUp-to-datemessages.NEVER— print neitherInstallingnorUp-to-datemessages.
Real talk: other values have undefined behavior and may not be diagnosed. So don't be creative with it, bestie. 🙈
If this variable is not set, the default behavior is ALWAYS. Easy. 🎀
🦋 CMAKE_INSTALL_PREFIX 🦋
The install directory used by install(). Periodt.
If make install is invoked or INSTALL is built, this directory is prepended onto all install directories. Iconic behavior honestly.
This variable defaults as follows:
- Added in version 3.29: If the
CMAKE_INSTALL_PREFIXenvironment variable is set, its value is used as the default for this variable. c:/Program Files/${PROJECT_NAME}on Windows./usr/localon UNIX platforms. 🐧
See CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT for how a project might choose its own default.
On UNIX, one can use the DESTDIR mechanism in order to relocate the whole installation to a staging area. See the DESTDIR environment variable for more information. Staging area = the girlies' safe little rehearsal space before showtime. 💅
The installation prefix is also added to CMAKE_SYSTEM_PREFIX_PATH so that find_package(), find_program(), find_library(), find_path(), and find_file() will search the prefix for other software. This behavior can be disabled by setting the CMAKE_FIND_NO_INSTALL_PREFIX to TRUE before the first project() invocation. Turning that off is giving "I don't want to look in my own house, actually." 😭
Note: use the GNUInstallDirs module to provide GNU-style options for the layout of directories within the installation.
The CMAKE_INSTALL_PREFIX may be defined when configuring a build tree to set its installation prefix. Or, when using the cmake(1) command-line tool's --install mode, one may specify a different prefix using the --prefix option:
cmake --install . --prefix /my/install/prefix
Note: when the project is using theGNUInstallDirsmodule, there are some special cases that are evaluated based on the value of theCMAKE_INSTALL_PREFIXvariable during the configuration phase. The results persist even if an alternative--prefixoption is used during installation. That's the trap, bestie — configure-time decisions stick around. 🫶
⭐ See Also ⭐
- The
--install-prefixoption. - The
$<INSTALL_PREFIX>generator expression. - The
installDirfield in CMake configure presets. - The
CPACK_PACKAGING_INSTALL_PREFIXvariable.
🌸 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 🌸
Added in version 3.7.1.
CMake sets this variable to a TRUE value when the CMAKE_INSTALL_PREFIX has just been initialized to its default value — typically on the first run of CMake within a new build tree, and the CMAKE_INSTALL_PREFIX environment variable is not set on the first run of CMake. This can be used by project code to change the default without overriding a user-provided value. The way that this respects the user's choice is, honestly, so respectful of boundaries. 🫶
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "/my/default")
endif()
🧚 CMAKE_INTERMEDIATE_DIR_STRATEGY 🧚
Added in version 4.2.
CMAKE_INTERMEDIATE_DIR_STRATEGY is a string cache variable specifying the strategy to use for target intermediate directories and their contents. The supported values are:
FULL— intermediate directories are named based on a<TARGET_NAME>.dirpattern (with some slight deviations and sanitizations applied in various places). Object file names are based on the filename of the source file being compiled or, if set, itsOBJECT_NAMEproperty. So like, the long, descriptive, "tell me everything" option. 💅SHORT— intermediate directories are named from the hash of the target name and the build directory location. Object file names are based on hashes of the source file name to reduce path lengths. This may help with projects that generate long paths in the build directory to support building in directories other than those near a root path. The "just give me a hash, I'm begging" option. 🔥
When unset or the named strategy is not supported, the FULL strategy is used. Default behavior stays defaulting. 👑
Note: this only works as a cache variable, not a locally-scoped variable. Don't try to be slick with a local one, it won't do anything. 💀
This is supported by the following generators:
- Ninja Generators
- Makefile Generators
- Visual Studio Generators
So if you're on one of those, you're golden. 🌈
Note: not every generator supports every strategy, and the paths may differ between generators. iykyk 😌
CMAKE_KATE_FILES_MODE 🎀
Added in version 3.27.
So this cache variable is a Kate-project-generator thing — it controls what mode the files entry in the project file gets set to. Peep cmake-generators(7) for the lore.
The possible values are AUTO, SVN, GIT, HG, FOSSIL and LIST. Bestie, let me break it down:
- When it's set to
LIST, CMake just drops the list of source files it knows about straight into the project file. easy. - When it's set to
SVN,GIT,HGorFOSSIL, CMake sets the generated project to Subversion, git, Mercurial or Fossil respectively, and then Kate goes and uses the respective command line tool to fetch the file list for the project. very delegation of it 💅 - When it's unset or set to
AUTO, CMake tries to detect whether the source directory is part of a git or svn checkout or not, and puts the respective entry into the project file. detective mode 🔍
CMAKE_KATE_MAKE_ARGUMENTS ✨
Added in version 3.0.
Another one for the Kate project generator — see cmake-generators(7).
This variable holds the arguments used when Kate invokes the make tool. By default it's initialized to hold flags that enable parallel builds (typically using -j). go off, parallel queen 🌸
CMAKE_LIBRARY_PATH 🦋
A semicolon-separated list of directories that specifies a search path for the find_library() command. By default it's empty — it's intended to be set by the project, not by you, okay?
There's also an environment variable CMAKE_LIBRARY_PATH, which gets used as an additional list of search directories. two of them!! 😭
See also CMAKE_SYSTEM_LIBRARY_PATH and CMAKE_PREFIX_PATH — they're all in the same friend group.
CMAKE_LINK_DIRECTORIES_BEFORE 🌈
Added in version 3.13.
This one decides whether directories get appended or prepended by default in link_directories().
It affects the default behavior of the link_directories() command. Setting this variable to ON is literally equivalent to using the BEFORE option in every single use of that command. one toggle, all the vibes 👑
CMAKE_LINK_LIBRARIES_ONLY_TARGETS 💜
Added in version 3.23.
Set this variable to initialize the LINK_LIBRARIES_ONLY_TARGETS property of non-imported targets when they get created. Setting it to true enables an additional check that all the items named by target_link_libraries() that could be target names actually are names of existing targets. very "are you who you say you are" of it 🫶
See the target property documentation for the full details.
CMAKE_MAXIMUM_RECURSION_DEPTH 🔥
Added in version 3.14.
Maximum recursion depth for CMake scripts. It's intended to be set on the command line with -DCMAKE_MAXIMUM_RECURSION_DEPTH=<x>, or inside CMakeLists.txt by projects that require a large recursion depth.
Projects that set this variable should give the user a way to override it. no gatekeeping!! 🫶
Like, for example:
# About to perform deeply recursive actions
if(NOT CMAKE_MAXIMUM_RECURSION_DEPTH)
set(CMAKE_MAXIMUM_RECURSION_DEPTH 2000)
endif()
If it's not set, or it's set to a non-integer value, a sensible default limit gets used. And if the recursion limit is actually reached? The script terminates immediately with a fatal error. no cap, it's over 💀
Calling any of these commands increases the recursion depth:
include()find_package()add_subdirectory()try_compile()ctest_read_custom_files()ctest_run_script()(unlessNEW_PROCESSis specified)- User-defined
function()'s andmacro()'s (note thatfunction()andmacro()themselves don't increase recursion depth — it's the calling that does) - Reading or writing variables that are being watched by a
variable_watch()
See also the CMAKE_MAXIMUM_RECURSION_DEPTH environment variable. twins 💖
CMAKE_MESSAGE_CONTEXT 🧚
Added in version 3.17.
When it's enabled by the cmake --log-context command line option or by the CMAKE_MESSAGE_CONTEXT_SHOW variable, the message() command converts the CMAKE_MESSAGE_CONTEXT list into a dot-separated string, wraps it in square brackets, and prepends it to each line for messages of log level NOTICE and below. cute little prefix, iconic 💅
For logging contexts to work effectively, projects should generally APPEND and POP_BACK an item to the current value of CMAKE_MESSAGE_CONTEXT rather than replacing it. And projects should not assume the message context at the top of the source tree is empty — there are scenarios where the context might already be set (hierarchical projects, for example). don't assume!! 🙈
Warning: valid context names are restricted to anything that could be used as a CMake variable name. All names that begin with an underscore or the string cmake_ are also reserved for use by CMake and should not be used by projects.
Example:
function(bar)
list(APPEND CMAKE_MESSAGE_CONTEXT "bar")
message(VERBOSE "bar VERBOSE message")
endfunction()
function(baz)
list(APPEND CMAKE_MESSAGE_CONTEXT "baz")
message(DEBUG "baz DEBUG message")
endfunction()
function(foo)
list(APPEND CMAKE_MESSAGE_CONTEXT "foo")
bar()
message(TRACE "foo TRACE message")
baz()
endfunction()
list(APPEND CMAKE_MESSAGE_CONTEXT "top")
message(VERBOSE "Before `foo`")
foo()
message(VERBOSE "After `foo`")
list(POP_BACK CMAKE_MESSAGE_CONTEXT)
Which results in the following output:
-- [top] Before `foo`
-- [top.foo.bar] bar VERBOSE message
-- [top.foo] foo TRACE message
-- [top.foo.baz] baz DEBUG message
-- [top] After `foo`
CMAKE_MESSAGE_CONTEXT_SHOW ⭐
Added in version 3.17.
Setting this variable to true enables showing a context with each line logged by the message() command (see CMAKE_MESSAGE_CONTEXT for how the context itself is specified). yes bestie, they're a duo 🫶
This variable is an alternative to providing the --log-context option on the cmake command line. The difference? The command line option applies only to that one CMake run, whereas setting CMAKE_MESSAGE_CONTEXT_SHOW to true as a cache variable means subsequent CMake runs will keep showing the message context. persistence, we love her 💖
Projects should not set CMAKE_MESSAGE_CONTEXT_SHOW. It's intended for users, so they can control whether context gets included with messages or not. hands off, projects ✋
CMAKE_MESSAGE_INDENT 🌸
Added in version 3.16.
The message() command joins the strings from this list, and then for log levels of NOTICE and below, it prepends the resulting string to each line of the message. pretty indentation, slay 🎀
Example:
list(APPEND listVar one two three)
message(VERBOSE [[Collected items in the "listVar":]])
list(APPEND CMAKE_MESSAGE_INDENT " ")
foreach(item IN LISTS listVar)
message(VERBOSE ${item})
endforeach()
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(VERBOSE "No more indent")
Which results in the following output:
-- Collected items in the "listVar":
-- one
-- two
-- three
-- No more indent
CMAKE_MESSAGE_LOG_LEVEL 💀
Added in version 3.17.
When it's set, this variable specifies the logging level used by the message() command. Valid values are the same as the ones for the --log-level command line option of the cmake(1) program. And if this variable is set and the --log-level command line option is given? The command line option wins. it's giving precedence 💅
The main advantage of using this variable is making a log level stick around between CMake runs. Setting it as a cache variable means subsequent CMake runs keep using the chosen log level. set it and forget it vibes ✨
Projects should not set this variable — it's intended for users so they can control the log level according to their own needs. say it louder for the people in the back 📢
Added in version 3.25: see the cmake_language(GET_MESSAGE_LOG_LEVEL) command for a way to query the current message logging level. peeping tom behavior, love that for us 👀
CMAKE_MFC_FLAG 👑
Use the MFC library for an executable or dll.
This enables the use of the Microsoft Foundation Classes (MFC). It should be set to 1 for the static MFC library, and 2 for the shared MFC library. This is used in Visual Studio project files.
Contents of CMAKE_MFC_FLAG may use generator expressions. fancy 🔥
Examples
Usage example:
set(CMAKE_MFC_FLAG 2)
add_executable(CMakeSetup WIN32 ${SRCS})
# Visual Studio generators add this flag automatically based on the
# CMAKE_MFC_FLAG value, but generators matching "Make" require it:
target_compile_definitions(CMakeSetup PRIVATE _AFXDLL)
See Also
- The
FindMFCmodule, to check whether MFC is installed and available. 🕵️
CMAKE_MODULE_PATH 🦋
A semicolon-separated list of directories, represented using forward slashes, specifying a search path for CMake modules to be loaded by the include() or find_package() commands — and it gets checked before the default modules that come with CMake. By default it's empty. It's intended to be set by the project.
It's fairly common for a project to have a directory containing various *.cmake files to help with development, and adding that directory to CMAKE_MODULE_PATH makes loading them so much simpler. Like, a project's top-level CMakeLists.txt file may contain:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Foo) # Loads ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Foo.cmake
find_package(Bar) # Loads ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindBar.cmake
look at that, everything just works 😭💖
CMAKE_PKG_CONFIG_DISABLE_UNINSTALLED 🌟
Added in version 4.0.
Enable / Disable the default "uninstalled" search behavior of the cmake_pkg_config() command. When this variable is false, package files with an -uninstalled suffix have higher priority than exact package name matches. priority queue but make it pkg-config 👑
CMAKE_PKG_CONFIG_PC_LIB_DIRS 🍓
Added in version 4.0.
A semicolon-separated list of primary paths which the cmake_pkg_config() command will search for package files by default. It's also used to derive the pc_path package variable. multi-purpose icon 💅
CMAKE_PKG_CONFIG_PC_PATH 💜
Added in version 4.0.
Okay so this next one is the semicolon-separated list of supplementary paths that the cmake_pkg_config() command will search for package files by default — and it's also used to derive the pc_path package variable. Two jobs, zero complaints, we love a multitasker 💅
CMAKE_PKG_CONFIG_SYSROOT_DIR</p>
Added in version 4.0.
A path that gets prepended to the -I include directories and -L library directories that cmake_pkg_config() extracts by default. It's also used to derive the pc_sysrootdir package variable. ✨
CMAKE_PKG_CONFIG_TOP_BUILD_DIR</p>
Added in version 4.0.
A path used to derive the pc_top_builddir package variable by the cmake_pkg_config() command, by default. That's it, that's the whole vibe 🎀
CMAKE_POLICY_DEFAULT_CMP<NNNN>
The default for CMake Policy CMP<NNNN> when it's otherwise left unset. 👑
The commands cmake_minimum_required(VERSION) and cmake_policy(VERSION) by default leave policies introduced after the given version unset. Set CMAKE_POLICY_DEFAULT_CMP<NNNN> to OLD or NEW to specify the default for policy CMP<NNNN>, where <NNNN> is the policy number.
Okay bestie, listen — this variable should not be set by a project in CMake code as a way to set its own policies. Use cmake_policy(SET) for that instead. This one is meant to externally set policies for which a project has not itself been updated 🫶
- Users running CMake may set this variable in the cache (e.g.
-DCMAKE_POLICY_DEFAULT_CMP<NNNN>=<OLD|NEW>). Set it toOLDto quiet a policy warning while using old behavior, or toNEWto try building the project with new behavior. - Projects may set this variable before a call to
add_subdirectory()that adds a third-party project, in order to set its policies without modifying third-party code.
See CMAKE_POLICY_VERSION_MINIMUM — that one sets policies to NEW based on the version of CMake that introduced them. Cute, right? 🌸
CMAKE_POLICY_VERSION_MINIMUM
Added in version 4.0.
Specify a minimum Policy Version for a project without modifying its calls to cmake_minimum_required(VERSION) and cmake_policy(VERSION). Sneaky? No. Iconic? Yes 💫
Same deal as above, bestie: this variable should not be set by a project in CMake code as a way to set its own policy version. Usecmake_minimum_required(VERSION)and/orcmake_policy(VERSION)for that. This variable is meant to externally set policies for which a project has not itself been updated ✨
- Users running CMake may set this variable in the cache, e.g.,
-DCMAKE_POLICY_VERSION_MINIMUM=3.5, to try configuring a project that has not been updated to set at least that policy version itself.
Alternatively, users may set the CMAKE_POLICY_VERSION_MINIMUM environment variable to initialize the cache entry in new build trees automatically. Set it once, forget it forever, main character energy 🔥
- Projects may set this variable before a call to
add_subdirectory()that adds a third-party project in order to set its policy version without modifying third-party code.
See CMAKE_POLICY_DEFAULT_CMP<NNNN> to set individual policies. 🎀
CMAKE_POLICY_WARNING_CMP<NNNN>
Explicitly enable or disable the warning when CMake Policy CMP<NNNN> has not been set explicitly by cmake_policy() or implicitly by cmake_minimum_required(). This is meaningful only for the policies that don't warn by default, and here's the full roster — no skipping, we're reading the whole list 📋
CMAKE_POLICY_WARNING_CMP0025controlled the warning for policyCMP0025in CMake versions before 4.0.CMAKE_POLICY_WARNING_CMP0047controlled the warning for policyCMP0047in CMake versions before 4.0.CMAKE_POLICY_WARNING_CMP0056controlled the warning for policyCMP0056in CMake versions before 4.0.CMAKE_POLICY_WARNING_CMP0060controlled the warning for policyCMP0060in CMake versions before 4.0.CMAKE_POLICY_WARNING_CMP0065controlled the warning for policyCMP0065in CMake versions before 4.0.CMAKE_POLICY_WARNING_CMP0066controls the warning for policyCMP0066.CMAKE_POLICY_WARNING_CMP0067controls the warning for policyCMP0067.CMAKE_POLICY_WARNING_CMP0082controls the warning for policyCMP0082.CMAKE_POLICY_WARNING_CMP0089controls the warning for policyCMP0089.CMAKE_POLICY_WARNING_CMP0102controls the warning for policyCMP0102.CMAKE_POLICY_WARNING_CMP0112controls the warning for policyCMP0112.CMAKE_POLICY_WARNING_CMP0116controls the warning for policyCMP0116.CMAKE_POLICY_WARNING_CMP0126controls the warning for policyCMP0126.CMAKE_POLICY_WARNING_CMP0128controls the warning for policyCMP0128.CMAKE_POLICY_WARNING_CMP0129controls the warning for policyCMP0129.CMAKE_POLICY_WARNING_CMP0133controls the warning for policyCMP0133.CMAKE_POLICY_WARNING_CMP0172controls the warning for policyCMP0172.CMAKE_POLICY_WARNING_CMP0206controls the warning for policyCMP0206.
Ngl bestie, this variable should not be set by a project in CMake code. Project developers running CMake may set this variable in their cache to enable the warning (e.g.-DCMAKE_POLICY_WARNING_CMP<NNNN>=ON). Alternatively, runningcmake(1)with the--debug-output,--trace, or--trace-expandoption will also enable the warning. Three ways to get the same tea ☕
CMAKE_PREFIX_PATH
A semicolon-separated list of directories specifying installation prefixes to be searched by the find_package(), find_program(), find_library(), find_file(), and find_path() commands. Each command will add appropriate subdirectories (like bin, lib, or include) as specified in its own documentation. 🦋
By default this is empty. It is intended to be set by the project.
There's also an environment variable CMAKE_PREFIX_PATH, which is used as an additional list of search prefixes. Double dipping, we love to see it 💜
See also CMAKE_SYSTEM_PREFIX_PATH, CMAKE_INCLUDE_PATH, CMAKE_LIBRARY_PATH, CMAKE_PROGRAM_PATH, and CMAKE_IGNORE_PATH. A whole friend group of path variables 🌈
CMAKE_PROGRAM_PATH
A semicolon-separated list of directories specifying a search path for the find_program() command. By default it is empty, and it's intended to be set by the project. 🫶
There's also an environment variable CMAKE_PROGRAM_PATH, which is used as an additional list of search directories.
See also CMAKE_SYSTEM_PROGRAM_PATH and CMAKE_PREFIX_PATH.
CMAKE_PROJECT_INCLUDE
Added in version 3.15.
A CMake language file to be included as the last step of all project() command calls. This is intended for injecting custom code into project builds without modifying their source. See Code Injection for a more detailed discussion of files potentially included during a project() call 💉
Added in version 3.29: This variable can be a semicolon-separated list of CMake language files to be included sequentially. It can also now refer to module names to be found in CMAKE_MODULE_PATH or as a builtin CMake module. Glow-up complete ✨
See also the CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE, CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE, CMAKE_PROJECT_INCLUDE_BEFORE, and CMAKE_PROJECT_TOP_LEVEL_INCLUDES variables.
CMAKE_PROJECT_INCLUDE_BEFORE
Added in version 3.15.
A CMake language file to be included as the first step of all project() command calls. Same deal — this is intended for injecting custom code into project builds without modifying their source. See Code Injection for a more detailed discussion of files potentially included during a project() call 🎀
Added in version 3.29: This variable can be a semicolon-separated list of CMake language files to be included sequentially. It can also now refer to module names to be found in CMAKE_MODULE_PATH or as a builtin CMake module. ✨
See also the CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE, CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE, CMAKE_PROJECT_INCLUDE, and CMAKE_PROJECT_TOP_LEVEL_INCLUDES variables.
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE
A CMake language file to be included as the last step of any project() command calls that specify <PROJECT-NAME> as the project name. This is intended for injecting custom code into project builds without modifying their source. See Code Injection for a more detailed discussion of files potentially included during a project() call 💖
Added in version 3.29: This variable can be a semicolon-separated list of CMake language files to be included sequentially. It can also now refer to module names to be found in CMAKE_MODULE_PATH or as a builtin CMake module. 🦋
See also the CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE, CMAKE_PROJECT_INCLUDE, CMAKE_PROJECT_INCLUDE_BEFORE, and CMAKE_PROJECT_TOP_LEVEL_INCLUDES variables.
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE
Added in version 3.17.
...a CMake language file that gets included as the very first step of any project() call that specifies <PROJECT-NAME> as the project name. Like, before anything else happens, this file gets its moment. It's for injecting custom code into project builds without touching their source — sneaky but in a slay way. Peep the Code Injection discussion if you want the full lore on which files can potentially get included during a project() call. 💅
Added in version 3.29: this variable can be a semicolon-separated list of CMake language files, and they'll be included sequentially. It can also now refer to module names — ones found in CMAKE_MODULE_PATH or builtin to CMake. glow up ✨
Also go look at the CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE, CMAKE_PROJECT_INCLUDE, CMAKE_PROJECT_INCLUDE_BEFORE, and CMAKE_PROJECT_TOP_LEVEL_INCLUDES variables. they're the cousins.
🫶 CMAKE_PROJECT_TOP_LEVEL_INCLUDES
Added in version 3.24.
A semicolon-separated list of CMake language files to include as part of the very first project() call. The timing is honestly so specific: they get included immediately after the toolchain file has been read (if you specified one) and the platform variables have been set — but before any languages have been enabled. So yeah, language-specific variables, including stuff like CMAKE_<LANG>_COMPILER, might not be set yet. Not a bug, just the vibe of that moment. See Code Injection for the detailed discussion of files that might get included during a project() call.
Added in version 3.29: this variable can also now refer to module names found in CMAKE_MODULE_PATH or builtin to CMake. 💖
This one is for specifying files that do one-time setup for the build. It's your injection point for things like configuring package managers, adding logic you share between your projects (e.g. defining your own custom build types), and so on. It's primarily for users adding things specific to their environment — not for specifying toolchain details (use CMAKE_TOOLCHAIN_FILE for that, bestie, stay in your lane).
By default this variable is empty. It's meant to be set by the user.
See also:
CMAKE_PROJECT_INCLUDECMAKE_PROJECT_INCLUDE_BEFORECMAKE_PROJECT_<PROJECT-NAME>_INCLUDECMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFOREPROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
🎀 CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
Added in version 3.22.
The variable that makes a find_package() call REQUIRED. Basically a glow-up for your dependency checks. 👑
Every non-REQUIRED find_package() call in a project can be turned into REQUIRED by setting the variable CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> to TRUE. It's for asserting assumptions about your build environment and making sure the build fails early if they don't hold.
⚠️ heads up: setting this variable to true breaks some commonly used patterns. fr fr, read this part.
Multiple calls to find_package() are sometimes used to get a different search order than the default. For example, projects can force checking a known path for a particular package first, before searching any of the other default search paths:
find_package(something PATHS /some/local/path NO_DEFAULT_PATH)
find_package(something)
In the above, the first call looks for the something package in a specific directory. If CMAKE_REQUIRE_FIND_PACKAGE_something is set to true, then this first call must succeed, otherwise a fatal error occurs 😭. The second call never gets a chance to provide a fall-back to using the default search locations. rip to the fallback.
A similar pattern is used even by some of CMake's own Find modules to search for a config package first:
find_package(something CONFIG QUIET)
if(NOT something_FOUND)
# Fall back to searching using typical Find module logic...
endif()
Again, if CMAKE_REQUIRE_FIND_PACKAGE_something is true, the first call must succeed. Which effectively means a config package must be found for the dependency, and the Find module logic is never used. it's giving "no plan B".
See also the CMAKE_DISABLE_FIND_PACKAGE_<PackageName> variable.
💀 CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
Don't make the install target depend on the all target. that's the whole thing. 💅
By default, the install target depends on the all target. This has the effect that when make install is invoked or INSTALL is built, first the all target is built, then the installation starts. If CMAKE_SKIP_INSTALL_ALL_DEPENDENCY is set to TRUE, this dependency is not created, so the installation process will start immediately, independent of whether the project has been completely built or not. which, yes, means it can install half-built garbage if you're not paying attention. 🙈
See also CMAKE_SKIP_TEST_ALL_DEPENDENCY.
🦋 CMAKE_SKIP_TEST_ALL_DEPENDENCY
Added in version 3.29.
Controls whether the test target depends on the all target. vibe check for your test runs 🌸
If this variable is not defined, or is set to TRUE, then the test (or RUN_TESTS) target does not depend on the all (or ALL_BUILD) target. When the test target is built, e.g., via make test, the test process will start immediately, regardless of whether the project has been completely built or not.
If CMAKE_SKIP_TEST_ALL_DEPENDENCY is explicitly set to FALSE, then the test target will depend on the all target. When the test target is built, e.g., via make test, the all target will be built first, and then the tests will run.
See also CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.
🧚 CMAKE_STAGING_PREFIX
You can set this variable to a path to install to when cross-compiling. Super useful if the path in CMAKE_SYSROOT is read-only, or otherwise should stay pristine (like, don't touch the sysroot, she's not your project's storage unit).
The CMAKE_STAGING_PREFIX location is also used as a search prefix by the find_* commands. You can control that by setting the CMAKE_FIND_NO_INSTALL_PREFIX variable.
And if any RPATH/RUNPATH entries passed to the linker contain the CMAKE_STAGING_PREFIX, the matching path fragments get replaced with the CMAKE_INSTALL_PREFIX. little switcheroo ✨
🍓 CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
Added in version 3.8.
This variable contains a list of env vars, written as a list of tokens using the var=value syntax.
Example:
set(CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
"FOO=FOO1\;FOO2\;FOON"
"BAR=BAR1\;BAR2\;BARN"
"BAZ=BAZ1\;BAZ2\;BAZN"
"FOOBAR=FOOBAR1\;FOOBAR2\;FOOBARN"
"VALID="
)
In case of malformed variables, CMake will fail:
set(CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
"THIS_IS_NOT_VALID"
)
😭 yes, THIS_IS_NOT_VALID is literally the error message vibe. it will fail.
🌈 CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE
Added in version 3.8.
If this variable evaluates to ON at the end of the top-level CMakeLists.txt file, the Sublime Text 2 extra generator excludes the build tree from the .sublime-project if it is inside the source tree. clean 🧼
⭐ CMAKE_SUPPRESS_REGENERATION
Added in version 3.12.
If CMAKE_SUPPRESS_REGENERATION is OFF — which is default — then CMake adds a special target on which all other targets depend, that checks the build system and optionally re-runs CMake to regenerate the build system when the target specification source changes. she's ✨proactive✨
If this variable evaluates to ON at the end of the top-level CMakeLists.txt file, CMake will not add the regeneration target to the build system or perform any build system checks. 🛑 no thoughts, no re-runs.
💜 CMAKE_SYSROOT
Path to pass to the compiler in the --sysroot flag.
The CMAKE_SYSROOT content is passed to the compiler in the --sysroot flag, if supported. The path is also stripped from the RPATH/RUNPATH if necessary on installation. And the CMAKE_SYSROOT is also used to prefix paths searched by the find_* commands.
🚨 important: this variable may only be set in a toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable. nowhere else. don't try it. fr fr.
See also the CMAKE_SYSROOT_COMPILE and CMAKE_SYSROOT_LINK variables.
🎀 CMAKE_SYSROOT_COMPILE
Added in version 3.9.
Path to pass to the compiler in the --sysroot flag when compiling source files. Same as CMAKE_SYSROOT but used only for compiling sources and not linking. so it's the compile-only sister 💅
Same rule as above: this variable may only be set in a toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable.
🎀 CMAKE_SYSROOT_LINK
Added in version 3.9.
Path to pass to the compiler in the --sysroot flag when linking. Same as CMAKE_SYSROOT but used only for linking and not compiling sources. link-only sister, equally iconic 🫶
And again: this variable may only be set in a toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable.
🦋 CMAKE_SYSTEM_APPBUNDLE_PATH
Added in version 3.4.
Search path for macOS application bundles, used by the find_program() and find_package() commands. By default it contains the standard directories for the current system. It is not intended to be modified by the project — use CMAKE_APPBUNDLE_PATH for that instead. don't touch, it's hers 💅
🦋 CMAKE_SYSTEM_FRAMEWORK_PATH
Added in version 3.4.
Search path for macOS frameworks, used by the find_library(), find_package(), find_path(), and find_file() commands. By default it contains the standard directories for the current system. It is not intended to be modified by the project — use CMAKE_FRAMEWORK_PATH for that. same energy, different variable 🍓
🌸 CMAKE_SYSTEM_IGNORE_PATH
Semicolon-separated list of directories to be ignored by the various find...() commands.
Okay so, for find_program(), find_library(), find_file(), and find_path(): any file found in one of the listed directories is getting ignored, periodt 🙈. And lowkey a trap — those listed directories do not apply recursively, so any subdirectories you want ignored must also be explicitly listed. Every single one. No vibes-based guessing 💅.
Also, giant neon sign: CMAKE_SYSTEM_IGNORE_PATH does not affect the search prefixes used by those four commands. If you want to ignore individual paths under a search prefix (like bin, include, lib, etc.), each path must be listed in CMAKE_SYSTEM_IGNORE_PATH as a full absolute path 🎀. And heads up: CMAKE_SYSTEM_IGNORE_PREFIX_PATH is the more appropriate way to ignore a whole search prefix. Use the right tool, bestie 🫶.
find_package() is also affected by CMAKE_SYSTEM_IGNORE_PATH, but only for Config mode searches. Any <Name>Config.cmake or <name>-config.cmake file found in one of the specified directories will be ignored ✨. And in addition, any search prefix found in CMAKE_SYSTEM_IGNORE_PATH will be skipped for backward compatibility reasons — but new code should prefer to use CMAKE_SYSTEM_IGNORE_PREFIX_PATH to ignore prefixes instead. Old-school behaviour stays for the OGs, iykyk 💀.
Why even do this? Ignoring search locations can be useful in cross-compiling environments where some system directories contain incompatible but possibly linkable libraries 😭. For example, on cross-compiled cluster environments, this allows a user to ignore directories containing libraries meant for the front-end machine. Very much "this library is not for you, babe" energy 🔥.
Real talk though: CMAKE_SYSTEM_IGNORE_PATH is populated by CMake as part of its platform and toolchain setup. Its purpose is to ignore locations containing incompatible binaries meant for the host rather than the target platform. The project or end user should not modify this variable — they should use CMAKE_IGNORE_PATH instead 👑.
See also the following variables:
CMAKE_SYSTEM_IGNORE_PREFIX_PATHCMAKE_SYSTEM_PREFIX_PATHCMAKE_SYSTEM_LIBRARY_PATHCMAKE_SYSTEM_INCLUDE_PATHCMAKE_SYSTEM_PROGRAM_PATH
🦋 CMAKE_SYSTEM_IGNORE_PREFIX_PATH
Added in version 3.23 ✨.
A semicolon-separated list of search prefixes to be ignored by the find_program(), find_library(), find_file(), and find_path() commands. The prefixes are also ignored by the Config mode of the find_package() command (Module mode is unaffected — stay in your lane, Module mode 💅). Wanna ignore specific directories instead? See CMAKE_SYSTEM_IGNORE_PATH 🎀.
Ignoring search locations can be useful in cross-compiling environments where some system directories contain incompatible but possibly linkable libraries 😭. For example, on cross-compiled cluster environments, this allows a user to ignore directories containing libraries meant for the front-end machine. Iconic cross-compile survival behaviour, honestly 🌈.
CMAKE_SYSTEM_IGNORE_PREFIX_PATH is populated by CMake as part of its platform and toolchain setup. Its purpose is to ignore locations containing incompatible binaries meant for the host rather than the target platform. The project or end user should not modify this variable — they should use CMAKE_IGNORE_PREFIX_PATH instead 🫶.
See also the following variables:
CMAKE_SYSTEM_IGNORE_PATHCMAKE_SYSTEM_PREFIX_PATHCMAKE_SYSTEM_LIBRARY_PATHCMAKE_SYSTEM_INCLUDE_PATHCMAKE_SYSTEM_PROGRAM_PATH
🌸 CMAKE_SYSTEM_INCLUDE_PATH
A semicolon-separated list of directories specifying a search path for the find_file() and find_path() commands 🎀. By default this contains the standard directories for the current system. It is not intended to be modified by the project — use CMAKE_INCLUDE_PATH for this, okay? No touching 💅. See also CMAKE_SYSTEM_PREFIX_PATH 🌟.
🧚 CMAKE_SYSTEM_LIBRARY_PATH
A semicolon-separated list of directories specifying a search path for the find_library() command 🔥. By default this contains the standard directories for the current system. It is not intended to be modified by the project — use CMAKE_LIBRARY_PATH for this instead 🫶. See also CMAKE_SYSTEM_PREFIX_PATH ✨.
👑 CMAKE_SYSTEM_PREFIX_PATH
A semicolon-separated list of directories specifying installation prefixes to be searched by the find_package(), find_program(), find_library(), find_file(), and find_path() commands 🌈. Each command will add appropriate subdirectories (like bin, lib, or include) as specified in its own documentation. So like, it does the subdirectory math for you, slay 💅.
By default this contains the system directories for the current system, the CMAKE_INSTALL_PREFIX, and the CMAKE_STAGING_PREFIX. The installation and staging prefixes may be excluded by setting the CMAKE_FIND_NO_INSTALL_PREFIX variable before the first project() invocation — timing matters, bestie, don't @ me 💀.
The system directories that are contained in CMAKE_SYSTEM_PREFIX_PATH are locations that typically include installed software. An example being /usr/local for UNIX based platforms 🌸. In addition to standard platform locations, CMake will also add values to CMAKE_SYSTEM_PREFIX_PATH based on environment variables. The environment variables and search locations that CMake uses may evolve over time, as platforms and their conventions also evolve 👀. The following provides an indicative list of environment variables and locations that CMake searches, but they are subject to change:
CrayLinuxEnvironment:
ENV{SYSROOT_DIR}/ENV{SYSROOT_DIR}/usrENV{SYSROOT_DIR}/usr/local
Darwin:
ENV{SDKROOT}/usr— whenCMAKE_OSX_SYSROOTis not explicitly specified 🍓
OpenBSD:
ENV{LOCALBASE}
Unix:
ENV{CONDA_PREFIX}— when using a conda compiler 🐍
MSYSTEM environment with MinGW toolchain: Added in version 3.28 ✨.
ENV{MSYSTEM_PREFIX}/localENV{MSYSTEM_PREFIX}
Windows:
ENV{ProgramW6432}ENV{ProgramFiles}ENV{ProgramFiles(x86)}ENV{SystemDrive}/Program FilesENV{SystemDrive}/Program Files (x86)
CMAKE_SYSTEM_PREFIX_PATH is not intended to be modified by the project — use CMAKE_PREFIX_PATH for this, please and thank you 🫶.
See also CMAKE_SYSTEM_INCLUDE_PATH, CMAKE_SYSTEM_LIBRARY_PATH, CMAKE_SYSTEM_PROGRAM_PATH, and CMAKE_SYSTEM_IGNORE_PATH 💖.
🎀 CMAKE_SYSTEM_PROGRAM_PATH
A semicolon-separated list of directories specifying a search path for the find_program() command 🦋. By default this contains the standard directories for the current system. It is not intended to be modified by the project — use CMAKE_PROGRAM_PATH for this instead 💅. See also CMAKE_SYSTEM_PREFIX_PATH ⭐.
🔐 CMAKE_TLS_CAINFO
Specify the default value for the file(DOWNLOAD) and file(UPLOAD) commands' TLS_CAINFO options 🎀. It is unset by default. Chill, it's not secretive, it's just unset 🙈.
This variable is also used by the ExternalProject and FetchContent modules for internal calls to file(DOWNLOAD) ✨.
🔒 CMAKE_TLS_VERIFY
Specify the default value for the file(DOWNLOAD) and file(UPLOAD) commands' TLS_VERIFY options 🛡️. If this variable is not set, the commands check the CMAKE_TLS_VERIFY environment variable. If neither is set, the default is on 👑.
Changed in version 3.31: The default is on. Previously, the default was off 😱. Users may set the CMAKE_TLS_VERIFY environment variable to 0 to restore the old default. (Living dangerously, I see 💀.)
This variable is also used by the ExternalProject and FetchContent modules for internal calls to file(DOWNLOAD) ✨.
TLS verification can help provide confidence that one is connecting to the desired server 🫶. When downloading known content, one should also use file hashes to verify it — verification besties, both of them, no skipping 💅.
set(CMAKE_TLS_VERIFY TRUE)
🦋 CMAKE_TLS_VERSION
Added in version 3.30 ✨.
Specify the default value for the file(DOWNLOAD) and file(UPLOAD) commands' TLS_VERSION option 🌈. If this variable is not set, the commands check the CMAKE_TLS_VERSION environment variable. If neither is set, the default is TLS 1.2 🎀.
Changed in version 3.31: The default is TLS 1.2. Previously, no minimum version was enforced by default 😭.
The value may be one of:
1.01.11.21.3
This variable is also used by the ExternalProject and FetchContent modules for internal calls to file(DOWNLOAD) and git clone 🔥.
🧚 CMAKE_USER_MAKE_RULES_OVERRIDE
Specify a CMake file that overrides platform information 👑.
CMake loads the specified file while enabling support for each language from either the project() or enable_language() commands 🎀. It is loaded after CMake's builtin compiler and platform information modules have been loaded but before the information is used — that window right there, that's your moment ⏱️. The file may set platform information variables to override CMake's defaults 💅. See CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG> for the language-specific version of this variable 🌟.
This whole feature is only for overriding information variables that have to be set before CMake builds its very first test project to check that a compiler for a given language actually works. It is not for loading a file in cases where a normal include() would do the job. Use it only as a last resort, for behavior you literally cannot achieve any other way. For example, you could set CMAKE_<LANG>_FLAGS_INIT to change the default value used to initialize CMAKE_<LANG>_FLAGS before it gets cached. The override file should NOT be used to set anything that could be set after languages are enabled — like, say, variables such as CMAKE_RUNTIME_OUTPUT_DIRECTORY that affect the placement of binaries. And heads up: information set in the file gets used for try_compile() and try_run() builds too.
🎀 CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
Tells the cmake_install.cmake script to warn you every single time it bumps into a file with an absolute INSTALL DESTINATION. Every time. No cap. 😭
This variable is used by CMake-generated cmake_install.cmake scripts. If you set this variable to ON while running the script, you may get warning messages from the script.
✨ Added in version 4.4: the CMD_INSTALL_ABSOLUTE_DESTINATION diagnostic can be used to generate warnings for absolute install destinations at generate time.
See also CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION. 💜
🌈 CMAKE_XCODE_GENERATE_SCHEME
Added in version 3.9.
If enabled, the Xcode generator will generate schema files. These are super useful for invoking analyze, archive, build-for-testing and test actions straight from the command line. 👑
This variable initializes the XCODE_GENERATE_SCHEME target property on all targets.
🦋 CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY
Added in version 3.11.
If enabled, the Xcode generator will generate only a single Xcode project file for the topmost project() command instead of generating one for every project() command. One project, one file, that's it. ✨
This could be useful to speed up the CMake generation step for large projects, and to work around a bug in the ZERO_CHECK logic. (Yes, a real bug. We don't make the rules. 💀)
💅 CMAKE_XCODE_LINK_BUILD_PHASE_MODE
Added in version 3.19.
This variable is used to initialize the XCODE_LINK_BUILD_PHASE_MODE property on targets. It affects the methods that the Xcode generator uses to link different kinds of libraries. Its default value is NONE.
🧚 CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER
Added in version 3.13.
Whether to enable Address Sanitizer in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_ADDRESS_SANITIZER property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties. 🫶
🍓 CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
Added in version 3.13.
Whether to enable Detect use of stack after return in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🌸 CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
Added in version 3.16.
Whether to enable Allow debugging when using document Versions Browser in the Options section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
💖 CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
Added in version 3.13.
Whether to disable the Main Thread Checker in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
⭐ CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
Added in version 3.13.
Whether to enable Dynamic Library Loads in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🎀 CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
Added in version 3.13.
Whether to enable Dynamic Linker API usage in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🔥 CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
Added in version 3.25.
Populate Metal: API Validation in the Options section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_ENABLE_GPU_API_VALIDATION property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🌈 CMAKE_XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
Added in version 3.23.
Populate GPU Frame Capture in the Options section of the generated Xcode scheme. Example values are Metal and Disabled.
This variable initializes the XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🦋 CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
Added in version 3.25.
Populate Metal: Shader Validation in the Options section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
👑 CMAKE_XCODE_SCHEME_ENVIRONMENT
Added in version 3.17.
Specify environment variables that should be added to the Arguments section of the generated Xcode scheme. 🫶
If set to a list of environment variables and values of the form MYVAR=value those environment variables will be added to the scheme.
This variable initializes the XCODE_SCHEME_ENVIRONMENT property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
💜 CMAKE_XCODE_SCHEME_GUARD_MALLOC
Added in version 3.13.
Whether to enable Guard Malloc in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_GUARD_MALLOC property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
✨ CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
Added in version 3.25.
Set the build configuration to run the target.
This variable initializes the XCODE_SCHEME_LAUNCH_CONFIGURATION property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🧚 CMAKE_XCODE_SCHEME_LAUNCH_MODE
Added in version 3.25.
Populate Launch in the Info section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_LAUNCH_MODE property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🌸 CMAKE_XCODE_SCHEME_LLDB_INIT_FILE
Added in version 4.0.
Populate LLDB Init File in the Info section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_LLDB_INIT_FILE property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
💖 CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
Added in version 3.13.
Whether to enable the Main Thread Checker option Pause on issues in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🍓 CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
Added in version 3.13.
Whether to enable Malloc Guard Edges in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_MALLOC_GUARD_EDGES property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🎀 CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
Added in version 3.13.
Whether to enable Malloc Scribble in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_MALLOC_SCRIBBLE property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode schema related properties.
🦋 CMAKE_XCODE_SCHEME_MALLOC_STACK
Added in version 3.13.
Whether to enable Malloc Stack over in the Diagnostics section of the generated Xcode scheme. 💅
This variable initializes the XCODE_SCHEME_MALLOC_STACK property on all targets.
And please go read the XCODE_GENERATE_SCHEME target property docs, bestie — that's where all the Xcode scheme-related properties live. 🎀
CMAKE_XCODE_SCHEME_TEST_CONFIGURATION
Added in version 4.0.
Sets the build configuration for testing targets. 🧪
This variable initializes the XCODE_SCHEME_TEST_CONFIGURATION property on all targets.
Again — the XCODE_GENERATE_SCHEME target property documentation is your one-stop shop for every Xcode scheme-related property. ✨
CMAKE_XCODE_SCHEME_THREAD_SANITIZER
Added in version 3.13.
Whether to enable Thread Sanitizer in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_THREAD_SANITIZER property on all targets.
Refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode scheme related properties. 🦋
CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
Added in version 3.13.
Whether to enable Thread Sanitizer - Pause on issues in the Diagnostics section of the generated Xcode scheme. 😭
This variable initializes the XCODE_SCHEME_THREAD_SANITIZER_STOP property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode scheme related properties.
CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
Added in version 3.13.
Whether to enable Undefined Behavior Sanitizer in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode scheme related properties. 🫶
CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
Added in version 3.13.
Whether to enable the Undefined Behavior Sanitizer option Pause on issues in the Diagnostics section of the generated Xcode scheme.
This variable initializes the XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode scheme related properties. 🌸
CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
Added in version 3.17.
Specifies the Working Directory of the Run and Profile actions in the generated Xcode scheme. 👑
This variable initializes the XCODE_SCHEME_WORKING_DIRECTORY property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode scheme related properties.
CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
Added in version 3.13.
Whether to enable Zombie Objects in the Diagnostics section of the generated Xcode scheme. 🧟💀
This variable initializes the XCODE_SCHEME_ZOMBIE_OBJECTS property on all targets.
Please refer to the XCODE_GENERATE_SCHEME target property documentation to see all Xcode scheme related properties.
CMAKE_XCODE_XCCONFIG
Added in version 3.24.
If you set this, the Xcode generator will register the file you specify as a global XCConfig file. If you're looking for per-target XCConfig files, that's over at the XCODE_XCCONFIG target property. 💅
This feature exists to make migrating from native Xcode projects over to CMake projects less painful — it's giving "we got you". 🫶
The contents of CMAKE_XCODE_XCCONFIG are allowed to use generator expressions. ✨
<PackageName>_ROOT
Added in version 3.12.
Calls to find_package(<PackageName>) will search in the prefixes specified by the <PackageName>_ROOT CMake variable — where <PackageName> is the name you gave to the find_package() call, with its case preserved, and _ROOT is literal, bestie. So for example, find_package(Foo) searches the prefixes set in the Foo_ROOT CMake variable (if it's set, anyway). See policy CMP0074. 🎀
This variable can hold a single prefix, or a semicolon-separated list of multiple prefixes. 😌
Also go check out the <PackageName>_ROOT environment variable, iykyk.
<PACKAGENAME>_ROOT
Added in version 3.27.
Calls to find_package(<PackageName>) will also search in the prefixes specified by the upper-case <PACKAGENAME>_ROOT CMake variable. See policy CMP0144. 👀
🌈 VARIABLES THAT DESCRIBE THE SYSTEM 🌈
AIX
Added in version 4.0.
Set to true when the target system is AIX.
ANDROID
Added in version 3.7.
Set to 1 when the target system (CMAKE_SYSTEM_NAME) is Android. 🤖
APPLE
Set to True when the target system is an Apple platform — that's macOS, iOS, tvOS, visionOS or watchOS. 🍎
BORLAND
True if the Borland compiler is being used.
This one is set to true if the Borland compiler is being used.
BSD
Added in version 3.25.
Set to a string value when the target system is BSD. That value can be one of the following: DragonFlyBSD, FreeBSD, OpenBSD, or NetBSD. 🐡
CMAKE_ANDROID_NDK_VERSION
Added in version 3.20.
When cross compiling for Android with the NDK, and you're using Android NDK version 11 or higher, CMake hands you this variable to report the NDK version number. 🧚
CMAKE_CL_64
Discouraged. Use CMAKE_SIZEOF_VOID_P instead, fr fr.
Set to a true value when you're using a Microsoft Visual Studio cl compiler that targets a 64-bit architecture.
CMAKE_COMPILER_2005
Using the Visual Studio 2005 compiler from Microsoft.
Set to true when you're using the Visual Studio 2005 compiler from Microsoft. 😭 (throwback era ngl)
CMAKE_HOST_AIX
Added in version 4.0.
Set to true when the host system is AIX.
CMAKE_HOST_APPLE
True for Apple macOS operating systems.
Set to true when the host system is Apple macOS. 🍏
CMAKE_HOST_BSD
Added in version 3.25.
Set to a string value when the host system is BSD. That value can be one of the following: DragonFlyBSD, FreeBSD, OpenBSD, or NetBSD.
CMAKE_HOST_EXECUTABLE_SUFFIX
Added in version 3.31.
The suffix for executables on the host platform. Heads up: this may be different from the suffix for the target platform, CMAKE_EXECUTABLE_SUFFIX. 👀
It's the suffix to use for the end of an executable filename, if there is one — .exe on Windows, for example.
See also CMAKE_EXECUTABLE_SUFFIX.
CMAKE_HOST_LINUX
Added in version 3.25.
Set to true when the host system is Linux. 🐧
CMAKE_HOST_SOLARIS
Added in version 3.6.
True for Oracle Solaris operating systems.
Set to true when the host system is Oracle Solaris. ☀️
CMAKE_HOST_SYSTEM
The composite name of the OS CMake is being run on.
This variable is literally the composite of CMAKE_HOST_SYSTEM_NAME and CMAKE_HOST_SYSTEM_VERSION, like ${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_VERSION}. But if CMAKE_HOST_SYSTEM_VERSION isn't set, then this variable is just the same as CMAKE_HOST_SYSTEM_NAME. 💅
CMAKE_HOST_SYSTEM_NAME
The name of the OS CMake is running on.
On systems that have the uname command, this variable is set to the output of uname -s. And the values you'll find on the big three operating systems are Linux, Windows, and Darwin for macOS. 👑
For a list of possible values, go look at CMAKE_SYSTEM_NAME.
CMAKE_HOST_SYSTEM_PROCESSOR
The name of the CPU CMake is running on. 🧠
Windows Platforms
On Windows, this variable is set to the value of the environment variable PROCESSOR_ARCHITECTURE.
Unix Platforms
On systems that support uname, this variable is set to the output of:
uname -mon GNU, Linux, Cygwin, Android, orarchon OpenBSD, or- on other systems,
uname -pif its exit code is nonzero, oruname -motherwise.
macOS Platforms
The value of uname -m is used by default.
On Apple Silicon hosts, the architecture printed by uname -m may vary based on CMake's own architecture and that of the invoking process tree. 🌀
Added in version 3.19.2: On Apple Silicon hosts:
- The
CMAKE_APPLE_SILICON_PROCESSORvariable or theCMAKE_APPLE_SILICON_PROCESSORenvironment variable may be set to specify the host architecture explicitly. - If
CMAKE_OSX_ARCHITECTURESis not set, CMake adds explicit flags to tell the compiler to build for the host architecture, so the toolchain doesn't have to guess based on the process tree's architecture. 🫶
CMAKE_HOST_SYSTEM_VERSION
The OS version CMake is running on.
It's a numeric version string for the system. On systems that support uname, this variable is set to the output of uname -r. On other systems, it's set to major-minor version numbers.
CMAKE_HOST_UNIX
True for UNIX and UNIX like operating systems.
Set to true when the host system is UNIX or UNIX like (i.e. APPLE and CYGWIN). 🐚
CMAKE_HOST_WIN32
True if the host system is running Windows — including Windows 64-bit and MSYS. 🪟
Set to false on Cygwin. (not me, Cygwin, catching strays 😭)
CMAKE_LIBRARY_ARCHITECTURE
Target architecture library directory name, if it's been detected.
This is the value of CMAKE_<LANG>_LIBRARY_ARCHITECTURE as detected for one of the enabled languages. ✨
CMAKE_LIBRARY_ARCHITECTURE_REGEX
A regex matching the possible target architecture library directory names.
It's used to detect CMAKE_<LANG>_LIBRARY_ARCHITECTURE from the implicit linker search path, by matching the <arch> name. 🔍
CMAKE_OBJECT_PATH_MAX
Maximum object file full-path length allowed by native build tools. 📏 Don't exceed it — the build tools will not be chill about it.
Okay so real talk, bestie: CMake computes, for every single source file, an object file name that is unique to that source file and deterministic with respect to the full path to the source file. Why do we care? Because that's how multiple source files in one target get to share the same name when they live in different directories without triggering a rebuild the moment one gets added or removed. Iconic behavior honestly. 🎀
But 😭 it can produce long full paths in a few cases, so CMake shortens the path using a hashing scheme when the full path to an object file exceeds a limit. CMake has a built-in limit for each platform that's sufficient for common tools, but some native tools may have a lower limit. This variable may be set to specify the limit explicitly — and the value must be an integer no less than 128. Like, that's the floor, no negotiating. 🙅♀️
CMAKE_SYSTEM
Composite name of the operating system CMake is compiling for. ✨
This variable is the composite of CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_VERSION, e.g. ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}. And if CMAKE_SYSTEM_VERSION is not set? Then this variable is literally the same as CMAKE_SYSTEM_NAME. Simple as that. 💅
CMAKE_SYSTEM_NAME
The name of the operating system for which CMake is to build. Peep the CMAKE_SYSTEM_VERSION variable for the OS version. 🦋
Heads up bestie: CMAKE_SYSTEM_NAME is not set to anything by default when running in script mode, since it's not building anything. No build, no system name, that's the vibe.
System Name for Host Builds
CMAKE_SYSTEM_NAME is by default set to the same value as the CMAKE_HOST_SYSTEM_NAME variable, so that the build targets the host system. 🫶
System Name for Cross Compiling
CMAKE_SYSTEM_NAME may be set explicitly when first configuring a new build tree in order to enable cross compiling. In this case the CMAKE_SYSTEM_VERSION variable must also be set explicitly. Both or nothing, periodt. 🔥
System Names Known to CMake
The following is a list of possible values, each associated with corresponding operating systems or environments. Buckle up, it's a long one. 💀
Apple Platforms 🍓
Darwin— Apple stationary operating systems (macOS, OS X, etc.)iOS— Apple mobile phone operating system. Added in version 3.14.tvOS— Apple TV operating system. Added in version 3.14.visionOS— Apple mixed reality operating system. Added in version 3.28.watchOS— Apple watch operating system. Added in version 3.14.
UNIX Platforms 🧚
ADSP— Analog Devices Audio Digital Signal ProcessingAIX— IBM Unix operating systemAndroid— Android operating system. Added in version 3.1.ARTOS— Operating system for microcontrollers. Added in version 3.4.BeOS— Operating system for personal computers (discontinued)BlueGeneL— Blue Gene/L static environmentBlueGeneP-dynamic— Blue Gene/P dynamic environmentBlueGeneP-static— Blue Gene/P static environmentBlueGeneQ-dynamic— Blue Gene/Q dynamic environment. Added in version 3.3.BlueGeneQ-static— Blue Gene/Q static environment. Added in version 3.3.BSDOS— BSD operating system (discontinued)Catamount— Operating system for Cray XT seriesCrayLinuxEnvironment— Cray Linux Environment. Added in version 3.5.DragonFly— BSD-derived operating systemeCos— Real-time embedded operating systemEmscripten— Compiler toolchain to WebAssembly. Added in version 4.2.Euros— Real-time operating system for embedded devices. Added in version 3.4.FreeBSD— FreeBSD operating systemFuchsia— Operating system by Google based on the Zircon kernel. Added in version 3.8.Generic-ADSP— Generic ADSP (Audio DSP) environmentGeneric-ELF— Generic ELF (Executable and Linkable Format) environment. Added in version 3.23.Generic— Some platforms, e.g. bare metal embedded devicesGHS-MULTI— Green Hills Software MULTI environment. Added in version 3.3.GNU— GNU/Hurd-based operating systemHaiku— Unix operating system inspired by BeOSHP-UX— Hewlett Packard Unix (discontinued)Linux— All Linux-based distributionsMirBSD— MirOS BSD operating systemMP-RAS— MP-RAS UNIX operating systemNetBSD— NetBSD operating systemsOHOS— OpenHarmony family of operating systems (e.g., HarmonyOS). Added in version 3.30. Toolchain file can set this value when targeting OpenHarmony operating systems.OpenBSD— OpenBSD operating systemsOpenVMS— OpenVMS operating system by HPOS2— OS/2 operating system. Added in version 3.18.OSF1— Compaq Tru64 UNIX (formerly DEC OSF/1, Digital Unix) (discontinued)QNX— Unix-like operating system by BlackBerryRISCos— RISC OS operating systemSCO_SV— SCO OpenServer 5SerenityOS— Unix-like operating system. Added in version 3.25.SINIX— SINIX operating systemSunOS— Oracle Solaris and all illumos operating systemssyllable— Syllable operating systemTru64— Compaq Tru64 UNIX (formerly DEC OSF/1) operating systemULTRIX— Unix operating system (discontinued)UNIX_SV— SCO UnixWare (pre release 7)UnixWare— SCO UnixWare 7WASI— WebAssembly System Interface. Added in version 3.31.Xenix— SCO Xenix Unix operating system (discontinued)
Windows Platforms 🌈
CYGWIN— Cygwin environment for Windows. Cygwin's cmake package (/usr/bin/cmake) uses system nameCYGWIN. A non-cygwin CMake on Windows (e.g.$PROGRAMFILES/CMake/bin/cmake) uses system nameWindowseven when it runs under a Cygwin environment.DOS— MS-DOS or compatibleMidipix— POSIX-compatible layer for Windows. Added in version 3.10.MSYS— MSYS environment (MSYSTEM=MSYS). MSYS2's msys/cmake package (/usr/bin/cmake) works only underMSYSTEM=MSYSenvironments, with system nameMSYS. Under other environments likeMSYSTEM=MINGW64, use another package such as mingw64/mingw-w64-x86_64-cmake (/mingw64/bin/cmake), which targetsMSYSTEM=MINGW64with system nameWindows.Windows— Windows stationary operating systemsWindowsCE— Windows Embedded CompactWindowsKernelModeDriver— Windows Kernel-Mode Driver. Added in version 4.1. When building drivers for Kernel-Mode Driver Framework on Windows, toolchain file can set this value. See also theCMAKE_WINDOWS_KMDF_VERSIONvariable.WindowsPhone— Windows mobile phone operating system. Added in version 3.1.WindowsStore— Universal Windows Platform applications. Added in version 3.1.
Removed Platforms 💀
The following platforms were once supported by CMake and got removed either due to platform's EOL, or other incompatibilities:
kFreeBSD— FreeBSD kernel with a GNU userland. Changed in version 4.1: Removed from CMake.
CMAKE_SYSTEM_PROCESSOR
When not cross-compiling, this variable has the same value as the CMAKE_HOST_SYSTEM_PROCESSOR variable. In many cases, this will correspond to the target architecture for the build, but that is not guaranteed. (E.g. on Windows, the host may be AMD64 even when using a MSVC cl compiler with a 32-bit target. Sneaky like that. 🙈)
When cross-compiling, a CMAKE_TOOLCHAIN_FILE should set the CMAKE_SYSTEM_PROCESSOR variable to match the target architecture that it specifies (via CMAKE_<LANG>_COMPILER and perhaps CMAKE_<LANG>_COMPILER_TARGET). Don't leave it guessing, bestie. 💅
CMAKE_SYSTEM_VERSION
The version of the operating system for which CMake is to build. Peep the CMAKE_SYSTEM_NAME variable for the OS name. ⭐
System Version for Host Builds
When the CMAKE_SYSTEM_NAME variable takes its default value, then CMAKE_SYSTEM_VERSION is by default set to the same value as the CMAKE_HOST_SYSTEM_VERSION variable, so that the build targets the host system version. 🫶
In the case of a host build, then CMAKE_SYSTEM_VERSION may be set explicitly when first configuring a new build tree in order to enable targeting the build for a different version of the host operating system than is actually running on the host. This is allowed and not considered cross compiling, so long as the binaries built for the specified OS version can still run on the host. iykyk. 🔥
System Version for Cross Compiling
When the CMAKE_SYSTEM_NAME variable is set explicitly to enable cross compiling, then the value of CMAKE_SYSTEM_VERSION must also be set explicitly to specify the target system version. Both flags, every time. Periodt.
CYGWIN
True for Cygwin.
Set to true when using Cygwin. 🐧
GHSMULTI
Added in version 3.3.
1 when using the Green Hills MULTI generator. 🌸
Also, set to 1 when the target system is a Green Hills platform (i.e. when CMAKE_SYSTEM_NAME is GHS-MULTI). Two ways in, same vibe.
IOS
Added in version 3.14.
Set to 1 when the target system (CMAKE_SYSTEM_NAME) is iOS. 🍎
LINUX
Added in version 3.25.
Set to true when the target system is Linux. 🐧✨
MINGW
Added in version 3.2.
Set to a true value when at least one language is enabled with a compiler targeting the GNU ABI on Windows (MinGW).
Otherwise, this variable is not set by CMake. Like, it's just not there. Don't go checking it expecting false, okay? 😭
MSVC
Set to true when the compiler is some version of Microsoft Visual C++ or another compiler simulating the Visual C++ cl command-line syntax.
See also the MSVC_VERSION variable. 👑
MSVC_IDE
True when using the Microsoft Visual C++ IDE.
Set to true when the target platform is the Microsoft Visual C++ IDE, as opposed to the command line compiler. 🖥️
Note: This variable is only available after compiler detection has been performed, so it is not available to toolchain files or before the firstproject()orenable_language()call which uses an MSVC-like compiler. Plan accordingly bestie, it will lowkey not exist yet. 💀
MSVC_TOOLSET_VERSION
Added in version 3.12.
The toolset version of Microsoft Visual C/C++ that's in play, if any. If an MSVC-like compiler is being used, this baby gets set based on the compiler version as given by the MSVC_VERSION variable. iykyk 🫶
The known toolset version numbers are, bestie, exactly these:
80— VS 2005 (8.0)90— VS 2008 (9.0)100— VS 2010 (10.0)110— VS 2012 (11.0)120— VS 2013 (12.0)140— VS 2015 (14.0)141— VS 2017 (15.0)142— VS 2019 (16.0)143— VS 2022 (17.0)145— VS 2026 (18.0)
Compiler versions newer than the ones CMake knows about? They just get reported as the latest known toolset version. No cap, that's the whole deal 💅
See also the MSVC_VERSION variable.
💜 MSVC_VERSION 💜
The version of Microsoft Visual C/C++ being used, if any. If a compiler that's simulating Visual C++ is being used, this variable gets set to the toolset version being simulated, as given by the _MSC_VER preprocessor definition. Sneaky but iconic ✨
The known version numbers are:
1200— VS 6.01300— VS 7.01310— VS 7.11400— VS 8.0 (v80 toolset)1500— VS 9.0 (v90 toolset)1600— VS 10.0 (v100 toolset)1700— VS 11.0 (v110 toolset)1800— VS 12.0 (v120 toolset)1900— VS 14.0 (v140 toolset)1910-1919— VS 15.0 (v141 toolset)1920-1929— VS 16.0 (v142 toolset)1930-1949— VS 17.0 (v143 toolset)1950-1959— VS 18.0 (v145 toolset)
See also the CMAKE_<LANG>_COMPILER_VERSION and MSVC_TOOLSET_VERSION variable. 🎀
🌸 MSYS 🌸
Added in version 3.14.
True when you're using the MSYS Makefiles generator. That's it. That's the vibe check. ✅
🦋 UNIX 🦋
Set to True when the target system is UNIX or UNIX-like (e.g. APPLE and CYGWIN). Literally the whole Unix family reunion 🫶
Bestie pls note: if you need a more specific understanding of the target system, you should query the CMAKE_SYSTEM_NAME variable instead. Don't just assume, okay?
💖 WASI 💖
Added in version 3.31.
Set to 1 when the target system is WebAssembly System Interface (that's when CMAKE_SYSTEM_NAME is WASI). WebAssembly girlies rise 🔥
⭐ WIN32 ⭐
Set to True when the target system is Windows, including Win64. Windows gang, we see you 👑
🎀 WINCE 🎀
Added in version 3.1.
True when the CMAKE_SYSTEM_NAME variable is set to WindowsCE.
🍓 WINDOWS_PHONE 🍓
Added in version 3.1.
True when the CMAKE_SYSTEM_NAME variable is set to WindowsPhone.
🌈 WINDOWS_STORE 🌈
Added in version 3.1.
True when the CMAKE_SYSTEM_NAME variable is set to WindowsStore.
🧚 XCODE 🧚
Added in version 3.7.
True when you're using the Xcode generator. Apple devs stay winning 🍎
👑 XCODE_VERSION 👑
Version of Xcode (Xcode generator only).
Under the Xcode generator, this is the version of Xcode as specified in Xcode.app/Contents/version.plist (such as 3.1.2). Fr fr, that's where it lives.
🔥 VARIABLES THAT CONTROL THE BUILD 🔥
Okay bestie, this is the big one — the section where you actually steer the build. Buckle up 💅
💅 CMAKE_ADSP_ROOT 💅
Added in version 3.24.
When Cross Compiling for ADSP SHARC/Blackfin, this variable holds the absolute path to the latest CCES or VDSP++ install. The directory is expected to contain the cc21k.exe and ccblkfn.exe compilers. And the best part? It gets set automatically if a default install of CCES or VDSP++ can be found. Not me being helpful for once 😭
See also the ADSP_ROOT environment variable.
✨ CMAKE_AIX_EXPORT_ALL_SYMBOLS ✨
Added in version 3.17.
Default value for the AIX_EXPORT_ALL_SYMBOLS target property. This variable is used to initialize that property on each target as it's created. Set it and forget it, hottie 🫶
🎀 CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 🎀
Added in version 3.31.
On AIX, enable or disable creation of shared library archives.
This variable initializes the AIX_SHARED_LIBRARY_ARCHIVE target property on non-imported SHARED library targets as they're created by add_library(). Peep that target property for the details, okay? 💖
🦋 CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS 🦋
Added in version 3.4.
Default value for the ANDROID_ANT_ADDITIONAL_OPTIONS target property. Go read that target property for the extra info, bestie 📖
🌸 CMAKE_ANDROID_API 🌸
Added in version 3.1.
When Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio Edition, this variable may be set to specify the default value for the ANDROID_API target property. See that target property for additional information.
And when you're Cross Compiling for Android, the CMAKE_SYSTEM_VERSION variable represents the Android API version number targeted. For historical reasons (🙈 messy but we love her), if a toolchain file sets CMAKE_ANDROID_API but not CMAKE_SYSTEM_VERSION, the latter will be initialized using the former.
⭐ CMAKE_ANDROID_API_MIN ⭐
Added in version 3.2.
Default value for the ANDROID_API_MIN target property. See that target property for additional information. Short and sweet 💅
🌈 CMAKE_ANDROID_ARCH 🌈
Added in version 3.4.
When Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio Edition, this variable may be set to specify the default value for the ANDROID_ARCH target property. See that target property for additional information.
Otherwise, when Cross Compiling for Android, this variable provides the name of the Android architecture corresponding to the value of the CMAKE_ANDROID_ARCH_ABI variable. The architecture name may be one of:
armarm64mipsmips64x86x86_64
🍓 CMAKE_ANDROID_ARCH_ABI 🍓
Added in version 3.7.
When Cross Compiling for Android, this variable specifies the target architecture and ABI to be used. The valid values are, and I'm quoting the vibe exactly:
arm64-v8aarmeabi-v7aarmeabi-v6armeabimipsmips64x86x86_64
See also the CMAKE_ANDROID_ARM_MODE and CMAKE_ANDROID_ARM_NEON variables. Teamwork makes the dream work 🫶
🧚 CMAKE_ANDROID_ARM_MODE 🧚
Added in version 3.7.
When Cross Compiling for Android and CMAKE_ANDROID_ARCH_ABI is set to one of the armeabi architectures, set CMAKE_ANDROID_ARM_MODE to ON to target 32-bit ARM processors (-marm). Otherwise, the default is to target the 16-bit Thumb processors (-mthumb). Tiny thumb energy, lowkey adorable 😭
💜 CMAKE_ANDROID_ARM_NEON 💜
Added in version 3.7.
When Cross Compiling for Android and CMAKE_ANDROID_ARCH_ABI is set to armeabi-v7a, set CMAKE_ANDROID_ARM_NEON to ON to target ARM NEON devices. Slay that vectorization 🎀
CMAKE_ANDROID_ASSETS_DIRECTORIES 🍓
Added in version 3.4.
This is the default value for the ANDROID_ASSETS_DIRECTORIES target property — that's literally her whole job. Need the deets? Go read that target property, bestie, she spills everything. ✨
CMAKE_ANDROID_EXCEPTIONS 🎀
Added in version 3.20.
When you're cross compiling for Android with the NDK, you can set this variable to specify whether exceptions are enabled. That's the vibe check. 💅
CMAKE_ANDROID_GUI 🦋
Added in version 3.1.
The default value for the ANDROID_GUI target property on executables. See that target property for additional information — she's the main character, this variable is just her understudy. ✨
CMAKE_ANDROID_JAR_DEPENDENCIES 🌸
Added in version 3.4.
Default value for the ANDROID_JAR_DEPENDENCIES target property. See that target property for additional information, iykyk. 💖
CMAKE_ANDROID_JAR_DIRECTORIES 🧚
Added in version 3.4.
Default value for the ANDROID_JAR_DIRECTORIES target property. See that target property for additional information. No notes. 🎀
CMAKE_ANDROID_JAVA_SOURCE_DIR 🌈
Added in version 3.4.
Default value for the ANDROID_JAVA_SOURCE_DIR target property. See that target property for additional information. Slay. 💅
CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES ⭐
Added in version 3.4.
Default value for the ANDROID_NATIVE_LIB_DEPENDENCIES target property. See that target property for additional information. 💜
CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES 🫶
Added in version 3.4.
Default value for the ANDROID_NATIVE_LIB_DIRECTORIES target property. See that target property for additional information. That's it, that's the post. ✨
CMAKE_ANDROID_NDK 🔥
Added in version 3.7.
When cross compiling for Android with the NDK, this variable holds the absolute path to the root directory of the NDK. And listen — the directory must contain a platforms subdirectory holding the android-<api> directories. Not optional, bestie, it's giving requirement. 👑
CMAKE_ANDROID_NDK_DEPRECATED_HEADERS 💀
Added in version 3.9.
When cross compiling for Android with the NDK, you may set this variable to specify whether to use the deprecated per-api-level headers instead of the unified headers. (Deprecated ones, in case the name didn't tip you off 🙈)
If you don't specify it, the default is false when you're using an NDK version that provides the unified headers, and true otherwise. So like, it adapts. Iconic behaviour honestly. ✨
CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG 🎀
Added in version 3.7.1.
When cross compiling for Android with the NDK, this variable provides the NDK's "host tag" — which is what gets used to construct the path to prebuilt toolchains that run on the host. Path-building queen. 💅
CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION 🦋
Added in version 3.7.
When cross compiling for Android with the NDK, you may set this variable to specify the version of the toolchain to be used as the compiler.
Okay now the rules, because there are rules:
- On NDK r19 or above, this variable must be unset or set to
clang. - On NDK r18 or below, this variable must be set to one of these forms:
<major>.<minor>: GCC of specified versionclang<major>.<minor>: Clang of specified versionclang: Clang of most recent available version
A toolchain of the requested version will be selected automatically to match the ABI named in the CMAKE_ANDROID_ARCH_ABI variable. Match made in heaven fr fr. 💖
If not specified, the default will be a value that selects the latest available GCC toolchain.
CMAKE_ANDROID_PROCESS_MAX 🌸
Added in version 3.4.
Default value for the ANDROID_PROCESS_MAX target property. See that target property for additional information. 🎀
CMAKE_ANDROID_PROGUARD ⭐
Added in version 3.4.
Default value for the ANDROID_PROGUARD target property. See that target property for additional information. 💅
CMAKE_ANDROID_PROGUARD_CONFIG_PATH 🧚
Added in version 3.4.
Default value for the ANDROID_PROGUARD_CONFIG_PATH target property. See that target property for additional information. 🦋
CMAKE_ANDROID_RTTI 💜
Added in version 3.20.
When cross compiling for Android with the NDK, you may set this variable to specify whether RTTI is enabled. Yes/no, on/off, that's the whole gig. ✨
CMAKE_ANDROID_SECURE_PROPS_PATH 🌈
Added in version 3.4.
Default value for the ANDROID_SECURE_PROPS_PATH target property. See that target property for additional information. 🫶
CMAKE_ANDROID_SKIP_ANT_STEP 🍓
Added in version 3.4.
Default value for the ANDROID_SKIP_ANT_STEP target property. See that target property for additional information. Skipping the ant step? Living that skip-the-whole-thing lifestyle. 💅
CMAKE_ANDROID_STANDALONE_TOOLCHAIN 🔥
Added in version 3.7.
When cross compiling for Android with a standalone toolchain, this variable holds the absolute path to the root directory of the toolchain. And the specified directory must contain a sysroot subdirectory. Non-negotiable, bestie. 💀
CMAKE_ANDROID_STL_TYPE 👑
Added in version 3.4.
Two whole situations here, so buckle up:
Situation one: When cross compiling for Android with NVIDIA Nsight Tegra Visual Studio Edition, you may set this variable to specify the default value for the ANDROID_STL_TYPE target property. See that target property for additional information.
Situation two: When cross compiling for Android with the NDK, you may set this variable to specify the STL variant to be used. And the value may be one of:
none— No C++ Supportsystem— Minimal C++ without STLgabi++_static— GAbi++ Staticgabi++_shared— GAbi++ Sharedgnustl_static— GNU libstdc++ Staticgnustl_shared— GNU libstdc++ Sharedc++_static— LLVM libc++ Staticc++_shared— LLVM libc++ Sharedstlport_static— STLport Staticstlport_shared— STLport Shared
The default value is gnustl_static on NDK versions that provide it and otherwise c++_static. And heads up — this default differs from the native NDK build system, because CMake may be used to build projects for Android that are not natively implemented for it and use the C++ standard library. So don't come for her about the mismatch, the reasoning is right there. 😭
CMAKE_APPLE_SILICON_PROCESSOR 🦋
Added in version 3.19.2.
On Apple Silicon hosts running macOS, set this variable to tell CMake what architecture to use for CMAKE_HOST_SYSTEM_PROCESSOR. The value must be either arm64 or x86_64 — those are the only two options, no freestyling. 💅
The value of this variable should never be modified by project code. It's meant to be set as a cache entry provided by the user, e.g. via -DCMAKE_APPLE_SILICON_PROCESSOR=.... Like, hands off, project code. 🙈
See also the CMAKE_APPLE_SILICON_PROCESSOR environment variable. ✨
CMAKE_ARCHIVE_OUTPUT_DIRECTORY 🎀
Where to put all the ARCHIVE target files when built. 📦
This variable is used to initialize the ARCHIVE_OUTPUT_DIRECTORY property on all the targets. See that target property for additional information. ✨
CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG> 🌸
Added in version 3.3.
Where to put all the ARCHIVE target files when built for a specific configuration. Same energy, one config at a time. 💅
This variable is used to initialize the ARCHIVE_OUTPUT_DIRECTORY_<CONFIG> property on all the targets. See that target property for additional information. 🎀
CMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG ⭐
Added in version 3.29.
This variable is used to initialize the AUTOGEN_BETTER_GRAPH_MULTI_CONFIG property on all targets as they are created. See that target property for additional information.
By default CMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG is unset. 💜
CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX 🔥
Added in version 3.29.
This is the command line length limit for autogen targets — i.e. moc or uic — that triggers the use of response files on Windows instead of passing all arguments to the command line. She's the bouncer at the command line club. 👑
By default CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX is unset. ✨
CMAKE_AUTOGEN_ORIGIN_DEPENDS 🧚
Added in version 3.14.
This is the switch for forwarding origin target dependencies to the corresponding <ORIGIN>_autogen targets.
Note: If the<ORIGIN>_autogen_timestamp_depstarget is created, additional target dependencies are added to it instead of the<ORIGIN>_autogentarget. When using the Visual Studio Generators, themocanduicstep may be part of the<ORIGIN>target itself, in which case the dependencies are added to<ORIGIN>. See thecmake-qt(7)manual for details. 🫶
This variable is used to initialize the AUTOGEN_ORIGIN_DEPENDS property on all the targets. See that target property for additional information.
By default CMAKE_AUTOGEN_ORIGIN_DEPENDS is ON. 🎀
CMAKE_AUTOGEN_PARALLEL 🌈
Added in version 3.11.
Number of parallel moc or uic processes to start when using AUTOMOC and AUTOUIC. Parallelism, we love to see it. 💅
This variable is used to initialize the AUTOGEN_PARALLEL property on all the targets. See that target property for additional information.
By default CMAKE_AUTOGEN_PARALLEL is unset. ✨
CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE 🍓
Added in version 3.27.
This variable is used to initialize the AUTOGEN_USE_SYSTEM_INCLUDE property on all targets as they are created. See that target property for additional information.
By default CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE is unset. 💜
CMAKE_AUTOGEN_VERBOSE 🌸
Added in version 3.13.
Sets the verbosity of AUTOMOC, AUTOUIC and AUTORCC. A positive integer value or a true boolean value lets the AUTO* generators output additional processing information. She's loud and she's proud. 📣
Setting CMAKE_AUTOGEN_VERBOSE has the same effect as setting the VERBOSE environment variable during generation (e.g. by calling make VERBOSE=1). The extra verbosity is limited to the AUTO* generators though — so no, the rest of the build isn't gonna start oversharing. 🙈
By default CMAKE_AUTOGEN_VERBOSE is unset. 🦋
CMAKE_AUTOMOC 👑
Whether to handle moc automatically for Qt targets.
This variable is used to initialize the AUTOMOC property on all the targets. See that target property for additional information. 💅
🎀 CMAKE_AUTOMOC_COMPILER_PREDEFINES
Added in version 3.10. ✨
Okay so this one initializes the AUTOMOC_COMPILER_PREDEFINES property on, like, all the targets. See that target property for the extra deets, bestie.
Default? ON. Periodt. 💅
🦋 CMAKE_AUTOMOC_DEPEND_FILTERS
Added in version 3.9. ✨
These are the filter definitions that CMAKE_AUTOMOC uses to pull file names out of your source code so they can become extra dependencies for the moc file. iykyk.
This variable initializes the AUTOMOC_DEPEND_FILTERS property on all the targets — go peek at that target property for more info.
Default is empty. Ngl, it's giving blank canvas. 🌸
🧚 CMAKE_AUTOMOC_EXECUTABLE
Added in version 3.27. ✨
Initializes the AUTOMOC_EXECUTABLE property on every single target. Check that target property for the full story.
By default it's empty. 🫶
💜 CMAKE_AUTOMOC_INCLUDE_DIRECTORIES
Added in version 4.1. ✨
This one specifies zero or more include directories for AUTOMOC to pass explicitly to the Qt Meta-Object Compiler (moc) — instead of automatically discovering each target's include directories. Not me letting you take control. 😭
The directories you list here will replace any include paths discovered from target properties like INCLUDE_DIRECTORIES. So yeah, they're overridden. 💀
This variable initializes the AUTOMOC_INCLUDE_DIRECTORIES property on all the targets. See that target property for additional information.
⭐ CMAKE_AUTOMOC_MACRO_NAMES
Added in version 3.10. ✨
A semicolon-separated list (yes, that kind of list) of macro names that CMAKE_AUTOMOC uses to figure out whether a C++ file needs to be processed by moc.
This variable initializes the AUTOMOC_MACRO_NAMES property on all the targets. See that target property for additional information.
The default value is Q_OBJECT;Q_GADGET;Q_NAMESPACE;Q_NAMESPACE_EXPORT. Slay. 👑
🌈 Example
Let CMake know that source files containing CUSTOM_MACRO gotta be moc-processed too:
set(CMAKE_AUTOMOC ON)
list(APPEND CMAKE_AUTOMOC_MACRO_NAMES "CUSTOM_MACRO")
🍓 CMAKE_AUTOMOC_MOC_OPTIONS
Extra options for moc when you're using CMAKE_AUTOMOC. Obsessed with customization fr fr.
This variable initializes the AUTOMOC_MOC_OPTIONS property on all the targets. See that target property for additional information.
💖 CMAKE_AUTOMOC_PATH_PREFIX
Added in version 3.16. ✨
Whether to generate the -p path prefix option for moc on AUTOMOC-enabled Qt targets. The way this just works. 🦋
This variable initializes the AUTOMOC_PATH_PREFIX property on all the targets. See that target property for additional information.
The default value is OFF.
🌸 CMAKE_AUTORCC
Whether to handle rcc automatically for Qt targets. Lowkey essential.
This variable initializes the AUTORCC property on all the targets. See that target property for additional information.
🫶 CMAKE_AUTORCC_EXECUTABLE
Added in version 3.27. ✨
Initializes the AUTORCC_EXECUTABLE property on all the targets. See that target property for the full tea.
By default it's empty. 🎀
🔥 CMAKE_AUTORCC_OPTIONS
Extra options for rcc when you're using CMAKE_AUTORCC. Customize away bestie.
This variable initializes the AUTORCC_OPTIONS property on all the targets. See that target property for additional information.
✨ EXAMPLE
# ...
set(CMAKE_AUTORCC_OPTIONS "--compress;9")
# ...
💅 CMAKE_AUTOUIC
Whether to handle uic automatically for Qt targets. Main character energy.
This variable initializes the AUTOUIC property on all the targets. See that target property for additional information.
🌈 CMAKE_AUTOUIC_EXECUTABLE
Added in version 3.27. ✨
Initializes the AUTOUIC_EXECUTABLE property on all the targets. See that target property for more.
By default it's empty. ⭐
🦋 CMAKE_AUTOUIC_OPTIONS
Extra options for uic when you're using CMAKE_AUTOUIC. So good.
This variable initializes the AUTOUIC_OPTIONS property on all the targets. See that target property for additional information.
✨ EXAMPLE
# ...
set_property(CMAKE_AUTOUIC_OPTIONS "--no-protection")
# ...
🧚 CMAKE_AUTOUIC_SEARCH_PATHS
Added in version 3.9. ✨
The search path list CMAKE_AUTOUIC uses to find included .ui files. It's giving detective era. 🔍
This variable initializes the AUTOUIC_SEARCH_PATHS property on all the targets. See that target property for additional information.
By default it's empty. 💜
🎀 CMAKE_BUILD_RPATH
Added in version 3.8. ✨
A semicolon-separated list specifying runtime path (RPATH) entries to add to binaries linked in the build tree — but only on platforms that support it, bestie. These entries won't be used for binaries in the install tree. Also peep CMAKE_INSTALL_RPATH if you're nosy.
This initializes the BUILD_RPATH target property for all targets.
👑 CMAKE_BUILD_RPATH_USE_ORIGIN
Added in version 3.14. ✨
Whether to use relative paths for the build RPATH. Relative?? Iconic behavior.
This initializes the BUILD_RPATH_USE_ORIGIN target property for all targets — see that property for more details.
🍓 CMAKE_BUILD_WITH_INSTALL_NAME_DIR
Added in version 3.9. ✨
Whether to use INSTALL_NAME_DIR on targets in the build tree. Big decision, ngl.
This variable initializes the BUILD_WITH_INSTALL_NAME_DIR property on all targets.
💖 CMAKE_BUILD_WITH_INSTALL_RPATH
Use the install path for the RPATH. Okay so here's the lore:
Normally CMake uses the build tree for the RPATH when building executables etc. on systems that use RPATH. When the software gets installed, the executables etc. are relinked by CMake to have the install RPATH. But if you set this variable to true, the software is always built with the install path for the RPATH — and doesn't need to be relinked when installed. Efficiency queen. ✨
This initializes the BUILD_WITH_INSTALL_RPATH target property for all targets.
🦋 CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
Added in version 3.1. ✨
Output directory for MS debug symbol .pdb files generated by the compiler while it's building source files.
This variable initializes the COMPILE_PDB_OUTPUT_DIRECTORY property on all the targets.
🌸 CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
Added in version 3.1. ✨
Per-configuration output directory for those MS debug symbol .pdb files the compiler generates while building source files. It's the per-config glow-up of CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY 💅
This variable initializes the COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG> property on all the targets.
⭐ CMAKE_COMPILE_WARNING_AS_ERROR
Added in version 3.24. ✨
Specify whether to treat warnings on compile as errors. Scary but make it fashion. 😭
This variable initializes the COMPILE_WARNING_AS_ERROR property on all the targets.
🎀 CMAKE_<CONFIG>_POSTFIX
Default filename postfix for libraries under configuration <CONFIG>.
When a non-executable target gets created, its <CONFIG>_POSTFIX target property is initialized with the value of this variable — but only if it's set. Conditional queen. 🌈
🔥 CMAKE_CROSS_CONFIGS
Added in version 3.17. ✨
Specifies a semicolon-separated list of configurations available from all build-<Config>.ninja files in the Ninja Multi-Config generator. This variable activates cross-config mode — so targets from each config you specify here can be built from any build-<Config>.ninja file. Custom commands will use the configuration native to build-<Config>.ninja.
If you set it to all, then all configurations from CMAKE_CONFIGURATION_TYPES are cross-configs. If it's not specified, or it's empty, each build-<Config>.ninja file will only contain build rules for its own configuration. No sharing, no slay. 💀
The value of this variable must be a subset of CMAKE_CONFIGURATION_TYPES.
🦋 CMAKE_CTEST_ARGUMENTS
Added in version 3.17. ✨
Set this to a semicolon-separated list of command-line arguments to pass to ctest(1) when you're running tests through the test (or RUN_TESTS) target of the generated build system. Pass the vibes along, bestie. 🫶
💜 CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
Added in version 3.16. ✨
Default value for the CUDA_RESOLVE_DEVICE_SYMBOLS target property when it's defined. But heads up — by default this variable is not defined.
This variable initializes the property on each target as it's created.
🌈 CMAKE_CUDA_RUNTIME_LIBRARY
Added in version 3.17. ✨
Select the CUDA runtime library for use when compiling and linking CUDA. This variable initializes the CUDA_RUNTIME_LIBRARY property on all targets as they're created.
The allowed case insensitive values are:
None— Link with-cudart=noneor equivalent flag(s) to use no CUDA runtime library.Shared— Link with-cudart=sharedor equivalent flag(s) to use a dynamically-linked CUDA runtime library.Static— Link with-cudart=staticor equivalent flag(s) to use a statically-linked CUDA runtime library.
Contents of CMAKE_CUDA_RUNTIME_LIBRARY may use generator expressions.
If this variable isn't set, then the CUDA_RUNTIME_LIBRARY target property won't be set automatically. And if that property isn't set, CMake uses an appropriate default value based on the compiler to select the CUDA runtime library. It's giving "figure it out yourself." 😌
Note: 💀 This property has effect only when the CUDA language is enabled. To control the CUDA runtime linking when you're only using the CUDA SDK with the C or C++ language, we recommend using the FindCUDAToolkit module. ✨
🍓 CMAKE_CUDA_SEPARABLE_COMPILATION
Added in version 3.11. ✨
Default value for the CUDA_SEPARABLE_COMPILATION target property. This variable initializes the property on each target as it's created. 🫶
CMAKE_CXX_MODULE_STD
✨ Added in version 3.30.
okay so this one's a yes/no vibe check: do we add utility targets as dependencies to targets that have at least cxx_std_23, or not? 🫶
💀 Note: this setting is only meaningful when experimental support forimport std;has been enabled by theCMAKE_EXPERIMENTAL_CXX_IMPORT_STDgate. Like, the door's gotta be open first, bestie.
This variable is used to initialize the CXX_MODULE_STD property on all the targets. See that target property for the extra deets, iykyk.
CMAKE_CXX_SCAN_FOR_MODULES
✨ Added in version 3.28.
Whether we scan C++ source files for module dependencies or not. 🔍
This variable is used to initialize the CXX_SCAN_FOR_MODULES property on all the targets. See that target property for additional information.
CMAKE_DEBUG_POSTFIX
See the variable CMAKE_<CONFIG>_POSTFIX.
This one is literally just a special case of the more-general CMAKE_<CONFIG>_POSTFIX variable, but for the DEBUG configuration. That's it, that's the whole thing. 🎀
CMAKE_DEBUGGER_WORKING_DIRECTORY
✨ Added in version 4.0.
This variable is used to initialize the DEBUGGER_WORKING_DIRECTORY property on each target as it is created. See that target property for additional information. 🐛
CMAKE_DEFAULT_BUILD_TYPE
✨ Added in version 3.17.
Specifies the configuration to use by default in a build.ninja file in the Ninja Multi-Config generator. 👑
If this variable is specified, build.ninja uses build rules from build-<Config>.ninja by default. All custom commands are executed with this configuration.
If the variable is not specified, the first item from CMAKE_CONFIGURATION_TYPES is used instead.
⚠️ The value of this variable must be one of the items from CMAKE_CONFIGURATION_TYPES.
CMAKE_DEFAULT_CONFIGS
✨ Added in version 3.17.
Specifies a semicolon-separated list of configurations to build for a target in build.ninja if no :<Config> suffix is specified, in the Ninja Multi-Config generator. 🦋
- If it is set to
all, all configurations fromCMAKE_CROSS_CONFIGSare used. - If it is not specified, it defaults to
CMAKE_DEFAULT_BUILD_TYPE.
For example, if you set CMAKE_DEFAULT_BUILD_TYPE to Release, but set CMAKE_DEFAULT_CONFIGS to Debug or all, all <target> aliases in build.ninja will resolve to <target>:Debug or <target>:all — but custom commands will still use the Release configuration. iconic behaviour tbh.
💀 The value of this variable must be a subset ofCMAKE_CROSS_CONFIGS, or be the same asCMAKE_DEFAULT_BUILD_TYPE. It must not be specified ifCMAKE_DEFAULT_BUILD_TYPEorCMAKE_CROSS_CONFIGSis not used.
CMAKE_DEPENDS_USE_COMPILER
✨ Added in version 3.20.
For the Makefile Generators, source dependencies are now — for a selection of compilers — generated by the compiler itself. 🛠️
By defining this variable with value FALSE, you can restore the legacy behavior (i.e. using CMake for dependencies discovery). yes she has a nostalgia mode, don't @ me.
CMAKE_DISABLE_PRECOMPILE_HEADERS
✨ Added in version 3.16.
Default value for DISABLE_PRECOMPILE_HEADERS of targets.
By default CMAKE_DISABLE_PRECOMPILE_HEADERS is OFF. 🌸
CMAKE_DLL_NAME_WITH_SOVERSION
✨ Added in version 3.27.
This variable is used to initialize the DLL_NAME_WITH_SOVERSION property on shared library targets for the Windows platform — which is selected when the WIN32 variable is set. 🪟
See this target property for additional information.
🙈 Please note that setting this variable has no effect if versioned filenames are globally disabled with the CMAKE_PLATFORM_NO_VERSIONED_SONAME variable.
CMAKE_EXECUTABLE_ENABLE_EXPORTS
✨ Added in version 3.27.
Specify whether executables export symbols for loadable modules.
This variable is used to initialize the ENABLE_EXPORTS target property for executable targets when they are created by calls to the add_executable() command. See the property documentation for details. 📦
This variable supersedes the CMAKE_ENABLE_EXPORTS variable. she's the upgrade, periodt.
See Also
- The
CMAKE_SHARED_LIBRARY_ENABLE_EXPORTSvariable.
CMAKE_EXE_LINKER_FLAGS
Linker flags to be used to create executables. 🔗
These flags will be used by the linker when creating an executable for all build configurations.
Handling Compiler Driver Differences
✨ Added in version 4.0.
So to pass options to the linker tool, each compiler driver has its own little syntax situation going on. The LINKER: prefix and , separator can be used to specify, in a portable way, options to pass to the linker tool.
LINKER:gets replaced by the appropriate driver option,gets replaced 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.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC. two different outfits, same look, slay 💅
The LINKER: prefix supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. The previous example then becomes "LINKER:SHELL:-z defs".
💀 Note: Specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. like, it has to go first, no cutting the line.
This support implies to parse and re-quote the content of the variable. See policy CMP0181.
See Also
CMAKE_EXE_LINKER_FLAGS_<CONFIG>
CMAKE_EXE_LINKER_FLAGS_<CONFIG>
Flags to be used when linking an executable.
These flags will be used by the linker when creating an executable for the <CONFIG> configuration. 🎯
Handling Compiler Driver Differences
✨ Added in version 4.0.
To pass options to the linker tool, each compiler driver has its own syntax. The LINKER: prefix and , separator can be used to specify, in a portable way, options to pass to the linker tool.
LINKER:is replaced by the appropriate driver option,is replaced 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.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC.
The LINKER: prefix supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. The previous example then becomes "LINKER:SHELL:-z defs".
💀 Note: Specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported.
This support implies to parse and re-quote the content of the variable. See policy CMP0181.
See Also
CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT
✨ Added in version 3.7.
Value used to initialize the CMAKE_EXE_LINKER_FLAGS_<CONFIG> cache entry the first time a build tree is configured. 🌱
This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform.
See also CMAKE_EXE_LINKER_FLAGS_INIT.
CMAKE_EXE_LINKER_FLAGS_INIT
✨ Added in version 3.7.
Value used to initialize the CMAKE_EXE_LINKER_FLAGS cache entry the first time a build tree is configured. 🌱
This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform.
See also the configuration-specific variable CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT.
CMAKE_EXPORT_FIND_PACKAGE_NAME
🧪 Note: Experimental. Gated by CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES.
Initializes the value of EXPORT_FIND_PACKAGE_NAME. ngl, she's still in beta — handle with care 🫶
CMAKE_FOLDER
✨ Added in version 3.17. — wait, no, Added in version 3.12. 🎀
Set the folder name. Use it to organize targets in an IDE. 🗂️
This variable is used to initialize the FOLDER property on all the targets. See that target property for additional information.
CMAKE_Fortran_FORMAT
Set to FIXED or FREE to indicate the Fortran source layout. 🧚
This variable is used to initialize the Fortran_FORMAT property on all the targets. See that target property for additional information.
CMAKE_Fortran_MODULE_DIRECTORY
Fortran module output directory. 📁
This variable is used to initialize the Fortran_MODULE_DIRECTORY property on all the targets. See that target property for additional information.
CMAKE_Fortran_PREPROCESS
✨ Added in version 3.18.
Default value for Fortran_PREPROCESS of targets.
This variable is used to initialize the Fortran_PREPROCESS property on all the targets. See that target property for additional information.
CMAKE_FRAMEWORK
✨ Added in version 3.15.
Default value for FRAMEWORK of targets. 🍎
This variable is used to initialize the FRAMEWORK property on all the targets. See that target property for additional information.
CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
✨ Added in version 3.18.
Default framework filename postfix under configuration <CONFIG> when using a multi-config generator.
When a framework target is created, its FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG> target property is initialized with the value of this variable if it is set. ✨
CMAKE_GHS_NO_SOURCE_GROUP_FILE
✨ Added in version 3.14.
An ON / OFF boolean to control if the project file for a target should be one single file or multiple files. 🗃️
Refer to GHS_NO_SOURCE_GROUP_FILE for further details.
CMAKE_GLOBAL_AUTOGEN_TARGET
✨ Added in version 3.14.
Okay so this is the switch that turns on a global autogen target, and she is iconic for Qt girlies 🧚
When CMAKE_GLOBAL_AUTOGEN_TARGET is enabled, a custom target called autogen gets generated for you. That target depends on all the AUTOMOC and AUTOUIC generated <ORIGIN>_autogen targets in the project. So by building the global autogen target, every single AUTOMOC and AUTOUIC file in the project gets generated. one build, all the moc, no cap ✨
You can rename the global autogen target by setting CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.
By default CMAKE_GLOBAL_AUTOGEN_TARGET is unset.
See the cmake-qt(7) manual for the full lore on using CMake with Qt 💜
Note (read this one bestie):<ORIGIN>_autogentargets inherit their origin target's dependencies by default. That can lowkey cause unintended dependency target builds when you're only building the<ORIGIN>_autogentargets 😭 The solution is to disableAUTOGEN_ORIGIN_DEPENDSon the respective origin targets.
✨ CMAKE_GLOBAL_AUTOGEN_TARGET_NAME ✨
Added in version 3.14.
This one changes the name of the global autogen target. Cute, right? 🎀
When CMAKE_GLOBAL_AUTOGEN_TARGET is enabled, a global custom target named autogen gets created. CMAKE_GLOBAL_AUTOGEN_TARGET_NAME lets you set a different name for that target — because autogen isn't always the vibe you're going for 💅
By default CMAKE_GLOBAL_AUTOGEN_TARGET_NAME is unset.
See the cmake-qt(7) manual for more info on using CMake with Qt.
🦋 CMAKE_GLOBAL_AUTORCC_TARGET 🦋
Added in version 3.14.
The switch that enables generation of a global autorcc target 🎀
When CMAKE_GLOBAL_AUTORCC_TARGET is enabled, a custom target autorcc gets generated. This target depends on all the AUTORCC generated <ORIGIN>_arcc_<QRC> targets in the project. So by building the global autorcc target, all the AUTORCC files in the project get generated. every single one, periodt ✨
You can rename the global autorcc target by setting CMAKE_GLOBAL_AUTORCC_TARGET_NAME.
By default CMAKE_GLOBAL_AUTORCC_TARGET is unset.
See the cmake-qt(7) manual for more info on using CMake with Qt.
🌸 CMAKE_GLOBAL_AUTORCC_TARGET_NAME 🌸
Added in version 3.14.
Changes the name of the global autorcc target. main character energy, but renameable 💅
When CMAKE_GLOBAL_AUTORCC_TARGET is enabled, a global custom target named autorcc gets created. CMAKE_GLOBAL_AUTORCC_TARGET_NAME lets you set a different name for that target.
By default CMAKE_GLOBAL_AUTORCC_TARGET_NAME is unset.
See the cmake-qt(7) manual for more info on using CMake with Qt.
💖 CMAKE_GNUtoMS 💖
Converts GNU import libraries (.dll.a) into MS format (.lib). it's giving translator 💫
This variable is used to initialize the GNUtoMS property on targets when they're created. Peep that target property for the additional details, bestie.
⭐ CMAKE_INCLUDE_CURRENT_DIR ⭐
Automatically adds the current source and build directories to the include path. so convenient it hurts 😭
If this variable is enabled, CMake automatically adds CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to the include path for each directory. Heads up though: these extra include directories do not propagate down to subdirectories. They stay in their lane 🚫
This is useful mainly for out-of-source builds, where files generated into the build tree are included by files living in the source tree.
By default CMAKE_INCLUDE_CURRENT_DIR is OFF.
🫶 CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE 🫶
Automatically adds the current source and build directories to the INTERFACE_INCLUDE_DIRECTORIES target property.
If this variable is enabled, CMake automatically adds — for each shared library target, static library target, module target and executable target — CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to the INTERFACE_INCLUDE_DIRECTORIES target property. yes, all of them. every type 💅
By default CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE is OFF.
🍓 CMAKE_INSTALL_NAME_DIR 🍓
The directory name for installed targets on Apple platforms 🍎
CMAKE_INSTALL_NAME_DIR is used to initialize the INSTALL_NAME_DIR property on all targets. Go read that target property for the deets.
🌈 CMAKE_INSTALL_OBJECT_NAME_STRATEGY 🌈
Added in version 4.2.
The strategy to use for naming installed object files. yes we have strategies now, we're so serious 🎀
CMAKE_INSTALL_OBJECT_NAME_STRATEGY is used to initialize the INSTALL_OBJECT_NAME_STRATEGY property on all targets. See that target property for the full tea.
🦋 CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION 🦋
Added in version 4.2.
This one controls whether the install(DESTINATION) for object libraries is used as-is, or supplemented with conflict-avoiding subdirectories. choose your fighter ⚔️
CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION is used to initialize the INSTALL_OBJECT_ONLY_USE_DESTINATION property on all targets. That target property has the details, iykyk.
💜 CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH 💜
Added in version 3.16.
Sets the default for whether toolchain-defined rpaths should be removed during installation. it's a whole cleanup moment ✨
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH is a boolean that provides the default value for the INSTALL_REMOVE_ENVIRONMENT_RPATH property of all subsequently created targets. subsequently!! timing matters 🕐
👑 CMAKE_INSTALL_RPATH 👑
The rpath to use for installed targets.
A semicolon-separated list specifying the rpath to use in installed targets (on platforms that support it, obviously). This is used to initialize the target property INSTALL_RPATH for all targets.
🔥 CMAKE_INSTALL_RPATH_USE_LINK_PATH 🔥
Adds paths to the linker search and installed rpath.
CMAKE_INSTALL_RPATH_USE_LINK_PATH is a boolean — if you set it to True, it appends to the runtime search path (rpath) of installed binaries any directories outside the project that are in the linker search path or that contain linked library files. Those directories get appended after the value of the INSTALL_RPATH target property. order matters, bestie 💅
This variable is used to initialize the target property INSTALL_RPATH_USE_LINK_PATH for all targets.
💫 CMAKE_INTERPROCEDURAL_OPTIMIZATION 💫
Added in version 3.9.
The default value for INTERPROCEDURAL_OPTIMIZATION on targets.
This variable is used to initialize the INTERPROCEDURAL_OPTIMIZATION property on all the targets. See that target property for additional info — she has lore.
✨ See Also ✨
- The
CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>variable.
🧚 CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG> 🧚
Added in version 3.9.
The default value for INTERPROCEDURAL_OPTIMIZATION_<CONFIG> on targets.
This variable is used to initialize the INTERPROCEDURAL_OPTIMIZATION_<CONFIG> property on all the targets. See that target property for additional information 💖
✨ See Also ✨
- The
CMAKE_INTERPROCEDURAL_OPTIMIZATIONvariable.
🎀 CMAKE_<LANG>_CLANG_TIDY 🎀
Added in version 3.6.
The default value for the <LANG>_CLANG_TIDY target property when <LANG> is C, CXX, OBJC or OBJCXX. four languages, one very opinionated linter 💅
This variable is used to initialize the property on each target as it's created. For example:
set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-*)
add_executable(foo foo.cxx)
🌟 CMAKE_<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR 🌟
Added in version 3.26.
The default value for the <LANG>_CLANG_TIDY_EXPORT_FIXES_DIR target property when <LANG> is C, CXX, OBJC or OBJCXX.
This variable is used to initialize the property on each target as it's created. For example:
set(CMAKE_CXX_CLANG_TIDY_EXPORT_FIXES_DIR clang-tidy-fixes)
add_executable(foo foo.cxx)
💫 CMAKE_<LANG>_COMPILER_LAUNCHER 💫
Added in version 3.4.
The default value for the <LANG>_COMPILER_LAUNCHER target property. This variable is used to initialize the property on each target as it's created — but only when <LANG> is C, CXX, Fortran, HIP, ISPC, OBJC, OBJCXX, or CUDA. the whole squad 🫶
This variable is initialized to the CMAKE_<LANG>_COMPILER_LAUNCHER environment variable if that's set. (yes, environment variable — know the difference, bestie)
🦋 CMAKE_<LANG>_CPPCHECK 🦋
Added in version 3.10.
The default value for the <LANG>_CPPCHECK target property. This variable is used to initialize the property on each target as it's created. This happens only when <LANG> is C or CXX.
🌈 CMAKE_<LANG>_CPPLINT 🌈
Added in version 3.8.
The default value for the <LANG>_CPPLINT target property. This variable is used to initialize the property on each target as it's created. Only when <LANG> is C or CXX. just the two, bestie 💅
🍓 CMAKE_<LANG>_ICSTAT 🍓
Added in version 4.1.
The default value for the <LANG>_ICSTAT target property. This variable is used to initialize the property on each target as it's created. And again — only when <LANG> is C or CXX.
⭐ CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE ⭐
Added in version 3.3.
The default value for the <LANG>_INCLUDE_WHAT_YOU_USE target property. This variable is used to initialize the property on each target as it's created. And — you guessed it — only when <LANG> is C or CXX.
💜 CMAKE_<LANG>_LINK_DEF_FILE_FLAG 💜
Added in version 4.1.
The linker flag used to specify a .def file for dll creation with the toolchain for language <LANG> 🎀
CMake sets this variable automatically during toolchain inspection, via calls to the project() or enable_language() commands. so you don't even gotta lift a finger ✨
If the CMAKE_<LANG>_LINK_DEF_FILE_FLAG variable is defined, it takes precedence over the language-agnostic CMAKE_LINK_DEF_FILE_FLAG variable. specific beats general, always 💅
🧚 CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE> 🧚
Added in version 3.24.
So like, this variable is the whole blueprint for how a group of libraries gets linked when someone uses a LINK_GROUP generator expression and the target's link language is <LANG>. 💅 But bestie, it does absolutely nothing unless its ride-or-die buddy CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED is set to true. No cap.
If your feature is link-language-agnostic (it doesn't care which <LANG> you're rocking), then you want to set CMAKE_LINK_GROUP_USING_<FEATURE> instead. 🫶
Feature names are case-sensitive, and they can only contain letters, numbers and underscores. And heads up: any feature name written in ALL UPPERCASE is reserved for CMake's own built-in features (peep Predefined Features further down 👀).
🎀 Feature Definitions 🎀
A group feature definition is a list with exactly two elements:
<PREFIX> <SUFFIX>
On the linker command line, <PREFIX> goes right before the list of libraries in the group, and <SUFFIX> comes right after. Periodt. ✨
For the elements of this variable, you can use the LINKER: prefix.
Now — to pass options to the linker tool, every compiler driver has its own little syntax situation going on 😭. That's where the LINKER: prefix and the , separator come in clutch: they let you specify linker-tool options in a portable way. LINKER: gets swapped for the appropriate driver option, and , gets swapped for the appropriate driver separator. The driver prefix and driver separator are literally given by the values of the CMAKE_<LANG>_LINKER_WRAPPER_FLAG and CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP variables. 💖
Example time — "LINKER:-z,defs" turns into -Xlinker -z -Xlinker defs for Clang, and -Wl,-z,defs for GNU GCC. Slay.
The LINKER: prefix can also be specified as part of a SHELL: prefix expression.
And the LINKER: prefix supports an alternative syntax too: specifying arguments using the SHELL: prefix and a space as the separator. So the previous example becomes "LINKER:SHELL:-z defs".
⚠️ Note: specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Don't do it, bestie. 🙈
✨ Examples ✨
🔗 Solving cross-references between two static libraries
Okay so picture this: a project defines two or more static libraries with circular dependencies between them. 😭 For the linker to actually resolve all the symbols at link time, it may need to search repeatedly among the libraries until no new undefined references get created. Different linkers use different syntax for this. The example below shows how it may be implemented for some linkers.
💀 Important vibe check: this is for illustration purposes only. Projects should use the built-in RESCAN group feature instead (see Predefined Features), because it's a more complete and more robust implementation of this whole functionality. iykyk.
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_C_LINK_GROUP_USING_cross_refs
"LINKER:--start-group"
"LINKER:--end-group"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(CMAKE_C_LINK_GROUP_USING_cross_refs
"LINKER:-z,rescan-start"
"LINKER:-z,rescan-end"
)
else()
# feature not yet supported for the other environments
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE)
endif()
add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)
if(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED)
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>")
else()
target_link_libraries(lib2 PRIVATE lib1 external)
endif()
CMake will generate these linker command line fragments when linking lib2:
- GNU:
-Wl,--start-group /path/to/lib1.a -lexternal -Wl,--end-group - SunPro:
-Wl,-z,rescan-start /path/to/lib1.a -lexternal -Wl,-z,rescan-end
👑 Predefined Features 👑
These built-in group features come pre-defined by CMake, no assembly required:
RESCAN— Some linkers are single-pass only 😔. For those linkers, circular references between libraries typically end in unresolved symbols. This feature tells the linker to search the specified static libraries repeatedly until no new undefined references get created.
Normally a static library is searched only once, in the order it's specified on the command line. So if a symbol in that library is needed to resolve an undefined symbol referred to by an object in a library that appears later on the command line, the linker just wouldn't be able to resolve that reference. But by grouping the static libraries with the RESCAN feature, they all get searched repeatedly until all possible references are resolved. ✨ This uses linker options like --start-group and --end-group, or on SunOS, -z rescan-start and -z rescan-end.
🔥 Heads up: using this feature has a significant performance cost. Best to only use it when you've got unavoidable circular references between two or more static libraries. No cap.
This feature is available when using toolchains that target Linux, BSD, and SunOS. It can also be used when targeting Windows platforms if the GNU toolchain is used.
Added in version 4.4: RESCAN is additionally available when using toolchains targeting Haiku. 🐧
CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED
Added in version 3.24.
This variable says whether <FEATURE> is supported for the link language <LANG>. If it's true, then <FEATURE> must be defined by CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>, and the more generic CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED and CMAKE_LINK_GROUP_USING_<FEATURE> variables are not used. 🚫
If CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED is false or just isn't set, then it's the CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED variable that decides whether <FEATURE> is deemed to be supported. 💅
CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES
Added in version 3.30.
This variable defines the semantics of the specified link library <FEATURE> when linking with the link language <LANG>. It takes precedence over CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES if that variable is also defined for the same <FEATURE> — but otherwise it has similar effects. Head over to CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES for the full deets. 🫶
CMAKE_<LANG>_LINK_LIBRARY_FILE_FLAG
Added in version 3.16.
A language-specific flag used to link a library that's specified by a path to its file.
The flag gets used before a library file path is handed to the linker. It's only needed on very few platforms — rare icon behavior. 🦋
CMAKE_<LANG>_LINK_LIBRARY_FLAG
Added in version 3.16.
The flag used to link a library into a shared library or executable.
This flag specifies a library to link to a shared library or an executable for the specific language. On most compilers, this is -l. 💖
CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>
Added in version 3.24.
This variable defines how to link a library or framework for the specified <FEATURE> when a LINK_LIBRARY generator expression is used and the link language for the target is <LANG>. For this variable to have any effect, the associated CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED variable must be set to true. (Yes, same energy as before. 💅)
The CMAKE_LINK_LIBRARY_USING_<FEATURE> variable should be defined instead for features that are independent of the link language.
Feature names are case-sensitive and may only contain letters, numbers and underscores. Feature names defined in all uppercase are reserved for CMake's own built-in features (see Predefined Features further below). 👑
Some aspects of feature behavior can be defined by the CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES and CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES variables.
🌸 Feature Definitions 🌸
A library feature definition is a list with one or three elements:
[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]
When <PREFIX> and <SUFFIX> are specified, they precede and follow — respectively — the whole list of libraries specified in the LINK_LIBRARY expression, not each library item individually. Okay and this is the messy part, bestie 😭: there's no guarantee the list of specified libraries will be kept grouped together, so <PREFIX> and <SUFFIX> may appear more than once if CMake reorganizes the library list to satisfy other constraints. Which means constructs like --start-group and --end-group, as supported by the GNU ld linker, cannot be used this way. Use the LINK_GROUP generator expression instead for those constructs. Periodt.
<LIBRARY_EXPRESSION> is what you use to specify the pattern for constructing the corresponding fragment on the linker command line for each library. These placeholders are available in the expression:
<LIBRARY>— expands to the full path to the library for CMake targets, or to a platform-specific value based on the item otherwise (the same as<LINK_ITEM>on Windows, or the library base name for other platforms).<LINK_ITEM>— expands to how the library would normally be linked on the linker command line.<LIB_ITEM>— expands to the full path to the library for CMake targets, or to the item itself exactly as specified in the<LIBRARY_EXPRESSION>otherwise.
On top of all that, you can have one pattern for paths (CMake targets and external libraries specified with file paths) and another for other items specified by name only. The PATH{} and NAME{} wrappers provide the expansion for those two cases, respectively. When wrappers are used, both must be present. Like so:
set(CMAKE_LINK_LIBRARY_USING_weak_library
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)
And for all three elements of this variable (<PREFIX>, <LIBRARY_EXPRESSION>, and <SUFFIX>), the LINKER: prefix can be used. 🎀
To pass options to the linker tool, each compiler driver has its own syntax, which is honestly so annoying 😭. That's why there's the LINKER: prefix and the , separator — together they let you specify options to hand to the linker tool in a way that's portable. LINKER: gets replaced by whatever the appropriate driver option is, and , gets swapped for the appropriate driver separator. Where do those come from? The values of the CMAKE_<LANG>_LINKER_WRAPPER_FLAG and CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP variables. Slay. ✨
So for example — and this is the glow-up moment bestie — "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang, and -Wl,-z,defs for GNU GCC. Same intent, different outfit. 💅
The LINKER: prefix can be specified as part of a SHELL: prefix expression.
And plot twist: LINKER: also supports, as an alternative syntax, specifying arguments using the SHELL: prefix and a space as the separator. So that previous example becomes "LINKER:SHELL:-z defs". Cute, right? 🎀
Note: specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Genuinely do not do it. 🙈
🧪 Examples
Loading a whole static library — okay so a super common need is stopping the linker from discarding any symbols from a static library. Different linkers use different syntax for that, because of course they do. 💀 The example below shows how this may be implemented for some linkers. Note that this is for illustration purposes only — projects should use the built-in WHOLE_ARCHIVE feature instead (see Predefined Features), which provides a more complete and more robust implementation of this functionality.
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>")
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive
"LINKER:--push-state,--whole-archive"
"<LINK_ITEM>"
"LINKER:--pop-state"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
else()
# feature not yet supported for the other environments
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED FALSE)
endif()
add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)
if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED)
# The -force_load Apple linker option requires a file name
set(external_lib
"$<IF:$<LINK_LANG_AND_ID:C,AppleClang>,libexternal.a,external>"
)
target_link_libraries(lib2 PRIVATE
"$<LINK_LIBRARY:load_archive,lib1,${external_lib}>"
)
else()
target_link_libraries(lib2 PRIVATE lib1 external)
endif()
CMake will generate the following link expressions:
- AppleClang:
-force_load /path/to/lib1.a -force_load libexternal.a - GNU:
-Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state - MSVC:
/WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib
Linking a library as weak — on macOS, it's possible to link a library in weak mode (the library and all references are marked as weak imports). Different flags must be used for a library specified by file path compared to one specified by name. That constraint can be solved using PATH{} and NAME{} wrappers 🫶. Again, the example below shows how this may be implemented for some linkers, but it is for illustration purposes only. Projects should use the built-in WEAK_FRAMEWORK or WEAK_LIBRARY features instead (see Predefined Features), which provide more complete and more robust implementations of this functionality.
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(CMAKE_LINK_LIBRARY_USING_weak_library
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)
set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE)
endif()
add_library(lib SHARED ...)
add_executable(main ...)
if(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED)
target_link_libraries(main PRIVATE "$<LINK_LIBRARY:weak_library,lib,external>")
else()
target_link_libraries(main PRIVATE lib external)
endif()
CMake will generate the following linker command line fragment when linking main using the AppleClang toolchain:
-weak_library /path/to/lib -Xlinker -weak-lexternal.
👑 Predefined Features
The following built-in library features are pre-defined by CMake, and they are iconic:
DEFAULT— this feature corresponds to standard linking, essentially equivalent to using no feature at all. It is typically only used with theLINK_LIBRARY_OVERRIDEandLINK_LIBRARY_OVERRIDE_<LIBRARY>target properties.WHOLE_ARCHIVE— force inclusion of all members of a static library when linked as a dependency of consuming Executables, Shared Libraries, and Module Libraries. This feature is only supported for the following platforms, with limitations as noted:- Linux.
- All BSD variants.
- SunOS.
- All Apple variants. The library must be specified as a CMake target name, a library file name (such as
libfoo.a), or a library file path (such as/path/to/libfoo.a). Due to a limitation of the Apple linker, it cannot be specified as a plain library name likefoo, wherefoois not a CMake target. - Windows. When using a MSVC or MSVC-like toolchain, the MSVC version must be greater than
1900. - Cygwin.
- MSYS.
Note: since Static Libraries are archives and not linked binaries, CMake records their link dependencies for transitive use when linking consuming binaries. Therefore WHOLE_ARCHIVE does not cause a static library's objects to be included in other static libraries. Use Object Libraries for that. 🫡
FRAMEWORK— this option tells the linker to search for the specified framework using the-frameworklinker option. It can only be used on Apple platforms, and only with a linker that understands the option used (i.e. the linker provided with Xcode, or one compatible with it). The framework can be specified as a CMake framework target, a bare framework name, or a file path. If a target is given, that target must have theFRAMEWORKtarget property set to true. For a file path, if it contains a directory part, that directory will be added as a framework search path.
add_library(lib SHARED ...)
target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>")
# The constructed linker command line will contain:
# -F/path/to -framework my_framework
File paths must conform to one of the following patterns (* is a wildcard, and optional parts are shown as [...]):
[/path/to/]FwName[.framework][/path/to/]FwName.framework/FwName[suffix][/path/to/]FwName.framework/Versions/*/FwName[suffix]
Note that CMake recognizes and automatically handles framework targets, even without using the $<LINK_LIBRARY:FRAMEWORK,...> expression. The generator expression can still be used with a CMake target if the project wants to be explicit about it, but it is not required to do so. The linker command line may have some differences between using the generator expression or not, but the final result should be the same. On the other hand, if a file path is given, CMake will recognize some paths automatically, but not all cases. The project may want to use $<LINK_LIBRARY:FRAMEWORK,...> for file paths so that the expected behavior is clear. 💖
Added in version 3.25: the FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG> target property as well as the suffix of the framework library name are now supported by the FRAMEWORK features.
NEEDED_FRAMEWORK— this is similar to theFRAMEWORKfeature, except it forces the linker to link with the framework even if no symbols are used from it. It uses the-needed_frameworkoption and has the same linker constraints asFRAMEWORK.REEXPORT_FRAMEWORK— this is similar to theFRAMEWORKfeature, except it tells the linker that the framework should be available to clients linking to the library being created. It uses the-reexport_frameworkoption and has the same linker constraints asFRAMEWORK.WEAK_FRAMEWORK— this is similar to theFRAMEWORKfeature, except it forces the linker to mark the framework and all references to it as weak imports. It uses the-weak_frameworkoption and has the same linker constraints asFRAMEWORK.NEEDED_LIBRARY— this is similar to theNEEDED_FRAMEWORKfeature, except it is for use with non-framework targets or libraries (Apple platforms only). It uses the-needed_libraryor-needed-loption as appropriate, and has the same linker constraints asNEEDED_FRAMEWORK.REEXPORT_LIBRARY— this is similar to theREEXPORT_FRAMEWORKfeature, except it is for use with non-framework targets or libraries (Apple platforms only). It uses the-reexport_libraryor-reexport-loption as appropriate, and has the same linker constraints asREEXPORT_FRAMEWORK.WEAK_LIBRARY— this is similar to theWEAK_FRAMEWORKfeature, except it is for use with non-framework targets or libraries (Apple platforms only). It uses the-weak_libraryor-weak-loption as appropriate, and has the same linker constraints asWEAK_FRAMEWORK.
🌸 CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED 🌸
Added in version 3.24.
Set to TRUE if the <FEATURE>, as defined by variable CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>, is supported for the linker language <LANG>. Like, "yes bestie, this one works here" ✅.
Note: this variable is evaluated before the more generic variable CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED. Order matters, iykyk. 💅
🦋 CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG 🦋
Added in version 3.22.
Linker flag used by LINK_WHAT_YOU_USE to tell the linker to link all the shared libraries named on the command line, even if literally none of their symbols is needed. It's an implementation detail, bestie — it exists so that the command in CMAKE_LINK_WHAT_YOU_USE_CHECK can peek at the binary and spot shared libraries that got linked for no reason. 🕵️♀️
⚠️ Do not rely on this abstraction to intentionally link to shared libraries whose symbols are not needed. Like, that's not what she's for. 🙅♀️
CMAKE_<LANG>_LINKER_LAUNCHER 🚀
🎀 Added in version 3.21.
Default value for the <LANG>_LINKER_LAUNCHER target property. This variable initializes the property on every target as it gets created — but only when <LANG> is one of these besties:
CCXXOBJCOBJCXXFortran
🌸 Added in version 4.1.
This variable gets initialized from the CMAKE_<LANG>_LINKER_LAUNCHER environment variable, if that's set. iykyk 💅
CMAKE_<LANG>_PVS_STUDIO 🔍
✨ Added in version 4.3.
Default value for the <LANG>_PVS_STUDIO target property, when <LANG> is C or CXX.
This variable is used to initialize the property on each target as it's created. For example:
set(CMAKE_CXX_PVS_STUDIO pvs-studio-analyzer analyze -a "GA\;OP")
add_executable(foo foo.cxx)
CMAKE_<LANG>_USING_LINKER_<TYPE> 🔗
✨ Added in version 3.29.
This variable defines how to specify the <TYPE> linker for the link step, as controlled by the CMAKE_LINKER_TYPE variable or the LINKER_TYPE target property. Depending on the value of CMAKE_<LANG>_LINK_MODE, CMAKE_<LANG>_USING_LINKER_<TYPE> can hold compiler flags for the link step, or the path to the linker tool. Two whole vibes. 🦋
🔄 Changed in version 4.0.
The type of info stored in this variable is now determined by the CMAKE_<LANG>_LINK_MODE variable instead of the CMAKE_<LANG>_USING_LINKER_MODE variable. Glow-up era fr.
📌 Note: the specified linker tool is generally expected to be reachable through the PATH environment variable. Keep that in mind, bestie.
For example, the LLD linker for GNU compilers is defined like so:
# CMAKE_C_LINK_MODE holds value "DRIVER"
set(CMAKE_C_USING_LINKER_LLD "-fuse-ld=lld")
On Windows, with Clang compilers simulating MSVC with the GNU front-end:
# CMAKE_C_LINK_MODE holds value "DRIVER"
set(CMAKE_C_USING_LINKER_LLD "-fuse-ld=lld-link")
And for the MSVC compiler, or Clang compilers simulating MSVC with the MSVC front-end, the linker is invoked directly, not via the compiler front-end:
# CMAKE_C_LINK_MODE holds value "LINKER"
set(CMAKE_C_USING_LINKER_LLD "/path/to/lld-link.exe")
You can also define a custom linker type — usually in a toolchain file:
set(CMAKE_LINKER_TYPE lld_launcher)
set(CMAKE_C_USING_LINKER_lld_launcher "-fuse-ld=/path/to/lld-launcher.sh")
CMAKE_<LANG>_VISIBILITY_PRESET 👀
Default value for the <LANG>_VISIBILITY_PRESET target property when a target is created. She sets the vibe from the jump. ✨
CMAKE_LIBRARY_OUTPUT_DIRECTORY 📁
Where to put all the LIBRARY target files when they're built. 🏠
This variable is used to initialize the LIBRARY_OUTPUT_DIRECTORY property on all the targets. See that target property for the extra deets.
CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG> 🗂️
✨ Added in version 3.3.
Where to put all the LIBRARY target files when built for a specific configuration.
This variable is used to initialize the LIBRARY_OUTPUT_DIRECTORY_<CONFIG> property on all the targets. Again, the target property has the full story — go read her. 💖
CMAKE_LIBRARY_PATH_FLAG 🏷️
The flag used to add a library search path to a compiler.
The flag will be used to specify a library directory to the compiler. On most compilers this is -L. Periodt.
CMAKE_LINK_DEF_FILE_FLAG 📄
Linker flag used to specify a .def file for dll creation.
The flag is used to add a .def file when creating a dll on Windows — so yes, this is only defined on Windows. 💀
CMake sets this variable automatically during toolchain inspection by calls to the project() or enable_language() commands.
If the per-language CMAKE_<LANG>_LINK_DEF_FILE_FLAG variable is defined, it takes precedence over CMAKE_LINK_DEF_FILE_FLAG. She wins the crown. 👑
CMAKE_LINK_DEPENDS_NO_SHARED 🚫
Whether to skip link dependencies on shared library files.
This variable initializes the LINK_DEPENDS_NO_SHARED property on targets when they're created. See that target property for more info. 🫶
CMAKE_LINK_DEPENDS_USE_LINKER 🛠️
✨ Added in version 3.27.
For the Makefile and Ninja generators, link dependencies are now — for a selection of linkers — generated by the linker itself. Define this variable with value FALSE and you can deactivate this feature. Bye bestie 👋
This feature is also deactivated if the LINK_DEPENDS_NO_SHARED target property is true.
📌 Note: CMake version 4.4.5 defaults this variable toFALSEif the linker is one from the GNU binutils linkers (ldandld.bfdfor version less than2.41, orld.goldfor any version) because it generates spurious dependencies on temporary files when LTO is enabled. See GNU bug 30568 (https://sourceware.org/bugzilla/show_bug.cgi?id=30568). Not the vibe. 😭
CMAKE_LINK_GROUP_USING_<FEATURE> 🧚
✨ Added in version 3.24.
This variable defines how to link a group of libraries for the specified <FEATURE> when a LINK_GROUP generator expression is used. Both of the following conditions have to be met for this variable to do literally anything:
- The associated
CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTEDvariable must be set to true. ✅ - There is no language-specific definition for the same
<FEATURE>. This meansCMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTEDcannot be true for the link language used by the target for which theLINK_GROUPgenerator expression is evaluated. 🚫
For features that are dependent on the link language, you should define the CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE> variable instead.
Feature names are case-sensitive and may only contain letters, numbers and underscores. Feature names defined in all uppercase are reserved for CMake's own built-in features — see Predefined Features further below. 👇
Feature Definitions 🎀
A group feature definition is a list that contains exactly two elements:
<PREFIX> <SUFFIX>
On the linker command line, <PREFIX> will come before the list of libraries in the group, and <SUFFIX> will follow after. Bookends, basically. 📚
For the elements of this variable, the LINKER: prefix can be used.
To pass options to the linker tool, each compiler driver has its own syntax. The LINKER: prefix and , separator can be used to 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. 🪄
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang, and -Wl,-z,defs for GNU GCC.
The LINKER: prefix can be specified as part of a SHELL: prefix expression.
The LINKER: prefix also supports, as an alternative syntax, specifying arguments using the SHELL: prefix and a space as separator. The previous example then becomes "LINKER:SHELL:-z defs". Two ways to slay the same fit. 💅
📌 Note: specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Don't do it, bestie, she will not forgive you.
Examples 💫
Solving cross-references between two static libraries 🧩
A project may define two or more static libraries that have circular dependencies between them. For the linker to resolve all the symbols at link time, it may need to search repeatedly among the libraries until no new undefined references get created. Different linkers use different syntax for this. The following example shows how this may be implemented for some linkers. Note that this is for illustration purposes only — projects should use the built-in RESCAN group feature instead (see Predefined Features), which provides a more complete and more robust implementation of this functionality. Trust the built-in, she ate. 🔥
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_C_LINK_GROUP_USING_cross_refs
"LINKER:--start-group"
"LINKER:--end-group"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(CMAKE_C_LINK_GROUP_USING_cross_refs
"LINKER:-z,rescan-start"
"LINKER:-z,rescan-end"
)
else()
# feature not yet supported for the other environments
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE)
endif()
add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)
if(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED)
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>")
else()
target_link_libraries(lib2 PRIVATE lib1 external)
endif()
CMake will generate the following linker command line fragments when linking lib2:
- GNU:
-Wl,--start-group /path/to/lib1.a -lexternal -Wl,--end-group - SunPro:
-Wl,-z,rescan-start /path/to/lib1.a -lexternal -Wl,-z,rescan-end
Predefined Features 👑
The following built-in group features are pre-defined by CMake:
RESCAN— Some linkers are single-pass only. For such linkers, circular references between libraries typically result in unresolved symbols. 😭 This feature instructs the linker to search the specified static libraries repeatedly until no new undefined references are created. Iconic behaviour, no notes. ✨
Normally, a static library is searched only once in the order that it's specified on the command line. And like… if a symbol in that library is needed to resolve an undefined symbol that some object in a library later on the command line refers to? The linker literally cannot resolve that reference. It's over. It's giving unread-message energy. 😭
But bestie — group those static libraries with the RESCAN feature and they all get searched repeatedly until every possible reference is resolved. Slay. It does this using linker options like --start-group and --end-group, or on SunOS, -z rescan-start and -z rescan-end. ✨
⚠️ Vibe check: using this feature has a significant performance cost. Use it only when there are unavoidable circular references between two or more static libraries. No cap, it's expensive.
This feature is available when using toolchains that target Linux, BSD, and SunOS. It can also be used when targeting Windows platforms if the GNU toolchain is used. 🪟
Added in version 4.4: RESCAN is additionally available when using toolchains targeting Haiku.
🦋 CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED 🦋
Added in version 3.24.
This variable says whether the <FEATURE> is supported regardless of the link language. So if this one's true, then <FEATURE> must be defined by CMAKE_LINK_GROUP_USING_<FEATURE>. Periodt. 💅
Lowkey important note: this variable has no effect if CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED is true for the link language of the target. Like, that one already spoke, bestie. 🙈
💖 CMAKE_LINK_INTERFACE_LIBRARIES 💖
The default value for the LINK_INTERFACE_LIBRARIES property of targets.
This variable initializes the LINK_INTERFACE_LIBRARIES property on all the targets — yes, all of them, main character energy 🌟 — so check out that target property for the extra info if you want the full story.
🎀 CMAKE_LINK_LIBRARIES_STRATEGY 🎀
Added in version 3.31.
This one lets you specify a strategy for ordering targets' direct link dependencies on linker command lines. Ordering matters, bestie, it's literally the whole thing. 😌
If you set it, this variable acts as the default value for the LINK_LIBRARIES_STRATEGY target property when a target is created. And if you only want a specific vibe for one single target? Set that property directly instead. Easy. 🫶
🔥 CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES 🔥
Added in version 3.30.
This variable defines the behavior of the specified link library <FEATURE>. It tells CMake how <FEATURE> interacts with other features, when <FEATURE> should be applied, and aspects of how <FEATURE> should be handled when CMake assembles that final linker command line (think de-duplication, bestie). 🧚
The syntax of the linker flags for <FEATURE>? That's controlled by the CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE> and CMAKE_LINK_LIBRARY_USING_<FEATURE> variables. And whether <FEATURE> is even available at all is controlled by CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED and CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED. Teamwork, honestly. 👑
When linking for a particular language <LANG>, CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES is ignored if CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES is also defined for the same <FEATURE>. Like sorry, the language-specific one ate. 💀
And here's the timing detail that matters: the value of CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES and CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES at the end of the directory scope in which a target is defined is what matters. Not the start. The end. Remember that. ⭐
🌸 Feature Attributes Definition 🌸
A feature attributes definition is a semicolon-separated list of attribute=value(s) items. If an attribute has multiple values, those values must be comma-separated. Commas, not semicolons. Don't mix them up or it's giving chaos. 🙈
The following attributes are supported:
LIBRARY_TYPE=<library-type-list>— specifies the library types supported by the feature. Supported values are:STATIC,SHARED,MODULE, andEXECUTABLE.
If you don't specify this attribute, the default is LIBRARY_TYPE=STATIC,SHARED,MODULE,EXECUTABLE. Generous king. 👑
If the feature gets used with an unsupported library type, CMake will emit a developer warning and the feature will just be ignored. Rude but fair. 😭
OVERRIDE=<feature-list>— specifies which features this one replaces in the event of a conflict. Heads up though: this override mechanism is superseded byLINK_LIBRARY_OVERRIDEorLINK_LIBRARY_OVERRIDE_<LIBRARY>target property definitions, if those are defined. So if the target property said something, that's the final word. 💅
If you don't specify this attribute, the default is an empty list.
DEDUPLICATION=YES|NO|DEFAULT— specifies the de-duplication strategy for a library using this feature.YES— the library is always de-duplicated. The default strategy CMake would normally apply is ignored.NO— the library is never de-duplicated. The default strategy CMake would normally apply is ignored.DEFAULT— let CMake determine a de-duplication strategy automatically.
If you don't specify this attribute, DEFAULT will be used.
🫶 Example 🫶
A common need is the loading of a full archive as part of the creation of a shared library. The built-in WHOLE_ARCHIVE feature can be used for that purpose. The implementation of that built-in feature sets the following link library feature attributes:
set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES
LIBRARY_TYPE=STATIC
OVERRIDE=DEFAULT
DEDUPLICATION=YES
)
LIBRARY_TYPE=STATIC— this feature is only meaningful for static libraries.OVERRIDE=DEFAULT— theDEFAULTfeature will be overridden by theWHOLE_ARCHIVEfeature because they are compatible and they enhance the user's experience: standard library specification and$<LINK_LIBRARY:WHOLE_ARCHIVE>can be used freely. Besties fr fr. 🫶DEDUPLICATION=YES— when this feature is used, the linker loads all symbols from the static library, so there's no need to repeat the library on the linker command line. Iconic. ✨
The WHOLE_ARCHIVE feature can be used like so:
add_library(A STATIC ...)
add_library(B STATIC ...)
target_link_libraries(B PUBLIC A)
target_link_libraries(A PUBLIC B)
add_library(global SHARED ...)
target_link_libraries(global PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,A>)
The resulting link command will only have one instance of the A library specified, and the linker flags will ensure that all symbols are loaded from the A library. Chef's kiss. 👑✨
🍓 CMAKE_LINK_LIBRARY_FILE_FLAG 🍓
Flag to be used to link a library specified by a path to its file.
The flag will be used before a library file path is given to the linker. This is needed only on very few platforms — like, niche platforms. Rare species. 🦋
🌈 CMAKE_LINK_LIBRARY_FLAG 🌈
Flag to be used to link a library into an executable.
The flag will be used to specify a library to link to an executable. On most compilers this is -l. Yep, just -l. That's the whole vibe. 💅
💜 CMAKE_LINK_LIBRARY_USING_<FEATURE> 💜
Added in version 3.24.
This variable defines how to link a library or framework for the specified <FEATURE> when a LINK_LIBRARY generator expression is used. And listen — both of the following conditions must be met for this variable to have any effect at all:
- The associated
CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDvariable must be set to true. ✅ - There is no language-specific definition for the same
<FEATURE>. Which meansCMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTEDcannot be true for the link language used by the target for which theLINK_LIBRARYgenerator expression is evaluated. 🚫
Feature names are case-sensitive and may only contain letters, numbers and underscores. Feature names defined in all uppercase are reserved for CMake's own built-in features (see Predefined Features further below). So don't go claiming MYFEATURE in all caps, that's not your name, bestie. 😭
Some aspects of feature behavior can be defined by the CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES and CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES variables.
🧚 Feature Definitions 🧚
A library feature definition is a list that contains one or three elements:
[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]
When <PREFIX> and <SUFFIX> are specified, they precede and follow respectively the whole list of libraries specified in the LINK_LIBRARY expression — not each library item individually. Important distinction! 🌟
But lowkey there's no guarantee that the list of specified libraries will be kept grouped together, so <PREFIX> and <SUFFIX> may appear more than once if the library list gets reorganized by CMake to satisfy other constraints. Which means constructs like --start-group and --end-group, as supported by the GNU ld linker, cannot be used in this way. Use the LINK_GROUP generator expression instead for such constructs. That's the move. 💅
<LIBRARY_EXPRESSION> is used to specify the pattern for constructing the corresponding fragment on the linker command line for each library. The following placeholders can be used in the expression:
<LIBRARY>is expanded to the full path to the library for CMake targets, or to a platform-specific value based on the item otherwise (the same as<LINK_ITEM>on Windows, or the library base name for other platforms).<LINK_ITEM>is expanded to how the library would normally be linked on the linker command line.<LIB_ITEM>is expanded to the full path to the library for CMake targets, or the item itself exactly as specified in the<LIBRARY_EXPRESSION>otherwise.
In addition to the above, it's possible to have one pattern for paths (CMake targets and external libraries specified with file paths) and another for other items specified by name only. The PATH{} and NAME{} wrappers can be used to provide the expansion for those two cases, respectively. When wrappers are used, both must be present. Like, both or neither, no halfsies. 🫶 For example:
set(CMAKE_LINK_LIBRARY_USING_weak_library
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)
For all three elements of this variable (<PREFIX>, <LIBRARY_EXPRESSION>, and <SUFFIX>), the LINKER: prefix can be used. ✨
To pass options to the linker tool, every compiler driver has its own little syntax situation going on 😭 — like, they all want it said differently. That's why LINKER: prefix plus the , separator exists: it lets you say what you want portably and lets CMake translate. LINKER: gets swapped for whatever driver option is right, and , gets swapped for whatever driver separator is right. And where do those come from? The values of CMAKE_<LANG>_LINKER_WRAPPER_FLAG and CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP variables. Slay, delegation. 💅
Example time: "LINKER:-z,defs" turns into -Xlinker -z -Xlinker defs for Clang, and -Wl,-z,defs for GNU GCC. Same input, different outfit, iconic behavior fr fr ✨
And yes, the LINKER: prefix can be specified as part of a SHELL: prefix expression. 🫶
Also! LINKER: has an alternative syntax where you specify arguments using the SHELL: prefix and a space as the separator. So the previous example becomes "LINKER:SHELL:-z defs". Cute, lowkey 😌
Note, bestie, and this one matters: specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Don't test it. Don't be that girl. 💀
Examples 🎀
Loading a whole static library
Okay so a super common need is stopping the linker from discarding any symbols from a static library. Different linkers have different syntax for it. The example below shows how that may be implemented for some linkers — BUT, huge caveat: this is for illustration purposes only. Projects should use the built-in WHOLE_ARCHIVE feature instead (see Predefined Features), because that gives you a more complete and more robust implementation of this functionality. Use the real one, bestie 🫶
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>")
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive
"LINKER:--push-state,--whole-archive"
"<LINK_ITEM>"
"LINKER:--pop-state"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
else()
# feature not yet supported for the other environments
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED FALSE)
endif()
add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)
if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED)
# The -force_load Apple linker option requires a file name
set(external_lib
"$<IF:$<LINK_LANG_AND_ID:C,AppleClang>,libexternal.a,external>"
)
target_link_libraries(lib2 PRIVATE
"$<LINK_LIBRARY:load_archive,lib1,${external_lib}>"
)
else()
target_link_libraries(lib2 PRIVATE lib1 external)
endif()
CMake will generate the following link expressions for you, no cap:
- AppleClang:
-force_load /path/to/lib1.a -force_load libexternal.a - GNU:
-Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state - MSVC:
/WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib
Linking a library as weak 🌸
On macOS, it is possible to link a library in weak mode — meaning the library and all references are marked as weak imports. The catch: different flags must be used for a library specified by file path compared to one specified by name 😤. That constraint can be solved using the PATH{} and NAME{} wrappers. Again — and I cannot stress this enough — the following example shows how this may be implemented for some linkers, but it is for illustration purposes only. Projects should use the built-in WEAK_FRAMEWORK or WEAK_LIBRARY features instead (see Predefined Features), which provide more complete and more robust implementations of this functionality. ✨
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(CMAKE_LINK_LIBRARY_USING_weak_library
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)
set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE)
endif()
add_library(lib SHARED ...)
add_executable(main ...)
if(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED)
target_link_libraries(main PRIVATE "$<LINK_LIBRARY:weak_library,lib,external>")
else()
target_link_libraries(main PRIVATE lib external)
endif()
When linking main using the AppleClang toolchain, CMake will generate this linker command line fragment:
-weak_library /path/to/lib -Xlinker -weak-lexternal.
Predefined Features 👑
These are the built-in library features that CMake pre-defines for you. Gifts, honestly 🎁
DEFAULT
This feature corresponds to standard linking, essentially equivalent to using no feature at all. It is typically only used with the LINK_LIBRARY_OVERRIDE and LINK_LIBRARY_OVERRIDE_<LIBRARY> target properties. The plain-jane of features and she's thriving 💅
WHOLE_ARCHIVE
Forces inclusion of all members of a static library when linked as a dependency of consuming Executables, Shared Libraries, and Module Libraries. This feature is only supported for the following platforms, with limitations as noted — read the fine print, bestie:
- Linux.
- All BSD variants.
- SunOS.
- All Apple variants. The library must be specified as a CMake target name, a library file name (such as
libfoo.a), or a library file path (such as/path/to/libfoo.a). Due to a limitation of the Apple linker, it cannot be specified as a plain library name likefoo, wherefoois not a CMake target. - Windows. When using a MSVC or MSVC-like toolchain, the MSVC version must be greater than
1900. - Cygwin.
- MSYS.
Note: since Static Libraries are archives and not linked binaries, CMake records their link dependencies for transitive use when linking consuming binaries. Therefore WHOLE_ARCHIVE does not cause a static library's objects to be included in other static libraries. Use Object Libraries for that. Different feature, different job, okay? 🙈
FRAMEWORK
This option tells the linker to search for the specified framework using the -framework linker option. It can only be used on Apple platforms, and only with a linker that understands the option used (i.e. the linker provided with Xcode, or one compatible with it). Apple girlies only 💖
The framework can be specified as a CMake framework target, a bare framework name, or a file path. If a target is given, that target must have the FRAMEWORK target property set to true. For a file path, if it contains a directory part, that directory will be added as a framework search path.
add_library(lib SHARED ...)
target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>")
# The constructed linker command line will contain:
# -F/path/to -framework my_framework
File paths must conform to one of the following patterns (* is a wildcard, and optional parts are shown as [...]):
[/path/to/]FwName[.framework][/path/to/]FwName.framework/FwName[suffix][/path/to/]FwName.framework/Versions/*/FwName[suffix]
Note that CMake recognizes and automatically handles framework targets, even without using the $<LINK_LIBRARY:FRAMEWORK,...> expression. The generator expression can still be used with a CMake target if the project wants to be explicit about it, but it is not required to do so. The linker command line may have some differences between using the generator expression or not, but the final result should be the same. On the other hand, if a file path is given, CMake will recognize some paths automatically, but not all cases. The project may want to use $<LINK_LIBRARY:FRAMEWORK,...> for file paths so that the expected behavior is clear. Clarity is self-care ✨
Added in version 3.25: the FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG> target property as well as the suffix of the framework library name are now supported by the FRAMEWORK features. Upgrade glow-up 🦋
NEEDED_FRAMEWORK
Similar to the FRAMEWORK feature, except it forces the linker to link with the framework even if no symbols are used from it. It uses the -needed_framework option and has the same linker constraints as FRAMEWORK.
REEXPORT_FRAMEWORK
Similar to the FRAMEWORK feature, except it tells the linker that the framework should be available to clients linking to the library being created. It uses the -reexport_framework option and has the same linker constraints as FRAMEWORK.
WEAK_FRAMEWORK
Similar to the FRAMEWORK feature, except it forces the linker to mark the framework and all references to it as weak imports. It uses the -weak_framework option and has the same linker constraints as FRAMEWORK.
NEEDED_LIBRARY
Similar to the NEEDED_FRAMEWORK feature, except it is for use with non-framework targets or libraries (Apple platforms only). It uses the -needed_library or -needed-l option as appropriate, and has the same linker constraints as NEEDED_FRAMEWORK.
REEXPORT_LIBRARY
Similar to the REEXPORT_FRAMEWORK feature, except it is for use with non-framework targets or libraries (Apple platforms only). It uses the -reexport_library or -reexport-l option as appropriate, and has the same linker constraints as REEXPORT_FRAMEWORK.
WEAK_LIBRARY
Similar to the WEAK_FRAMEWORK feature, except it is for use with non-framework targets or libraries (Apple platforms only). It uses the -weak_library or -weak-l option as appropriate, and has the same linker constraints as WEAK_FRAMEWORK.
✨ CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED ✨
Added in version 3.24.
Set to TRUE if the <FEATURE>, as defined by variable CMAKE_LINK_LIBRARY_USING_<FEATURE>, is supported regardless the linker language. Look at her, going language-agnostic 👑
Note: this variable is evaluated if, and only if, the variable CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED is not defined. Conditional queen 💅
🎀 CMAKE_LINK_WARNING_AS_ERROR 🎀
Added in version 4.0.
Okay so this one is literally the "warnings on link" glow-up — specify whether to treat warnings on link as errors, bestie 💅
This variable is used to initialize the LINK_WARNING_AS_ERROR property on all the targets. Slay.
🎀 CMAKE_LINK_WHAT_YOU_USE 🎀
Added in version 3.7.
Default value for the LINK_WHAT_YOU_USE target property. This variable is used to initialize the property on each target as it is created. no cap, it just shows up and sets the vibe for every baby target ✨
🦋 CMAKE_LINK_WHAT_YOU_USE_CHECK 🦋
Added in version 3.22.
Command executed by LINK_WHAT_YOU_USE after the linker, to check for unnecessarily-linked shared libraries. This check is currently only defined on ELF platforms with value ldd -u -r. like, that's the whole guest list rn 🙈
See also the CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG variables. iykyk.
💜 CMAKE_LINKER_TYPE 💜
Added in version 3.29.
Specify which linker will be used for the link step. main character decision fr.
This variable is used to initialize the LINKER_TYPE property on each target created by a call to add_library() or add_executable(). It is meaningful only for targets having a link step. If set, its value is also used by the try_compile() command.
⚠️ Note: It is assumed that the linker specified is fully compatible with the default one the compiler would normally invoke. CMake will not do any option translation. so like, don't set this to something cursed and expect CMake to fix it for you, bestie — it will not 💀
Linker types are case-sensitive and may only contain letters, numbers and underscores. Linker types defined in all uppercase are reserved for CMake's own built-in types. The pre-defined linker types are:
DEFAULT— This type corresponds to standard linking, essentially equivalent to theLINKER_TYPEtarget property not being set at all.SYSTEM— Use the standard linker provided by the platform or toolchain. For example, this implies the Microsoft linker for all MSVC-compatible compilers. This type is supported for the following platform-compiler combinations:- Linux: GNU, Clang, LLVMFlang, NVIDIA, and Swift compilers.
- Apple platforms: AppleClang, Clang, GNU, and Swift compilers.
- Windows: MSVC, GNU, Clang, NVIDIA, and Swift compilers.
LLD— Use the LLVM linker. This type is supported for the following platform-compiler combinations:- Linux: GNU, Clang, LLVMFlang, NVIDIA, and Swift compilers.
- Apple platforms: Clang, AppleClang, and Swift compilers.
- Windows: GNU, Clang with MSVC-like front-end, Clang with GNU-like front-end, MSVC, NVIDIA with MSVC-like front-end, and Swift.
BFD— Use the GNU linker. This type is supported for the following platform-compiler combinations:- Linux: GNU, Clang, LLVMFlang, and NVIDIA compilers.
- Windows: GNU, Clang with GNU-like front-end.
GOLD— Supported on Linux platform with GNU, Clang, LLVMFlang, NVIDIA, and Swift compilers.MOLD— Use the mold linkerhttps://github.com/rui314/mold. This type is supported on the following platform-compiler combinations:- Linux: GNU, Clang, LLVMFlang, and NVIDIA compilers.
- Apple platforms: Clang and AppleClang compilers (acts as an alias to the sold linker
https://github.com/bluewhalesystems/sold).
SOLD— Use the sold linkerhttps://github.com/bluewhalesystems/sold. This type is only supported on Apple platforms with Clang and AppleClang compilers.WILD— Added in version 4.4. Use the wild linkerhttps://github.com/wild-linker/wild. This type is only supported on Linux platforms with Clang and GNU compilers.APPLE_CLASSIC— Use the Apple linker in the classic behavior (i.e. before Xcode 15.0). This type is only supported on Apple platforms with GNU, Clang, AppleClang, and Swift compilers.MSVC— Use the Microsoft linker. This type is only supported on the Windows platform with MSVC, Clang with MSVC-like front-end, and Swift compilers.
like, pick your fighter 💅
🌸 CMAKE_MACOSX_BUNDLE 🌸
Default value for MACOSX_BUNDLE of targets.
This variable is used to initialize the MACOSX_BUNDLE property on all the targets. See that target property for additional information. 🫶
This variable is set to ON by default if CMAKE_SYSTEM_NAME equals to iOS, tvOS, visionOS or watchOS. so the Apple-y platforms get bundles automatically, periodt.
🌈 CMAKE_MACOSX_RPATH 🌈
Whether to use rpaths on macOS and iOS.
This variable is used to initialize the MACOSX_RPATH property on all targets. yes bestie, all of them ✨
🍓 CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> 🍓
Default value for MAP_IMPORTED_CONFIG_<CONFIG> of targets.
This variable is used to initialize the MAP_IMPORTED_CONFIG_<CONFIG> property on all the targets. See that target property for additional information. the <CONFIG> is a placeholder btw, don't type it literally 😭
⭐ CMAKE_MODULE_LINKER_FLAGS ⭐
Linker flags to be used to create modules.
These flags will be used by the linker when creating a module for all build configurations. every single one, no skipping 🎀
Handling Compiler Driver Differences
Added in version 4.0.
To pass options to the linker tool, each compiler driver has its own syntax. The LINKER: prefix and , separator can be used to specify, in a portable way, options to pass to the linker tool. LINKER: is 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.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC. iconic translation service ngl ✨
The LINKER: prefix supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. The previous example then becomes "LINKER:SHELL:-z defs".
🙈 Note: Specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. like, beginning only, bestie, don't try it.
This support implies to parse and re-quote the content of the variable. See policy CMP0181.
See Also
CMAKE_MODULE_LINKER_FLAGS_<CONFIG>
🧚 CMAKE_MODULE_LINKER_FLAGS_<CONFIG> 🧚
Flags to be used when linking a module.
These flags will be used by the linker when creating a module for the <CONFIG> configuration. one config at a time, we love a dedicated moment 💜
Handling Compiler Driver Differences
Added in version 4.0.
To pass options to the linker tool, each compiler driver has its own syntax. The LINKER: prefix and , separator can be used to specify, in a portable way, options to pass to the linker tool. LINKER: is 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.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC.
The LINKER: prefix supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. The previous example then becomes "LINKER:SHELL:-z defs".
🙈 Note: Specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported.
This support implies to parse and re-quote the content of the variable. See policy CMP0181.
See Also
CMAKE_MODULE_LINKER_FLAGS
🎀 CMAKE_MODULE_LINKER_FLAGS_<CONFIG>_INIT 🎀
Added in version 3.7.
Value used to initialize the CMAKE_MODULE_LINKER_FLAGS_<CONFIG> cache entry the first time a build tree is configured. This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform. so it's a starting point, not the final word, okurrr 💅
See also CMAKE_MODULE_LINKER_FLAGS_INIT.
🦋 CMAKE_MODULE_LINKER_FLAGS_INIT 🦋
Added in version 3.7.
Value used to initialize the CMAKE_MODULE_LINKER_FLAGS cache entry the first time a build tree is configured. This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform.
See also the configuration-specific variable CMAKE_MODULE_LINKER_FLAGS_<CONFIG>_INIT. bestie duo fr fr 🫶
🔥 CMAKE_MSVC_DEBUG_INFORMATION_FORMAT 🔥
Added in version 3.25.
Select the MSVC debug information format targeting the MSVC ABI. This variable is used to initialize the MSVC_DEBUG_INFORMATION_FORMAT property on all targets as they are created. It is also propagated by calls to the try_compile() command into the test project. spreading the vibe, love that for us ✨
The allowed values are:
Embedded— Compile with-Z7or equivalent flag(s) to produce object files with full symbolic debugging information.ProgramDatabase— Compile with-Zior equivalent flag(s) to produce a program database that contains all the symbolic debugging information.EditAndContinue— Compile with-ZIor equivalent flag(s) to produce a program database that supports the Edit and Continue feature.
The value is ignored on compilers not targeting the MSVC ABI, but an unsupported value will be rejected as an error when using a compiler targeting the MSVC ABI. so like, wrong value = hard no 💀
The value may also be the empty string (""), in which case no debug information format flag will be added explicitly by CMake.
Use generator expressions to support per-configuration specification. For example, the code:
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>")
selects for all following targets the program database debug information format for the Debug and RelWithDebInfo configurations. chef's kiss, genuinely obsessed 😭💖
If you don't set this variable, the MSVC_DEBUG_INFORMATION_FORMAT target property just... won't get set for you. And if that property is empty too, CMake picks a debug info format itself using the default value $<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase> — but only if the compiler supports it — and otherwise falls back to $<$<CONFIG:Debug,RelWithDebInfo>:Embedded>. 💅
Note: this variable only does anything when policyCMP0141is set toNEWbefore the firstproject()orenable_language()command that enables a language with a compiler targeting the MSVC ABI. Order matters, bestie. ✨
CMAKE_MSVC_RUNTIME_CHECKS
Added in version 4.0. 🎀
This one picks the list of runtime checks that get enabled when you're targeting the MSVC ABI. It's used to initialize the MSVC_RUNTIME_CHECKS property on every target the moment it's created — and it also gets propagated into the test project by calls to the try_compile() command. 🫶
The allowed values are:
PossibleDataLoss— compile with-RTCcor equivalent flag(s) to turn on possible data loss checks.StackFrameErrorCheck— compile with-RTCsor equivalent flag(s) to turn on stack frame error checks.UninitializedVariable— compile with-RTCuor equivalent flag(s) to turn on uninitialized variables checks.
The value is straight-up ignored on compilers not targeting the MSVC ABI — but an unsupported value will be rejected as an error when you're using a compiler that does target the MSVC ABI. 😭
The value can also be the empty string (""), and in that case CMake won't explicitly add any runtime error check flags at all.
Use generator expressions to get per-configuration specification, iykyk. For example, this code:
set(CMAKE_MSVC_RUNTIME_CHECKS "$<$<CONFIG:Debug,RelWithDebInfo>:PossibleDataLoss;UninitializedVariable>")
enables for the target foo the possible data loss and uninitialized variables checks for the Debug and RelWithDebInfo configurations. 🌈
If this variable isn't set, the MSVC_RUNTIME_CHECKS target property will not be set automatically. And if that property isn't set either, CMake picks runtime checks using the default value $<$<CONFIG:Debug>:StackFrameErrorCheck;UninitializedVariable> if the compiler supports it, or an empty value otherwise. 💀
Note: this variable only has effect when policyCMP0184is set toNEWprior to the firstproject()orenable_language()command that enables a language using a compiler targeting the MSVC ABI.
CMAKE_MSVC_RUNTIME_LIBRARY
Added in version 3.15. ✨
Okay so this is the big one — it selects the MSVC runtime library for compilers targeting the MSVC ABI. It initializes the MSVC_RUNTIME_LIBRARY property on all targets as they're created, and it also gets propagated by calls to the try_compile() command into the test project. 👑
The allowed values are:
""(set but empty) — no runtime library selection flag gets added explicitly by CMake. Heads up tho: with Visual Studio Generators, the native build system may choose to add its own default runtime library selection flag. 🙈MultiThreaded— compile with-MTor equivalent flag(s) to use a multi-threaded statically-linked runtime library.MultiThreadedDLL— compile with-MDor equivalent flag(s) to use a multi-threaded dynamically-linked runtime library.MultiThreadedDebug— compile with-MTdor equivalent flag(s) to use a multi-threaded statically-linked runtime library.MultiThreadedDebugDLL— compile with-MDdor equivalent flag(s) to use a multi-threaded dynamically-linked runtime library.
The value is ignored on compilers not targeting the MSVC ABI, but an unsupported value gets rejected as an error when using a compiler targeting the MSVC ABI. No cap. 💅
Use generator expressions to support per-configuration specification. For example, the code:
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
selects for all following targets a multi-threaded statically-linked runtime library with or without debug information depending on the configuration. Obsessed with how clean that is tbh. 🦋
If this variable is not set then the MSVC_RUNTIME_LIBRARY target property will not be set automatically. If that property isn't set then CMake uses the default value MultiThreaded$<$<CONFIG:Debug>:Debug>DLL to select a MSVC runtime library.
Note: this variable has effect only when policyCMP0091is set toNEWprior to the firstproject()orenable_language()command that enables a language using a compiler targeting the MSVC ABI.
CMAKE_MSVCIDE_RUN_PATH
Added in version 3.10. 🎀
Extra PATH locations that should be used when executing add_custom_command() or add_custom_target() while using Visual Studio Generators. This is the move when you need to run commands and use dll's that the IDE environment literally has no idea about. 😭
If you don't set it explicitly, the value gets initialized from the CMAKE_MSVCIDE_RUN_PATH environment variable (if it's set), and otherwise it's just left empty. 🫶
CMAKE_NINJA_OUTPUT_PATH_PREFIX
Added in version 3.6. 🦋
Tells the Ninja Generators to slap a prefix onto every output path in build.ninja. A trailing slash gets appended to the prefix if it's missing. ✨
This is so useful when the generated ninja file is meant to be embedded as a subninja file into a super ninja project. For example, the command:
cd super-build-dir &&
cmake -G Ninja -S /path/to/src -B sub -DCMAKE_NINJA_OUTPUT_PATH_PREFIX=sub/
# ^^^---------- these match -----------^^^
generates a build directory with its top-level (CMAKE_BINARY_DIR) in super-build-dir/sub. The path to the build directory ends in the output path prefix, which makes it suitable for use in a separately-written super-build-dir/build.ninja file with a directive like this:
subninja sub/build.ninja
The auto-regeneration rule in super-build-dir/build.ninja must have an order-only dependency on sub/build.ninja. Don't forget that part, bestie. 💅
Added in version 3.27: the Ninja Multi-Config generator supports this variable. 🌈
Note: whenCMAKE_NINJA_OUTPUT_PATH_PREFIXis set, the project generated by CMake cannot be used as a standalone project. No default targets are specified. The value ofCMAKE_NINJA_OUTPUT_PATH_PREFIXmust match one or more path components at the end ofCMAKE_BINARY_DIR, or the behavior is undefined. And yeah — that requirement is not checked automatically. So like, be careful. 😬
CMAKE_NO_BUILTIN_CHRPATH
Do not use the builtin binary editor to fix runtime library search paths on installation.
Here's the vibe: when an ELF or XCOFF binary needs to have a different runtime library search path after installation than it does in the build tree, CMake uses a builtin editor to change the runtime search path in the installed copy. But if this variable is set to true, CMake will relink the binary before installation instead of using its builtin editor. 🔥
For more info on RPATH handling, see the INSTALL_RPATH and BUILD_RPATH target properties.
Added in version 3.20: this variable also applies to XCOFF binaries' LIBPATH. Before the XCOFF editor landed in CMake 3.20, this variable applied only to ELF binaries' RPATH/RUNPATH. 👑
CMAKE_NO_SYSTEM_FROM_IMPORTED
Default value for NO_SYSTEM_FROM_IMPORTED of targets. 💖
This variable is used to initialize the NO_SYSTEM_FROM_IMPORTED property on all the targets. See that target property for additional information — it's got the deets. 🫶
CMAKE_OPTIMIZE_DEPENDENCIES
Added in version 3.19. ⭐
Initializes the OPTIMIZE_DEPENDENCIES target property. That's it, that's the whole thing. Short and iconic. 💅
CMAKE_OSX_ARCHITECTURES
Target specific architectures for macOS and iOS. 🍓
This variable is used to initialize the OSX_ARCHITECTURES property on each target as it is created. See that target property for additional information.
If CMAKE_OSX_ARCHITECTURES is not set, the compiler's default target architecture gets used. For compilers provided by Xcode, that's the host machine's architecture. 🎀
Lowkey important: the value of this variable should be set prior to the first project() or enable_language() command invocation, because it may influence configuration of the toolchain and flags. It's intended to be set locally by the user creating a build tree. And it should be set as a CACHE entry (or else CMake may remove it while initializing a cache entry of the same name) unless policy CMP0126 is set to NEW. 😭
Despite the OSX part in the variable name(s), they apply to other SDKs than macOS too — like iOS, tvOS, visionOS, or watchOS. 🌸
This variable is ignored on platforms other than Apple. 🧚
CMAKE_OSX_DEPLOYMENT_TARGET
Specify the minimum version of the target platform — e.g., macOS or iOS — on which the target binaries are to be deployed. 🦋
For builds targeting macOS (CMAKE_SYSTEM_NAME is Darwin), if CMAKE_OSX_DEPLOYMENT_TARGET isn't explicitly set, a default gets set:
- If the
MACOSX_DEPLOYMENT_TARGETenvironment variable is non-empty, its value is the default. ✨ - Otherwise, if using the Xcode generator, and the host's macOS version is older than the macOS SDK (
CMAKE_OSX_SYSROOT, if set, or Xcode's default SDK), the host's macOS version is the default. Changed in version 4.0: previously this was done for all generators, not just Xcode. - Otherwise, the default is empty. 🙈
The effects of CMAKE_OSX_DEPLOYMENT_TARGET depend on the generator:
- Xcode — if
CMAKE_OSX_DEPLOYMENT_TARGETis set to a non-empty value, it gets added to the generated Xcode project as theMACOSX_DEPLOYMENT_TARGETsetting. Otherwise, no such setting gets added, so Xcode's default deployed target is used — typically based on the SDK version. 👑
✨ Other Generators ✨
okay so we're still hanging out in CMAKE_OSX_DEPLOYMENT_TARGET land, just the generator corner of it 💅 here's the teal deer:
- If
CMAKE_OSX_DEPLOYMENT_TARGETis set to a non-empty value, it gets passed to the compiler via the-mmacosx-version-minflag or equivalent. Otherwise? No flag, no drama — the compiler's default deployment target is used, and that's just how it is 🫶
Set this value before the very first project() or enable_language() command runs, bestie, because it may influence configuration of the toolchain and flags. It's intended to be set locally by the user creating a build tree. Also: set it as a CACHE entry (or else CMake may remove it while initializing a cache entry of the same name) unless policy CMP0126 is set to NEW. Not me warning you twice 💀
Despite the OSX part in the variable name(s), they apply also to other SDKs than macOS — like iOS, tvOS, visionOS, or watchOS. The name is lowkey lying to you, iykyk 🌈
This variable is ignored on platforms other than Apple. Periodt.
🍎 CMAKE_OSX_SYSROOT
Specify the location or name of the macOS platform SDK to be used. It's giving "which SDK are we building against" main character energy 💖
If not set explicitly, the value is initialized by the SDKROOT environment variable, if set. Otherwise, the value defaults to empty, and the compiler is expected to choose a default macOS SDK on its own.
Changed in version 4.0: the default is now empty. Previously a default was computed based on the CMAKE_OSX_DEPLOYMENT_TARGET or the host platform. So if you're on an older mental model of this, update the brain cache 🧠✨
In order to pass an explicit macOS SDK via the compiler's -isysroot flag, users may configure their build tree with -DCMAKE_OSX_SYSROOT=macosx, or export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" in their environment. Both slay, pick your fave 🎀
Notes:
- macOS compilers in
/usr/bin, when not invoked with-isysroot, search for headers in/usr/local/includebefore system SDK paths, matching the convention on many platforms. Users on macOS-x86_64 hosts with Homebrew installed in/usr/localshould pass an explicit SDK, as described above, when not building with Homebrew tools. Like, don't let Homebrew headers sneak into your build, bestie 🙈 - Some Clang compilers have no default macOS SDK selection. For these, if
CMAKE_OSX_SYSROOTis empty, CMake will automatically pass-isysrootwith the macOS SDK printed byxcrun --show-sdk-path. CMake's got your back 🫶
The value of this variable should be set prior to the first project() or enable_language() command invocation because it may influence configuration of the toolchain and flags. It is intended to be set locally by the user creating a build tree. This variable should be set as a CACHE entry (or else CMake may remove it while initializing a cache entry of the same name) unless policy CMP0126 is set to NEW.
Despite the OSX part in the variable name(s) they apply also to other SDKs than macOS like iOS, tvOS, visionOS, or watchOS.
This variable is ignored on platforms other than Apple. Fr fr, non-Apple platforms don't even see it 👑
📦 CMAKE_PCH_INSTANTIATE_TEMPLATES
Added in version 3.19.
This variable is used to initialize the PCH_INSTANTIATE_TEMPLATES property of targets when they are created. Precompiled headers but make it ✨instantiate✨ — set it and forget it, bestie.
🚨 CMAKE_PCH_WARN_INVALID
Added in version 3.18.
This variable is used to initialize the PCH_WARN_INVALID property of targets when they are created. It's the "hey bestie your PCH is invalid" alarm 🎀
🐛 CMAKE_PDB_OUTPUT_DIRECTORY
Output directory for MS debug symbol .pdb files generated by the linker for executable and shared library targets. Yes, the debug symbols are getting their own little home 🏠💜
This variable is used to initialize the PDB_OUTPUT_DIRECTORY property on all the targets. See that target property for additional information — it's the source of truth, okurrr.
🐛 CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG>
Per-configuration output directory for MS debug symbol .pdb files generated by the linker for executable and shared library targets.
This is a per-configuration version of CMAKE_PDB_OUTPUT_DIRECTORY. This variable is used to initialize the PDB_OUTPUT_DIRECTORY_<CONFIG> property on all the targets. See that target property for additional information. One dir per config, because we contain multitudes 💅
🧜 CMAKE_PLATFORM_NO_VERSIONED_SONAME
Added in version 3.1.
This variable is used to globally control whether the VERSION and SOVERSION target properties should be used for shared libraries. When set to true, adding version information to each shared library target is disabled. Global switch, big main character energy 🔥
By default this variable is set only on platforms where CMake knows it is needed. On other platforms, the specified properties will be used for shared libraries. So don't go flipping it without a reason, ngl.
🧚 CMAKE_POSITION_INDEPENDENT_CODE
Default value for the POSITION_INDEPENDENT_CODE target property. PIC but make it a default, we love to see it 💖
This variable is used to initialize the POSITION_INDEPENDENT_CODE property on targets that are not SHARED or MODULE library targets. If set, its value is also used by the try_compile() command. Sneaky little cameo there ✨
The SHARED and MODULE library targets have by default position independent code enabled regardless of this variable. To disable PIC on these library types, only manually setting the target property disables it. So don't think you can just unset this variable and call it a day — that's not how it works, bestie 😭
💜 See Also
- The
CheckPIESupportedmodule to pass PIE-related options to the linker for executables.
🏃 CMAKE_RUNTIME_OUTPUT_DIRECTORY
Where to put all the RUNTIME target files when built. The "where do the runtime artifacts live" question, answered 💅
This variable is used to initialize the RUNTIME_OUTPUT_DIRECTORY property on all the targets. See that target property for additional information.
🏃♀️ CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
Added in version 3.3.
Where to put all the RUNTIME target files when built for a specific configuration. Debug runtime here, Release runtime there, everyone gets a folder 🎀
This variable is used to initialize the RUNTIME_OUTPUT_DIRECTORY_<CONFIG> property on all the targets. See that target property for additional information.
🦀 CMAKE_Rust_EDITION
Added in version 4.4.
Note: Experimental. Gated by CMAKE_EXPERIMENTAL_RUST. So like, it's real but it's also in its experimental era, proceed accordingly 🙈
Default value for Rust_EDITION target property if set when a target is created. Rust girlies, this one's for you 💜
🔗 CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS
Added in version 3.27.
Specify whether shared library generates an import file. It's giving "do you want the exports or not" 🤔
This variable is used to initialize the ENABLE_EXPORTS target property for shared library targets when they are created by calls to the add_library() command. See the property documentation for details.
💜 See Also
- The
CMAKE_EXECUTABLE_ENABLE_EXPORTSvariable.
🧷 CMAKE_SHARED_LINKER_FLAGS
Linker flags to be used to create shared libraries. Straight up "here's what the linker gets" vibes 🔥
These flags will be used by the linker when creating a shared library for all build configurations. All of them. Every single one. No cap.
🛠️ Handling Compiler Driver Differences
Added in version 4.0.
okay so to pass options to the linker tool, each compiler driver has its own syntax (annoying, I know 😭). The LINKER: prefix and , separator can be used to specify, in a portable way, options to pass to the linker tool. LINKER: is 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.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC. Same intent, different driver drip 💅
The LINKER: prefix supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. The previous example then becomes "LINKER:SHELL:-z defs".
Note: Specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Beginning only. Don't try it 🙈
This support implies to parse and re-quote the content of the variable. See policy CMP0181.
💜 See Also
CMAKE_SHARED_LINKER_FLAGS_<CONFIG>
🧷 CMAKE_SHARED_LINKER_FLAGS_<CONFIG>
Flags to be used when linking a shared library. Same as above but ✨configured✨
These flags will be used by the linker when creating a shared library for the <CONFIG> configuration.
🛠️ Handling Compiler Driver Differences
Added in version 4.0.
To pass options to the linker tool, each compiler driver has its own syntax. The LINKER: prefix and , separator can be used to specify, in a portable way, options to pass to the linker tool. LINKER: is 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.
For example, "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang and -Wl,-z,defs for GNU GCC.
The LINKER: prefix supports, as an alternative syntax, specification of arguments using the SHELL: prefix and space as separator. The previous example then becomes "LINKER:SHELL:-z defs".
Note: Specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported. Same rule as before, bestie, it's not a suggestion 💀
This support implies to parse and re-quote the content of the variable. See policy CMP0181.
💜 See Also
CMAKE_SHARED_LINKER_FLAGS
🌱 CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT
Added in version 3.7.
Value used to initialize the CMAKE_SHARED_LINKER_FLAGS_<CONFIG> cache entry the first time a build tree is configured. First time only — it's giving "first impression" energy ✨
This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform. So your value is the starting point, not necessarily the final word 🫶
See also CMAKE_SHARED_LINKER_FLAGS_INIT.
🌱 CMAKE_SHARED_LINKER_FLAGS_INIT
Added in version 3.7.
Value used to initialize the CMAKE_SHARED_LINKER_FLAGS cache entry the first time a build tree is configured. Again: toolchain file territory, bestie 🎀
This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform.
See also the configuration-specific variable CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT.
🚫 CMAKE_SKIP_BUILD_RPATH
Do not include RPATHs in the build tree. That's it. That's the whole thing. Short king 👑
Okay so normally CMake uses the build tree for the RPATH when it's building executables and stuff on systems that use RPATH 💅. Then, when the software gets installed, the executables etc are relinked by CMake so they have the install RPATH. But if this variable is set to TRUE, then the software is always built with no RPATH. Iconic, but make sure that's actually what you want bestie 🫶.
This is what initializes the SKIP_BUILD_RPATH target property for all targets. For more info on RPATH handling, go peek at the INSTALL_RPATH and BUILD_RPATH target properties ✨.
See also CMAKE_SKIP_INSTALL_RPATH. And if you want to omit RPATH in both the build and install steps, use CMAKE_SKIP_RPATH instead — one variable, zero RPATH, no notes 💀.
CMAKE_SKIP_INSTALL_RPATH
Do not include RPATHs in the install tree 🚫.
Normally CMake uses the build tree for the RPATH when building executables etc on systems that use RPATH. When the software is installed, the executables etc are relinked by CMake to have the install RPATH. If this variable is set to true, then the software is always installed without RPATH, even if RPATH is enabled when building 🔥. This is literally so useful for things like letting you run tests from the build directory with RPATH enabled before the installation step. Chef's kiss 🎀.
See also the CMAKE_SKIP_BUILD_RPATH variable. To omit RPATH in both the build and install steps, use CMAKE_SKIP_RPATH instead ✨.
For more information on RPATH handling see the INSTALL_RPATH and BUILD_RPATH target properties 💖.
CMAKE_SKIP_LINTING
Added in version 4.2.
This is the default value for the SKIP_LINTING target property 🧹.
It's used to initialize the SKIP_LINTING target property for all targets created afterward. So like, everything you make after setting this gets the vibe, iykyk 🌸.
CMAKE_STATIC_LINKER_FLAGS
Flags to be used to create static libraries ✨. These flags get passed to the archiver when creating a static library.
See also CMAKE_STATIC_LINKER_FLAGS_<CONFIG> 💜.
Note: static libraries do not actually link! They're essentially archives of object files 📦. The use of the name "linker" in the name of this variable is kept for compatibility. So yeah, the name is a little bit of a lie but we love her anyway 😭.
CMAKE_STATIC_LINKER_FLAGS_<CONFIG>
Flags to be used to create static libraries ✨. These flags get passed to the archiver when creating a static library in the <CONFIG> configuration.
See also CMAKE_STATIC_LINKER_FLAGS 💜.
Note: static libraries do not actually link. They are essentially archives of object files 📦. The use of the name "linker" in the name of this variable is kept for compatibility. Same disclaimer, same energy 💅.
CMAKE_STATIC_LINKER_FLAGS_<CONFIG>_INIT
Added in version 3.7.
Value used to initialize the CMAKE_STATIC_LINKER_FLAGS_<CONFIG> cache entry the first time a build tree is configured 🌱. This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform 👀 — so don't be shocked if what you see isn't literally just what you typed.
See also CMAKE_STATIC_LINKER_FLAGS_INIT 💖.
CMAKE_STATIC_LINKER_FLAGS_INIT
Added in version 3.7.
Value used to initialize the CMAKE_STATIC_LINKER_FLAGS cache entry the first time a build tree is configured 🌱. This variable is meant to be set by a toolchain file. CMake may prepend or append content to the value based on the environment and target platform 👀.
See also the configuration-specific variable CMAKE_STATIC_LINKER_FLAGS_<CONFIG>_INIT 💖.
CMAKE_TASKING_TOOLSET
Added in version 3.25.
Select the Tasking toolset which provides the compiler 🔧.
Architecture compilers are provided by different toolchains with incompatible versioning schemes 😭. Set this variable in a toolchain file so CMake can detect the compiler features correctly. If no toolset is specified, Standalone is assumed.
Due to the different versioning schemes, the compiler version (CMAKE_<LANG>_COMPILER_VERSION) depends on the toolset and architecture in use 👑. If projects can be built with multiple toolsets or architectures, the specified CMAKE_TASKING_TOOLSET and the automatically determined CMAKE_<LANG>_COMPILER_ARCHITECTURE_ID must be taken into account when comparing against the CMAKE_<LANG>_COMPILER_VERSION. No cap, version checks here have lore 🫶.
TriCore— compilers are provided by the TriCore toolset.SmartCode— compilers are provided by the SmartCode toolset.Standalone— compilers are provided by the standalone toolsets.
Note: for the TriCore architecture, the compiler from the TriCore toolset is selected as standalone compiler 💀.
CMAKE_TRY_COMPILE_CONFIGURATION
Build configuration used for try_compile() and try_run() projects ⚙️.
Projects built by try_compile() and try_run() are built synchronously during the CMake configuration step. So a specific build configuration must be chosen even if the generated build system supports multiple configurations 👀. Like, there's no "we'll figure it out later" here bestie, you gotta pick one.
CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
Added in version 3.24.
Set this to a true value to tell the try_compile() command not to propagate any platform variables into the test project 🙅♀️.
The try_compile() command normally passes some CMake variables that configure the platform and toolchain behavior into test projects. See policy CMP0137. This variable may be set to disable that behavior ✨.
CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
Added in version 3.6.
List of variables that the try_compile() command source file signature must propagate into the test project in order to target the same platform as the host project 🌈.
This variable should not be set by project code 🚨. It's meant to be set by CMake's platform information modules for the current toolchain, or by a toolchain file when used with CMAKE_TOOLCHAIN_FILE.
Variables meaningful to CMake, such as CMAKE_<LANG>_FLAGS, are propagated automatically 💅. The CMAKE_TRY_COMPILE_PLATFORM_VARIABLES variable may be set to pass custom variables meaningful to a toolchain file. For example, a toolchain file may contain:
set(CMAKE_SYSTEM_NAME ...)
set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES MY_CUSTOM_VARIABLE)
# ... use MY_CUSTOM_VARIABLE ...
If a user passes -DMY_CUSTOM_VARIABLE=SomeValue to CMake, then this setting will be made visible to the toolchain file both for the main project and for test projects generated by the try_compile() command source file signature 👑.
Changed in version 3.24: listed variables are propagated to the try_compile() whole-project signature too. See CMP0137 💖.
Added in version 3.24: the CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES variable may be set to disable passing platform variables into the test project 🫶.
CMAKE_TRY_COMPILE_TARGET_TYPE
Added in version 3.6.
Type of target generated for try_compile() calls using the source file signature 🎯. Valid values are:
EXECUTABLE— useadd_executable()to name the source file in the generated project. This is the default if no value is given ⭐.STATIC_LIBRARY— useadd_library()with theSTATICoption to name the source file in the generated project. This avoids running the linker and is intended for use with cross-compiling toolchains that can't link without custom flags or linker scripts 🔥.
CMAKE_UNITY_BUILD
Added in version 3.16.
This variable is used to initialize the UNITY_BUILD property of targets when they're created 🌱. Setting it to true enables batch compilation of multiple sources within each target. This feature is known as a Unity or Jumbo build 🐘✨.
Projects should not set this variable — it's intended as a developer control to be set on the cmake(1) command line or other equivalent methods 💅. The developer must have the ability to enable or disable unity builds according to the capabilities of their own machine and compiler. Respect the dev's machine, bestie 🫶.
By default, this variable is not set, which will result in unity builds being disabled 🚫.
Note: this option currently does not work well in combination with the CMAKE_EXPORT_COMPILE_COMMANDS variable 😭. Just so you know before you try it and get confused.
CMAKE_UNITY_BUILD_BATCH_SIZE
Added in version 3.16.
This variable is used to initialize the UNITY_BUILD_BATCH_SIZE property of targets when they're created 🌱. It specifies the default upper limit on the number of source files that may be combined in any one unity source file when unity builds are enabled for a target 📦📦📦.
CMAKE_UNITY_BUILD_RELOCATABLE
Added in version 4.0.
This variable is used to initialize the UNITY_BUILD_RELOCATABLE property of targets when they're created 🌱. Setting it to true causes sources generated for CMAKE_UNITY_BUILD to #include the original source files using relative paths where possible 🛤️✨.
CMAKE_UNITY_BUILD_UNIQUE_ID
Added in version 3.20.
This variable is used to initialize the UNITY_BUILD_UNIQUE_ID property of targets when they're created 🌱. It specifies the name of the unique identifier generated per file in a unity build 🏷️. Every file gets its own little name tag, cute.
CMAKE_VERIFY_INTERFACE_HEADER_SETS
Added in version 3.24.
This variable is used to initialize the VERIFY_INTERFACE_HEADER_SETS property of targets when they're created 🌱. Setting it to true enables interface header set verification ✅.
Projects should not normally set this variable — it's intended as a developer control to be set on the cmake(1) command line or other equivalent methods 💅. The developer must have the ability to enable or disable header set verification according to the capabilities of their own machine and compiler 🫶. Again: let the dev decide, that's the whole vibe.
Honestly? Developers do NOT care about verifying a dependency's header sets. It's just not the vibe. So FetchContent_MakeAvailable() lowkey sets CMAKE_VERIFY_INTERFACE_HEADER_SETS and CMAKE_VERIFY_PRIVATE_HEADER_SETS to false for the duration of its call, then restores the original values before it returns. Iconic behavior, no notes. 💅
And if your project pulls a dependency directly into the main build (like, calling add_subdirectory() on a vendored project from a git submodule), it should do the same little dance. For example:
# Save original setting so we can restore it later
set(want_interface_header_set_verification ${CMAKE_VERIFY_INTERFACE_HEADER_SETS})
set(want_private_header_set_verification ${CMAKE_VERIFY_PRIVATE_HEADER_SETS})
# Include the vendored dependency with header set verification disabled
set(CMAKE_VERIFY_INTERFACE_HEADER_SETS OFF)
set(CMAKE_VERIFY_PRIVATE_HEADER_SETS OFF)
add_subdirectory(...) # Vendored sources, e.g. from git submodules
# Add the project's own sources. Restore the developer's original choice
# for whether to enable header set verification.
set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${want_interface_header_set_verification})
set(CMAKE_VERIFY_PRIVATE_HEADER_SETS ${want_private_header_set_verification})
add_subdirectory(src)
By default this variable is not set, and that means interface header set verification is just… off. Not a single thing happening. 🦋
See also CMAKE_VERIFY_PRIVATE_HEADER_SETS.
🌸 CMAKE_VERIFY_PRIVATE_HEADER_SETS
Added in version 4.3.
Okay so this one initializes the VERIFY_PRIVATE_HEADER_SETS property on targets as they get created. Set it to true and boom — private header set verification is enabled. ✨
Bestie, listen: projects should not normally set this variable. It's a developer control, meant to be set on the cmake(1) command line or via other equivalent methods. The dev has to be able to turn header set verification on or off depending on what their own machine and compiler can actually handle. That's the whole point. 🫶
Now, verifying a dependency's header sets? Not typically interesting to developers. So FetchContent_MakeAvailable() explicitly sets CMAKE_VERIFY_PRIVATE_HEADER_SETS and CMAKE_VERIFY_INTERFACE_HEADER_SETS to false for the duration of its call, then restores their original values before returning. If a project brings a dependency directly into the main build (e.g. calling add_subdirectory() on a vendored project from a git submodule), it should also do likewise. Like this:
# Save original setting so we can restore it later
set(want_interface_header_set_verification ${CMAKE_VERIFY_INTERFACE_HEADER_SETS})
set(want_private_header_set_verification ${CMAKE_VERIFY_PRIVATE_HEADER_SETS})
# Include the vendored dependency with header set verification disabled
set(CMAKE_VERIFY_INTERFACE_HEADER_SETS OFF)
set(CMAKE_VERIFY_PRIVATE_HEADER_SETS OFF)
add_subdirectory(...) # Vendored sources, e.g. from git submodules
# Add the project's own sources. Restore the developer's original choice
# for whether to enable header set verification.
set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${want_interface_header_set_verification})
set(CMAKE_VERIFY_PRIVATE_HEADER_SETS ${want_private_header_set_verification})
add_subdirectory(src)
By default, this variable is not set, which means private header set verification stays disabled. Nothing to see here. 🙈
See also CMAKE_VERIFY_INTERFACE_HEADER_SETS.
💜 CMAKE_VISIBILITY_INLINES_HIDDEN
This is the default value for the VISIBILITY_INLINES_HIDDEN target property at the moment a target is created. Short, sweet, to the point. 🎀
🦋 CMAKE_VS_DEBUGGER_COMMAND
Added in version 3.27.
This variable initializes the VS_DEBUGGER_COMMAND property on every target as it gets created. Need more deets? Go read that target property, it's got you. ✨
🦋 CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS
Added in version 3.27.
This variable initializes the VS_DEBUGGER_COMMAND_ARGUMENTS property on each target as it's created. Additional info lives over in that target property. 💅
🦋 CMAKE_VS_DEBUGGER_ENVIRONMENT
Added in version 3.27.
This variable initializes the VS_DEBUGGER_ENVIRONMENT property on each target as it is created. Yeah — same deal as the others, check the target property for the extra lore. 🌸
🦋 CMAKE_VS_DEBUGGER_WORKING_DIRECTORY
Added in version 3.27.
This variable initializes the VS_DEBUGGER_WORKING_DIRECTORY property on each target as it is created. See that target property for additional information, bestie. 🫶
⭐ CMAKE_VS_GLOBALS
Added in version 3.13.
A list of Key=Value records, set per target as target properties VS_GLOBAL_<variable> with variable=Key and value Value. So basically each pair becomes its own property, no cap. 👑
For example:
set(CMAKE_VS_GLOBALS
"DefaultLanguage=en-US"
"MinimumVisualStudioVersion=14.0"
)
That sets the properties VS_GLOBAL_DefaultLanguage to en-US and VS_GLOBAL_MinimumVisualStudioVersion to 14.0 for all targets — except INTERFACE libraries, they're sitting this one out. 💀
This variable is meant to be set by a toolchain file (CMAKE_TOOLCHAIN_FILE). iykyk.
🌈 CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
Added in version 3.3.
Include the INSTALL target in the default build. ✨
In a Visual Studio solution, the INSTALL target is by default not part of the default build. Set this variable and the INSTALL target gets to be part of the default build. It's giving main character energy.
🌈 CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD
Added in version 3.8.
Include the PACKAGE target in the default build. ✨
In a Visual Studio solution, the PACKAGE target will not be part of the default build by default. Setting this variable enables the PACKAGE target to be part of the default build. Slay.
💖 CMAKE_VS_JUST_MY_CODE_DEBUGGING
Added in version 3.15.
Enable Just My Code with the Visual Studio debugger. 🎀
This variable is used to initialize the VS_JUST_MY_CODE_DEBUGGING property on all targets when they are created. See that target property for additional information.
🔥 CMAKE_VS_NO_COMPILE_BATCHING
Added in version 3.24.
Turn off compile batching when using Visual Studio Generators. Periodt. 🔥
This variable is used to initialize the VS_NO_COMPILE_BATCHING property on all targets when they are created. Go check out that target property for additional information.
Example
This shows setting the property for the target foo using the variable:
set(CMAKE_VS_NO_COMPILE_BATCHING ON)
add_library(foo SHARED foo.cpp)
🌟 CMAKE_VS_SDK_EXCLUDE_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Exclude Directories. Override it, babe. 💅
🌟 CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Executable Directories.
🌟 CMAKE_VS_SDK_INCLUDE_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Include Directories.
🌟 CMAKE_VS_SDK_LIBRARY_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Library Directories.
🌟 CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Library WinRT Directories.
🌟 CMAKE_VS_SDK_REFERENCE_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Reference Directories.
🌟 CMAKE_VS_SDK_SOURCE_DIRECTORIES
Added in version 3.12.
This variable lets you override Visual Studio's default Source Directories.
👑 CMAKE_VS_WINRT_BY_DEFAULT
Added in version 3.13.
This one informs the Visual Studio Generators for VS 2010 and above that the target platform enables WinRT compilation by default, and that it therefore needs to be explicitly disabled if /ZW or VS_WINRT_COMPONENT is omitted — which is the opposite of enabling it when either of those options is present. Subtle, but iconic. ✨
The whole point: it makes cmake configuration consistent across platforms in terms of WinRT. If you didn't explicitly enable WinRT compilation, it's gonna be disabled — either by never enabling it, or by explicitly disabling it. No mysterious in-between. 🦋
Note: WinRT compilation is always explicitly disabled for C language source files, even if it is explicitly enabled for a project.
This variable is meant to be set by a toolchain file (CMAKE_TOOLCHAIN_FILE) for such platforms. 🫶
🍓 CMAKE_WATCOM_RUNTIME_LIBRARY
Added in version 3.24.
Pick the Watcom runtime library for compilers targeting the Watcom ABI. This variable initializes the WATCOM_RUNTIME_LIBRARY property on all targets as they're created, and it's also propagated by calls to try_compile() into the test project. Sneaky but correct. 🍓
The allowed values are:
SingleThreaded— compile with no extra flags to use a single-threaded statically-linked runtime library.SingleThreadedDLL— compile with-bror equivalent flag(s) to use a single-threaded dynamically-linked runtime library. This one is not available for Linux targets. 😭MultiThreaded— compile with-bmor equivalent flag(s) to use a multi-threaded statically-linked runtime library.MultiThreadedDLL— compile with-bm -bror equivalent flag(s) to use a multi-threaded dynamically-linked runtime library. Also not available for Linux targets. 😭
The value is ignored on non-Watcom compilers, but an unsupported value will be rejected as an error when you're using a compiler targeting the Watcom ABI. So don't get cute with it. 💀
The value may also be the empty string (""), in which case CMake will not explicitly add any runtime library selection flag. Nothing added, nothing claimed.
Use generator expressions (see cmake-generator-expressions(7)) if you want per-configuration specification. 🌈
For example, this code:
set(CMAKE_WATCOM_RUNTIME_LIBRARY "MultiThreaded")
selects a multi-threaded statically-linked runtime library for all following targets. Slay.
If this variable is not set, then the WATCOM_RUNTIME_LIBRARY target property won't be set automatically. And if that property isn't set either, CMake falls back to the default value MultiThreadedDLL on Windows and SingleThreaded on other platforms when selecting a Watcom runtime library. Defaults got your back. 💖
💡 Note, bestie: this variable only does anything when policyCMP0136is set toNEWbefore the firstproject()orenable_language()call that enables a language using a compiler targeting the Watcom ABI. Timing matters, okay? ⏰
💖 CMAKE_WIN32_EXECUTABLE
The default value for the WIN32_EXECUTABLE property on targets. 🪟
So basically this variable gets used to initialize the WIN32_EXECUTABLE property on all the targets. Peep that target property if you want the extra lore.
💖 CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
Added in version 3.4.
This is the default value for the WINDOWS_EXPORT_ALL_SYMBOLS target property, and it's used to initialize that property on every target as it gets created. 🎀
💖 CMAKE_XCODE_ATTRIBUTE_<an-attribute>
Added in version 3.1.
Sets Xcode target attributes directly. Like, right in there. 🛠️
It tells the Xcode generator to set <an-attribute> to whatever value you give it in the generated Xcode project. Any other generator? Literally ignored. 🙈
This is low-level control over the generated Xcode project file, and it's meant as a last resort for settings that CMake doesn't otherwise have a way to control. Like, you can override a setting CMake normally produces on its own — but doing that bypasses CMake's whole model of the project and can break things. 💀 Fr fr, be careful.
If you wanna set attributes on one specific target instead, check out the XCODE_ATTRIBUTE_<an-attribute> target property.
The contents of CMAKE_XCODE_ATTRIBUTE_<an-attribute> may use "generator expressions" with the syntax $<...>. See the cmake-generator-expressions(7) manual for the available expressions, and the cmake-buildsystem(7) manual for more on defining buildsystem properties. ✨
💖 EXECUTABLE_OUTPUT_PATH
The old executable location variable. Vintage! 🕰️
The target property RUNTIME_OUTPUT_DIRECTORY supersedes this variable for a target if it's set. Otherwise, executable targets get placed in this directory.
💖 LIBRARY_OUTPUT_PATH
The old library location variable. Also vintage. 📚
The target properties ARCHIVE_OUTPUT_DIRECTORY, LIBRARY_OUTPUT_DIRECTORY, and RUNTIME_OUTPUT_DIRECTORY supersede this variable for a target if they're set. Otherwise, library targets get placed in this directory.
🌸 VARIABLES FOR LANGUAGES 🌸
💜 CMAKE_C_COMPILE_FEATURES
Added in version 3.1.
A list of features known to the C compiler. 👑
These features are known to be available for use with the C compiler, and this list is a subset of the features listed in the CMAKE_C_KNOWN_FEATURES global property.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_C_EXTENSIONS
Added in version 3.1.
The default value for the C_EXTENSIONS target property — but only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_C_STANDARD
Added in version 3.1.
The default value for the C_STANDARD target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_C_STANDARD_REQUIRED
Added in version 3.1.
The default value for the C_STANDARD_REQUIRED target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CUDA_ARCHITECTURES
Added in version 3.18.
The default value for the CUDA_ARCHITECTURES property of targets. 🖥️⚡
It gets initialized by the CUDAARCHS environment variable if that's set. Otherwise, it works like this, depending on CMAKE_CUDA_COMPILER_ID:
- For Clang: the oldest architecture that works.
- For NVIDIA: the default architecture chosen by the compiler. See policy
CMP0104.
👀 Users are encouraged to override this, because the default varies across compilers and compiler versions. Don't just leave it on default and hope, bestie.
This variable is used to initialize the CUDA_ARCHITECTURES property on all targets. See the target property for the extra details.
✨ Examples
cmake_minimum_required(VERSION)
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 75)
endif()
project(example LANGUAGES CUDA)
CMAKE_CUDA_ARCHITECTURES will default to 75 unless the user overrides it. Slay. 💅
💜 CMAKE_CUDA_COMPILE_FEATURES
Added in version 3.17.
A list of features known to the CUDA compiler. ⚡
These features are known to be available for use with the CUDA compiler, and this list is a subset of the features listed in the CMAKE_CUDA_KNOWN_FEATURES global property.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CUDA_EXTENSIONS
Added in version 3.8.
The default value for the CUDA_EXTENSIONS target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CUDA_HOST_COMPILER
Added in version 3.10.
This is the original CUDA-specific name for the more general CMAKE_<LANG>_HOST_COMPILER variable. Go read that one for the details — it's the glow-up version. ✨
💜 CMAKE_CUDA_STANDARD
Added in version 3.8.
The default value for the CUDA_STANDARD target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CUDA_STANDARD_REQUIRED
Added in version 3.8.
The default value for the CUDA_STANDARD_REQUIRED target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
Added in version 3.8.
Once the CUDA language has been enabled, this gives you a semicolon-separated list of the include directories provided by the CUDA Toolkit. 📂
Super handy for C++ source files that need to include CUDA headers. iykyk. 😌
💜 CMAKE_CXX_COMPILE_FEATURES
Added in version 3.1.
A list of features known to the C++ compiler. 🔥
These features are known to be available for use with the C++ compiler, and this list is a subset of the features listed in the CMAKE_CXX_KNOWN_FEATURES global property.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CXX_COMPILER_IMPORT_STD
Added in version 3.30.
A list of C++ standard levels for which import std support exists for the current C++ toolchain. 🌈
You can detect support for C++<NN> by using a <NN> IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD predicate with the if() command. Cute, right?
💡 Note: this variable is only meaningful when experimental support forimport std;has been enabled by theCMAKE_EXPERIMENTAL_CXX_IMPORT_STDgate. Gate's gotta be open, bestie. 🚪
💜 CMAKE_CXX_EXTENSIONS
Added in version 3.1.
The default value for the CXX_EXTENSIONS target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CXX_STANDARD
Added in version 3.1.
The default value for the CXX_STANDARD target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_CXX_STANDARD_REQUIRED
Added in version 3.1.
The default value for the CXX_STANDARD_REQUIRED target property — only if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_Fortran_MODDIR_DEFAULT
The Fortran default module output directory. 🏰
Most Fortran compilers write .mod files to the current working directory. For the ones that don't, this gets set to . and is used when the Fortran_MODULE_DIRECTORY target property isn't set.
💜 CMAKE_Fortran_MODDIR_FLAG
The Fortran flag for the module output directory. 🚩
This stores the flag you need to pass the value of the Fortran_MODULE_DIRECTORY target property through to the compiler.
💜 CMAKE_Fortran_MODOUT_FLAG
The Fortran flag to enable module output. 🔧
Most Fortran compilers write .mod files out by default. For the others, this stores the flag needed to turn module output on.
💜 CMAKE_HIP_ARCHITECTURES
Added in version 3.21.
A list of GPU architectures to generate device code for. 🎛️ Architecture names are interpreted based on CMAKE_HIP_PLATFORM.
It gets initialized based on the value of CMAKE_HIP_PLATFORM:
amd— uses architectures reported byrocm_agent_enumeratorif available, and otherwise falls back to a default chosen by the compiler.spirv— defaults toOFF. The HIP package (e.g.,chipStar) handles targeting via its own configuration.
This variable is used to initialize the HIP_ARCHITECTURES property on all targets. See the target property for the additional info. 🫶
💜 CMAKE_HIP_COMPILE_FEATURES
Added in version 3.21.
A list of features known to the HIP compiler. 💫
These features are known to be available for use with the HIP compiler, and this list is a subset of the features listed in the CMAKE_HIP_KNOWN_FEATURES global property.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🫶
💜 CMAKE_HIP_EXTENSIONS
Added in version 3.21.
Default value for HIP_EXTENSIONS target property if set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 💖
🌸 CMAKE_HIP_PLATFORM
Added in version 3.28.
Bestie, this is the GPU platform your HIP language sources get compiled for. 🦋
The value has to be one of these, no improvising:
amd— AMD GPUs 💜nvidia— NVIDIA GPUs 💚spirv— Added in version 4.3. the SPIR-V target (e.g.,chipStar)
If you don't specify it, a default gets computed via hipconfig --platform ✨
Heads up: CMAKE_HIP_ARCHITECTURES entries are interpreted as architectures of the GPU platform. And CMAKE_HIP_COMPILER must target the same GPU platform — like, they gotta match, no cap. 🫶
💅 CMAKE_HIP_STANDARD
Added in version 3.21.
Default value for the HIP_STANDARD target property, if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🎀
👑 CMAKE_HIP_STANDARD_REQUIRED
Added in version 3.21.
Default value for the HIP_STANDARD_REQUIRED target property, if it's set when a target is created.
See the cmake-compile-features(7) manual for info on compile features and a list of supported compilers. 🌸
🧚 CMAKE_ISPC_HEADER_DIRECTORY
Added in version 3.19.
The ISPC generated header output directory, periodt. 💫
This variable initializes the ISPC_HEADER_DIRECTORY property on all the targets. Peep the target property for the extra deets.
🍓 CMAKE_ISPC_HEADER_SUFFIX
Added in version 3.19.2.
The output suffix used for ISPC generated headers. 🎀
This one initializes the ISPC_HEADER_SUFFIX property on all the targets. Target property has the additional info, iykyk.
🌈 CMAKE_ISPC_INSTRUCTION_SETS
Added in version 3.19.
Default value for the ISPC_INSTRUCTION_SETS property of targets. 🔥
This variable initializes the ISPC_INSTRUCTION_SETS property on all targets. See the target property for additional information.
💀 CMAKE_<LANG>_ANDROID_TOOLCHAIN_MACHINE
Added in version 3.7.1.
When cross compiling for Android, this variable contains the toolchain binutils machine name (e.g. gcc -dumpmachine). The binutils typically have a <machine>- prefix on their name. 🦋
See also CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX and CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX.
🌟 CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX
Added in version 3.7.
When cross compiling for Android, this variable contains the absolute path prefixing the toolchain GNU compiler and its binutils. 💜
See also CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX and CMAKE_<LANG>_ANDROID_TOOLCHAIN_MACHINE.
For example, the path to the linker is literally this:
${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ld${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}
🎀 CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX
Added in version 3.7.
When cross compiling for Android, this variable contains the host platform suffix of the toolchain GNU compiler and its binutils. ✨
See also CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX and CMAKE_<LANG>_ANDROID_TOOLCHAIN_MACHINE.
🔥 CMAKE_<LANG>_ARCHIVE_APPEND
Rule variable to append to a static archive. 💅
So this is a rule variable that tells CMake how to append to a static archive. It gets used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY on some platforms, specifically so you can support large object counts. See also CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_FINISH.
🦋 CMAKE_<LANG>_ARCHIVE_CREATE
Rule variable to create a new static archive. ✨
A rule variable that tells CMake how to create a static archive. It's used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY on some platforms so large object counts are supported. See also CMAKE_<LANG>_ARCHIVE_APPEND and CMAKE_<LANG>_ARCHIVE_FINISH.
🌸 CMAKE_<LANG>_ARCHIVE_FINISH
Rule variable to finish an existing static archive. 🎀
A rule variable that tells CMake how to finish a static archive. Like its siblings, it's used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY on some platforms, in order to support large object counts. See also CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_APPEND.
👑 CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG
Added in version 4.0.
Defines the syntax of the compiler driver option used to pass options to the archiver tool. It gets used to translate the ARCHIVER: prefix in the static library options (see STATIC_LIBRARY_OPTIONS). 💫
This variable holds a semicolon-separated list of tokens. If a space (i.e. " ") is specified as the last token, the flag and the ARCHIVER: arguments will be specified as separate arguments to the compiler driver. The CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG_SEP variable can be specified to manage concatenation of arguments. 🫶
See the CMAKE_<LANG>_LINKER_WRAPPER_FLAG variable for examples of definitions, because CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG uses the exact same syntax.
💜 CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG_SEP
Added in version 4.0.
This variable is used together with CMAKE_<LANG>_ARCHIVER_WRAPPER_FLAG to format the ARCHIVER: prefix in the static library options (see STATIC_LIBRARY_OPTIONS). 🌟
When it's specified, arguments of the ARCHIVER: prefix get concatenated using this value as the separator.
🌈 CMAKE_<LANG>_BYTE_ORDER
Added in version 3.20.
The byte order of the <LANG> compiler target architecture, if it's known. If defined and not empty, the value is one of:
BIG_ENDIAN— the target architecture is Big Endian. 🐘LITTLE_ENDIAN— the target architecture is Little Endian. 🐜
This is defined for the languages C, CXX, OBJC, OBJCXX, and CUDA.
And listen — if CMAKE_OSX_ARCHITECTURES specifies multiple architectures, then the value of CMAKE_<LANG>_BYTE_ORDER is non-empty only if all architectures share the same byte order. Otherwise it's just vibes and emptiness 😭
⭐ Examples ⭐
🧚 Example: Checking Endianness
Checking the endianness (byte order) of the target architecture in a CMake project, where C language is one of the enabled languages, and storing the result in a variable WORDS_BIGENDIAN:
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()
Or, if the project doesn't have C language enabled, you can swap in some other enabled language. For example, if CXX is enabled:
if(CMAKE_CXX_BYTE_ORDER STREQUAL "BIG_ENDIAN")
set(WORDS_BIGENDIAN TRUE)
elseif(CMAKE_CXX_BYTE_ORDER STREQUAL "LITTLE_ENDIAN")
set(WORDS_BIGENDIAN FALSE)
else()
set(WORDS_BIGENDIAN FALSE)
message(WARNING "Endianness could not be determined.")
endif()
Note that in most cases this can be simplified by only checking for a big-endian target:
if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN")
set(WORDS_BIGENDIAN TRUE)
else()
set(WORDS_BIGENDIAN FALSE)
endif()
🦋 Example: Per-language Endianness Check
Most of the time, the architectures used today are consistent in endianness across compilers. But here's when a per-language endianness check can actually matter:
- Cross-compilation to different architectures (e.g., a big-endian embedded system). 💀
- Heterogeneous toolchains where one target architecture is for C language and another target is for a different language.
- Static libraries or binaries reused across platforms (e.g., distributing precompiled CUDA kernels).
if(CMAKE_C_BYTE_ORDER)
message(STATUS "C byte order: ${CMAKE_C_BYTE_ORDER}")
endif()
if(CMAKE_CXX_BYTE_ORDER)
message(STATUS "C++ byte order: ${CMAKE_CXX_BYTE_ORDER}")
endif()
if(CMAKE_CUDA_BYTE_ORDER)
message(STATUS "CUDA byte order: ${CMAKE_CUDA_BYTE_ORDER}")
endif()
💫 CMAKE_<LANG>_COMPILE_OBJECT
Rule variable to compile a single object file. ✨
It's a rule variable that tells CMake how to compile a single object file for the language <LANG>. That's it, that's the whole vibe.
🌟 CMAKE_<LANG>_COMPILER
The full path to the compiler for LANG. 👑
This is the command that will be used as the <LANG> compiler. Once it's set, you can not change this variable. Periodt. 🚫
Note: with IDE Build Tool Generators, including Visual Studio Generators and Xcode, this variable is computed automatically and should not be set. Instead, specify a toolset using cmake -T. 🙈
Usage
With Command-Line Build Tool Generators, this variable can be set by the user the first time a build tree is configured. 🎀
If you supply a non-full path value, then CMake will resolve the full path of the compiler. ✨
The variable could be set in a user supplied toolchain file or via -D on the command line.
Note: options that are required to make the compiler work correctly can be included as items in a list; they can not be changed. 💀
#set within user supplied toolchain file
set(CMAKE_C_COMPILER /full/path/to/qcc --arg1 --arg2)
or
$ cmake ... -DCMAKE_C_COMPILER='qcc;--arg1;--arg2'
💜 CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
The external toolchain for cross-compiling, if supported. 🦋
Okay so real talk: some compiler toolchains are out here not shipping their own auxiliary utilities 😭 like archivers and linkers? not them forgetting the whole supporting cast 💀
But the compiler driver might actually be chill and support a command-line argument where you tell it where those tools live. That's where CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN comes in — set it to a path pointing at the external toolchain, and it gets passed along to the compiler driver if it's supported 🫶
Bestie, listen: this variable may only be set in a toolchain file that's specified by the CMAKE_TOOLCHAIN_FILE variable. Nowhere else. That's the rule 👑
CMAKE_<LANG>_COMPILER_ID
Compiler identification string ✨ like a little name tag for your compiler, iykyk 🎀
Like literally a short string that's unique to the compiler vendor — that's the whole vibe. And bestie, here's the possible-values menu, so you can spot your fave at a glance 👀
Absoft— Absoft Fortran 💜ADSP— Analog VisualDSP++AppleClang— Apple Clang 🍎ARMCC— ARM CompilerARMClang— ARM Compiler based on ClangBruce— Bruce C CompilerCCur— Concurrent FortranClang— LLVM Clang <https://clang.llvm.org> ✨Cray— Cray CompilerCrayClang— Cray Clang-based CompilerDiab— Wind River Systems Diab Compiler <https://www.windriver.com/resource/wind-river-diab-compiler-product-overview>Embarcadero, Borland— Embarcadero <https://www.embarcadero.com>Flang— Classic Flang Fortran Compiler <https://github.com/flang-compiler/flang>LLVMFlang— LLVM Flang Fortran Compiler <https://github.com/llvm/llvm-project/tree/main/flang>Fujitsu— Fujitsu HPC compiler (Trad mode)FujitsuClang— Fujitsu HPC compiler (Clang mode)G95— G95 Fortran <https://g95.sourceforge.net>GNU— GNU Compiler Collection <https://gcc.gnu.org> 🐃GHS— Green Hills Software <https://www.ghs.com/products/compiler.html>HP— Hewlett-Packard CompilerIAR— IAR SystemsIntel— Intel Classic CompilerIntelLLVM— Intel LLVM-Based Compiler <https://www.intel.com/content/www/us/en/developer/tools/oneapi/overview.html>LCC— MCST Elbrus C/C++/Fortran CompilerLFortran— LFortran Fortran CompilerMSVC— Microsoft Visual Studio <https://visualstudio.microsoft.com>NVHPC— NVIDIA HPC Compiler <https://developer.nvidia.com/hpc-compilers>NVIDIA— NVIDIA CUDA Compiler <https://developer.nvidia.com/cuda-llvm-compiler>OrangeC— OrangeC Compiler <https://github.com/LADSoft/OrangeC> 🍊OpenWatcom— Open Watcom <https://open-watcom.github.io>PellesC— Pelles C <https://pellesc.se>PGI— The Portland GroupPathScale— PathScaleQCC— QNX C/C++ compilerRenesas— Renesas Compiler <https://www.renesas.com>SCO— SCO OpenServer/UnixWare
ngl, that's a lot of vendors — but every one of them is a real value you might get back, so don't be out here guessing, just check the list 🫶
…and the roster just keeps going, bestie 💅 here's the rest of the table (still two columns: the compiler ID on the left, what it actually is on the right):
SDCC— Small Device C Compiler<https://sdcc.sourceforge.net>SunPro— Oracle Developer StudioTasking— Tasking Compiler Toolsets<https://www.tasking.com>TI— Texas InstrumentsTIClang— Texas Instruments Clang-based Compilers<https://www.ti.com/tool/download/ARM-CGT-CLANG>TinyCC— Tiny C Compiler<https://bellard.org/tcc>XL,VisualAge,zOS— IBM XLXLClang— IBM Clang-based XLIBMClang— IBM LLVM-based CompilerIBMFlang— IBM LLVM/Flang-based Fortran Compiler
Real talk though: this variable is not guaranteed to be defined for all compilers or languages 🙈 so don't come for me if your weird little cross-compiler doesn't show up, okay?
CMAKE_<LANG>_COMPILER_LOADED
Defined to true if the language is enabled, periodt ✨
When language <LANG> gets enabled by project() or enable_language(), this variable is literally defined to 1. That's it. That's the whole vibe check 💅
CMAKE_<LANG>_COMPILER_PREDEFINES_COMMAND
Added in version 3.10. 🌸
Command that outputs the compiler pre definitions. Slay.
Peep AUTOMOC, which uses CMAKE_CXX_COMPILER_PREDEFINES_COMMAND to generate AUTOMOC_COMPILER_PREDEFINES. iykyk 🧚
CMAKE_<LANG>_COMPILER_TARGET
The target for cross-compiling, if supported — key words, bestie 👑
Some compiler drivers are inherently cross-compilers, such as clang and QNX qcc. These compiler drivers support a command-line argument to specify the target to cross-compile for. Iconic behavior honestly.
⚠️ Heads up: this variable may only be set in a toolchain file specified by theCMAKE_TOOLCHAIN_FILEvariable. Nowhere else. Not yourCMakeLists.txt. Not your little scripts. Don't try it 🙈
CMAKE_<LANG>_COMPILER_VERSION
Compiler version string. The number goes brrr 💀
Compiler version in major[.minor[.patch[.tweak]]] format. And again — this variable is not guaranteed to be defined for all compilers or languages 😭
For example, CMAKE_C_COMPILER_VERSION and CMAKE_CXX_COMPILER_VERSION might indicate the respective C and C++ compiler version. Might!! It's giving "we'll see" energy fr fr.
CMAKE_<LANG>_CREATE_SHARED_LIBRARY
Rule variable to create a shared library. 🎀
This is a rule variable that tells CMake how to create a shared library for the language <LANG>. It's a ; delimited list of commands to run to perform the linking step. Yes, semicolons. No, it's not a typo. That's just how she rolls 💅
CMAKE_<LANG>_CREATE_SHARED_LIBRARY_ARCHIVE
Added in version 3.31. ⭐
Rule variable to create a shared library with archive.
This is a rule variable that tells CMake how to create a shared library with an archive for the language <LANG>. This rule variable is a ; delimited list of commands to run to perform the linking step. Same delimited-list situation, new fit ✨
CMAKE_<LANG>_CREATE_SHARED_MODULE
Rule variable to create a shared module. 🦋
This is a rule variable that tells CMake how to create a shared library for the language <LANG>. This rule variable is a ; delimited list of commands to run. (Yes, the description says "shared library" — that's what the manpage says, and I'm not about to editorialize 👀)
CMAKE_<LANG>_CREATE_STATIC_LIBRARY
Rule variable to create a static library. 🌈
This is a rule variable that tells CMake how to create a static library for the language <LANG>. Short and sweet, main character energy 👑
CMAKE_<LANG>_EXTENSIONS
The variations are:
CMAKE_C_EXTENSIONSCMAKE_CXX_EXTENSIONSCMAKE_CUDA_EXTENSIONSCMAKE_HIP_EXTENSIONSCMAKE_OBJC_EXTENSIONSCMAKE_OBJCXX_EXTENSIONS
Default values for <LANG>_EXTENSIONS target properties if set when a target is created. For the compiler's default setting, see CMAKE_<LANG>_EXTENSIONS_DEFAULT. 💖
For supported CMake versions, see the respective pages. (Yes, plural, go look it up bestie.)
See the cmake-compile-features(7) manual for information on compile features and a list of supported compilers. Super useful, highly recommend 🫶
CMAKE_<LANG>_EXTENSIONS_DEFAULT
Added in version 3.22. 🎀
Compiler's default extensions mode. Used as the default for the <LANG>_EXTENSIONS target property when CMAKE_<LANG>_EXTENSIONS is not set (see CMP0128).
💀 This variable is read-only. Modifying it is undefined behavior. Do NOT touch her. Hands off. Not even a little. Not even set() with good intentions. Undefined behavior is not a cute look.
CMAKE_<LANG>_FLAGS
Language-wide flags for language <LANG> used when building for all configurations. These flags will be passed to all invocations of the compiler. That includes invocations that drive compiling and those that drive linking. Everyone's invited 🎉
For each language, if this variable is not defined, it is initialized and stored in the cache using values from environment variables in combination with CMake's builtin defaults for the toolchain:
CMAKE_C_FLAGS: Initialized by theCFLAGSenvironment variable.CMAKE_CXX_FLAGS: Initialized by theCXXFLAGSenvironment variable.CMAKE_CUDA_FLAGS: Initialized by theCUDAFLAGSenvironment variable.CMAKE_Fortran_FLAGS: Initialized by theFFLAGSenvironment variable.CMAKE_CSharp_FLAGS: Initialized by theCSFLAGSenvironment variable.CMAKE_HIP_FLAGS: Initialized by theHIPFLAGSenvironment variable.CMAKE_ISPC_FLAGS: Initialized by theISPCFLAGSenvironment variable.CMAKE_OBJC_FLAGS: Initialized by theOBJCFLAGSenvironment variable.CMAKE_OBJCXX_FLAGS: Initialized by theOBJCXXFLAGSenvironment variable.
This value is a command-line string fragment. Therefore, multiple options should be separated by spaces, and options with spaces should be quoted. Yes, quoted. I know. I know. Just do it 💅
The flags in this variable will be passed before those in the per-configuration CMAKE_<LANG>_FLAGS_<CONFIG> variable. On invocations driving compiling, flags from both variables will be passed before flags added by commands such as add_compile_options() and target_compile_options(). On invocations driving linking, they will be passed before flags added by commands such as add_link_options() and target_link_options().
Order matters, bestie. It's giving ✨ hierarchy ✨ and you're at the top of the pile but below the commands. Keep up 🔥
CMAKE_<LANG>_FLAGS_<CONFIG>
Language-wide flags for language <LANG> used when building for the <CONFIG> configuration. These flags will be passed to all invocations of the compiler in the corresponding configuration. Again — invocations that drive compiling and those that drive linking. Everybody getting these flags, no exceptions 🫶
The flags in this variable will be passed after those in the CMAKE_<LANG>_FLAGS variable. On invocations driving compiling, flags from both variables will be passed before flags added by commands such as add_compile_options() and target_compile_options(). On invocations driving linking, they will be passed before flags added by commands such as add_link_options() and target_link_options().
(Yes, after the language-wide ones, before the command ones. That's the sandwich. Respect the sandwich 🥪)
CMAKE_<LANG>_FLAGS_<CONFIG>_INIT
Added in version 3.11. 🌸
Value used to initialize the CMAKE_<LANG>_FLAGS_<CONFIG> cache entry the first time a build tree is configured for language <LANG>. This variable is meant to be set by a toolchain file. Note that CMake may prepend or append content to the value based on the environment and target platform — so it's an init, not a promise, bestie 🙈
See also CMAKE_<LANG>_FLAGS_INIT.
CMAKE_<LANG>_FLAGS_DEBUG
This variable is the Debug variant of the CMAKE_<LANG>_FLAGS_<CONFIG> variable. Same energy, debug-flavored 🐛💜
CMAKE_<LANG>_FLAGS_DEBUG_INIT
Added in version 3.7. ⭐
This variable is the Debug variant of the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variable. Init-ception but make it Debug 🎀
CMAKE_<LANG>_FLAGS_INIT
Added in version 3.7. 🦋
...it's the value that initializes the CMAKE_<LANG>_FLAGS cache entry the very first time a build tree gets configured for language <LANG> ✨. This one is meant to be set by a toolchain file, okay? That's its whole moment. CMake may prepend or append stuff to your value based on the environment and the target platform — for example, the contents of a xxxFLAGS environment variable get prepended, where xxx is language-specific but not necessarily the same as <LANG> (like CXXFLAGS for CXX, FFLAGS for Fortran, and so on, iykyk 💅).
Also, heads up: this value is a command-line string fragment. So multiple options gotta be separated by spaces, and options with spaces gotta be quoted. Non-negotiable bestie 🫶
See also the config-specific CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variable 👀
CMAKE_<LANG>_FLAGS_MINSIZEREL
It's literally the MinSizeRel variant of the CMAKE_<LANG>_FLAGS_<CONFIG> variable. Same energy, different config 🎀
CMAKE_<LANG>_FLAGS_MINSIZEREL_INIT
Added in version 3.7 — so she's been iconic for a minute ⭐
This is the MinSizeRel variant of the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variable.
CMAKE_<LANG>_FLAGS_RELEASE
The Release variant of the CMAKE_<LANG>_FLAGS_<CONFIG> variable. Slay 🔥
CMAKE_<LANG>_FLAGS_RELEASE_INIT
Added in version 3.7 ✨
The Release variant of the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variable.
CMAKE_<LANG>_FLAGS_RELWITHDEBINFO
The RelWithDebInfo variant of the CMAKE_<LANG>_FLAGS_<CONFIG> variable. Yes the name is long, no we're not shortening it 💀
CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT
Added in version 3.7 🌸
The RelWithDebInfo variant of the CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variable.
CMAKE_<LANG>_HOST_COMPILER
Added in version 3.10 as CMAKE_CUDA_HOST_COMPILER — and added in version 3.28 for CMAKE_HIP_HOST_COMPILER 💖
This variable is only available when <LANG> is CUDA or HIP.
When CMAKE_<LANG>_COMPILER_ID is NVIDIA, CMAKE_<LANG>_HOST_COMPILER selects the compiler executable to use when compiling host code for CUDA or HIP language files 🌈. It maps directly to the nvcc -ccbin option. Fr fr.
You can set the CMAKE_<LANG>_HOST_COMPILER variable explicitly before CUDA or HIP is first enabled by a project() or enable_language() command. Ways to do it:
- Slap
-DCMAKE_<LANG>_HOST_COMPILER=...on the command line - Set it in a toolchain file
- Or set the
CUDAHOSTCXXorHIPHOSTCXXenvironment variable to provide a default value 🐚
⚠️ Once the CUDA or HIP language is enabled, CMAKE_<LANG>_HOST_COMPILER is read-only, and changes to it are undefined behavior. Do not touch. Hands off. 🙈
💀 Note: SinceCMAKE_<LANG>_HOST_COMPILERis only meaningful whenCMAKE_<LANG>_COMPILER_IDisNVIDIA, it does not make sense to setCMAKE_<LANG>_HOST_COMPILERwithout also settingCMAKE_<LANG>_COMPILERtoNVCC.
💀 Note: Projects should not try to setCMAKE_<LANG>_HOST_COMPILERto matchCMAKE_CXX_COMPILERthemselves. It is the end-user's responsibility, not the project's, to ensure that NVCC targets the same ABI as the C++ compiler. Like, stay in your lane, project 💅
💀 Note: Ignored when using Visual Studio Generators.
Go check the CMAKE_<LANG>_HOST_COMPILER_ID and CMAKE_<LANG>_HOST_COMPILER_VERSION variables for the tea on the host compiler used by nvcc — whether it's the default one or the one you specified with CMAKE_<LANG>_HOST_COMPILER 👑
CMAKE_<LANG>_HOST_COMPILER_ID
Added in version 3.31 ⭐
This variable is available when <LANG> is CUDA or HIP and CMAKE_<LANG>_COMPILER_ID is NVIDIA. It contains the identity of the host compiler invoked by nvcc — either by default or as specified by CMAKE_<LANG>_HOST_COMPILER — among the possibilities documented by CMAKE_<LANG>_COMPILER_ID 🦋
CMAKE_<LANG>_HOST_COMPILER_VERSION
Added in version 3.31 ⭐
This variable is available when <LANG> is CUDA or HIP and CMAKE_<LANG>_COMPILER_ID is NVIDIA. It contains the version of the host compiler invoked by nvcc — either by default or as specified by CMAKE_<LANG>_HOST_COMPILER — in the exact same format as CMAKE_<LANG>_COMPILER_VERSION 💜
CMAKE_<LANG>_IGNORE_EXTENSIONS
File extensions that should be ignored by the build 🚫
This is a list of file extensions that may be part of a project for a given language, but are not compiled. Sitting there, existing, contributing nothing. We respect it.
CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES
The directories the compiler implicitly searches for header files 🎀
CMake does not explicitly specify these directories on compiler command lines for language <LANG>. Why? Because that prevents system include directories from being treated as user include directories on some compilers — which is super important for C, CXX, and CUDA, so you don't go overriding standard library headers on accident 😭
This value is not used for Fortran, because Fortran has no standard library headers, and some compilers do not search their implicit include directories for module .mod files. Different beast entirely 🐴
CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES
The implicit linker search path detected for language <LANG> 🔍
Compilers typically pass directories containing language runtime libraries and default library search paths when they invoke a linker. These paths are the implicit linker search directories for the compiler's language. Iconic behavior honestly.
For each language enabled by the project() or enable_language() command, CMake automatically detects these directories and reports the results in this variable ✨ The CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES_EXCLUDE environment variable may be set to exclude specific directories from the automatically detected results. Use it wisely bestie.
When linking to a static library, CMake adds the implicit link directories from this variable for each language used in the static library — except the language whose compiler is used to drive linking 👀 In the case of an imported static library, the IMPORTED_LINK_INTERFACE_LANGUAGES target property lists the languages whose implicit link information is needed.
If any of those languages isn't enabled, its value for the CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES variable may instead be provided by the project. Or, a toolchain file may set the variable to a value known for the specified toolchain — it'll either be overridden when the language is enabled, or used as a fallback. Either/or, it's covered 💅
⚠️ Some toolchains read implicit directories from an environment variable such as LIBRARY_PATH. If you're using such an environment variable, keep its value consistent while operating in a given build tree, because CMake saves the value detected when it first created the build tree. Change it later and you're on your own 😭
In CMake versions prior to 4.0, if policy CMP0060 is not set to NEW, then when a library in one of these directories is given by full path to target_link_libraries(), CMake will generate the -l<name> form on link lines — for historical purposes. Old lore. Ancient vibes 🏺
See also the CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES variable.
CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
The implicit linker framework search path detected for language <LANG> 🍎
These paths are the implicit linker framework search directories for the compiler's language. CMake automatically detects these directories for each language and reports the results in this variable. Set and forget, she handles it ✨
CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES
Implicit link libraries and flags detected for language <LANG> 🔥
Compilers typically pass language runtime library names and other flags when they invoke a linker. These flags are the implicit link options for the compiler's language — the compiler just sneaks them in, lowkey.
For each language enabled by the project() or enable_language() command, CMake automatically detects these libraries and flags and reports the results in this variable 🫶 The CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES_EXCLUDE environment variable may be set to exclude specific libraries from the automatically detected results.
When linking to a static library, CMake adds the implicit link libraries and flags from this variable for each language used in the static library — again, except the language whose compiler is used to drive linking. In the case of an imported static library, the IMPORTED_LINK_INTERFACE_LANGUAGES target property lists the languages whose implicit link information is needed.
If any of the languages is not enabled, its value for the CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES variable may instead be provided by the project. Or, a toolchain file may set the variable to a value known for the specified toolchain. It will either be overridden when the language is enabled, or used as a fallback. Same deal as the directories, no cap 🤝
See also the CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES variable.
CMAKE_<LANG>_LIBRARY_ARCHITECTURE
The target architecture library directory name detected for <LANG> 🏗️
If the <LANG> compiler passes to the linker an architecture-specific system library search directory such as <prefix>/lib/<arch>, this variable contains the <arch> name — if/as detected by CMake. That's it, that's the whole vibe.
CMAKE_<LANG>_LINK_EXECUTABLE
Rule variable to link an executable 💅
Literally what it says: a rule variable to link an executable for the given language. She does one thing and she does it well.
CMAKE_<LANG>_LINK_FLAGS
Added in version 4.3 ⭐
Language-wide flags for language <LANG> used when linking for all configurations 🌈 These flags will be passed to all invocations of the compiler which drive linking. Every single one. No exceptions.
The flags in this variable obey the following behavior with respect to ordering of flags from other variables:
- They will be passed after those added by
CMAKE_<LANG>_FLAGSandCMAKE_<LANG>_FLAGS_<CONFIG>🔥
…and the ordering tea continues, bestie, because where your flags land in the lineup is literally everything:
- They get passed after the ones added by
CMAKE_EXE_LINKER_FLAGS,CMAKE_EXE_LINKER_FLAGS_<CONFIG>,CMAKE_SHARED_LINKER_FLAGS,CMAKE_SHARED_LINKER_FLAGS_<CONFIG>,CMAKE_MODULE_LINKER_FLAGS, andCMAKE_MODULE_LINKER_FLAGS_<CONFIG>— which one depends on the target type you're building, iykyk. - They get passed before the ones added by
CMAKE_<LANG>_LINK_FLAGS_<CONFIG>. - They get passed before the ones added by commands like
add_link_options()andtarget_link_options().
This whole variable only kicks in when policy CMP0210 is NEW. Periodt.
Handling Compiler Driver Differences
Added in version 4.0.
Okay so every compiler driver has its own little dialect for handing options to the linker tool, and that's annoying 😭. That's what the LINKER: prefix and the , separator are for — they let you say it portably. LINKER: gets swapped out for the right driver option, and , gets swapped for the right driver separator. Where do those come from? The values of the CMAKE_<LANG>_LINKER_WRAPPER_FLAG and CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP variables, bestie 💅.
So like, "LINKER:-z,defs" turns into -Xlinker -z -Xlinker defs for Clang, and -Wl,-z,defs for GNU GCC. Same input, different fits ✨.
The LINKER: prefix also supports an alternate syntax where you specify the arguments using the SHELL: prefix and a space as the separator. That same example then becomes "LINKER:SHELL:-z defs".
Note: putting theSHELL:prefix anywhere other than the beginning of theLINKER:prefix is not supported, no cap 🙈.
This support implies parsing and re-quoting the content of the variable. That's the whole vibe.
See Also
CMAKE_<LANG>_LINK_FLAGS_<CONFIG>CMAKE_<LANG>_FLAGSCMP0210
CMAKE_<LANG>_LINK_FLAGS_<CONFIG>
Added in version 4.3.
These are the language-wide flags for language <LANG> used when linking, specifically for the <CONFIG> configuration. They get passed to all invocations of the compiler that drive linking — every single one, bestie 🫶.
For how these flags order up against other variables, go look at CMAKE_<LANG>_LINK_FLAGS. The headline you actually need: flags in CMAKE_<LANG>_LINK_FLAGS_<CONFIG> are passed after those in CMAKE_<LANG>_LINK_FLAGS.
Handling Compiler Driver Differences
Added in version 4.0.
Yes we're doing this again, because it applies here too 😌. Each compiler driver has its own syntax for passing options to the linker tool. The LINKER: prefix and , separator let you specify those options in a portable way: LINKER: becomes the appropriate driver option, , becomes the appropriate driver separator. Both of those come from CMAKE_<LANG>_LINKER_WRAPPER_FLAG and CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP.
Example time ⭐: "LINKER:-z,defs" becomes -Xlinker -z -Xlinker defs for Clang, and -Wl,-z,defs for GNU GCC.
You can also use the alternative SHELL: prefix syntax with a space separator, so the example above becomes "LINKER:SHELL:-z defs".
Note: specifying theSHELL:prefix anywhere other than at the beginning of theLINKER:prefix is not supported 💀.
This support implies parsing and re-quoting the content of the variable.
See Also
CMAKE_<LANG>_LINK_FLAGSCMAKE_<LANG>_FLAGS_<CONFIG>
CMAKE_<LANG>_LINKER_WRAPPER_FLAG
Added in version 3.13.
This one defines the syntax of the compiler driver option used to pass options through to the linker tool. CMake uses it to translate that LINKER: prefix in your link options — you know, the ones in add_link_options() and target_link_options() 👑
It holds a semicolon-separated list of tokens. If a space (like, literally " ") is given as the last token, then the flag and the LINKER: arguments get specified as separate arguments to the compiler driver. And the CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP variable is there to manage concatenation of arguments when you need it.
Concrete examples, because examples ate 💅 — for Clang:
set (CMAKE_C_LINKER_WRAPPER_FLAG "-Xlinker" " ")
With that, specifying "LINKER:-z,defs" will be transformed into -Xlinker -z -Xlinker defs.
For GNU GCC:
set (CMAKE_C_LINKER_WRAPPER_FLAG "-Wl,")
set (CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
Specifying "LINKER:-z,defs" will be transformed into -Wl,-z,defs.
And for SunPro:
set (CMAKE_C_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ")
set (CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
Specifying "LINKER:-z,defs" will be transformed into -Qoption ld -z,defs.
Three drivers, three fits, one prefix. Iconic 🌈.
CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP
Added in version 3.13.
This one teams up with the CMAKE_<LANG>_LINKER_WRAPPER_FLAG variable to format the LINKER: prefix inside your link options — again, that's add_link_options() and target_link_options() 🎀.
When it's set, the arguments of the LINKER: prefix get concatenated using this value as the separator. That's it, that's the whole job 🦋.
CMAKE_<LANG>_OUTPUT_EXTENSION
The extension for the output of a compile for a single file.
So basically it's the extension an object file gets for the given <LANG>. Example: .obj for C on Windows 💖.
CMAKE_<LANG>_SIMULATE_ID
The identification string of the "simulated" compiler.
Some compilers literally cosplay other compilers so they can be drop-in replacements — main character energy, honestly 👑. When CMake detects one of these, it sets this variable to whatever the CMAKE_<LANG>_COMPILER_ID would have been for the compiler being simulated.
Note: in other words, this variable describes the ABI compatibility of the generated code. That's the actual tea ☕.
CMAKE_<LANG>_SIMULATE_VERSION
The version string of the "simulated" compiler.
Same story as above — some compilers simulate other compilers as drop-in replacements. When CMake spots one, it sets this variable to what the CMAKE_<LANG>_COMPILER_VERSION would have been for the simulated compiler 🌸.
CMAKE_<LANG>_SIZEOF_DATA_PTR
The size of pointer-to-data types for language <LANG>.
This holds the size, in bytes, of pointer-to-data types in the target platform ABI. Heads up: it's defined for the languages C and CXX (C++) only 🫶.
CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS
The extensions of source files for the given language.
Literally just the list of extensions for the source files of a given language. Short and slay ✨.
CMAKE_<LANG>_STANDARD
The variations are:
CMAKE_C_STANDARDCMAKE_CXX_STANDARDCMAKE_CUDA_STANDARDCMAKE_HIP_STANDARDCMAKE_OBJC_STANDARDCMAKE_OBJCXX_STANDARD
These are the default values for the <LANG>_STANDARD target property — but only if they're set at the moment a target is created. Timing matters, bestie ⏰.
For which CMake versions support what, check the respective pages. And for the full lore on compile features plus a list of supported compilers, the cmake-compile-features(7) manual is your bestie fr fr.
CMAKE_<LANG>_STANDARD_DEFAULT
Added in version 3.9.
The compiler's default standard for the language <LANG>. It's empty if the compiler has no conception of standard levels — some just don't think about it like that, and we respect it 💅.
CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES
Added in version 3.6.
Include directories to be used for every source file compiled with the <LANG> compiler. This exists to specify the system include directories that the language needs for the current platform. These directories always show up at the end of the include path passed to the compiler. End of the line, no cutting 🎀.
Important: project code should not set this variable. It's meant to be set by CMake's platform information modules for the current toolchain, or by a toolchain file when you're using CMAKE_TOOLCHAIN_FILE. Hands off, bestie 🙈.
See also CMAKE_<LANG>_STANDARD_LIBRARIES.
CMAKE_<LANG>_STANDARD_LATEST
Added in version 3.30.
Okay this one is kind of a big deal 👑. This variable represents the minimum between two things:
- the latest version of the standard for language
<LANG>that the current compiler supports, and - the latest version that CMake supports.
Its value gets set to one of the supported values of the corresponding <LANG>_STANDARD target property — peep the docs of that property for the list of supported languages 📋.
For info on compile features and a list of supported compilers, hit up the cmake-compile-features(7) manual.
Note:CMAKE_<LANG>_STANDARD_LATESTwill never be set to a language standard that CMake recognizes but provides no support for. And unless explicitly stated otherwise, every value supported by the corresponding<LANG>_STANDARDtarget property represents a standard of language<LANG>that is both recognized and supported by CMake. Both boxes checked ✅.
Checking for Language Standard Support
You can absolutely use the value of CMAKE_<LANG>_STANDARD_LATEST to check whether a language standard is supported. Super useful for stuff like conditionally enabling optional features for a distributed library — chef's kiss 🍓.
But when you do it, be careful and do not rely on integer value comparisons between standard levels. Why? Because some older standards of a given language that CMake supports (say C++98, represented as 98) have a higher numerical value than newer standards of that same language. Numbers are lying to you, bestie 😭.
Here's how you'd correctly check for C++17 support:
# Careful! We cannot do direct integer comparisons with
# CMAKE_CXX_STANDARD_LATEST because some earlier C++ standards (e.g.,
# C++98) will have a higher numerical value than our requirement (C++17).
#
# Instead, we keep a list of unsupported C++ standards and check if
# CMAKE_CXX_STANDARD_LATEST appears in that list.
set(UNSUPPORTED_CXX_STANDARDS
98
11
14
)
list(FIND UNSUPPORTED_CXX_STANDARDS ${CMAKE_CXX_STANDARD_LATEST} UNSUPPORTED_CXX_STANDARDS_INDEX)
if(UNSUPPORTED_CXX_STANDARDS_INDEX EQUAL -1)
# We know that the current compiler supports at least C++17. Enabling
# some optional feature...
else()
message(STATUS
"Feature X is disabled because it requires C++17, but the current "
"compiler only supports C++${CMAKE_CXX_STANDARD_LATEST}."
)
endif()
CMAKE_<LANG>_STANDARD_LIBRARIES</p>
Added in version 3.6.
Okay so this one is literally the list of libraries that get linked into every executable and shared library built for language <LANG>. Like, every single one, no cap. It exists so the language can say "hey bestie, this platform needs these system libs to even function" 💅
Do NOT set this from your project code. Fr fr. It's meant to be set by CMake's platform information modules for the current toolchain, or by a toolchain file when you're using CMAKE_TOOLCHAIN_FILE. That's the whole vibe check — hands off, project.
Also go look at CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES if you want the include-side sibling 🫶
CMAKE_<LANG>_STANDARD_LINK_DIRECTORIES</p>
Added in version 3.31.
Same energy as the last one but for link directories — these get specified for every executable and library linked for language <LANG>. It's specifically for the system link directories the language needs on the current platform 🌸
Again, not yours to set. Project code should leave this alone. It's for CMake's platform information modules for the current toolchain, or a toolchain file used with CMAKE_TOOLCHAIN_FILE, periodt.
See also its bestie CMAKE_<LANG>_STANDARD_LIBRARIES ✨
CMAKE_<LANG>_STANDARD_REQUIRED</p>
The variations are (one per language, collect them all 🎀):
CMAKE_C_STANDARD_REQUIREDCMAKE_CXX_STANDARD_REQUIREDCMAKE_CUDA_STANDARD_REQUIREDCMAKE_HIP_STANDARD_REQUIREDCMAKE_OBJC_STANDARD_REQUIREDCMAKE_OBJCXX_STANDARD_REQUIRED
These are the default values for the <LANG>_STANDARD_REQUIRED target property — but only if they're set at the moment the target gets created 👑 Like, the property gets stamped in at birth, iykyk.
For which CMake versions support which ones, check the respective pages 💖
And for the whole lore dump on compile features plus a list of supported compilers, the cmake-compile-features(7) manual is right there waiting for you 🦋
CMAKE_OBJC_EXTENSIONS</p>
Added in version 3.16.
Default value for the OBJC_EXTENSIONS target property if it's set when a target is created 💅
See cmake-compile-features(7) for info on compile features and a list of supported compilers.
CMAKE_OBJC_STANDARD</p>
Added in version 3.16.
Default value for the OBJC_STANDARD target property if it's set when a target is created 🌸
See cmake-compile-features(7) for info on compile features and a list of supported compilers.
CMAKE_OBJC_STANDARD_REQUIRED</p>
Added in version 3.16.
Default value for the OBJC_STANDARD_REQUIRED target property if it's set when a target is created ✨
See cmake-compile-features(7) for info on compile features and a list of supported compilers.
CMAKE_OBJCXX_EXTENSIONS</p>
Added in version 3.16.
Default value for the OBJCXX_EXTENSIONS target property if it's set when a target is created 🦋
See cmake-compile-features(7) for info on compile features and a list of supported compilers.
CMAKE_OBJCXX_STANDARD</p>
Added in version 3.16.
Default value for the OBJCXX_STANDARD target property if it's set when a target is created 💜
See cmake-compile-features(7) for info on compile features and a list of supported compilers.
CMAKE_OBJCXX_STANDARD_REQUIRED</p>
Added in version 3.16.
Default value for the CMAKE_OBJCXX_STANDARD_REQUIRED target property if it's set when a target is created 🎀 (and yes, it's the OBJCXX_STANDARD_REQUIRED target property — that's the one.)
See cmake-compile-features(7) for info on compile features and a list of supported compilers.
CMAKE_Swift_LANGUAGE_VERSION</p>
Added in version 3.7.
Set this to the Swift language version number 🐦 If you don't set it, CMake assumes the oldest legacy version known to be available in the host Xcode version. Like, the safe boring default, bestie:
- Swift
4.0for Xcode 10.2 and above. - Swift
3.0for Xcode 8.3 and above. - Swift
2.3for Xcode 8.2 and below.
CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG></p>
Point this at a CMake file that overrides platform information for <LANG> 👑
It's the language-specific version of CMAKE_USER_MAKE_RULES_OVERRIDE, and it only gets loaded when you're enabling language <LANG>. Selective loading, main character energy 💅
✨ VARIABLES FOR CTEST ✨
CTEST_BINARY_DIRECTORY</p>
Added in version 3.1.
Specifies the CTest BuildDirectory setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 🎀
CTEST_BUILD_COMMAND</p>
Added in version 3.1.
Specifies the CTest MakeCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 💖
CTEST_BUILD_NAME</p>
Added in version 3.1.
Specifies the CTest BuildName setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 🌸
CTEST_BUILD_PRESET</p>
Added in version 4.4.
Specifies the PRESET option for the ctest_build() command in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 🔥
See also CTEST_PRESET and CTEST_PRESETS_FILE 🫶
CTEST_BZR_COMMAND</p>
Added in version 3.1.
Specifies the CTest BZRCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 🦋
CTEST_BZR_UPDATE_OPTIONS</p>
Added in version 3.1.
Specifies the CTest BZRUpdateOptions setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option ⭐
CTEST_CHANGE_ID</p>
Added in version 3.4.
Specifies the CTest ChangeId setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 💅
So this setting lets CTest pass arbitrary info about this build up to CDash. One iconic use case: letting CDash post comments on your pull request if anything goes wrong with your build 😭 Like it's snitching on your build, but helpfully.
CTEST_CHECKOUT_COMMAND</p>
Added in version 3.1.
Tells the ctest_start() command how to checkout or initialize the source directory in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 🎀
CTEST_CONFIGURATION_TYPE</p>
Added in version 3.1.
Specifies the CTest DefaultCTestConfigurationType setting in a ctest(1) Dashboard Client script.
And heads up: if the configuration type is set via -C <cfg> from the command line, then this variable gets populated accordingly 🔄✨
CTEST_CONFIGURE_COMMAND</p>
Added in version 3.1.
Specifies the CTest ConfigureCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 🌸
CTEST_CONFIGURE_PRESET</p>
Added in version 4.4.
Specifies the PRESET option for the ctest_configure() command in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 💖
See also CTEST_PRESET and CTEST_PRESETS_FILE 🧚
CTEST_COVERAGE_COMMAND</p>
Added in version 3.1.
Specifies the CTest CoverageCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option 💜
Cobertura
Okay bestie, story time 📖 Using Cobertura (https://cobertura.github.io/cobertura/) as your coverage generator inside a multi-module Java project can spit out a whole series of XML files. Messy.
The Cobertura Coverage parser expects to read coverage data from a single XML file that contains the coverage data for all modules. So Cobertura ships one program that merges the given cobertura.ser files, and another program that generates a combined XML file from that merged file 🫶 For command line testing, you can just do this by hand before CTest goes looking for the coverage files. For script builds, set the CTEST_COVERAGE_COMMAND variable to point at a file that performs these same steps — like a .sh or .bat file ✨
set(CTEST_COVERAGE_COMMAND .../run-coverage-and-consolidate.sh)
…where that run-coverage-and-consolidate.sh script is perhaps created by the configure_file() command and might contain the following code:
#!/usr/bin/env bash
CoberturaFiles="$(find "/path/to/source" -name "cobertura.ser")"
SourceDirs="$(find "/path/to/source" -name "java" -type d)"
cobertura-merge --datafile coberturamerge.ser $CoberturaFiles
cobertura-report --datafile coberturamerge.ser --destination . \
--format xml $SourceDirs
So the script uses find to capture the paths to all the cobertura.ser files found below the project's source directory 🦋 It keeps that list of files and hands it over as an argument to the cobertura-merge program. The --datafile argument says where the result of the merge will be kept.
Then that combined coberturamerge.ser file gets used to generate the XML report via the cobertura-report program. That call needs some named arguments 👑
--datafila— path to the merged.serfile--destination— path to put the output file(s)--format— file format to write output in:xmlorhtml
The rest of the supplied arguments are the full paths to the /src/main/java directories of each module in the source tree. Those directories are needed, so don't forget them, I'm begging 😭🙈
CTEST_COVERAGE_EXTRA_FLAGS</p>
Added in version 3.1.
CTEST_COVERAGE_EXTRA_FLAGS— specify the CTestCoverageExtraFlagssetting in actest(1)Dashboard Client script, or on thectestcommand line via the-Doption.
CTEST_CUSTOM_COVERAGE_EXCLUDE
A list of regular expressions 💅 — these get used to exclude files by their path from the coverage output that ctest_coverage() spits out.
It's initialized by ctest(1), but bestie you can absolutely edit it in a CTestCustom file. See the ctest_read_custom_files() docs for the deets. 🫶
CTEST_CUSTOM_ERROR_EXCEPTION
A list of regular expressions used to exclude stuff when ctest_build() is detecting error messages in build outputs. So like — errors that match these? not it, we're ignoring them. 🙈
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_ERROR_MATCH
A list of regular expressions used to detect error messages in build outputs, courtesy of ctest_build(). 🚨
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_ERROR_POST_CONTEXT
How many lines of context to include after an error message, as counted by ctest_build(). The default is 10. ✨
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_ERROR_PRE_CONTEXT
How many lines of context to include before an error message, as counted by ctest_build(). The default is 10. ✨
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
When a test fails and we're saving its output, this is the maximum size, in bytes, that ctest_test() will collect. Defaults to 307200 (that's 300 KiB, iconic). For the possible truncation modes, go look at CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION. ✂️
okay so there's an escape hatch: if a test's output contains the literal string "CTEST_FULL_OUTPUT", the output will not be truncated and may exceed the maximum size. no cap. 💀
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
For controlling output collection of passing tests, see CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE. 💖
CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
The max number of errors in a single build step that will be detected. After that point, the ctest_test() command will truncate the output. Defaults to 50. 🛑
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
The max number of warnings in a single build step that will be detected. After that point, the ctest_test() command will truncate the output. Defaults to 50. 🛑
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
When a test passes and we're saving its output, this is the max size in bytes that ctest_test() will collect. Defaults to 1024 (1 KiB, tiny but mighty). For the possible truncation modes, see CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION. ✂️
same escape hatch, bestie: if a test's output contains the literal string "CTEST_FULL_OUTPUT", nothing gets truncated and it may exceed the maximum size. 🔥
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
For controlling output collection of failing tests, see CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE. 💖
CTEST_CUSTOM_MEMCHECK_IGNORE
A list of regular expressions used to exclude tests during the ctest_memcheck() command. not today, tests. 🙅♀️
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_POST_MEMCHECK
A list of commands to run at the end of the ctest_memcheck() command. 🎬
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_POST_TEST
A list of commands to run at the end of the ctest_test() command. 🎬
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_PRE_MEMCHECK
A list of commands to run at the start of the ctest_memcheck() command. 🎬
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_PRE_TEST
A list of commands to run at the start of the ctest_test() command. 🎬
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION
Added in version 3.24. 🎀
Sets the test output truncation mode, for when a maximum size is configured via CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE or CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE. By default the tail of the output gets truncated. The other possible values are middle and head. 🧚
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_TESTS_IGNORE
A list of test names to exclude from the set of tests that ctest_test() runs. bye bestie, not running you. 👋
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_WARNING_EXCEPTION
A list of regular expressions used to exclude stuff when ctest_build() detects warning messages in build outputs. 🙈
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CUSTOM_WARNING_MATCH
A list of regular expressions used to detect warning messages in build outputs, via ctest_build(). ⚠️
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_CVS_COMMAND
Added in version 3.1. 🦋
Specifies the CTest CVSCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_CVS_UPDATE_OPTIONS
Added in version 3.1. 🦋
Specifies the CTest CVSUpdateOptions setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_DROP_LOCATION
Added in version 3.1. 🦋
Specifies the CTest DropLocation setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_DROP_METHOD
Added in version 3.1. 🦋
Specifies the CTest DropMethod setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_DROP_SITE
Added in version 3.1. 🦋
Specifies the CTest DropSite setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_DROP_SITE_CDASH
Added in version 3.1. 🦋
Specifies the CTest IsCDash setting in a ctest(1) Dashboard Client script. (heads up: this one's script-only, no -D mention — iykyk 💅)
CTEST_DROP_SITE_PASSWORD
Added in version 3.1. 🦋
Specifies the CTest DropSitePassword setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_DROP_SITE_USER
Added in version 3.1. 🦋
Specifies the CTest DropSiteUser setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_EXTRA_COVERAGE_GLOB
Added in version 3.4. 🌈
A list of regular expressions used to find files that should be covered by the ctest_coverage() command. obsessed with a thorough coverage report ngl. 🎯
Initialized by ctest(1), editable in a CTestCustom file. See ctest_read_custom_files().
CTEST_EXTRA_SUBMIT_FILES
Specifies files for ctest_submit(PARTS ExtraFiles) to submit in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. 📤
CTEST_GIT_COMMAND
Added in version 3.1. 🦋
Specifies the CTest GITCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_GIT_INIT_SUBMODULES
Added in version 3.6. 🦋
Specifies the CTest GITInitSubmodules setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option.
CTEST_GIT_UPDATE_CUSTOM
Added in version 3.1. 🦋
okay so this one sets the CTest GITUpdateCustom setting — you can drop it in a ctest(1) Dashboard Client script, or just yeet it on the ctest command line with the -D option. easy. ✨
CTEST_GIT_UPDATE_OPTIONS
added in version 3.1 🎀
Sets the CTest GITUpdateOptions setting, again either in your ctest(1) Dashboard Client script or straight-up on the ctest command line via -D. 💅
CTEST_HG_COMMAND
added in version 3.1 🌸
The CTest HGCommand setting — set it in a ctest(1) Dashboard Client script, or pass it on the ctest command line with -D.
CTEST_HG_UPDATE_OPTIONS
added in version 3.1 🦋
The CTest HGUpdateOptions setting — ctest(1) Dashboard Client script, or ctest command line via -D. same vibe, different name, bestie.
CTEST_LABELS_FOR_SUBPROJECTS
added in version 3.10 ⭐
The CTest LabelsForSubprojects setting — set it in your ctest(1) Dashboard Client script, or on the ctest command line via -D.
CTEST_MEMORYCHECK_COMMAND
added in version 3.1 🧚
The CTest MemoryCheckCommand setting — ctest(1) Dashboard Client script, or ctest command line via -D. your memory checker's whole address, fr.
CTEST_MEMORYCHECK_COMMAND_OPTIONS
added in version 3.1 💜
The CTest MemoryCheckCommandOptions setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_MEMORYCHECK_SANITIZER_OPTIONS
added in version 3.1 🔥
The CTest MemoryCheckSanitizerOptions setting — ctest(1) Dashboard Client script, or ctest command line via -D.
okay listen, this next bit matters: CTest prepends the correct sanitizer options from the *_OPTIONS environment variable to the executed command. And CTest adds its own log_path to the sanitizer options.
🚨 do not provide your own log_path. CTest has it handled, and doubling up is giving chaos energy.
CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
added in version 3.1 🍓
The CTest MemoryCheckSuppressionFile setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_MEMORYCHECK_TYPE
added in version 3.1 💖
The CTest MemoryCheckType setting — ctest(1) Dashboard Client script, or ctest command line via -D.
Valid values are, in order:
ValgrindPurifyBoundsCheckerDrMemoryCudaSanitizerThreadSanitizerAddressSanitizerLeakSanitizerMemorySanitizerUndefinedBehaviorSanitizer
those are the only ones, no cap. pick one of them. 👑
CTEST_NIGHTLY_START_TIME
added in version 3.1 🌈
The CTest NightlyStartTime setting — ctest(1) Dashboard Client script, or ctest command line via -D.
⚠️ heads up bestie: this variable must always be set for a nightly build in a dashboard script. it's literally the thing that lets nightly builds get grouped together properly in CDash. skip it and your builds are out here ungrouped and sad. 😭
CTEST_NOTES_FILES
okay this one's your ctest_submit(PARTS Notes) supply drop — it specifies the files for ctest_submit(PARTS Notes) to submit, in a ctest(1) Dashboard Client script, or on the ctest command line via -D. 📝
CTEST_P4_CLIENT
added in version 3.1 🎀
The CTest P4Client setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_P4_COMMAND
added in version 3.1 🌸
The CTest P4Command setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_P4_OPTIONS
added in version 3.1 🦋
The CTest P4Options setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_P4_UPDATE_OPTIONS
added in version 3.1 ✨
The CTest P4UpdateOptions setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_PRESET
added in version 4.4 ⭐
Specify a preset name to use for all the relevant ctest(1) Dashboard Client steps in a dashboard script, or on the ctest command line via -D. one name, many steps, main character energy.
So here's the tea: this variable sets the PRESET option for ctest_configure(), ctest_build(), ctest_test(), and ctest_memcheck() — but only when those commands aren't given an explicit PRESET argument and the corresponding command-specific variable (CTEST_CONFIGURE_PRESET, CTEST_BUILD_PRESET, or CTEST_TEST_PRESET) is also unset. like, it's the fallback friend in the group.
And the error handling is lowkey different per command:
- For
ctest_configure()— an error is raised if no configure preset with this name exists. - For
ctest_build(),ctest_test(), andctest_memcheck()— a warning is emitted and the variable is ignored if no preset of the matching type exists with this name.
also see CTEST_PRESETS_FILE. 🫶
CTEST_PRESETS_FILE
added in version 4.4 🧚
Specify the PRESETS_FILE option for all the relevant ctest(1) Dashboard Client step commands in a dashboard script, or on the ctest command line via -D.
This sets the PRESETS_FILE option for ctest_configure(), ctest_build(), ctest_test(), and ctest_memcheck() — but only when those commands aren't given an explicit PRESETS_FILE argument.
See also CTEST_PRESET, CTEST_CONFIGURE_PRESET, CTEST_BUILD_PRESET, and CTEST_TEST_PRESET. 💜
CTEST_RESOURCE_SPEC_FILE
added in version 3.18 🍓
The CTest ResourceSpecFile setting — ctest(1) Dashboard Client script, or ctest command line via -D.
You can also use this to specify the resource spec file from a CMake build. and the rule is: if no RESOURCE_SPEC_FILE is passed to ctest_test(), and CTEST_RESOURCE_SPEC_FILE isn't specified in the dashboard script, then the value of this variable from the build is used. slay, it falls back for you. ✨
CTEST_RUN_CURRENT_SCRIPT
Removed. 💀
yep. this variable once supported an undocumented feature that has since been removed. it's gone gone. don't come looking for it.
CTEST_SCRIPT_DIRECTORY
The directory containing the top-level CTest script. 🎀 the concept is similar to CMAKE_SOURCE_DIR. iykyk.
CTEST_SITE
added in version 3.1 🌸
The CTest Site setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_SOURCE_DIRECTORY
added in version 3.1 🦋
The CTest SourceDirectory setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_SUBMIT_INACTIVITY_TIMEOUT
added in version 3.23 ⭐
The CTest SubmitInactivityTimeout setting — ctest(1) Dashboard Client script, or ctest command line via -D. if the submit goes quiet, this is your girl. 🕐
CTEST_SUBMIT_PARTS
added in version 4.4 🔥
Specify a semicolon-separated list of parts for the ctest_submit() command to submit, in a ctest(1) Dashboard Client script, or on the ctest command line via -D.
The valid part names are the same ones the PARTS option of ctest_submit() accepts:
StartUpdateConfigureBuildTestCoverageMemCheckSubmitNotesExtraFilesUploadDone
Precedence check, because this matters: if ctest_submit() is given an explicit PARTS argument, that argument wins and this variable is ignored. 🫡
And when this variable is empty or unset (and no explicit PARTS argument is given), all available parts are submitted — that's the default behavior.
Example — submit only the Configure result in a single ctest invocation:
ctest -T Configure -T Submit -D CTEST_SUBMIT_PARTS=Configure
CTEST_SUBMIT_URL
added in version 3.14 💖
The CTest SubmitURL setting — ctest(1) Dashboard Client script, or ctest command line via -D. where your results get sent, bestie. 📮
CTEST_SVN_COMMAND
added in version 3.1 🧚
The CTest SVNCommand setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_SVN_OPTIONS
added in version 3.1 💜
The CTest SVNOptions setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_SVN_UPDATE_OPTIONS
added in version 3.1 🍓
The CTest SVNUpdateOptions setting — ctest(1) Dashboard Client script, or ctest command line via -D.
CTEST_TEST_LOAD
added in version 3.4 🌈
The TestLoad setting in the CTest Test Step of a ctest(1) Dashboard Client script, or on the ctest command line via -D. and this is cute because it sets the default value for the TEST_LOAD option of the ctest_test() command. defaults on defaults. ✨
CTEST_TEST_PRESET
added in version 4.4 👑
Specify the PRESET option for the ctest_test() and ctest_memcheck() commands in a ctest(1) Dashboard Client script, or on the ctest command line via -D. yes, both of them. it's giving efficiency. 💅
Also peep CTEST_PRESET and CTEST_PRESETS_FILE if you wanna go deeper 💫
⏱️ CTEST_TEST_TIMEOUT
Added in version 3.1.
This is the one that sets the CTest TimeOut setting inside a ctest(1) Dashboard Client script — or you can just slap it on the command line via the -D option like the boss you are 💅
🧪 CTEST_TEST_COVERAGE_TOOL
Added in version 4.4.
Sets the CTest CoverageTool setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. Coverage era, fr fr 🎀
🔒 CTEST_TLS_VERIFY
Added in version 3.30.
Okay so this one is the security vibe check ✨ It sets the CTest TLSVerify setting — you can put it in a ctest(1) Dashboard Client script, or in project CMakeLists.txt code before you include the CTest module, or on the ctest command line via the -D option. The value is a boolean telling you whether to verify the server certificate when submitting to a dashboard over https:// URLs 🦋
If CTEST_TLS_VERIFY isn't set, then the CMAKE_TLS_VERIFY variable or the CMAKE_TLS_VERIFY environment variable gets used instead. And if neither of those is set? The default is on 💚
Changed in version 3.31: the default is on. Previously the default was off 😭 If you're feeling nostalgic for the risky old days, you can set theCMAKE_TLS_VERIFYenvironment variable to0to restore the old default. (Bestie, why would you, but okay 🫶)
🛡️ CTEST_TLS_VERSION
Added in version 3.30.
Sets the CTest TLSVersion setting — again, in a ctest(1) Dashboard Client script, or in project CMakeLists.txt code before including the CTest module, or on the ctest command line via the -D option. The value here is the minimum TLS version allowed when you're submitting to a dashboard over https:// URLs 🔐
The value can be one of these iconic legends:
1.01.11.21.3
If CTEST_TLS_VERSION is not set, then the CMAKE_TLS_VERSION variable or the CMAKE_TLS_VERSION environment variable is used instead ✨
🔄 CTEST_UPDATE_COMMAND
Added in version 3.1.
Sets the CTest UpdateCommand setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. Update szn 💫
🎛️ CTEST_UPDATE_OPTIONS
Added in version 3.1.
Sets the CTest UpdateOptions setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. All the little knobs for your update, slay 🎀
1️⃣ CTEST_UPDATE_VERSION_ONLY
Added in version 3.1.
Sets the CTest UpdateVersionOnly setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. Just the version, nothing else, periodt 💅
🏷️ CTEST_UPDATE_VERSION_OVERRIDE
Added in version 3.15.
Sets the CTest UpdateVersionOverride setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. Overriding the version like the main character you are 👑
🚀 CTEST_USE_LAUNCHERS
Added in version 3.1.
Sets the CTest UseLaunchers setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. Launchers activated 🚀✨
📦 VARIABLES FOR CPACK 📦
Okay bestie, this is the CPack corner of the universe and it is lowkey iconic — let's get into it 🎁
📁 CPACK_ABSOLUTE_DESTINATION_FILES
List of files that got installed using an ABSOLUTE DESTINATION path 👀
This is a Read-Only variable — set internally by CPack during installation and before packaging, using CMAKE_ABSOLUTE_DESTINATION_FILES defined in cmake_install.cmake scripts. You can use the value inside your CPack project configuration file and/or the CPack<GEN>.cmake file of the <GEN> generator 🦋
🗂️ CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
Boolean toggle to include (or not) the top level directory — but the component case 🎀
Usage is basically the same as CPACK_INCLUDE_TOPLEVEL_DIRECTORY, just for the component situation. Check out the CPACK_INCLUDE_TOPLEVEL_DIRECTORY docs for the details, iykyk 💫
🛠️ CPACK_CUSTOM_INSTALL_VARIABLES
Added in version 3.21.
So here's the tea ☕ — CPack variables (the ones you set via like cpack -D, CPackConfig.cmake, or CPACK_PROJECT_CONFIG_FILE scripts) are not directly visible in installation scripts. Rude, I know 😭
Instead, you pass a list of varName=value pairs in the CPACK_CUSTOM_INSTALL_VARIABLES variable. At install time, each item in the list makes a variable with the specified name (varName) get set to the given value. Pro tip: the = can be omitted if you want an empty value ✨
CPACK_CUSTOM_INSTALL_VARIABLES lets the packaging installation be influenced by the user or the driving script at CPack runtime without having to regenerate the install scripts. Efficiency queen 🫶
📝 Example
install(FILES large.txt DESTINATION data)
install(CODE [[
if(ENABLE_COMPRESSION)
# "run-compressor" is a fictional tool that produces
# large.txt.xz from large.txt and then removes the input file
execute_process(COMMAND run-compressor $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/large.txt)
endif()
]])
With that snippet up there, cpack will by default run the installation script with ENABLE_COMPRESSION unset, so you end up with a package containing the uncompressed large.txt 🙈 But you can override it when you invoke cpack like this:
cpack -D "CPACK_CUSTOM_INSTALL_VARIABLES=ENABLE_COMPRESSION=TRUE"
Then the installation script runs with ENABLE_COMPRESSION set to TRUE, so the package contains the compressed large.txt.xz instead. Glow-up achieved 💅✨
🚨 CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
Tells CPack to error out the moment it encounters a file with an absolute INSTALL DESTINATION 💀
The fatal error fires before the offending file gets installed, so no half-done nonsense. Some CPack generators — looking at you, NSIS — enforce this internally anyway. This variable triggers the definition of CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs 🔥
🎀 CPACK_INCLUDE_TOPLEVEL_DIRECTORY
Boolean toggle to include or exclude the top level directory 🌸
When CPack is prepping a package, it installs the item under the so-called top level directory. The whole point of this variable is to include it in the package (set it to 1 or ON or TRUE) or not (set it to 0 or OFF or FALSE) 🦋
Every CPack generator has its own built-in default for this. For example, Archive generators (ZIP, TGZ, ...) include the top level, whereas RPM or DEB don't. You can override the default by setting this variable yourself, no cap 👑
There's a similar variable, CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY, that you can use to override the behavior for the component packaging case — which might have a different default value for historical (read: now backward-compatibility) reasons 😌
🔐 CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
Added in version 3.11.
Default permissions for directories that get implicitly created during packaging ✨
This variable does the exact same job during packaging that CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS does during installation (think make install). Twinsies 🫶
If you're using include(CPack), then by default this variable is set to the content of CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS 🎀
📍 CPACK_PACKAGING_INSTALL_PREFIX
The prefix used inside the built package 💫
Each CPack generator has a default value (like /usr). You can overwrite that default from the CMakeLists.txt or from the cpack(1) command line by setting an alternative value. Like so:
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
Heads up bestie: this does not have the same purpose as CMAKE_INSTALL_PREFIX — that one's used when installing from the build tree without building a package. Different vibes entirely, don't mix them up 🙈
🗃️ CPACK_SET_DESTDIR
Boolean toggle to make CPack use the DESTDIR mechanism when packaging 🎁
DESTDIR means DESTination DIRectory (cute, right?). Makefile users commonly use it to install software somewhere that isn't the default location. It's a basic relocation mechanism that should not be used on Windows (peep the CMAKE_INSTALL_PREFIX docs for that whole situation). It usually gets invoked like this:
make DESTDIR=/home/john install
...which installs the software using the installation prefix (say /usr/local) prepended with the DESTDIR value, giving you /home/john/usr/local in the end ✨
When preparing a package, CPack first installs the items to be packaged into a local (to the build tree) directory using that same DESTDIR mechanism. But if CPACK_SET_DESTDIR is set, CPack sets DESTDIR before doing the local install 👀
The most noticeable difference: without CPACK_SET_DESTDIR, CPack uses CPACK_PACKAGING_INSTALL_PREFIX as the prefix — whereas with CPACK_SET_DESTDIR set, CPack uses CMAKE_INSTALL_PREFIX as the prefix. Two totally different prefix eras 💅
Manually setting CPACK_SET_DESTDIR may help (or honestly just be necessary) if some install rules use an absolute DESTINATION (check the install() command). However — starting with CPack/CMake 2.8.3, RPM and DEB installers try to handle DESTDIR automatically, so it's seldom necessary for you to set it yourself. Convenient 🎀
⚠️ CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
Asks CPack to warn you every single time a file with an absolute INSTALL DESTINATION shows up 👀
This variable triggers the definition of CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs the cmake_install.cmake scripts. Not a full crash-out like the ERROR one — just a friendly lil heads-up, bestie 🫶✨
✨ VARIABLE EXPANSION OPERATORS ✨
🗄️ CACHE
Added in version 3.13.
Okay so this is the operator you use to read cache variables, bestie 💅
Use the syntax $CACHE{VAR} to read cache entry VAR. The cmake-language(7) variables documentation has the full lore on how normal variables and cache entries interact, if you want the deep dive 📖
When evaluating Variable References of the form ${VAR}, CMake first searches for a normal variable with that name, and if it doesn't find one, CMake will go search for a cache entry with that name. The $CACHE{VAR} syntax is how you do a direct cache lookup and straight-up ignore any normal variable that happens to exist 👑
Wanna actually write or delete cache variables? That's the set() and unset() commands' whole job — go check those out 🫶
🌍 ENV
The operator for reading environment variables 🌱
Use the syntax $ENV{VAR} to read environment variable VAR.
Want to test whether an environment variable is even defined? Use the signature if(DEFINED ENV{<name>}) of the if() command — that's the vibe check ✅
⚠️ Note: environment variable names containing special characters like parentheses may need to be escaped. (PolicyCMP0053must also be enabled.) For example, to get the value of the Windows environment variableProgramFiles(x86), use:
set(ProgramFiles_x86 "$ENV{ProgramFiles\(x86\)}")
For general info on environment variables, see the Environment Variables section in the cmake-language(7) manual 💜
🔒 INTERNAL VARIABLES
CMake has so many internal variables, seriously — most of them are undocumented 🙈 Some of them, though, were at some point described as normal variables, which means you might run into them in legacy code. Heads up: they are subject to change, and they are not recommended for use in project code. Like, don't. 💀
🏠 CMAKE_HOME_DIRECTORY
Path to top of source tree. Same as CMAKE_SOURCE_DIR.
This is an internal cache entry used to locate the source directory when loading a CMakeCache.txt from a build tree. It should not be used in project code 🚫 The variable CMAKE_SOURCE_DIR has the same value and should be preferred — use that one instead, bestie 🎀
🧬 CMAKE_INTERNAL_PLATFORM_ABI
An internal variable subject to change.
This is used in determining the compiler ABI and is subject to change.
🧬 CMAKE_<LANG>_COMPILER_ABI
An internal variable subject to change.
This is used in determining the compiler ABI and is subject to change.
🏷️ CMAKE_<LANG>_COMPILER_VERSION_INTERNAL
Added in version 3.10.
An internal variable subject to change.
This is used to identify the variant of a compiler based on an internal version number. For some compilers this is needed to determine the correct usage 👀
🔗 CMAKE_<LANG>_LINKER_PREFERENCE
An internal variable subject to change.
Preference value for linker language selection ✨
So here's the tea: the "linker language" for executable, shared library, and module targets is the language whose compiler will invoke the linker. The LINKER_LANGUAGE target property sets the language explicitly. Otherwise, the linker language is the one whose linker preference value is highest among the languages compiled and linked into the target 🔥 See also the CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES variable.
🪄 CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES
An internal variable subject to change.
True if CMAKE_<LANG>_LINKER_PREFERENCE propagates across targets.
This gets used when CMake selects a linker language for a target. Languages compiled directly into the target are always considered — no questions asked. A language compiled into static libraries linked by the target is considered if this variable is true 👑💫
🧬 CMAKE_<LANG>_PLATFORM_ID
An internal variable subject to change.
This is used in determining the platform and is subject to change.
🚩 CMAKE_NOT_USING_CONFIG_FLAGS
Skip _BUILD_TYPE flags if true.
This is an internal flag used by the generators in CMake to tell CMake to skip the _BUILD_TYPE flags.
🧱 CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
When generating for Visual Studio 14 2015 or greater with the Intel Fortran plugin installed, this specifies the .vfproj project file format version. This is intended for internal use by CMake and should not be used by project code 🙅♀️
🕰️ DEPRECATED VARIABLES THAT PROVIDE INFORMATION
⌛ CMAKE_CFG_INTDIR
Deprecated since version 3.21: this variable has poor support on Ninja Multi-Config, and it predates the existence of the $<CONFIG> generator expression. Use $<CONFIG> instead, fr fr 🫡
Build-time reference to per-configuration output subdirectory.
For native build systems supporting multiple configurations in the build tree (such as Visual Studio Generators and Xcode), the value is a reference to a build-time variable specifying the name of the per-configuration output subdirectory. On Makefile Generators this evaluates to . because there is only one configuration in a build tree. Example values:
$(Configuration)— Visual Studio$(CONFIGURATION)— Xcode.— Make-based tools.— Ninja${CONFIGURATION}— Ninja Multi-Config
Since these values are evaluated by the native build system, this variable is suitable only for use in command lines that will be evaluated at build time. Example of intended usage:
add_executable(mytool mytool.c)
add_custom_command(
OUTPUT out.txt
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool
${CMAKE_CURRENT_SOURCE_DIR}/in.txt out.txt
DEPENDS mytool in.txt
)
add_custom_target(drive ALL DEPENDS out.txt)
Note that CMAKE_CFG_INTDIR is no longer necessary for this purpose but has been left for compatibility with existing projects. Instead, add_custom_command() recognizes executable target names in its COMMAND option, so ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool can be replaced by just mytool 😌✨
💀 This variable is read-only. Setting it is undefined behavior. In multi-configuration build systems the value of this variable is passed as the value of preprocessor symbol CMAKE_INTDIR to the compilation of all source files.
⌛ CMAKE_EXTRA_GENERATOR
Deprecated since version 3.27: support for Extra Generators is deprecated and will be removed from a future version of CMake. IDEs may use the cmake-file-api(7) to view CMake-generated project build trees 👀
The extra generator used to build the project. See cmake-generators(7).
When using the Eclipse, CodeBlocks, CodeLite, Kate or Sublime generators, CMake generates Makefiles (CMAKE_GENERATOR) and additionally project files for the respective IDE. This IDE project file generator is stored in CMAKE_EXTRA_GENERATOR (e.g. Eclipse CDT4) 🧚
💅 DEPRECATED VARIABLES THAT CHANGE BEHAVIOR 💅
Ok bestie, this whole section is basically the graveyard wing of the CMake museum 🪦 — every single one of these still exists, but they all come with a "please don't" attached. Let's tour it.
🎀 CMAKE_AUTOMOC_RELAXED_MODE
Deprecated since version 3.15. 👋
Switch between strict and relaxed automoc mode.
So here's the tea: by default, AUTOMOC behaves exactly as described in the documentation of the AUTOMOC target property. No surprises, no drama, periodt. But when you set this bad boy to TRUE, it accepts more input and tries to find the correct input file for moc even if it differs from the documented behavior. In this mode it e.g. also checks whether a header file is intended to be processed by moc when a "foo.moc" file has been included. 🔍
Relaxed mode has to be enabled for KDE4 compatibility. (iykyk 💀)
🌸 CMAKE_BACKWARDS_COMPATIBILITY
Removed. Gone. No cap, it's not here anymore. See policy CMP0001. 🫶
✨ CMAKE_ERROR_DEPRECATED
Deprecated since version 4.4. Yes, the variable that yells at you for using deprecated stuff is itself deprecated. It's giving irony. 😭
Whether to issue errors for deprecated functionality.
This is a deprecated mechanism for interacting with the CMD_DEPRECATED diagnostic. If policy CMP0218 is set to NEW, this variable is ignored.
If policy CMP0218 is not set to NEW, the message() command's DEPRECATION message type will use CMAKE_WARN_DEPRECATED and CMAKE_ERROR_DEPRECATED to determine the severity of a deprecation diagnostic. The severity will be:
IGNORE, ifCMAKE_WARN_DEPRECATEDisOFFandCMAKE_ERROR_DEPRECATEDis unset orOFF.WARN, ifCMAKE_WARN_DEPRECATEDis unset orONandCMAKE_ERROR_DEPRECATEDis unset orOFF.FATAL_ERRORifCMAKE_ERROR_DEPRECATEDisON. 🚨
Setting CMAKE_ERROR_DEPRECATED in the cache will alter the default state of the CMD_DEPRECATED diagnostic; however, the -W[no-][error=]deprecated option, and warnings.deprecated and/or errors.deprecated preset fields, will take precedence. CMake will also update the cached value of CMAKE_ERROR_DEPRECATED to reflect the actual state of the diagnostic as of the start of script execution. Yeah, it just overwrites your vibe. 🙈
🦋 CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
Added in version 3.1.
Deprecated since version 3.16: Use the CMAKE_FIND_USE_PACKAGE_REGISTRY variable instead. Older, cuter name → retired. 💅
By default this variable is not set. If neither CMAKE_FIND_USE_PACKAGE_REGISTRY nor CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY is set, then find_package() will use the User Package Registry unless the NO_CMAKE_PACKAGE_REGISTRY option is provided.
CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY is ignored if CMAKE_FIND_USE_PACKAGE_REGISTRY is set. Literally ignored. Not even a side-eye. 👀
In some cases, for example to locate only system wide installations, it is not desirable to use the User Package Registry when searching for packages. If the CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY variable is TRUE, all the find_package() commands will skip the User Package Registry as if they were called with the NO_CMAKE_PACKAGE_REGISTRY argument.
See also Disabling the Package Registry. 🎀
🌈 CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
Added in version 3.1.
Deprecated since version 3.16: Use the CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY variable instead. Same glow-up, different registry. ✨
By default this variable is not set. If neither CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY nor CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY is set, then find_package() will use the System Package Registry unless the NO_CMAKE_SYSTEM_PACKAGE_REGISTRY option is provided.
CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY is ignored if CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY is set.
In some cases, it is not desirable to use the System Package Registry when searching for packages. If the CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY variable is TRUE, all the find_package() commands will skip the System Package Registry as if they were called with the NO_CMAKE_SYSTEM_PACKAGE_REGISTRY argument.
See also Disabling the Package Registry. 🫶
⭐ CMAKE_WARN_DEPRECATED
Deprecated since version 4.4. The warning variable is now the warned-about one. Character development fr fr. 😭
Whether to issue warnings for deprecated functionality.
This is a deprecated mechanism for interacting with the CMD_DEPRECATED diagnostic. If policy CMP0218 is set to NEW, this variable is ignored.
If policy CMP0218 is not set to NEW, the message() command's DEPRECATION message type will use CMAKE_WARN_DEPRECATED and CMAKE_ERROR_DEPRECATED to determine the severity of a deprecation diagnostic. The severity will be:
IGNORE, ifCMAKE_WARN_DEPRECATEDisOFFandCMAKE_ERROR_DEPRECATEDis unset orOFF.WARN, ifCMAKE_WARN_DEPRECATEDis unset orONandCMAKE_ERROR_DEPRECATEDis unset orOFF.FATAL_ERRORifCMAKE_ERROR_DEPRECATEDisON. 💀
Setting CMAKE_WARN_DEPRECATED in the cache will alter the default state of the CMD_DEPRECATED diagnostic; however, the -W[no-][error=]deprecated option, and warnings.deprecated and/or errors.deprecated preset fields, will take precedence. CMake will also update the cached value of CMAKE_WARN_DEPRECATED to reflect the actual state of the diagnostic as of the start of script execution. Same energy as its error twin above. 🙈
🧚 DEPRECATED VARIABLES THAT DESCRIBE THE SYSTEM 🧚
This whole squad is discouraged — that's the actual word used, bestie, which is somehow worse than deprecated. All of them are just vibes about which MSVC you're on, and every single one is like "girl just use MSVC_VERSION". 💅
💜 MSVC10
Discouraged. Use the MSVC_VERSION variable instead.
True when using the Microsoft Visual Studio v100 toolset (cl version 16) or another compiler that simulates it.
💜 MSVC11
Discouraged. Use the MSVC_VERSION variable instead.
True when using the Microsoft Visual Studio v110 toolset (cl version 17) or another compiler that simulates it.
💜 MSVC12
Discouraged. Use the MSVC_VERSION variable instead.
True when using the Microsoft Visual Studio v120 toolset (cl version 18) or another compiler that simulates it.
💜 MSVC14
Added in version 3.1.
Discouraged. Use the MSVC_VERSION variable instead.
True when using the Microsoft Visual Studio v140 or v141 toolset (cl version 19) or another compiler that simulates it. Yes, two toolsets, one variable. Slay. 🔥
🍓 MSVC60
Discouraged. Use the MSVC_VERSION variable instead.
True when using Microsoft Visual C++ 6.0.
Set to true when the compiler is version 6.0 of Microsoft Visual C++.
🍓 MSVC70
Discouraged. Use the MSVC_VERSION variable instead.
True when using Microsoft Visual C++ 7.0.
Set to true when the compiler is version 7.0 of Microsoft Visual C++.
🍓 MSVC71
Discouraged. Use the MSVC_VERSION variable instead.
True when using Microsoft Visual C++ 7.1.
Set to true when the compiler is version 7.1 of Microsoft Visual C++.
🍓 MSVC80
Discouraged. Use the MSVC_VERSION variable instead.
True when using the Microsoft Visual Studio v80 toolset (cl version 14) or another compiler that simulates it.
🍓 MSVC90
Discouraged. Use the MSVC_VERSION variable instead.
True when using the Microsoft Visual Studio v90 toolset (cl version 15) or another compiler that simulates it.
👑 DEPRECATED VARIABLES THAT CONTROL THE BUILD 👑
🎀 CMAKE_ENABLE_EXPORTS
Added in version 3.4.
Deprecated since version 4.3: This variable has been deprecated in favor of the CMAKE_EXECUTABLE_ENABLE_EXPORTS and CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS variables, which have been available since CMake 3.27. It is provided for backward compatibility with older CMake code, but should not be used in new projects. 🚫
Specify whether executables export symbols for loadable modules.
This variable is used to initialize the ENABLE_EXPORTS target property for executable targets when they are created by calls to the add_executable() command. See the property documentation for details. 📖
🦋 CMAKE_IOS_INSTALL_COMBINED
Added in version 3.5.
Deprecated since version 3.28: This is deprecated because IOS_INSTALL_COMBINED is deprecated. Deprecation-ception. 🌀
Default value for IOS_INSTALL_COMBINED of targets.
This variable is used to initialize the IOS_INSTALL_COMBINED property on all the targets. See that target property for additional information.
💫 CMAKE_<LANG>_USING_LINKER_MODE
Deprecated since version 4.0: This variable is no longer used. The type of information stored in the CMAKE_<LANG>_USING_LINKER_<TYPE> variable is determined by the CMAKE_<LANG>_LINK_MODE variable. So yeah, it's retired — the newer variable does the deciding now. 😌
Added in version 3.29.
This variable controls how the value of the CMAKE_<LANG>_USING_LINKER_<TYPE> variable should be interpreted. The supported linker mode values are:
FLAG—CMAKE_<LANG>_USING_LINKER_<TYPE>holds a semicolon-separated list of flags to be passed to the compiler frontend. This is also the default behavior ifCMAKE_<LANG>_USING_LINKER_MODEis not set. 🏳️TOOL—CMAKE_<LANG>_USING_LINKER_<TYPE>holds the path to the linker tool. 🔧
Warning: ⚠️ The variable must be set accordingly to how CMake manage the link step: - valueTOOLis expected and required when the linker is used directly for the link step. - valueFLAGis expected or the variable not set when the compiler is used as driver for the link step.
Like, read this carefully bestie, because getting the mode wrong is not it. 🙏
🌸 CMAKE_USE_RELATIVE_PATHS
This variable has no effect. Literally zero. It is the decorative pillow of CMake variables. 🛋️ The partially implemented effect it had in previous releases was removed in CMake 3.4.
💜 DEPRECATED VARIABLES FOR LANGUAGES 💜
ok so these are the OG compiler-check girlies from way back, and they're giving "vintage but please retire her" energy. ✨
🎀 CMAKE_COMPILER_IS_GNUCC
Deprecated since version 3.24 — bestie, use theCMAKE_C_COMPILER_IDvariable (that's theCMAKE_<LANG>_COMPILER_IDone) instead, no cap.
So the CMAKE_COMPILER_IS_* variables were the go-to in early CMake versions, before the CMAKE_<LANG>_COMPILER_ID variables even existed in CMake 2.6. like, ancient history 💀
CMAKE_COMPILER_IS_GNUCC gets set to boolean true if the C compiler is GNU. that's it, that's the whole vibe.
✨ Examples ✨
In earlier versions of CMake, the CMAKE_COMPILER_IS_GNUCC variable was used to check if the C compiler was GNU:
if(CMAKE_COMPILER_IS_GNUCC)
# GNU C compiler-specific logic.
endif()
Starting with CMake 2.6, the CMAKE_C_COMPILER_ID variable should be used instead:
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
# GNU C compiler-specific logic.
endif()
When upgrading code, consider whether additional C compilers should be targeted beyond just GNU. In the past, the LCC and QCC compilers also had this variable set (see the CMP0047 and CMP0129 policies for details). To account for this, the following approach can be used:
# Targeting GNU, LCC, and QCC compilers for C:
if(CMAKE_C_COMPILER_ID MATCHES "^(GNU|LCC|QCC)$")
# ...
endif()
🦋 CMAKE_COMPILER_IS_GNUCXX
Deprecated since version 3.24 — use theCMAKE_CXX_COMPILER_IDvariable (theCMAKE_<LANG>_COMPILER_IDone) instead, periodt. 💅
Same origin story: the CMAKE_COMPILER_IS_* variables were used in early CMake versions before the introduction of the CMAKE_<LANG>_COMPILER_ID variables in CMake 2.6.
CMAKE_COMPILER_IS_GNUCXX is set to boolean true if the C++ (CXX) compiler is GNU. iconic but dated 🫶
✨ Examples ✨
In earlier versions of CMake, the CMAKE_COMPILER_IS_GNUCXX variable was used to check if the CXX compiler was GNU:
if(CMAKE_COMPILER_IS_GNUCXX)
# GNU C++ compiler-specific logic.
endif()
Starting with CMake 2.6, the CMAKE_CXX_COMPILER_ID variable should be used instead:
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# GNU C++ compiler-specific logic.
endif()
When upgrading code, consider whether additional CXX compilers should be targeted beyond just GNU. In the past, the LCC and QCC compilers also had this variable set (see the CMP0047 and CMP0129 policies for details). To account for this, the following approach can be used:
# Targeting GNU, LCC, and QCC compilers for CXX:
if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|LCC|QCC)$")
# ...
endif()
🌈 CMAKE_COMPILER_IS_GNUG77
Deprecated since version 3.24 — use theCMAKE_Fortran_COMPILER_IDvariable (yep,CMAKE_<LANG>_COMPILER_IDagain) instead, bestie.
The CMAKE_COMPILER_IS_* variables were used in early CMake versions before the introduction of the CMAKE_<LANG>_COMPILER_ID variables in CMake 2.6. (yes the lore is the same every time, I don't make the rules 💀)
CMAKE_COMPILER_IS_GNUG77 is set to boolean true if the Fortran compiler is GNU.
✨ Examples ✨
In earlier versions of CMake, the CMAKE_COMPILER_IS_GNUG77 variable was used to check if the Fortran compiler was GNU:
if(CMAKE_COMPILER_IS_GNUG77)
# GNU Fortran compiler-specific logic.
endif()
Starting with CMake 2.6, the CMAKE_Fortran_COMPILER_ID variable should be used instead:
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
# GNU Fortran compiler-specific logic.
endif()
🌸 DEPRECATED VARIABLES FOR CTEST 🌸
these ones are like the old flip phones of dashboard scripting — nostalgic, but babe, upgrade 📱✨
🎀 CTEST_CURL_OPTIONS
Deprecated since version 3.30 — use the CTEST_TLS_VERIFY variable instead.
Added in version 3.1.
Specify the CTest CurlOptions setting in a ctest(1) Dashboard Client script, or on the ctest command line via the -D option. that's the whole assignment 💅
🦋 CTEST_CVS_CHECKOUT
Deprecated since version 3.1 — use the CTEST_CHECKOUT_COMMAND variable instead.
💜 CTEST_SCP_COMMAND
Added in version 3.1.
Legacy option. Not used. literally just vibes, she does nothing 🫠
⭐ CTEST_TRIGGER_SITE
Added in version 3.1.
Legacy option. Not used. same energy, sitting there looking pretty 🙈
👑 Copyright
2000-2026 Kitware, Inc. and Contributors
and that's a wrap on the whole page, bestie!! 🎉 you made it to the very end of the CMAKE-VARIABLES(7) journey — this was CMake 4.4.5, dated Oct 28, 2026, and honestly? she ate. 🫶✨ go write some CMakeLists.txt files that would make me proud, and remember: use CMAKE_<LANG>_COMPILER_ID, not the deprecated girlies. mwah 💖🎀🦋
📦 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