2011-09-30 111 views
1

我有一个宏观的CMake像这样:一种将常量列表传递给cmake宏的方法?

macro(foo a b) 
    list(FIND b ${a} is_found) 
endmacro() 

我尝试调用它像这样:

foo("test" foo;bar;test) 

这是行不通的。此外,这并不工作:

foo("test" "foo;bar;test") 

在任何情况下,我得到is_found等于-1的时候,其实它应该已经被发现。我怎样才能像我想要的那样快速通过列表?

回答

3

发生这种情况是因为宏和特殊值(如ARGN)的参数不是通常CMake意义上的变量。它们是字符串替换,很像c预处理器对宏的处理。

您可以输入参数复制到变量,下一次该变量列表中找到:

macro(foo a) 
    set(b "${ARGN}") 
    list(FIND b "${a}" is_found) 
endmacro() 

至于导致以下所有变种工作:

foo(test foo bar test foo) 
foo("test" foo bar test foo) 
foo(test foo;bar;test;foo) 
foo("test" foo;bar;test;foo) 
foo(test "foo;bar;test;foo") 
foo("test" "foo;bar;test;foo") 

更新,更通用的版本 - 在由“NEXTLIST”字隔开的几个列表中搜索:

macro(foo a) 
    set(is_found) 
    set(foo_current_list) 
    foreach(arg ${ARGN}) 
    if(arg STREQUAL "NEXTLIST") 
     list(FIND foo_current_list "${a}" foo_is_found) 
     list(APPEND is_found ${foo_is_found}) 
     set(foo_current_list) 
    else() 
     list(APPEND foo_current_list ${arg}) 
    endif() 
    endforeach() 
    list(FIND foo_current_list "${a}" foo_is_found) 
    list(APPEND is_found ${foo_is_found}) 
    unset(foo_is_found) 
    unset(foo_current_list) 
endmacro() 

foo (test bar bar bar NEXTLIST foo test NEXTLIST test test x test) 
message("${is_found}") #-1;1;0 
+0

谢谢,这个工程。我忘记了ARGN。另一种情况下,你有2个你想传入'foo'的列表? –

+0

如果你想通过几个列表,那么你需要以某种方式分开它们。您可以为每个列表引入一个命名参数,但在这种情况下,您不能简单地将以空格分隔的值列表复制到宏。或者类似于许多cmake命令,您可以使用特殊分隔符来区分您的参数。我用一个能够在多个列表中搜索的通用版本更新了答案。 –