【问题标题】:Should I cache CMAKE_BUILD_TYPE?我应该缓存 CMAKE_BUILD_TYPE 吗?
【发布时间】:2023-03-03 17:33:02
【问题描述】:

如果您不设置CMAKE_BUILD_TYPE,则默认情况下它不会被缓存。我应该缓存它吗?例如我应该有:

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Release" )
  set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Type of build (Debug, Release etc." FORCE)
endif()

或者只是:

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Release" )
endif()

还是真的不重要?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    CMAKE_BUILD_TYPE 的缓存对于 cmake-gui 很有用:您项目的用户能够以一种很好的方式更改构建类型。

    有一个很好的模板可以设置默认CMAKE_BUILD_TYPE from developers:

    # Set a default build type if none was specified
    if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
      message(STATUS "Setting build type to 'Debug' as none was specified.")
      set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
      # Set the possible values of build type for cmake-gui
      set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
        "MinSizeRel" "RelWithDebInfo")
    endif()
    

    【讨论】:

    • 如果有“配置类型”,为什么没有“构建类型”?
    • 定义了CMAKE_CONFIGURATION_TYPES 变量意味着构建工具是多重配置 - 它可以一次配置多个构建类型。对于这样的工具(例如 Visual Studio),具体的构建类型在配置时是未知的,所以CMAKE_BUILD_TYPE 变量是没有意义的。
    【解决方案2】:

    CMAKE_BUILD_TYPE 在 CMake 的缓存中

    用户通常会通过命令行使用cmake -D ... 定义CMAKE_BUILD_TYPE。所以这确实会生成一个缓存条目。

    即使您没有为单个配置生成文件生成器提供CMAKE_BUILD_TYPE,CMake 也会自动create an empty cache entry(因此用户可以选择例如cmake-gui):

    //Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
    // CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
    CMAKE_BUILD_TYPE:STRING=
    

    如果 CMake 的平台/编译器定义通过 CMAKE_BUILD_TYPE_INIT 没有为 CMAKE_BUILD_TYPE 提供默认值,例如 Windows-MSVC

    # default to Debug builds
    set(CMAKE_BUILD_TYPE_INIT Debug)
    

    CMAKE_BUILD_TYPE 设置默认值

    所以是的,如果您想强制使用 GUI 中可见的默认值,请设置缓存变量(请参阅@Tsyvarev 答案)。

    我通常不强制缓存默认值,如果没有给出,我只是设置一个临时值。这允许例如我的项目将用作子项目。

    但这更多地取决于您的个人品味。

    在我的项目中,那些默认的 CMAKE_BUILD_TYPE 检查看起来有点复杂,因为我允许更多用例:

    # Make RelWithDebInfo the default (it does e.g. add '-O2 -g -DNDEBUG' for GNU)
    #   If not in multi-configuration environments, no explicit build type 
    #   is set by the user and if we are the root CMakeLists.txt file.
    if (NOT CMAKE_CONFIGURATION_TYPES AND 
        NOT CMAKE_NO_BUILD_TYPE AND
        NOT CMAKE_BUILD_TYPE AND
        CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
        set(CMAKE_BUILD_TYPE RelWithDebInfo)
    endif()
    
    if (CMAKE_BUILD_TYPE)
        string(TOUPPER "_${CMAKE_BUILD_TYPE}" MY_PROJECT_BUILD_TYPE_EXT)
    endif() 
    
    # Choose a configuration for our compiler tests
    if (NOT CMAKE_CONFIGURATION_TYPES AND 
        NOT CMAKE_NO_BUILD_TYPE)
        set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}")
    else()
        set(CMAKE_TRY_COMPILE_CONFIGURATION RelWithDebInfo)
    endif()
    

    但也许我应该更新此代码以考虑新的GENERATOR_IS_MULTI_CONFIG 全局属性(而不是检查CMAKE_NO_BUILD_TYPE)。

    参考文献

    【讨论】:

    • 我实际上并没有完全关注,尤其是 w.r.t.子项目和 com “编译配置与“构建类型”。
    • @einpoklum 如果我的项目通过add_subdirectory() 用作子项目,则不应设置/强制全局属性。因此,如果您的父项目没有给出默认值,那么您也不应该这样做。但正如我所说,这更多的是品味问题,这里的重要部分是CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR 检查。
    猜你喜欢
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多