CMake 模块

注意:此模块的功能受 Meson 混合构建系统规则 的约束。

此模块提供用于生成 cmake 包文件的辅助工具。它还支持使用基于 CMake 的子项目,类似于正常的 Meson 子项目

用法

要使用此模块,只需执行:cmake = import('cmake')。然后,以下函数将作为名为 cmake 的对象上的方法可用。当然,您可以将 cmake 这个名字替换为其他任何东西。

通常建议使用最新的 Meson 版本和 CMake >=3.17 以获得最佳兼容性。CMake 子项目通常也适用于较旧的 CMake 版本。但是,在极少数情况下,这会导致意想不到的问题。

CMake 子项目

使用 CMake 子项目类似于使用“正常”的 Meson 子项目。它们也必须位于 subprojects 目录中。

示例

add_library(cm_lib SHARED ${SOURCES})
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])

subproject 方法几乎与正常的 Meson subproject() 函数相同。唯一的区别在于配置的是 CMake 项目而不是 Meson 项目。

返回的 sub_proj 支持与“正常”子项目相同的选项。Meson 会自动检测 CMake 构建目标,这些目标可以通过下面列出的方法访问 这里

通常,在构建目标中使用 dependency() 方法返回的依赖项对象就足够了。这几乎与使用来自正常 Meson 子项目的 declare_dependency() 对象相同。

也可以使用 target() 方法将 CMake 项目中定义的可执行文件用作代码生成器。

add_executable(cm_exe ${EXE_SRC})
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@']
)

需要注意的是,并非所有项目都能保证工作。最安全的方法仍然是为相关子项目创建 meson.build

配置选项

Meson 0.55.0 中新增

Meson 还支持将配置选项传递给 CMake 并覆盖从 CMake 子项目中提取的某些构建细节。

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

请参阅 CMake 选项对象 以获取所有支持函数的完整参考。

CMake 配置选项对象与 cfg_data 对象非常类似,该对象由 configuration_data() 返回。它是通过 subproject_options 方法生成的。

所有配置选项必须在配置子项目之前设置,并且必须通过 options 键传递给 subproject 方法。更改配置对象不会对之前的 cmake.subproject 调用产生任何影响。

在早期的 Meson 版本中,CMake 命令行参数可以通过 cmake_options 关键字参数设置。但是,此功能已在 0.55.0 中弃用,仅保留用于兼容性。它将无法与 options 关键字参数一起使用。

subproject 对象

此对象由上面描述的 subproject 方法返回,并支持以下方法

  • dependency(target) 返回任何 CMake 目标的依赖项对象。include_type 关键字参数(0.56.0 中新增)控制返回的依赖项对象的包含类型,类似于 dependency() 函数中的相同关键字参数。
  • include_directories(target) 返回指定目标的 Meson inc 对象。如果使用依赖项对象,则无需使用此方法。
  • target(target) 返回原始构建目标。
  • target_type(target) 以字符串形式返回目标的类型。
  • target_list() 返回所有目标名称的列表。
  • get_variable(name) 从子项目内部获取指定的变量。通常应优先使用 dependency()target() 来提取构建目标。
  • found 如果子项目可用,则返回 true,否则返回 false Meson 0.53.2 中新增

cmake 选项 对象

此对象由 subproject_options() 方法返回,并由 subproject 方法的 options 关键字参数使用。支持以下方法

  • add_cmake_defines({'opt1': val1, ...}) 添加其他 CMake 命令行定义
  • set_override_option(opt, val) 为目标设置特定 构建选项。这将有效地将 opt=val 添加到 build_target()override_options 数组中。
  • set_install(bool) 覆盖目标是否应该安装。
  • append_compile_args(lang, arg1, ...) 将特定语言的编译标志附加到目标。
  • append_link_args(arg1, ...) 将链接器参数附加到目标。
  • clear() 重置 cmake 选项 对象中的所有数据。

方法 set_override_optionset_installappend_compile_argsappend_link_args 支持可选的 target 关键字参数。如果指定,设置的选项会影响特定目标。否则,选项的效果对于子项目是全局的。

例如,如果调用 opt_var.set_install(false),则无论 CMake 设置了什么,都不会安装任何目标。但是,仍然可以通过设置 target 关键字参数来安装特定目标(此处为 foo):opt_var.set_install(true, target: 'foo')

未设置的选项不会影响生成的子项目。因此,例如,如果未调用 set_install,则将使用从 CMake 中提取的值。

交叉编译

0.56.0 中新增

Meson 将尝试从交叉和本地文件中的现有条目自动猜测大多数所需的 CMake 工具链变量。这些变量将存储在构建目录中自动生成的 CMake 工具链文件中。无法猜测的剩余变量可以由用户在 [cmake] 交叉/本地文件部分中添加(0.56.0 中新增)

使用 [properties] 部分中的 cmake_toolchain_file 设置也支持添加手动 CMake 工具链文件。直接在 meson.build 中使用 -DCMAKE_TOOLCHAIN_FILE=/path/to/some/Toolchain.cmake 设置 CMake 工具链文件不支持,因为自动生成的工具链文件也被 Meson 用于将任意代码注入 CMake 以启用 CMake 子项目支持。

最接近仅使用手动 CMake 工具链文件的配置是,在机器文件中设置这些选项。

[properties]

cmake_toolchain_file = '/path/to/some/Toolchain.cmake'
cmake_defaults       = false

[cmake]

# No entries in this section

这将导致一个工具链文件,其中仅包含启用 CMake 子项目支持的绝对必要项,并且将 include() cmake_toolchain_file 作为最后一条指令。

有关更多信息,请参阅 交叉和本地文件规范

CMake 配置文件

cmake.write_basic_package_version_file()

此方法相当于相应的 CMake 函数,它生成一个 name 包版本文件。

  • name:包的名称。
  • version:生成的包文件的版本。
  • compatibility:一个字符串,指示兼容性类型,可接受的值为 AnyNewerVersionSameMajorVersionSameMinorVersionExactVersion。默认为 AnyNewerVersion。根据您的 cmake 安装,某些兼容性类型可能不可用。
  • arch_independent0.62.0 中新增,如果为 true,生成的包文件将跳过架构检查。对于仅包含头的库很有用。
  • install_dir:可选的安装目录,默认为 $(libdir)/cmake/$(name)

示例

cmake = import('cmake')

cmake.write_basic_package_version_file(name: 'myProject', version: '1.0.0')

cmake.configure_package_config_file()

此方法相当于相应的 CMake 函数,它从 input 模板文件生成一个 name 包配置文件。就像此文件中的 cmake 函数一样,@PACKAGE_INIT@ 语句将被适当的 cmake 代码块替换。等效的 PATH_VARS 参数通过 configuration 参数提供。

  • name:包的名称。
  • input:将被处理以进行变量替换的模板文件,这些变量替换包含在 configuration 中。
  • install_dir:可选的安装目录,默认为 $(libdir)/cmake/$(name)
  • configuration:一个 configuration_data 对象,将用于在模板文件中进行变量替换。自 0.62.0 起,它可以接受字典代替。

示例

meson.build

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

@PACKAGE_INIT@

set(MYVAR VAR)

搜索结果是