CMake: create a list and iterate over it to set SOURCE properties.
01 Nov 2022I have wrangled with CMake for a few days; I needed to set compile options for all but one file in the target. After blundering for a while, it seemed like setting the soure properties for all of the files in one group, and then the other, might work (and it did work)!
Create a list
There’s some list()
options, but if you haven’t defined a variable, that won’t help much. So first we use set()
to create two lists,
set(a_SOURCES
file1.cpp
file1.hpp
file2.cpp
...
)
set(b_SOURCES
file20.cpp
file20.hpp
file21.cpp
...
)
Add the sources to a target with a list
Here, instead of listing all of the sources, we can just use the list(s). Super handy if you have multiple targets.
add_executable(my_PROGRAM ${a_SOURCES} ${b_SOURCES})
Iterate through the lists
This is a sort of silly example, apologies. I created two sets of compile option flags, a_FLAGS
and b_FLAGS
. Then, for each source file in each list, the compile options are set for that file. Note: inclusion of debugging and optimization flags in the CMakeLists.txt file is not the “cmake way”, where the preferred method is to use Debug or Release configurations and the command line, cmake -DCMAKE_BUILD_TYPE=Debug
etc., see a SO answer for more details.
set(a_FLAGS -Wextra -Wall -g3 -fno-inline -O0 -fopenmp CACHE STRING "; list of flags usually used w. my projects")
set(b_FLAGS -Wextra -Wall -g3 CACHE STRING "; smaller list")
foreach(loopVAR IN LISTS a_SOURCES)
message("Source from a SOURCES: ${loopVAR}")
set_property(SOURCE ${loopVAR} PROPERTY COMPILE_OPTIONS ${a_FLAGS})
endforeach()
foreach(loopVAR IN LISTS b_SOURCES)
message("Source from b SOURCES: ${loopVAR}")
set_property(SOURCE ${loopVAR} PROPERTY COMPILE_OPTIONS ${b_FLAGS})
endforeach()
Debugging
A neat tool is CMakePrintHelpers
. I use it for debugging as follows:
include(CMakePrintHelpers)
...
get_source_file_property(myCompileCheck file20.cpp COMPILE_OPTIONS)
cmake_print_variables(myCompileCheck)
And then from the cmake output you can see that everything is set the way you expect, before getting into a build.
Version
I’m using cmake version 3.24.2.