CMake ExternalProject pass lists

CMake ExternalProject builds arbitrary projects without interacting with the top level CMake project. Via ExternalProject, CMake can build child projects for virtually any build system including Make, Autotools, Meson, CMake, etc. A distinct technique is needed to pass a CMake list to ExternalProject. As a reminder, CMake lists are defined as semicolon-separated strings.

ExternalProject example of passing lists:

include(ExternalProject)

set(my_list "apple;cat")

ExternalProject_Add(CHILD1
# project url/repo omitted for simplicity

CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/child1 -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING:BOOL=false  # arbitrary

CMAKE_CACHE_ARGS -Dmyvar:STRING=${my_list}
)

In this example the CMAKE_ARGS are arbitrary, we just put some typical arguments. The key syntax to observe are that CMAKE_CACHE_ARGS is used to pass any lists. A reason this is necessary is that CMAKE_ARGS is passed as a command line. CMAKE_ARGS can also have problems if many long arguments are used, particularly on Windows where the maximum command line length could be exceeded. We don’t use CMAKE_CACHE_ARGS carte blanche because some arguments may not be intended to be cache variables.

NOTE: the variable type must be passed to CMAKE_CACHE_ARGS, as when setting any cache variable.