The other answer was not enough for me as it flattens all the filesystem hierarchy. I don't know other simple solutions so I just recursed all the hierarchy and create filters accordingly. In this way the filter is the equivalent of a filesystem view:
# EXCLUDE_CURRENT to exclude source in the current directory
function(glob_source sources curdir)
glob_source_recurse(sources ${curdir} "" ${ARGN})
# Need to set sources in the parent scope https://stackoverflow.com/a/50953059/213871
set(${sources} ${${sources}} ${SOURCE_FILES} PARENT_SCOPE)
endfunction()
macro(glob_source_recurse sources curdir prefix)
subdirlist(subdirs ${curdir})
foreach(subdir ${subdirs})
if ("${prefix}" STREQUAL "")
glob_source_recurse(sources "${curdir}/${subdir}" "${subdir}")
else()
glob_source_recurse(sources "${curdir}/${subdir}" "${prefix}/${subdir}")
endif()
endforeach()
set (extra_macro_args ${ARGN})
if (NOT extra_macro_args STREQUAL "EXCLUDE_CURRENT")
file(GLOB SOURCE_FILES "${curdir}/*.cpp" "${curdir}/*.h" "${curdir}/*.hpp")
source_group("${prefix}" FILES ${SOURCE_FILES})
list(APPEND sources ${SOURCE_FILES})
endif()
endmacro()
It can be used with:
glob_source(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR})
You can edit according to your needs.