4

taking inspiration from : https://cmake.org/cmake/help/v3.0/command/macro.html

I do:

macro(ARGS_TEST)
  message(WARNING "\nARGN: ${ARGN}\n")
  foreach(arg IN LISTS ARGN)
     message(WARNING "\n ARG : ${arg} \n")
  endforeach()
endmacro()

ARGS_TEST(test 1 2 3)

which prints:

ARGN: test;1;2;3

but nothing after this, meaning iteration over ARGN does not seem to be happening.

Anything I am missing ?

Answer to following question: Passing a list to a cmake macro

shows how to print the arguments as a list, but not how to iterate over them

Community
  • 1
  • 1
Vince
  • 3,979
  • 10
  • 41
  • 69
  • You miss the thing, that inside a macro `ARGN` is [not a normal variable](https://cmake.org/cmake/help/v3.7/command/macro.html). About overcoming this for lists see here: http://stackoverflow.com/questions/5248749/passing-a-list-to-a-cmake-macro – Tsyvarev Mar 08 '17 at 22:57
  • @Tsyvarev yep, but I am following the example from the doc --; About the possible duplicate, it does not seem to answer my question, it casts the list to a string rather than allowing to iterate over it (or I failed to understand the answer ?) – Vince Mar 08 '17 at 23:51
  • `I am following the example from the doc` - If you talk about the last example, it uses macro call **inside the function**. In that case macro takes *ARGN* variable *from the function*. Read it carefully. But the duplicate is actually wrong for your case, sorry. – Tsyvarev Mar 09 '17 at 07:46

1 Answers1

4

Macro argument aren't variables. So ARGN isn't treated like other lists in this context. I see two ways to work around this issue:

In my reworkings of your samples I made your messages STATUS messages to ease my testing. This should work with WARNING as well.

The first way is to make this a function:

function(ARGS_TEST_FUNCTION)
  message(STATUS "\nARGN: ${ARGN}\n")
  foreach(arg IN LISTS ARGN)
     message(STATUS "\n ARG : ${arg} \n")
  endforeach()
endfunction()

ARGS_TEST_FUNCTION(test 1 2 3)

Like this ARGN is a variable and is expanded as expected. If you were wanting to set values in this loop you will need to use set and PARENT_SCOPE. Using parent scope might not be possible if you are calling other macros and do not know every variables they intend to set.

Alternatively we can do the expansion ourselves and tell the foreach we are passing a list:

macro(ARGS_TEST)
  message(STATUS "\nARGN: ${ARGN}\n")
  foreach(arg IN ITEMS ${ARGN})
     message(STATUS "\n ARG : ${arg} \n")
  endforeach()
endmacro()

ARGS_TEST(test 1 2 3)

This came from the foreach page in the CMake documentation

Sqeaky
  • 1,876
  • 3
  • 21
  • 40