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, andREMOVE_ATsupport only one index/valuePOP_BACKandPOP_FRONTdo not support getting the value into another out variable. Use C++ styleGETthenPOP_(BACK|FRONT).FILTERandTRANSFORMare 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()