目标\为多个CMake目标编译\定义?
我发现在CMake中直接设置目标\为多个CMake目标编译\定义?,cmake,dry,idioms,compiler-options,Cmake,Dry,Idioms,Compiler Options,我发现在CMake中直接设置CFLAGS是一种不好的做法,相反,我应该使用target\u compile\u definitions()命令 好的,但是-如果我想对多个(独立)目标使用类似/相同的定义,该怎么办?我不想一次又一次地重复我自己。我看到了三种可能的方法: 首选的一种,使用它可以通过命令将编译器定义自传播到目标,具体取决于它 使用可为多个目标设置相同的定义 您仍然可以使用和的“旧命令”来修改目录属性(这将预先设置此目录范围内的所有目标属性) 工具书类 tl;dr:您可以在循环中
CFLAGS
是一种不好的做法,相反,我应该使用target\u compile\u definitions()
命令
好的,但是-如果我想对多个(独立)目标使用类似/相同的定义,该怎么办?我不想一次又一次地重复我自己。我看到了三种可能的方法:
- tl;dr:您可以在循环中迭代目标。
如果你有一堆具有一些共同/相似特性的目标,你可能想简单地在一个循环中操纵它们!记住——CMake不像GNU Make,它是一种成熟的脚本语言(嗯,有点像)。所以你可以写:
set(my_targets
foo
bar
baz)
foreach(TARGET ${my_targets})
add_executable(${TARGET} "${TARGET}.cu")
target_compile_options(${TARGET} PRIVATE "--some_option=some_value")
target_link_libraries(${TARGET} PRIVATE some_lib)
# and so on
set_target_properties(
${TARGET}
PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED YES
C_EXTENSIONS NO )
endforeach(TARGET)
您还可以初始化一个空的目标列表,然后在这里和那里添加,最后只对所有目标集中应用您的公共选项和设置
注意:在本例中,我添加了
PRIVATE
编译选项,但如果需要使用目标将其中一些选项传播到目标,可以将它们设置为PUBLIC
)。另一个简洁的解决方案是定义接口库目标(不生成任何二进制文件的伪目标)使用所有必需的属性和编译器定义,然后针对它链接其他现有目标
例如:
add_library(myfakelib INTERFACE)
target_compile_definitions(myfakelib INTERFACE MY_NEEDED_DEFINITION)
add_executable(actualtarget1 main1.cpp)
add_executable(actualtarget2 main2.cpp)
set_property(
TARGET actualtarget1 actualtarget2
APPEND PROPERTY LINK_LIBRARIES myfakelib
)
参考文献:
编辑了我的问题,排除了选项1——我不是这个意思。我会尝试选择2。。。它是有效的。谢谢。注意选项2。如果所有目标都在与
set\u属性
调用相同的目录中创建,这可能是一个好主意。现代的CMake依赖于您将设置本地化并接近目标的定义。我个人会考虑对目标属性进行“长距离”的操作。代码>在CMake中直接设置CFLAGS之类的错误做法——如果您谈论设置变量CMake_CXX_FLAGS,那么这取决于您想要设置的选项类型。无需完全避免设置变量。@Tsyvarev:添加了一个视频链接。@einpoklum对于我们的内部构建系统,我们公司的每个人都在所有构建中使用,我们直接设置CMAKE\u CXX\u标志
,因此它们对于所有目标都是相同的。在我们的情况下,这是有道理的。如果您希望开放项目的源代码,并让其他人通过ExternalProject使用您的CmakeList,那么这样做将被视为不好的做法,因为您将构建标志强加给您的用户。这取决于你的爱好situation@SteveLorimer-。。。让其他人通过ExternalProject使用您的CmakeList,那么这样做将被视为不好的做法
-ExternalProject不会影响project的CMAKE\u CXX\u标志
。你是说改为添加_子目录吗?@SteveLorimer:实际上,在第二个问题上,请注意,无论其他人是否通过ExternalProject使用您的CmakeList,或者只是用户在构建它,这都是不好的做法,因为如果用户使用不同的C/C++编译器和不同的标志语法,那么您可能会被任何一种方式搞砸。它必须是接口库目标吗?它难道不是某种普通的人造目标吗?另外,库目标会传播C语言属性吗?任何库目标都会传播属性,“接口”类型实际上是一种“人工”类型,不会产生任何二进制文件,正如我所提到的