Reputation: 60481
I have two questions relative to CMake
Assume that we have a variable ${MY_CURRENT_DIR}
that contains the path of a directory that contains several subdirectories : mydir1, mydir2 and mydir3. I want to detect these subdirectories and put their names into ${SUBDIRS}
(not the complete path of these directories, only their name). How to do that automatically ?
Assume that ${SUBDIRS}
contains "mydir1 mydir2 mydir3". How to replace
ADD_SUBDIRECTORY(mydir1)
ADD_SUBDIRECTORY(mydir2)
ADD_SUBDIRECTORY(mydir3)
by a loop over ${SUBDIRS}
?
Upvotes: 59
Views: 66588
Reputation: 31
@refaim answer didn't work for me with CMake 3.21.1, I had to do small changes:
MACRO(SUBDIRLIST result curdir)
FILE(GLOB children ${curdir}/*) # This was changed
SET(dirlist "")
FOREACH(child ${children})
IF(IS_DIRECTORY ${child}) # This was changed
LIST(APPEND dirlist ${child})
ENDIF()
ENDFOREACH()
SET(${result} ${dirlist})
ENDMACRO()
Upvotes: 3
Reputation: 63
For a modern simpler solution try this
For cmake 3.7 and above the GLOB module got a LIST_DIRECTORIES option
This link explains glob patterns
file(GLOB sources_list LIST_DIRECTORIES true YourGLOBPattern)
foreach(dir ${sources_list})
IF(IS_DIRECTORY ${dir})
add_subdirectory(${dir})
ELSE()
CONTINUE()
ENDIF()
endforeach()
Upvotes: 4
Reputation: 386
In regard to answer above: Use this macro:
MACRO(SUBDIRLIST result curdir)
FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
SET(dirlist "")
FOREACH(child ${children})
IF(IS_DIRECTORY ${curdir}/${child})
LIST(APPEND dirlist ${child})
ENDIF()
ENDFOREACH()
SET(${result} ${dirlist})
ENDMACRO()
Example:
SUBDIRLIST(SUBDIRS ${MY_CURRENT_DIR})
I had trouble with this FILE(GLOB command. (I'm on cmake 3.17.3) Otherwise the macro works great. I was getting FILE GLOB errors, something like "FILE GLOB requires a glob expression after the directory." (Maybe it didn't like RELATIVE and/or just using the curdir as the fourth paramter.)
I had to use:
FILE(GLOB children ${curdir}/*)
(taking out RELATIVE and the first ${curdir} (Please note my cmake version above, that could've been my issue (I'm unfamiliar with glob so far.).)
Upvotes: 3
Reputation: 1885
Use this macro:
MACRO(SUBDIRLIST result curdir)
FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
SET(dirlist "")
FOREACH(child ${children})
IF(IS_DIRECTORY ${curdir}/${child})
LIST(APPEND dirlist ${child})
ENDIF()
ENDFOREACH()
SET(${result} ${dirlist})
ENDMACRO()
Example:
SUBDIRLIST(SUBDIRS ${MY_CURRENT_DIR})
Use foreach
:
FOREACH(subdir ${SUBDIRS})
ADD_SUBDIRECTORY(${subdir})
ENDFOREACH()
Upvotes: 123