2011-09-30 24 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命令,您可以使用特殊分隔符來區分您的參數。我用一個能夠在多個列表中搜索的通用版本更新了答案。 –

相關問題