I currently define a ${SRCS}
variable in the CMakeLists.txt
file in my projects root directory, listing every source file required for my executable:
SET (SRCS main.cpp
dir1/file1.cpp
dir1/file2.cpp
dir2/file3.cpp
dir2/file4.cpp)
How can I distribute this list across the CMakeLists.txt
files in each of the subdirectories? That is:
CMakeLists.txt
Adds main.cpp to SRCS and subdirectories dir1 and dir2
dir1/CMakeLists.txt
Adds file1.cpp, file2.cpp to SRCS
dir2/CMakeLists.txt
Adds file3.cpp, file4.cpp to SRCS
It's best to hide all the details of setting up the variable SRCS
in a CMake macro. The macro can then be called in all the project CMake list files to add sources.
In the CMakeLists.txt
in the project root folder, add the following macro definition:
macro (add_sources)
file (RELATIVE_PATH _relPath "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
foreach (_src ${ARGN})
if (_relPath)
list (APPEND SRCS "${_relPath}/${_src}")
else()
list (APPEND SRCS "${_src}")
endif()
endforeach()
if (_relPath)
# propagate SRCS to parent directory
set (SRCS ${SRCS} PARENT_SCOPE)
endif()
endmacro()
add_sources(main.cpp)
add_subdirectory(dir1)
add_subdirectory(dir2)
message(STATUS "${SRCS}")
The macro first computes the path of the source file relative to the project root for each argument. If the macro is invoked from inside a project sub directory the new value of the variable SRCS needs to be propagated to the parent folder by using the PARENT_SCOPE option.
In the sub directories, you can simply add a macro call, e.g. in dir1/CMakeLists.txt
add:
add_sources(file1.cpp file2.cpp)
And in dir2/CMakeLists.txt
add:
add_sources(file3.cpp file4.cpp)
A similar macro like the one suggested by sakra was posted on the CMake mailing list by Michael Wild [1]. It uses global properties instead of propagating a variable upwards.
[1] http://www.cmake.org/pipermail/cmake/2010-March/035992.html
In dir1/CMakeLists.txt put this:
set(SRCS ${SRCS} file1.cpp PARENT_SCOPE)
If that wouldn't work, the only solution is to
set(DIR1_SRCS "file1.cpp" PARENT_SCOPE)
and then in ./CMakeLists.txt
set(SRCS ${DIR1_SRCS} ${DIR2_SRCS})