user3557896
user3557896

Reputation: 1

Pass multiple list to CMake without a splitting keyword

I need to pass several lists to an own add_executable macro. These lists are used in this macro. The code looks like this:

set(LIST_FILES
  foo.cpp
  bar.cpp
)

set(LIST_LIBRARIES
 libpng
 libfancy
)

add_own_executable(fancyfoobar ${LIST_FILES} ${LIST_LIBRARIES})

# The CMake macro
macro(add_own_executable target files libraries)
  # Do stuff
endmacro()

The problem is, that target has the value "fancyfoobar" (OK), but the parameter list is a single list item and not the whole list, means files have the value foo.cpp (NOT OK). ?libraries will have the value bar.cpp (NOT OK).

Is there a way to pass a "list" as a list and not in a way, that are items are appended. I think I have to introduce keywords, so I can iterate over all items and know when files/libraries are starting - is there a way to avoid such an "annoying solution" like this:

add_own_executable(fancyfoobar FILES ${LIST_FILES} LIBRARIES ${LIST_LIBRARIES})

Upvotes: 0

Views: 2634

Answers (3)

McManip
McManip

Reputation: 300

Since CMake macros perform a single-level of text replacement, one way to pass lists to a macro is to actually pass the names of lists and then inside the macro double dereference the lists.

For example:

Your macro:

macro(add_own_executable target files libs)
  add_executable(${target} ${${files}})
  target_link_libraries(${target} ${${libs}})
endmacro()

Usage:

set(LIST_FILES
  foo.cpp
  bar.cpp
)

set(LIST_LIBRARIES
  libpng
  libfancy
)

add_own_executable(fancyfoobar LIST_FILES LIST_LIBRARIES)

In this example, the call add_own_executable(fancyfoobar LIST_FILES LIST_LIBRARIES) would become equivalent to

add_executable(fancyfoobar ${LIST_FILES})
target_link_libraries(fancyfoobar ${LIST_LIBRARIES})

as CMake would do a single text replace for every occurrence of ${target}, ${files}, and ${libs}.

Upvotes: 4

fenix688
fenix688

Reputation: 2615

Try to pass the lists with double quotes:

add_own_executable(fancyfoobar "${LIST_FILES}" "${LIST_LIBRARIES}")

Upvotes: 4

Joel
Joel

Reputation: 2035

You can foreach-it the argument given in the macro to form another list, is not intuitive but It'll serve as workaround:

cmake_minimum_required (VERSION 3.0)
project ("dummy" VERSION "1.0" LANGUAGES C)

set (
    _FILES
        hello.c
        world.c
)

macro(show_them)
    set (TMP)
    foreach (ITEM ${ARGV})
        set (TMP "${TMP} ${ITEM}")
    endforeach ()
    message ("- Your list: [${TMP}]")
endmacro ()


show_them (${_FILES})

Upvotes: 0

Related Questions