I’ve commonly seen advice to avoid globbing for files because cmake won’t automatically rerun if a file is added.
Typically, people recommend to hardcode the list of files into a cmake variable.
This can be tedious to maintain, especially at the start of a project when the source files are changing more often, and it makes maintaining support for multiple build systems more difficult because the filelist is maintained in cmake code.
Instead of maintaining the list of files in the cmake code, would storing the file list in a newline separated file be reasonable?
something like
cmake_minimum_required(VERSION 3.4)
project(test_filelist)
function(read_filelist filelist_file return_var)
set(filelist "")
set(resolved_filelist "")
get_filename_component(fullpath_filelist "${filelist_file}" REALPATH)
if(NOT EXISTS "${fullpath_filelist}")
message(SEND_ERROR "filelist ${filelist_file} does not exist")
else()
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${fullpath_filelist}")
file(READ "${fullpath_filelist}" filelist)
string(REPLACE "\n" ";" filelist "${filelist}")
string(REGEX REPLACE ";[ \t\r\n]*$" "" filelist "${filelist}")
get_filename_component(filelist_dir "${fullpath_filelist}" DIRECTORY)
foreach(filename ${filelist})
if ("${filename}" STREQUAL "")
elseif (NOT IS_ABSOLUTE "${filename}")
list(APPEND resolved_filelist "${filelist_dir}/${filename}")
else()
list(APPEND resolved_filelist "${filename}")
endif()
endforeach()
endif()
set(${return_var} "${resolved_filelist}" PARENT_SCOPE)
endfunction()
read_filelist(src/filelist.txt filelist)
message(STATUS "filelist ${filelist}")
This would allow you to do something like
cd src; ls *.cpp > filelist.txt; cd ..
To update your list of files. This would be easy to maintain with a git hook or something.
I wasn’t sure whether I should post this on the code or development forum. This approach would be easier to use with a built-in cmake function, but I’m asking about coding best practice.
Can you think of any reasons to avoid this kind of approach?