Skip to main content

kmpkg_list

A replacement for CMake's list() function which improves handling of elements with internal semicolons, such as other lists.

Usage

kmpkg_list(SET <out-var> [<element>...])
kmpkg_list(<COMMAND> <list-var> [<other-arguments>...])

Notes

Use kmpkg_list() instead of list() whenever it is a requirement to correctly handle lists of lists.

kmpkg_list() supports all the subcommands of the built-in list() function, with the following restrictions:

  • GET, REMOVE_ITEM, and REMOVE_AT support only one index/value
  • POP_BACK and POP_FRONT do not support getting the value into another out variable. Use C++ style GET then POP_(BACK|FRONT).
  • FILTER and TRANSFORM are unsupported.

kmpkg_list also adds a kmpkg_list(SET) subcommand. This subcommand supports correctly creating a list of lists.

See the CMake documentation for list() for more information.

Remarks on Zero-Element lists

The most major weirdness is due to "" pulling double-duty as "list of zero elements", and "list of one element, which is empty". kmpkg_list always uses the former understanding. This can cause weird behavior, for example:

set(lst "")
kmpkg_list(APPEND lst "" "")
# lst = ";"

This is because you're appending two elements to the empty list. One very weird behavior that comes out of this would be:

set(lst "")
kmpkg_list(APPEND lst "")
# lst = ""

since "" is the empty list, we append the empty element and end up with a list of one element, which is empty. This does not happen for non-empty lists; for example:

set(lst "a")
kmpkg_list(APPEND lst "")
# lst = "a;"

only the empty list has this odd behavior.

Examples

Creating a list

kmpkg_list(SET foo_param)
if(DEFINED arg_FOO)
kmpkg_list(SET foo_param FOO "${arg_FOO}")
endif()

Appending to a list

set(OPTIONS -DFOO=BAR)
if(KMPKG_TARGET_IS_WINDOWS)
kmpkg_list(APPEND OPTIONS "-DOS=WINDOWS;FOO")
endif()

Popping the end off a list

if(NOT list STREQUAL "")
kmpkg_list(GET list end -1)
kmpkg_list(POP_BACK list)
endif()

Source

scripts/cmake/kmpkg_list.cmake