可以从几乎所有地方设置CMake缓存变量(请参阅@ Florian' s What's the CMake syntax to set and use variables?)。我假设设定值在任何地方都可见,甚至是之前解析过的CMake列表,但事实并非如此。
${CMAKE_MYDEF}
。CMAKE_MYDEF
。add_subdirectory(A)
之前调用add_subdirectory(B)
。cmake_minimum_required(VERSION 3.7)
project(test)
add_executable(EXEC test.cpp)
target_compile_definitions(EXEC PRIVATE MYDEF=${CMAKE_MYDEF})
set(CMAKE_MYDEF "MyValue" CACHE STRING "")
CMAKE_MYDEF
具有所需的值?按照@ Florian的回答,这里显示了解决方案的改编示例:
cmake_minimum_required(VERSION 3.7)
project(test)
add_executable(EXEC test.cpp)
target_link_libraries(EXEC MyOtherLib)
add_library(MyOtherLib INTERFACE)
set(CMAKE_MYDEF "MyValue" CACHE STRING "")
target_compile_definitions(MyOtherLib INTERFACE MYDEF=${CMAKE_MYDEF})
答案 0 :(得分:1)
CMake处理脚本顺序,从顶级CMakeLists.txt
开始并逐个执行其行。
因此,如果在分配变量之前读取变量,则不会得到任何结果。该场景中唯一具体的 CACHE 变量可能是在之前的cmake
调用中分配该变量。
在分配之前使用变量需要占据一席之地通常会发出关于糟糕设计的信号。在许多情况下(即使使用遗留代码),可以优雅地修复设计。
强制CMake重新配置项目可以完成,例如touching current script:
强制重新配置,可以" cmake -E touch" 在目标构建期间以某种方式CMAKE_CURRENT_LIST_FILE 或者其他一些。
答案 1 :(得分:1)
是的,我完全使用@Tsyvarev's answer,CMake的解析器按顺序工作。所以变量 - 甚至是缓存的 - 或生成器表达式 - 无法读取变量 - 在这里都不好。
我只想根据A和B之间的依赖关系添加使用目标和目录属性的可能性:
当A
取决于B
时,例如
target_link_libraries(A PUBLIC B)
然后一个简单的
target_compile_definitions(B PUBLIC MYDEF=SOME_DEF)
会将必要的定义传播到A
。
当B
取决于A
且A
已知时,
target_link_libraries(B PUBLIC A)
target_compile_definitions(A PUBLIC MYDEF=SOME_OTHER_DEF)
如果您正在使用子目录,我建议将定义全局放在根CMakeLists.txt
中:
add_definitions(-DMYDEF=GLOBAL_DEF)
最后,包含子目录的完整变体允许B
决定该怎么做:
<强>的CMakeLists.txt 强>
cmake_minimum_required(VERSION 3.7)
project(test)
add_subdirectory(A)
add_subdirectory(B)
:一种\的CMakeLists.txt 强>
file(WRITE a.cpp [=[
#include <iostream>
#ifndef MYDEF
#define MYDEF "Hello from A!"
#endif
void a()
{
std::cout << MYDEF << std::endl;
}
]=])
add_library(A a.cpp)
<强>乙\的CMakeLists.txt 强>
file(WRITE b.cpp [=[
void a();
void main()
{
a();
}
]=])
add_executable(B b.cpp)
target_link_libraries(B A)
if (TARGET "A")
target_compile_definitions(A PRIVATE MYDEF="Hello from B!")
else()
set_property(
DIRECTORY ".."
APPEND PROPERTY
COMPILE_DEFINITIONS "MYDEF=\"Hello from Global!\""
)
endif()