gpt4 book ai didi

recursion - Cmake设置变量是递归的吗?

转载 作者:行者123 更新时间:2023-12-02 10:20:12 25 4
gpt4 key购买 nike

我正在尝试修改某个目录下所有目录的编译器标志(即递归地修改所有当前目录子目录及其所有子目录)。所以我找到了here有两种方法:

add_directory(dir1)
# ...
add_directory(dirN)

add_compile_options(flag1 flag2 ...)
# or for CMake versions < 3.0 to do something more like:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} flag1 flag2 ...")

add_compile_options 的手册页非常清楚地表明效果将是“当前目录及以下”(这就是我想要的),但对于 set(CMAKE_CXX_FLAGS ...)我不太确定。

Cmake 设置变量是否递归?

最佳答案

简短的回答是,每个子目录都有自己的变量范围,并在 add_subdirectory() 调用时使用当前变量值的副本进行初始化。

有关详细答案,请参阅 What's the CMake syntax to set and use variables?

目录和目标属性与(全局)变量

add_compile_options() 之间存在差异。和 CMAKE_CXX_FLAGS由 CMake 处理:

  • 您使用 add_compile_options() 指定的所有内容都会附加到 COMPILE_OPTIONS目录属性。然后,“此属性用于在创建目标时初始化 COMPILE_OPTIONS 目标属性”,使用 add_library()add_executable()

    当解析器调用 add_subdirectory() 时,目录属性的当前状态用于初始化子目录属性。

  • CMAKE_CXX_FLAGS是一个全局缓存变量。您可以通过定义本地目录范围变量(隐藏全局缓存变量)来扩展/覆盖它。

    这些变量的上下文被复制到 add_subdirectory() 上的子目录作用域中(传播到子目录)。

    CMake 会在每个 CMakeLists.txt 文件的末尾查找其值,并将其应用于同一 CMakeLists.txt 中的所有 objective-c ode>(允许延迟声明,另请参阅下面的完整公式测试代码)。

  • 因此,对于 CMake 版本 < 3.0,相当于 add_compile_options()add_definitions() 。功能仍然存在,但将定义与编译选项混合在一起很奇怪。因此 add_compile_options() 被发明了。

编译器标志的完整生成器公式

它位于 CMake 的代码中(请参阅 cmCommonTargetGenerator::GetFlags()cmLocalGenerator::AddCompileOptions()cmLocalGenerator::AddLanguageFlags() )。

此示例显示了一个没有导出的 DEBUG 构建配置库,未考虑基于功能的标志或诸如 CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDESCMAKE_QUOTE_INCLUDE_PATHS 之类的内容:

  CMAKE_CXX_FLAGS       // as set at the end of target's CMakeLists.txt
+ CMAKE_CXX_FLAGS_DEBUG

+ Include Directories // pefixed with CMAKE_INCLUDE_FLAG_CXX/CMAKE_INCLUDE_SYSTEM_FLAG_CXX

(CMAKE_INCLUDE_CURRENT_DIR) ?
+ CMAKE_CURRENT_SOURCE_DIR + CMAKE_CURRENT_BINARY_DIR
+ CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
+ Target[INCLUDE_DIRECTORIES]
+ DependingTargets[INTERFACE_INCLUDE_DIRECTORIES]

+ Define Flags // compiler flags given with add_definitions()
+ Target[COMPILE_FLAGS] // deprecated
- Filtered by CMAKE_CXX_FLAG_REGEX
+ Target[COMPILE_OPTIONS]
+ DependingTargets[INTERFACE_COMPILE_OPTIONS]

测试代码

为了更好地理解,这里是我用于测试编译器选项的代码和我得到的结果:

注意:通常我会使用 add_definitions()target_compile_definitions() 而不是 add_compile_options()target_compile_options() 设置编译器定义,但为了演示编译器选项的传播,我(错误)使用了 -D 标志。

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

project(CxxFlagsTest)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCXX_FLAG")
add_compile_options("-DCOMPILE_OPTION")

add_subdirectory(lib)

file(WRITE main.cpp "int main() { return 0; }")
add_executable(main main.cpp)
target_link_libraries(main lib)

target_compile_options(main PRIVATE "-DMAIN_COMPILE_OPTION")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLATE_CXX_FLAG")

get_target_property(_main_compile_options main COMPILE_OPTIONS)
message(STATUS "main COMPILE_OPTIONS: ${_main_compile_options}")
get_directory_property(_root_compile_options COMPILE_OPTIONS)
message(STATUS "root COMPILE_OPTIONS: ${_root_compile_options}")
message(STATUS "root CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")

lib/CMakeLists.txt

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSUB_CXX_FLAG")
add_compile_options("-DSUB_COMPILE_OPTION")

file(WRITE lib.cpp "")
add_library(lib lib.cpp)

target_compile_options(lib PUBLIC "-DLIB_COMPILE_OPTION")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLATE_SUB_CXX_FLAG")

get_target_property(_lib_compile_options lib COMPILE_OPTIONS)
message(STATUS "lib COMPILE_OPTIONS: ${_lib_compile_options}")
get_directory_property(_sub_compile_options COMPILE_OPTIONS)
message(STATUS "sub COMPILE_OPTIONS: ${_sub_compile_options}")
message(STATUS "sub CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")

将导致以下消息:

-- lib COMPILE_OPTIONS: -DCOMPILE_OPTION;-DSUB_COMPILE_OPTION;-DLIB_COMPILE_OPTION
-- sub COMPILE_OPTIONS: -DCOMPILE_OPTION;-DSUB_COMPILE_OPTION
-- sub CMAKE_CXX_FLAGS: ... -DCXX_FLAG -DSUB_CXX_FLAG -DLATE_SUB_CXX_FLAG
-- main COMPILE_OPTIONS: -DCOMPILE_OPTION;-DMAIN_COMPILE_OPTION
-- root COMPILE_OPTIONS: -DCOMPILE_OPTION
-- root CMAKE_CXX_FLAGS: ... -DCXX_FLAG -DLATE_CXX_FLAG

并设置以下预处理器定义:

lib

CXX_FLAG
SUB_CXX_FLAG
LATE_SUB_CXX_FLAG
COMPILE_OPTION
SUB_COMPILE_OPTION
LIB_COMPILE_OPTION

主要

CXX_FLAG
LATE_CXX_FLAG
COMPILE_OPTION
MAIN_COMPILE_OPTION
LIB_COMPILE_OPTION

这里有趣的部分是 LATE CXX 标志和传播链接库的 LIB 编译选项。

引用文献

关于recursion - Cmake设置变量是递归的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33828855/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com