# CMake module **Note**: the functionality of this module is governed by [Meson's rules on mixing build systems](Mixing-build-systems.md). This module provides helper tools for generating cmake package files. It also supports the usage of CMake based subprojects, similar to the normal [meson subprojects](Subprojects.md). ## Usage To use this module, just do: **`cmake = import('cmake')`**. The following functions will then be available as methods on the object with the name `cmake`. You can, of course, replace the name `cmake` with anything else. It is generally recommended to use the latest Meson version and CMake >=3.17 for best compatibility. CMake subprojects will usually also work with older CMake versions. However, this can lead to unexpected issues in rare cases. ## CMake subprojects Using CMake subprojects is similar to using the "normal" meson subprojects. They also have to be located in the `subprojects` directory. Example: ```cmake add_library(cm_lib SHARED ${SOURCES}) ``` ```meson cmake = import('cmake') # Configure the CMake project sub_proj = cmake.subproject('libsimple_cmake') # Fetch the dependency object cm_lib = sub_proj.dependency('cm_lib') executable(exe1, ['sources'], dependencies: [cm_lib]) ``` The `subproject` method is almost identical to the normal meson `subproject` function. The only difference is that a CMake project instead of a meson project is configured. The returned `sub_proj` supports the same options as a "normal" subproject. Meson automatically detects CMake build targets, which can be accessed with the methods listed [below](#subproject-object). It is usually enough to just use the dependency object returned by the `dependency()` method in the build targets. This is almost identical to using `declare_dependency()` object from a normal meson subproject. It is also possible to use executables defined in the CMake project as code generators with the `target()` method: ```cmake add_executable(cm_exe ${EXE_SRC}) ``` ```meson cmake = import('cmake') # Subproject with the "code generator" sub_pro = cmake.subproject('cmCodeGen') # Fetch the code generator exe sub_exe = sub_pro.target('cm_exe') # Use the code generator generated = custom_target( 'cmake-generated', input: [], output: ['test.cpp'], command: [sub_exe, '@OUTPUT@'] ) ``` It should be noted that not all projects are guaranteed to work. The safest approach would still be to create a `meson.build` for the subprojects in question. ### Configuration options *New in meson 0.55.0* Meson also supports passing configuration options to CMake and overriding certain build details extracted from the CMake subproject. ```meson cmake = import('cmake') opt_var = cmake.subproject_options() # Call CMake with `-DSOME_OTHER_VAR=ON` opt_var.add_cmake_defines({'SOME_OTHER_VAR': true}) # Globally override the C++ standard to c++11 opt_var.set_override_option('cpp_std', 'c++11') # Override the previous global C++ standard # with c++14 only for the CMake target someLib opt_var.set_override_option('cpp_std', 'c++14', target: 'someLib') sub_pro = cmake.subproject('someLibProject', options: opt_var) # Further changes to opt_var have no effect ``` See [the CMake options object](#cmake-options-object) for a complete reference of all supported functions. The CMake configuration options object is very similar to the [configuration data object](Reference-manual.md#configuration-data-object) object returned by [`configuration_data`](Reference-manual.md#configuration_data). It is generated by the `subproject_options` function All configuration options have to be set *before* the subproject is configured and must be passed to the `subproject` method via the `options` key. Altering the configuration object won't have any effect on previous `cmake.subproject` calls. In earlier meson versions CMake command-line parameters could be set with the `cmake_options` kwarg. However, this feature is deprecated since 0.55.0 and only kept for compatibility. It will not work together with the `options` kwarg. ### `subproject` object This object is returned by the `subproject` function described above and supports the following methods: - `dependency(target)` returns a dependency object for any CMake target. - `include_directories(target)` returns a meson `include_directories()` object for the specified target. Using this function is not necessary if the dependency object is used. - `target(target)` returns the raw build target. - `target_type(target)` returns the type of the target as a string - `target_list()` returns a list of all target *names*. - `get_variable(name)` fetches the specified variable from inside the subproject. Usually `dependency()` or `target()` should be preferred to extract build targets. - `found` returns true if the subproject is available, otherwise false *new in meson 0.53.2* ### `cmake options` object This object is returned by the `subproject_options()` function and consumed by the `options` kwarg of the `subproject` function. The following methods are supported: - `add_cmake_defines({'opt1': val1, ...})` add additional CMake commandline defines - `set_override_option(opt, val)` set specific [build options](Build-options.md) for targets. This will effectively add `opt=val` to the `override_options` array of the [build target](Reference-manual.md#executable) - `set_install(bool)` override wether targets should be installed or not - `append_compile_args(lang, arg1, ...)` append compile flags for a specific language to the targets - `append_link_args(arg1, ...)` append linger args to the targets - `clear()` reset all data in the `cmake options` object The methods `set_override_option`, `set_install`, `append_compile_args` and `append_link_args` support the optional `target` kwarg. If specified, the set options affect the specific target. The effect of the option is global for the subproject otherwise. If, for instance, `opt_var.set_install(false)` is called, no target will be installed regardless of what is set by CMake. However, it is still possible to install specific targets (here `foo`) by setting the `target` kwarg: `opt_var.set_install(true, target: 'foo')` Options that are not set won't affect the generated subproject. So, if for instance, `set_install` was not called then the values extracted from CMake will be used. ## CMake configuration files ### cmake.write_basic_package_version_file() This function is the equivalent of the corresponding [CMake function](https://cmake.org/cmake/help/v3.11/module/CMakePackageConfigHelpers.html#generating-a-package-version-file), it generates a `name` package version file. * `name`: the name of the package. * `version`: the version of the generated package file. * `compatibility`: a string indicating the kind of compatibility, the accepted values are `AnyNewerVersion`, `SameMajorVersion`, `SameMinorVersion` or `ExactVersion`. It defaults to `AnyNewerVersion`. Depending on your cmake installation some kind of compatibility may not be available. * `install_dir`: optional installation directory, it defaults to `$(libdir)/cmake/$(name)` Example: ```meson cmake = import('cmake') cmake.write_basic_package_version_file(name: 'myProject', version: '1.0.0') ``` ### cmake.configure_package_config_file() This function is the equivalent of the corresponding [CMake function](https://cmake.org/cmake/help/v3.11/module/CMakePackageConfigHelpers.html#generating-a-package-configuration-file), it generates a `name` package configuration file from the `input` template file. Just like the cmake function in this file the `@PACKAGE_INIT@` statement will be replaced by the appropriate piece of cmake code. The equivalent `PATH_VARS` argument is given through the `configuration` parameter. * `name`: the name of the package. * `input`: the template file where that will be treated for variable substitutions contained in `configuration`. * `install_dir`: optional installation directory, it defaults to `$(libdir)/cmake/$(name)`. * `configuration`: a `configuration_data` object that will be used for variable substitution in the template file. Example: meson.build: ```meson cmake = import('cmake') conf = configuration_data() conf.set_quoted('VAR', 'variable value') cmake.configure_package_config_file( name: 'myProject', input: 'myProject.cmake.in', configuration: conf ) ``` myProject.cmake.in: ```text @PACKAGE_INIT@ set(MYVAR VAR) ```