2012-07-21 117 views
25

CMake的名单基本上只是分号分隔的字符串,但如果你通过这样一个变量的命令时,它得到扩展到多个参数 - 例如,如何正确地将标志的CMake列表(分号-sep)传递给set_target_properties?

set(FLAGS f1 f2 f3) 
# now FLAGS == 'f1;f2;f3' 
add_custom_command(
    ... 
    COMMAND my_cmd ${FLAGS} 
    ... 
) 

将正确调用my_cmd f1 f2 f3

现在,如果我这样做与

set_target_properties(
    myTarget PROPERTIES 
    LINK_FLAGS "${LD_FLAGS}" 
) 

扩张不会发生,我结束了与包含分号单LD_FLAG - 无用的,而不是扩大它变成一个空格分隔的字符串。

有什么办法可以让我把一个列表传递给LINK_FLAGS属性(或任何属性)时,它会被扩展为多个参数而不仅仅是一个?

感谢, 丹

回答

13

我不认为set_target_properties可以自动完成扩张,但您可以使用string (REPLACE ...)扩大列表为空格分隔字符串:

string (REPLACE ";" " " LD_FLAGS_STR "${LD_FLAGS}") 
set_target_properties(
    myTarget PROPERTIES 
    LINK_FLAGS "${LD_FLAGS_STR}" 
) 
+8

这真的是最好的方法是什么?为什么CMake设计为使用与其自己的'set_target_properties'命令不兼容的列表格式? – 2015-12-01 00:06:29

+0

这种技术的主要问题一般在于,如果任何标志包含空格,它们将导致问题。如果可能的话(例如,如果包含外部提供的文件名,其中可能包含空格),将需要进行一些转义以保留参数中的空格。 – 2016-06-01 16:35:59

+1

B +++ T。它不起作用。 'string(REPLACE“;”“”DEST $ {SRC})'用一个空字符串替换分号。只有这样才能工作:'foreach(OPT $ {LD_FLAGS})set(LINK_FLAGS“$ {LINK_FLAGS} $ {OPT}”) endforeach()'。这将是非常有趣的,除非这个C++ + p不是当今最流行的构建工具。 – Ethouris 2016-10-19 16:51:37

2

我使用它像串

set(FLAGS " f1 f2 f3")

注意,在前面的空间,它让你连接其他标志集。

对于更复杂的项目,而不是如果 - 别人的,你也可以做一个双扩张招:

set(GCC_FLAGS " -Wl,--relax") 
set(DIAB_FLAGS " -tPPCE500ES:cross") 
set(MSVC_FLAGS " /RAINBOW_CRAP) 
# ... 
# ...LINUX_FLAGS, WINDOWS_FLAGS, etc... 


set_target_properties(
    myTarget PROPERTIES 
    LINK_FLAGS "${${COMPILER}_FLAGS} ${${SYSTEM}_FLAGS}" 
) 

# COMPILER and SYSTEM is set somewhere else, in toolchain files for example 
5

对于使用cmake的列表,列表中,使用

${LD_FLAG} 

对于使用一个cmake列表作为字符串,(即列表项用';'分隔),使用

"${LD_FLAG}" 

所以在你的情况下,只要删除“”应该是足够的。

+0

这是正确的解决方案,谢谢 – 2017-09-15 13:50:59

+0

奇怪,但这一个并没有为我工作,版本3.9 :('set_target_properties调用参数数量不正确.' – Andry 2017-10-21 19:26:34

+0

@Andry什么是它显示如果你插入“MESSAGE(”$ {LD_FLAG}“)”?“ – 2017-11-07 01:05:03

5

set_property命令是专为这个

http://www.cmake.org/cmake/help/v3.0/command/set_property.html

set_property(TARGET tgt PROPERTY LINK_FLAGS foo bar) 
+0

谁说这不是? – steveire 2015-03-16 18:56:26

+0

Steveire - 我错误地认为它不在2.8.11中,因为我试图将'set_target_properties(foo ...)'改为'set_properties(TARGET foo ......)'但是现在我看到p有区别命令名称的虚拟化(复数与单数)。正确的名称是'set_property'(以'y'结尾)。 – 2015-03-16 20:47:59

+0

是的,你可以用这个答案显示的方式使用set_property(),但CMake将LINK_FLAGS视为一个纯字符串,而不是一个列表 - 这意味着在这个答案中,链接传递一个参数,'foo; bar'。这很不幸。同样有趣的是,现在有一个'COMPILE_OPTIONS'属性是一个列表,但旧的'COMPILE_FLAGS'是一个纯字符串。 – 2016-06-01 16:23:26

相关问题