alternative to GLOB?

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)

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")
    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}")
	list(APPEND resolved_filelist "${filename}")
  set(${return_var} "${resolved_filelist}" PARENT_SCOPE)
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?

You certainly could do that.

I wonder why you feel the need to support multiple build systems, especially if you’re concerned about maintainability. For any non-trivial project, maintaining just the CMake code is a large task.


I wonder why you feel the need to support multiple build systems

I don’t need to for anything I’m doing now.

1 Like