CMakeToolchain¶
CMakeToolchain 是 CMake 的工具链生成器。它生成工具链文件,该文件可以在 CMake 的命令行调用中使用 -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake。此生成器将当前的包配置、设置和选项转换为 CMake 工具链语法。
它可以声明为
from conan import ConanFile
class Pkg(ConanFile):
generators = "CMakeToolchain"
或者在 generate() 方法中完全实例化
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain
class App(ConanFile):
settings = "os", "arch", "compiler", "build_type"
requires = "hello/0.1"
generators = "CMakeDeps"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}
def generate(self):
tc = CMakeToolchain(self)
tc.variables["MYVAR"] = "MYVAR_VALUE"
tc.preprocessor_definitions["MYDEFINE"] = "MYDEF_VALUE"
tc.generate()
注意
CMakeToolchain 旨在与 CMakeDeps 依赖项生成器一起运行。请勿将其与其他 CMake 遗留生成器(如 cmake 或 cmake_paths)一起使用。
生成的文件¶
在 conan install (或在缓存中构建包) 之后,这将生成以下文件,其中包含在 generate() 方法中提供的信息以及从当前 settings 转换的信息
conan_toolchain.cmake:包含 Conan 设置到 CMake 变量的转换。此文件中将定义的一些内容
CMake 生成器平台和生成器工具集的定义
基于
fPIC选项定义CMAKE_POSITION_INDEPENDENT_CODE。根据需要定义 C++ 标准
定义用于 C++ 的标准库
禁用 OSX 中的 rpath
在 Windows 上使用 Visual Studio 时定义
CMAKE_VS_DEBUGGER_ENVIRONMENT。这设置PATH环境变量以指向包含 DLL 的目录,以便可以直接从 Visual Studio IDE 调试,而无需复制 DLL(需要 CMake 3.27)。定义
CONAN_RUNTIME_LIB_DIRS以允许收集运行时依赖项(共享库),有关详细信息,请参见下文。
conanvcvars.bat:在某些情况下,需要正确定义 Visual Studio 环境才能进行构建,例如在使用 Ninja 或 NMake 生成器时。如果需要,
CMakeToolchain将生成此脚本,以便更容易地定义正确的 Visual Studio 提示。CMakePresets.json:此工具链生成标准的 CMakePresets.json 文件。有关更多信息,请参阅 此处的文档。它当前使用 JSON 模式的第 3 版。Conan 向 JSON 文件添加了 configure、build 和 test 预设条目
- configurePresets 存储以下信息
要使用的 generator。
指向 conan_toolchain.cmake 的路径。
与无法在工具链中指定的情况下指定的设置相对应的缓存变量。
单配置生成器的 CMAKE_BUILD_TYPE 变量。
当配置 tools.build:skip_test 为 true 时,将 BUILD_TESTING 变量设置为 OFF。
一个环境部分,设置与 VirtualBuildEnv 相关的全部环境信息(如果适用)。可以通过在 CMakeToolchain.presets_build_environment 属性中传递环境,在配方中 generate() 方法中修改此环境。可以使用 tools.cmake.cmaketoolchain:presets_environment 配置跳过此部分的生成。
默认情况下,预设名称将为 conan-xxxx,但可以使用 CMakeToolchain.presets_prefix = “conan” 属性自定义 “conan-” 前缀。
预设名称由 layout() self.folders.build_folder_vars 定义控制,其中可以包含设置、选项、
self.name和self.version以及常量const.xxx,例如 [“settings.compiler”, “settings.arch”, “options.shared”, “const.myname”]。如果 CMake 作为直接 tool_requires 依赖项找到,或者如果设置了 tools.cmake:cmake_program,则配置预设将包含一个 cmakeExecutable 字段。此字段表示要用于此预设的 CMake 可执行文件的路径。如 CMake 文档所述,此字段保留供 IDE 使用,CMake 本身不使用它。
- buildPresets 存储以下信息
与此构建预设关联的 configurePreset。
- testPresets 存储以下信息
与此构建预设关联的 configurePreset。
一个环境部分,设置与 VirtualRunEnv 相关的全部环境信息(如果适用)。可以通过在 generate() 方法中通过 CMakeToolchain.presets_run_environment 属性传递环境,在配方中修改此环境。请注意,由于此预设从 configurePreset 继承,它还将继承其环境。可以使用`tools.cmake.cmaketoolchain:presets_environment` 配置跳过此部分的生成。
CMakeUserPresets.json:如果您在配方中声明了
layout(),并且您的CMakeLists.txt文件位于conanfile.source_folder文件夹中,则将生成一个CMakeUserPresets.json文件(如果尚未生成),其中自动包含CMakePresets.json(位于conanfile.generators_folder)以允许您的 IDE(Visual Studio、Visual Studio Code、CLion…)或cmake工具找到CMakePresets.json。可以使用user_presets_path属性进一步调整生成的CMakeUserPresets.json的位置,如下所述。生成的CMakeUserPresets.json的模式版本为“4”,需要 CMake >= 3.23。可以使用CMakeToolchain.user_presets_path = "CMakeUserPresets.json"属性配置此文件的文件名,因此,如果您想生成一个“ConanPresets.json”来包含在您自己的文件中,则可以在generate()方法中定义tc.user_presets_path = "ConanPresets.json"。有关完整示例,请参阅 扩展您自己的 CMake 预设。注意: 如果它已经存在并且不是由 Conan 生成的,Conan 将跳过生成
CMakeUserPresets.json。注意: 要列出所有可用的预设,请使用
cmake --list-presets命令
注意
生成的 CMakeUserPresets.json 的模式版本为 4(与 CMake>=3.23 兼容),CMakePresets.json 的模式为 3(与 CMake>=3.21 兼容)。
CONAN_RUNTIME_LIB_DIRS¶
在生成的 conan_toolchain.cmake 文件中,此变量包含一个目录列表,其中包含主机上下文中的所有依赖项的运行时库(如 DLL)。这旨在用于依赖 CMake 功能来收集共享库以创建可重定位捆绑包,如下例所示。
只需将 CONAN_RUNTIME_LIB_DIRS 变量传递到 install(RUNTIME_DEPENDENCY_SET ...) 调用中的 DIRECTORIES 参数。
install(RUNTIME_DEPENDENCY_SET my_app_deps
PRE_EXCLUDE_REGEXES
[[api-ms-win-.*]]
[[ext-ms-.*]]
[[kernel32\.dll]]
[[libc\.so\..*]] [[libgcc_s\.so\..*]] [[libm\.so\..*]] [[libstdc\+\+\.so\..*]]
POST_EXCLUDE_REGEXES
[[.*/system32/.*\.dll]]
[[^/lib.*]]
[[^/usr/lib.*]]
DIRECTORIES ${CONAN_RUNTIME_LIB_DIRS}
)
自定义¶
preprocessor_definitions¶
此属性允许为多个配置(Debug、Release 等)定义编译器预处理器定义。
def generate(self):
tc = CMakeToolchain(self)
tc.preprocessor_definitions["MYDEF"] = "MyValue"
tc.preprocessor_definitions.debug["MYCONFIGDEF"] = "MyDebugValue"
tc.preprocessor_definitions.release["MYCONFIGDEF"] = "MyReleaseValue"
# Setting to None will add the definition with no value
tc.preprocessor_definitions["NOVALUE_DEF"] = None
tc.generate()
这将转换为
在
conan_toolchain.cmake文件中为MYDEF定义一个add_compile_definitions()定义。使用 cmake 生成器表达式在
conan_toolchain.cmake文件中定义一个add_compile_definitions()定义,为不同的配置使用不同的值。
cache_variables¶
此属性允许定义 CMake 缓存变量。这些变量与 variables 不同,是单配置的。它们将存储在 CMakePresets.json 文件中(在 configurePreset 中的 cacheVariables 中),并使用 -D 参数在调用 cmake.configure 时应用,使用 CMake() 构建助手。
def generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["foo"] = True
tc.cache_variables["foo2"] = False
tc.cache_variables["var"] = "23"
分配给 cache_variable 的布尔值将在 CMake 中转换为 ON 和 OFF 符号。
variables¶
此属性允许为多个配置(Debug、Release 等)定义 CMake 变量。这些变量应用于定义与工具链相关的内容,并且在大多数情况下,您可能需要使用 cache_variables。此外,请注意,由于这些变量是在 conan_toolchain.cmake 文件中定义的,并且工具链会被 CMake 多次加载,因此这些变量的定义也会在这些点进行。
def generate(self):
tc = CMakeToolchain(self)
tc.variables["MYVAR"] = "MyValue"
tc.variables.debug["MYCONFIGVAR"] = "MyDebugValue"
tc.variables.release["MYCONFIGVAR"] = "MyReleaseValue"
tc.generate()
这将转换为
在
conan_toolchain.cmake文件中为MYVAR定义一个set()定义。使用 cmake 生成器表达式在
conan_toolchain.cmake文件中定义一个set()定义,为不同的配置使用不同的值。
分配给变量的布尔值将在 CMake 中转换为 ON 和 OFF 符号
def generate(self):
tc = CMakeToolchain(self)
tc.variables["FOO"] = True
tc.variables["VAR"] = False
tc.generate()
将生成句子:set(FOO ON ...) 和 set(VAR OFF ...)。
user_presets_path¶
此属性允许指定生成的 CMakeUserPresets.json 文件的位置。允许的值
一个绝对路径
相对于
self.source_folder的路径布尔值
False,完全禁止生成文件。
例如,我们可以通过以下方式防止生成器创建 CMakeUserPresets.json
def generate(self):
tc = CMakeToolchain(self)
tc.user_presets_path = False
tc.generate()
还可以使用实验性配置 tools.cmake.cmaketoolchain:user_presets 更改 CMakeUserPresets.json 文件的名称和位置。将其分配给空字符串将禁用文件的生成。有关更多信息,请查看 conf 部分。
presets_build_environment, presets_run_environment¶
这些属性通过分配 Environment 启用对与预设关联的构建和运行环境的修改,这可以在 generate() 方法中完成。
例如,您可以覆盖已在构建环境中设置的环境变量
def generate(self):
buildenv = VirtualBuildEnv(self)
buildenv.environment().define("MY_BUILD_VAR", "MY_BUILDVAR_VALUE_OVERRIDDEN")
buildenv.generate()
tc = CMakeToolchain(self)
tc.presets_build_environment = buildenv.environment()
tc.generate()
或者生成一个新环境并将其与已有的环境组合
def generate(self):
runenv = VirtualRunEnv(self)
runenv.environment().define("MY_RUN_VAR", "MY_RUNVAR_SET_IN_GENERATE")
runenv.generate()
env = Environment()
env.define("MY_ENV_VAR", "MY_ENV_VAR_VALUE")
env = env.vars(self, scope="run")
env.save_script("other_env")
tc = CMakeToolchain(self)
tc.presets_run_environment = runenv.environment().compose_env(env)
tc.generate()
额外的编译标志¶
您可以使用以下属性将额外的编译标志附加到工具链
extra_cxxflags (默认值
[]) 用于额外的 cxxflagsextra_cflags (默认值
[]) 用于额外的 cflagsextra_sharedlinkflags (默认值
[]) 用于额外的共享链接标志extra_exelinkflags (默认值
[]) 用于额外的 exe 链接标志
注意
标志优先级顺序:在 tools.build 配置中指定的标志,例如 cxxflags、cflags、sharedlinkflags 和 exelinkflags,始终优先于 CMakeToolchain 属性设置的标志。
presets_prefix¶
默认情况下为 "conan",它将生成名为“conan-xxxx”的 CMake 预设。这样做是为了避免与用户自己的预设发生潜在的名称冲突。
absolute_paths¶
默认情况下,CMakeToolchain 将生成相对路径。例如,CMakeUserPresets.json 将包含指向包含的 CMakePresets.json 的相对路径(这两个文件均由 CMakeToolchain 生成),并且 CMakePresets.json 文件将包含指向 conan_toolchain.cmake 文件的相对路径,该文件在其 toolchainFile 字段中定义,相对于 CMake 预设文档中指定的构建文件夹。
如果出于某种原因需要使用绝对路径,可以使用
def generate(self):
tc = CMakeToolchain(self)
tc.absolute_paths = True
tc.generate()
使用自定义工具链文件¶
提供自定义 CMake 工具链文件有两种方法
可以完全跳过
conan_toolchain.cmake文件并替换为用户自己的文件,定义tools.cmake.cmaketoolchain:toolchain_file=<filepath>配置值。请注意,这种方法会将所有工具链责任转移给用户提供的工具链,但如果没有一些帮助,定位依赖项所需的xxx-config.cmake文件可能会很困难。因此,在大多数情况下,建议使用以下tools.cmake.cmaketoolchain:user_toolchain,并在必要时使用tools.cmake.cmaketoolchain:enabled_blocks。可以添加一个自定义用户工具链文件(包含在)到
conan_toolchain.cmake中,方法是使用下面描述的user_toolchain块,并定义tools.cmake.cmaketoolchain:user_toolchain=["<filepath>"]配置值。可以在
global.conf中定义配置tools.cmake.cmaketoolchain:user_toolchain=["<filepath>"],也可以创建一个用于工具链的 Conan 包,并使用self.conf_info来声明工具链文件import os from conan import ConanFile class MyToolchainPackage(ConanFile): ... def package_info(self): f = os.path.join(self.package_folder, "mytoolchain.cmake") self.conf_info.define("tools.cmake.cmaketoolchain:user_toolchain", [f])
如果您将前一个包声明为
tool_require,则工具链将自动应用。如果您定义了多个
tool_requires,可以使用每个包中的append方法轻松地将所有用户工具链值组合在一起,例如import os from conan import ConanFile class MyToolRequire(ConanFile): ... def package_info(self): f = os.path.join(self.package_folder, "mytoolchain.cmake") # Appending the value to any existing one self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", f)
因此,它们将自动由您的
CMakeToolchain生成器应用,而无需编写任何额外的代码from conan import ConanFile from conan.tools.cmake import CMake class Pkg(ConanFile): settings = "os", "compiler", "arch", "build_type" exports_sources = "CMakeLists.txt" tool_requires = "toolchain1/0.1", "toolchain2/0.1" generators = "CMakeToolchain" def build(self): cmake = CMake(self) cmake.configure()
注意
重要说明
在大多数情况下,
tools.cmake.cmaketoolchain:user_toolchain将优先于tools.cmake.cmaketoolchain:toolchain_fileuser_toolchain文件可以定义用于交叉构建的变量,例如CMAKE_SYSTEM_NAME、CMAKE_SYSTEM_VERSION和CMAKE_SYSTEM_PROCESSOR。如果这些变量在用户工具链文件中定义,则会受到尊重,并且conan_toolchain.cmake推断的变量不会覆盖用户定义的变量。如果这些变量未在用户工具链文件中定义,则 Conan 自动推断的变量将被使用。在user_toolchain文件中定义的变量也比配置定义的变量(如tools.cmake.cmaketoolchain:system_name)具有更高的优先级。可以将
tools.cmake.cmaketoolchain:enabled_blocks的使用与tools.cmake.cmaketoolchain:user_toolchain结合使用,以仅启用某些块,但避免 CMakeToolchain 覆盖用户工具链文件中定义的 CMake 值。
扩展和高级自定义¶
CMakeToolchain 实现了强大的功能,用于扩展和自定义生成的工具链文件。
内容按 blocks 组织,可以对其进行自定义。以下是可用的预定义块,并按此顺序添加
user_toolchain:允许从
conan_toolchain.cmake文件中包含用户工具链。如果定义了配置tools.cmake.cmaketoolchain:user_toolchain=["xxxx", "yyyy"],则其值将为include(xxx)\ninclude(yyyy)作为conan_toolchain.cmake中的第一行。generic_system:定义
CMAKE_SYSTEM_NAME、CMAKE_SYSTEM_VERSION、CMAKE_SYSTEM_PROCESSOR、CMAKE_GENERATOR_PLATFORM、CMAKE_GENERATOR_TOOLSETcompilers:定义不同语言的
CMAKE_<LANG>_COMPILER,如tools.build:compiler_executables配置中定义。android_system:定义
ANDROID_PLATFORM、ANDROID_STL、ANDROID_ABI并包含ANDROID_NDK_PATH/build/cmake/android.toolchain.cmake,其中ANDROID_NDK_PATH来自tools.android:ndk_path配置值。apple_system:定义
CMAKE_OSX_ARCHITECTURES(请参阅 通用二进制部分)、CMAKE_OSX_SYSROOT用于 Apple 系统。fpic:定义
CMAKE_POSITION_INDEPENDENT_CODE,当存在options.fPIC时arch_flags:定义 C/C++ 标志,如
-m32, -m64(在必要时)。linker_scripts:定义任何提供的链接器脚本的标志。
libcxx:定义
-stdlib=libc++标志(在必要时)以及_GLIBCXX_USE_CXX11_ABI。vs_runtime:定义
CMAKE_MSVC_RUNTIME_LIBRARY变量,用于 Visual Studio 的多个配置的生成器表达式。vs_debugger_environment:定义
CMAKE_VS_DEBUGGER_ENVIRONMENT,来自依赖项的“bindirs”文件夹,仅用于 Visual Studio。cppstd:定义
CMAKE_CXX_STANDARD、CMAKE_CXX_EXTENSIONSparallel:定义 Visual 的
/MP并行构建标志。extra_flags:从
tools.build:cxxflags、tools.build:cflags、tools.build:defines、tools.build:sharedlinkflags等添加额外的定义、编译和链接标志。cmake_flags_init:定义
CMAKE_XXX_FLAGS变量,基于先前定义的 Conan 变量。上面的块仅定义CONAN_XXX变量,此块将定义 CMake 变量,如set(CMAKE_CXX_FLAGS_INIT "${CONAN_CXX_FLAGS}" CACHE STRING "" FORCE)。extra_variables:定义来自
tools.cmake.cmaketoolchain:extra_variables的额外的 CMake 变量try_compile:停止处理工具链,跳过下面的块,如果定义了 CMake 属性
IN_TRY_COMPILE。find_paths:定义
CMAKE_FIND_PACKAGE_PREFER_CONFIG、CMAKE_MODULE_PATH、CMAKE_PREFIX_PATH,以便从CMakeDeps生成的文件可以找到。pkg_config:基于
tools.gnu:pkg_config定义PKG_CONFIG_EXECUTABLE,并将CMAKE_CURRENT_LIST_DIR添加到ENV{PKG_CONFIG_PATH},以让 pkg-config 找到生成的 .pc 文件。rpath:定义
CMAKE_SKIP_RPATH。默认情况下,它被禁用,并且需要定义self.blocks["rpath"].skip_rpath=True如果您想激活CMAKE_SKIP_RPATHshared:定义
BUILD_SHARED_LIBS。output_dirs:定义
CMAKE_INSTALL_XXX变量。CMAKE_INSTALL_PREFIX:设置为
package_folder,因此如果运行“cmake install”操作,工件将转到该位置。CMAKE_INSTALL_BINDIR、CMAKE_INSTALL_SBINDIR 和 CMAKE_INSTALL_LIBEXECDIR:默认设置为
bin。CMAKE_INSTALL_LIBDIR:默认设置为
lib。CMAKE_INSTALL_INCLUDEDIR 和 CMAKE_INSTALL_OLDINCLUDEDIR:默认设置为
include。CMAKE_INSTALL_DATAROOTDIR:默认设置为
res。
如果您想更改默认值,请在
layout()方法中调整cpp.package对象def layout(self): ... # For CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_SBINDIR and CMAKE_INSTALL_LIBEXECDIR, takes the first value: self.cpp.package.bindirs = ["mybin"] # For CMAKE_INSTALL_LIBDIR, takes the first value: self.cpp.package.libdirs = ["mylib"] # For CMAKE_INSTALL_INCLUDEDIR, CMAKE_INSTALL_OLDINCLUDEDIR, takes the first value: self.cpp.package.includedirs = ["myinclude"] # For CMAKE_INSTALL_DATAROOTDIR, takes the first value: self.cpp.package.resdirs = ["myres"]
注意
在
package_info()方法中更改self.cpp_info是无效的,需要定义self.cpp.package。variables:定义来自
CMakeToolchain.variables属性的 CMake 变量。preprocessor:定义来自
CMakeToolchain.preprocessor_definitions属性的预处理器指令
自定义内容块¶
每个块都可以通过不同的方式自定义(请记住在自定义后调用 tc.generate())
# tc.generate() should be called at the end of every one
# remove an existing block, the generated conan_toolchain.cmake
# will not contain code for that block at all
def generate(self):
tc = CMakeToolchain(self)
tc.blocks.remove("generic_system")
# remove several blocks
def generate(self):
tc = CMakeToolchain(self)
tc.blocks.remove("generic_system", "cmake_flags_init")
# LEGACY: keep one block, remove all the others
# If you want to generate conan_toolchain.cmake with only that
# block. Use "tc.blocks.enabled()" instead
def generate(self):
tc = CMakeToolchain(self)
# this still leaves blocks "variables" and "preprocessor"
# use "tc.blocks.enabled()"" instead
tc.blocks.select("generic_system")
# LEGACY: keep several blocks, remove the other blocks
# Use "tc.blocks.enabled()" instead
def generate(self):
tc = CMakeToolchain(self)
# this still leaves blocks "variables" and "preprocessor"
# use "tc.blocks.enabled()" instead
tc.blocks.select("generic_system", "cmake_flags_init")
# keep several blocks, remove the other blocks
# This can be done from configuration with
# tools.cmake.cmaketoolchain:enabled_blocs
def generate(self):
tc = CMakeToolchain(self)
# Discard all the other blocks except ``generic_system``
tc.blocks.enabled("generic_system")
# iterate blocks
def generate(self):
tc = CMakeToolchain(self)
for block_name in tc.blocks.keys():
# do something with block_name
for block_name, block in tc.blocks.items():
# do something with block_name and block
# modify the template of an existing block
def generate(self):
tc = CMakeToolchain(self)
tmp = tc.blocks["generic_system"].template
new_tmp = tmp.replace(...) # replace, fully replace, append...
tc.blocks["generic_system"].template = new_tmp
# modify one or more variables of the context
def generate(self):
tc = CMakeToolchain(conanfile)
# block.values is the context dictionary
toolset = tc.blocks["generic_system"].values["toolset"]
tc.blocks["generic_system"].values["toolset"] = "other_toolset"
# modify the whole context values
def generate(self):
tc = CMakeToolchain(conanfile)
tc.blocks["generic_system"].values = {"toolset": "other_toolset"}
# modify the context method of an existing block
import types
def generate(self):
tc = CMakeToolchain(self)
generic_block = toolchain.blocks["generic_system"]
def context(self):
assert self # Your own custom logic here
return {"toolset": "other_toolset"}
generic_block.context = types.MethodType(context, generic_block)
# completely replace existing block
from conan.tools.cmake import CMakeToolchain
def generate(self):
tc = CMakeToolchain(self)
# this could go to a python_requires
class MyGenericBlock:
template = "HelloWorld"
def context(self):
return {}
tc.blocks["generic_system"] = MyGenericBlock
# add a completely new block
from conan.tools.cmake import CMakeToolchain
def generate(self):
tc = CMakeToolchain(self)
# this could go to a python_requires
class MyBlock:
template = "Hello {{myvar}}!!!"
def context(self):
return {"myvar": "World"}
tc.blocks["mynewblock"] = MyBlock
可以使用配置中的 tools.cmake.cmaketoolchain:enabled_blocks 选择哪些块处于活动状态。这是一个块列表,因此执行
[conf]
tools.cmake.cmaketoolchain:enabled_blocks=["generic_system"]
将仅留下 generic_system 块,并丢弃所有其他块。例如,当用户提供自己的工具链文件时,他们不需要 Conan CMakeToolchain 定义任何标志或 CMake 变量,除了为了找到依赖项而必要的路径。在这种情况下,应该能够执行类似的操作
[conf]
tools.cmake.cmaketoolchain:user_toolchain+=my_user_toolchain.cmake
tools.cmake.cmaketoolchain:enabled_blocks=["find_paths"]
有关这些块的更多信息,请查看源代码。
查找依赖项路径¶
生成的 conan_toolchain.cmake 在其 find_paths 块中包含有关变量的信息,例如 CMAKE_PROGRAM_PATH、CMAKE_LIBRARY_PATH、CMAKE_INCLUDE_PATH 等,这些变量允许 CMake 运行 find_program()、find_file() 和其他特殊的“查找器”例程,这些例程在没有通过整体推荐的 find_package() 显式包和目标定义的情况下找到工件。
使用新的孵化中的 CMakeConfigDeps,conan_toolchain.cmake 块中的 find_paths 不再自行定义信息,而是加载由 CMakeConfigDeps 生成器生成的新文件,即 conan_cmakedeps_paths.cmake 文件。 这样,创建依赖信息由 CMakeConfigDeps 生成器负责,并且该新文件可以在无法传递工具链的一些场景中使用。
交叉构建¶
generic_system 块包含一些基本的交叉构建能力。 在一般情况下,用户希望提供他们自己的用户工具链,定义所有具体内容,这可以通过配置 tools.cmake.cmaketoolchain:user_toolchain 来完成。 如果定义了此 conf 值,generic_system 块将包含提供的文件或文件,但不会进一步定义任何用于交叉构建的 CMake 变量。
如果未定义 user_toolchain 并且 Conan 检测到正在进行交叉构建,因为构建和主机配置文件包含不同的操作系统或架构,它将尝试定义以下变量
CMAKE_SYSTEM_NAME:如果定义了tools.cmake.cmaketoolchain:system_name配置,则使用它,否则它将尝试自动检测它。 如果是 Android 系统(由其他块管理),或者 x86_64、sparc 和 ppc 系统中的 64 位到 32 位构建,此块将考虑交叉构建。CMAKE_SYSTEM_VERSION:如果定义了tools.cmake.cmaketoolchain:system_versionconf,则使用它,否则使用定义的os.version子集(主机)。 在 Apple 系统上,此os.version将转换为相应的 Darwin 版本。CMAKE_SYSTEM_PROCESSOR:如果定义了tools.cmake.cmaketoolchain:system_processorconf,则使用它,否则使用定义的arch设置(主机)。
macOS 中的通用二进制支持¶
警告
此功能是实验性的,可能会发生重大更改。有关更多信息,请参阅 Conan 稳定性 部分。
从 Conan 2.2.0 开始,CMakeToolchain 提供了对 macOS 上构建通用二进制文件的初步支持。 要在 Conan 中为通用二进制文件指定多个架构,请在设置中定义架构时使用 | 分隔符。 这种方法可以传递架构列表。 例如,运行
conan create . --name=mylibrary --version=1.0 -s="arch=armv8|x86_64"
将创建一个包含 armv8 和 x86_64 架构的 mylibrary 的通用二进制文件,方法是在 conan_toolchain.cmake 文件中将 CMAKE_OSX_ARCHITECTURES 设置为 arm64;x86_64。
警告
重要的是要注意,此方法不适用于 CMake 或 Autotools 通过 CMakeToolchain 和 AutotoolsToolchain 以外的其他构建系统。
请注意,此功能主要用于构建用于发布目的的最终通用二进制文件。 Conan 管理每个架构一个二进制文件的默认行为通常提供更可靠和无忧的体验。 用户应谨慎,不要过度依赖此功能用于更广泛的用例。
参考¶
- class CMakeToolchain(conanfile, generator=None)¶
- generate()¶
此方法会将生成的文件保存到 conanfile.generators_folder
conf¶
CMakeToolchain 受以下 [conf] 变量影响
tools.cmake.cmaketoolchain:toolchain_file 用于替换
conan_toolchain.cmake的用户工具链文件。tools.cmake.cmaketoolchain:user_toolchain 要从
conan_toolchain.cmake文件包含的用户工具链列表。tools.android:ndk_path
ANDROID_NDK_PATH的值。tools.android:cmake_legacy_toolchain:
ANDROID_USE_LEGACY_TOOLCHAIN_FILE的布尔值。 仅当给定值时,它才会在conan_toolchain.cmake中定义。 这由 Android NDK 中指定的 CMake 工具链考虑,版本为r23c及更高版本。 如果通过tools.build:cflags或tools.build:cxxflags定义编译器标志,则可能需要将其设置为False,以防止 Android 的旧版 CMake 工具链覆盖这些值。 如果将其设置为False,请确保使用 CMake 3.21 或更高版本。tools.cmake.cmaketoolchain:system_name 在大多数情况下是不必要的,仅用于强制定义
CMAKE_SYSTEM_NAME。tools.cmake.cmaketoolchain:system_version 在大多数情况下是不必要的,仅用于强制定义
CMAKE_SYSTEM_VERSION。tools.cmake.cmaketoolchain:system_processor 在大多数情况下是不必要的,仅用于强制定义
CMAKE_SYSTEM_PROCESSOR。tools.cmake.cmaketoolchain:enabled_blocks 定义启用的块并丢弃其他块。
tools.cmake.cmaketoolchain:extra_variables:类似于字典的 Python 对象,指定 CMake 变量名称和值。 该值可以是纯字符串、数字或类似于字典的 Python 对象,该对象必须指定
value(字符串/数字)、cache(布尔值)、type(CMake 缓存类型)以及可选地docstring(字符串:默认为变量名称)和force(布尔值)键。 它可以覆盖 CMakeToolchain 定义的变量,用户自行承担风险。 例如:
[conf]
tools.cmake.cmaketoolchain:extra_variables={'MY_CMAKE_VAR': 'MyValue'}
结果是
set(MY_CMAKE_VAR "MyValue")
稍后将注入,以便它可以覆盖默认 Conan 变量。
另一个高级用法
tools.cmake.cmaketoolchain:extra_variables={'MyIntegerVariable': 42, 'CMAKE_GENERATOR_INSTANCE': '${ENV}/buildTools/'}
tools.cmake.cmaketoolchain:extra_variables*={'CACHED_VAR': {'value': '/var/run', 'cache': True, 'type': 'PATH', 'docstring': 'test cache var', 'force': True}}
结果是
set(MyIntegerVariable 42)
set(CMAKE_GENERATOR_INSTANCE "${ENV}/buildTools/")
set(CACHED_VAR "/var/run" CACHE BOOL "test cache var" FORCE)
此块注入 $,稍后将对其进行扩展。 它还在 conan_toolchain.cmake 中定义一个类型为 PATH 的缓存变量。
提示
使用 配置数据运算符 *= 来 更新(而不是重新定义)配置文件中或全局配置中已设置的 conf 变量。
tools.cmake.cmaketoolchain:toolset_arch:将在
conan_toolchain.cmake文件的CMAKE_GENERATOR_TOOLSET变量中添加,host=xxx说明符。tools.cmake.cmaketoolchain:toolset_cuda:(实验性)将在
conan_toolchain.cmake文件的CMAKE_GENERATOR_TOOLSET变量中添加,cuda=xxx说明符。tools.cmake.cmake_layout:build_folder_vars:设置、选项、
self.name和self.version以及常量const.uservalue,这些将生成不同的构建文件夹和不同的 CMake 预设名称。tools.cmake.cmaketoolchain:presets_environment:设置为
'disabled'以防止将环境部分添加到生成的 CMake 预设中。tools.cmake.cmaketoolchain:user_presets:(实验性)允许为 CMakeUserPresets.json 文件设置自定义名称或子文件夹。 空字符串将完全禁用文件生成。
tools.build:cxxflags 将附加到
CMAKE_CXX_FLAGS_INIT的额外 C++ 标志列表。tools.build:cflags 将附加到
CMAKE_C_FLAGS_INIT的额外纯 C 标志列表。tools.build:sharedlinkflags 将附加到
CMAKE_SHARED_LINKER_FLAGS_INIT的额外链接器标志列表。tools.build:exelinkflags 将附加到
CMAKE_EXE_LINKER_FLAGS_INIT的额外链接器标志列表。tools.build:defines 将由
add_definitions()使用的预处理器定义列表。tools.apple:sdk_path
CMAKE_OSX_SYSROOT的值。 在一般情况下,它是不需要的,并且将由设置值传递给 CMake。tools.apple:enable_bitcode 启用/禁用 Bitcode Apple Clang 标志的布尔值,例如
CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE。tools.apple:enable_arc 启用/禁用 ARC Apple Clang 标志的布尔值,例如
CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC。tools.apple:enable_visibility 启用/禁用 Visibility Apple Clang 标志的布尔值,例如
CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN。tools.build:sysroot 定义
CMAKE_SYSROOT的值。tools.microsoft:winsdk_version 根据 CMake 策略
CMP0149定义CMAKE_SYSTEM_VERSION或CMAKE_GENERATOR_PLATFORM。tools.build:compiler_executables 类似于字典的 Python 对象,指定编译器作为键,编译器可执行文件路径作为值。 这些键将映射如下:
c:将在 conan_toolchain.cmake 中设置CMAKE_C_COMPILER。cpp:将在 conan_toolchain.cmake 中设置CMAKE_CXX_COMPILER。RC:将在 conan_toolchain.cmake 中设置CMAKE_RC_COMPILER。objc:将在 conan_toolchain.cmake 中设置CMAKE_OBJC_COMPILER。objcpp:将在 conan_toolchain.cmake 中设置CMAKE_OBJCXX_COMPILER。cuda:将在 conan_toolchain.cmake 中设置CMAKE_CUDA_COMPILER。fortran:将在 conan_toolchain.cmake 中设置CMAKE_Fortran_COMPILER。asm:将在 conan_toolchain.cmake 中设置CMAKE_ASM_COMPILER。hip:将在 conan_toolchain.cmake 中设置CMAKE_HIP_COMPILER。ispc:将在 conan_toolchain.cmake 中设置CMAKE_ISPC_COMPILER。