6

假设我有一个包含两个独立子项目的项目。如果我对 cmake 的理解正确,那么想法是让一个根CMakeLists.txt定义 aproject(...)然后使用add_subdirectory(...)它来包含子项目。每个子项目都有自己CMakeLists.txt定义的项目。这种方式可以一起构建项目(使用根 cmake 文件)或单独构建(使用子项目 cmake 文件)。

我现在想更改CMAKE_CONFIGURATION_TYPES. 我应该在根CMakeLists.txt或每个子项目中执行此操作,还是两者都执行?

在根目录中更改它意味着单独构建子项目会提供错误的配置类型;其他选项将复制 cmake 代码。我想我在这里遗漏了一些东西。

4

2 回答 2

14

分解出设置依赖于配置的设置的代码。例如,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()

然后这个文件以'sinclude(..)开头。CMakeLists.txt

关于放置位置,您有两种选择SetUpConfigurations.cmake,这取决于您如何组织项目、存储库:

  1. quick'n'dirty 方法:将此脚本复制并提交到每个需要它的项目中。相对于项目的位置,它的位置是固定CMakeLists.txt的。所以你可以包括它,例如,include(${CMAKE_CURRENT_SOURCE_DIR}/<...>/SetUpConfigurations.cmake)

  2. 规范的方式:使用您的自定义 CMake 脚本维护一个存储库,例如这个。每次使用命令生成项目时,都会在变量cmake中传递此存储库的路径:CMAKE_MODULE_PATH

    cmake -DCMAKE_MODULE_PATH=<dir-of-cmake-script-repo> ...
    

include(SetUpConfigurations)在这种情况下,包括带有(无.cmake扩展名)的脚本。

关于什么是多配置生成器的注释:

Xcode并且Visual Studio是多配置生成器。它们尊重 的值CMAKE_CONFIGURATION_TYPESCMAKE_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()

您的项目将无法在多配置生成器中按预期工作。

于 2015-07-21T20:09:54.333 回答
1

add_subdirectory子项目目录中使用时,您将几乎所有变量传播到该子项目中,这与“子项目独立性”相矛盾。

相反,最好使用cmakeinside 嵌套调用来构建和安装子项目execute_process()。如果您想让某些子项目的定义可用于顶级项目,则需要在安装子项目时“导出”这些定义。这个问题/答案帖子描述了如何做到这一点。

于 2015-07-21T18:34:43.757 回答