在包含子项目的项目中设置 CMAKE_CONFIGURATION_TYPES 的位置
Where to set CMAKE_CONFIGURATION_TYPES in a project with subprojects
假设我有一个包含两个独立子项目的项目。如果我正确理解 cmake,我的想法是让一个根 CMakeLists.txt
定义一个 project(...)
,然后使用 add_subdirectory(...)
来包含子项目。每个子项目都有自己的 CMakeLists.txt
定义自己的项目。这样项目可以一起构建(使用根 cmake 文件)或单独构建(使用子项目 cmake 文件)。
我现在想换CMAKE_CONFIGURATION_TYPES
。我应该在根 CMakeLists.txt
或每个子项目中执行此操作,还是在两者中执行此操作?
在根目录中更改它意味着单独构建子项目会提供错误的配置类型;其他选项将复制 cmake 代码。我想我在这里遗漏了一些东西。
当在子项目目录中使用 add_subdirectory
时,您将几乎所有变量传播到该子项目中,这与 "subproject independency" 相矛盾。
相反,最好使用 execute_process()
中的嵌套 cmake
调用来构建和安装子项目。如果你想让一些子项目的定义可用于顶级项目,你需要在安装子项目时 "export" 这个定义。 This question/answer post 描述了如何做到这一点。
分解出设置依赖于配置的设置的代码。创建一个文件,例如 SetUpConfigurations.cmake
,内容如下:
if(NOT SET_UP_CONFIGURATIONS_DONE)
set(SET_UP_CONFIGURATIONS_DONE TRUE)
# No reason to set CMAKE_CONFIGURATION_TYPES if it's not a multiconfig generator
# Also no reason mess with CMAKE_BUILD_TYPE if it's a multiconfig generator.
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Profile" CACHE STRING "" FORCE)
else()
if(NOT CMAKE_BUILD_TYPE)
message("Defaulting to release build.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
# set the valid options for cmake-gui drop-down list
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Profile")
endif()
# now set up the Profile configuration
set(CMAKE_C_FLAGS_PROFILE "...")
set(CMAKE_CXX_FLAGS_PROFILE "...")
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "...")
endif()
然后include(..)
这个文件在CMakeLists.txt
的开头。
您有两种放置位置的选择 SetUpConfigurations.cmake
,这取决于您组织项目的方式,存储库:
快速又脏的方法:将此脚本复制并提交到每个需要它的项目中。它的位置将是固定的,相对于项目的 CMakeLists.txt
。所以你可以包含它,例如 include(${CMAKE_CURRENT_SOURCE_DIR}/<...>/SetUpConfigurations.cmake)
有规律的方法:使用您的自定义 CMake 脚本维护一个存储库,就像这个一样。每次使用 cmake
命令生成项目时,都会在 CMAKE_MODULE_PATH
变量中传递此存储库的路径:
cmake -DCMAKE_MODULE_PATH=<dir-of-cmake-script-repo> ...
在这种情况下,包含带有 include(SetUpConfigurations)
的脚本(没有 .cmake
扩展名)。
关于什么是多配置生成器的注释:
Xcode
和 Visual Studio
是多配置生成器。它们尊重 CMAKE_CONFIGURATION_TYPES
的值,但 CMAKE_BUILD_TYPE
没有效果,因为在处理 CMakeLists.txt
时没有定义具体配置。稍后将在 IDE 的用户界面上选择它。
另一方面,makefile 样式的生成器对 CMAKE_CONFIGURATION_TYPES
不感兴趣。 CMAKE_BUILD_TYPE
定义配置。它是 CMakeLists.txt
文件处理时的具体值,但仍然:永远不要根据 CMAKE_BUILD_TYPE
的值做出任何决定:
if(CMAKE_BUILD_TYPE STREQUAL "Release") # WRONG!
....
endif()
您的项目在多配置生成器中无法正常工作。
假设我有一个包含两个独立子项目的项目。如果我正确理解 cmake,我的想法是让一个根 CMakeLists.txt
定义一个 project(...)
,然后使用 add_subdirectory(...)
来包含子项目。每个子项目都有自己的 CMakeLists.txt
定义自己的项目。这样项目可以一起构建(使用根 cmake 文件)或单独构建(使用子项目 cmake 文件)。
我现在想换CMAKE_CONFIGURATION_TYPES
。我应该在根 CMakeLists.txt
或每个子项目中执行此操作,还是在两者中执行此操作?
在根目录中更改它意味着单独构建子项目会提供错误的配置类型;其他选项将复制 cmake 代码。我想我在这里遗漏了一些东西。
当在子项目目录中使用 add_subdirectory
时,您将几乎所有变量传播到该子项目中,这与 "subproject independency" 相矛盾。
相反,最好使用 execute_process()
中的嵌套 cmake
调用来构建和安装子项目。如果你想让一些子项目的定义可用于顶级项目,你需要在安装子项目时 "export" 这个定义。 This question/answer post 描述了如何做到这一点。
分解出设置依赖于配置的设置的代码。创建一个文件,例如 SetUpConfigurations.cmake
,内容如下:
if(NOT SET_UP_CONFIGURATIONS_DONE)
set(SET_UP_CONFIGURATIONS_DONE TRUE)
# No reason to set CMAKE_CONFIGURATION_TYPES if it's not a multiconfig generator
# Also no reason mess with CMAKE_BUILD_TYPE if it's a multiconfig generator.
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Profile" CACHE STRING "" FORCE)
else()
if(NOT CMAKE_BUILD_TYPE)
message("Defaulting to release build.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
# set the valid options for cmake-gui drop-down list
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Profile")
endif()
# now set up the Profile configuration
set(CMAKE_C_FLAGS_PROFILE "...")
set(CMAKE_CXX_FLAGS_PROFILE "...")
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "...")
endif()
然后include(..)
这个文件在CMakeLists.txt
的开头。
您有两种放置位置的选择 SetUpConfigurations.cmake
,这取决于您组织项目的方式,存储库:
快速又脏的方法:将此脚本复制并提交到每个需要它的项目中。它的位置将是固定的,相对于项目的
CMakeLists.txt
。所以你可以包含它,例如include(${CMAKE_CURRENT_SOURCE_DIR}/<...>/SetUpConfigurations.cmake)
有规律的方法:使用您的自定义 CMake 脚本维护一个存储库,就像这个一样。每次使用
cmake
命令生成项目时,都会在CMAKE_MODULE_PATH
变量中传递此存储库的路径:cmake -DCMAKE_MODULE_PATH=<dir-of-cmake-script-repo> ...
在这种情况下,包含带有 include(SetUpConfigurations)
的脚本(没有 .cmake
扩展名)。
关于什么是多配置生成器的注释:
Xcode
和 Visual Studio
是多配置生成器。它们尊重 CMAKE_CONFIGURATION_TYPES
的值,但 CMAKE_BUILD_TYPE
没有效果,因为在处理 CMakeLists.txt
时没有定义具体配置。稍后将在 IDE 的用户界面上选择它。
另一方面,makefile 样式的生成器对 CMAKE_CONFIGURATION_TYPES
不感兴趣。 CMAKE_BUILD_TYPE
定义配置。它是 CMakeLists.txt
文件处理时的具体值,但仍然:永远不要根据 CMAKE_BUILD_TYPE
的值做出任何决定:
if(CMAKE_BUILD_TYPE STREQUAL "Release") # WRONG!
....
endif()
您的项目在多配置生成器中无法正常工作。