|
|
|
# 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
|
|
|
|
[[@cfg_data]] object] object returned
|
|
|
|
by [[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. The
|
|
|
|
`include_type` kwarg *(new in 0.56.0)* controls the include type of the
|
|
|
|
returned dependency object similar to the same kwarg in the
|
|
|
|
[[dependency]] function.
|
|
|
|
- `include_directories(target)` returns a Meson [[@inc]]
|
|
|
|
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]]
|
|
|
|
- `set_install(bool)` override whether 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.
|
|
|
|
|
|
|
|
### Cross compilation
|
|
|
|
|
|
|
|
*New in 0.56.0*
|
|
|
|
|
|
|
|
Meson will try to automatically guess most of the required CMake
|
|
|
|
toolchain variables from existing entries in the cross and native
|
|
|
|
files. These variables will be stored in an automatically generate
|
|
|
|
CMake toolchain file in the build directory. The remaining variables
|
|
|
|
that can't be guessed can be added by the user in the `[cmake]`
|
|
|
|
cross/native file section (*new in 0.56.0*).
|
|
|
|
|
|
|
|
Adding a manual CMake toolchain file is also supported with the
|
|
|
|
`cmake_toolchain_file` setting in the `[properties]` section. Directly
|
|
|
|
setting a CMake toolchain file with
|
|
|
|
`-DCMAKE_TOOLCHAIN_FILE=/path/to/some/Toolchain.cmake` in the
|
|
|
|
`meson.build` is **not** supported since the automatically generated
|
|
|
|
toolchain file is also used by Meson to inject arbitrary code into
|
|
|
|
CMake to enable the CMake subproject support.
|
|
|
|
|
|
|
|
The closest configuration to only using a manual CMake toolchain file
|
|
|
|
would be to set these options in the machine file:
|
|
|
|
|
|
|
|
```ini
|
|
|
|
[properties]
|
|
|
|
|
|
|
|
cmake_toolchain_file = '/path/to/some/Toolchain.cmake'
|
|
|
|
cmake_defaults = false
|
|
|
|
|
|
|
|
[cmake]
|
|
|
|
|
|
|
|
# No entries in this section
|
|
|
|
```
|
|
|
|
|
|
|
|
This will result in a toolchain file with just the bare minimum to
|
|
|
|
enable the CMake subproject support and `include()` the
|
|
|
|
`cmake_toolchain_file` as the last instruction.
|
|
|
|
|
|
|
|
For more information see the [cross and native file
|
|
|
|
specification](Machine-files.md).
|
|
|
|
|
|
|
|
## CMake configuration files
|
|
|
|
|
|
|
|
### cmake.write_basic_package_version_file()
|
|
|
|
|
|
|
|
This function is the equivalent of the corresponding [CMake
|
|
|
|
function](https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:write_basic_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.
|
|
|
|
* `arch_independent`: *new in 0.62.0*, if true the generated package file
|
|
|
|
will skip architecture checks. Useful for header-only libraries.
|
|
|
|
* `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)
|
|
|
|
```
|