[CMake] list subdirectories

Robert Fleming robert.fleming.multigen at gmail.com
Tue Feb 26 16:27:41 EST 2008


Hi,

I'm working on a rather large project with about 100 libraries, and
they have a consistent directory structure (although each library is
built slightly differently) that I would like to take advantage of.

Rather than creating CMakeLists.txt files for each library and it's
unit tests / samples, I thought I might try my hand at autogenerating
them from one top level CMakeLists.txt file.  Using configure_file()
I've got it to where I can generate them.  Next I created a big global
list containing information on how to build each library, and I create
unique variables (that can later be used in add_library()) for each
library using the parse_arguments() macro:

http://www.cmake.org/Wiki/CMakeMacroParseArguments

The global list sounds like it would be as much work as just creating
CMakeLists.txt files for each project, except thanks to
parse_arguments() I can omit information that's the same for each
library, plus I think maintaining this list (in one file) would be
easier than maintaining possibly hundreds of CMakeLists.txt files.

My problem is I'm not sure how to traverse a list of subdirectories
without first autogenerating CMakeLists.txt files for those
subdirectories that then contain further traversal information.  I've
tried this approach and it leads me into a nightmare of escaping
quotes.  I've written a macro that lists subdirectories, but it only
works for the directory Cmake is currently parsing, which is my top
level directory.  What I'd like to do is be able to pass the macro an
absolute path and have it return a list of subdirectories relative to
that path:

# Scans the current directory and returns a list of subdirectories.
Third parameter is 1 if you want relative paths returned.
# Usage: list_subdirectories(the_list_is_returned_here C:/cwd 1)
macro(list_subdirectories retval curdir return_relative)
  file(GLOB sub-dir RELATIVE ${curdir} *)
  set(list_of_dirs "")
  foreach(dir ${sub-dir})
    if(IS_DIRECTORY ${curdir}/${dir})
      if (${return_relative})
        set(list_of_dirs ${list_of_dirs} ${dir})
      else()
        set(list_of_dirs ${list_of_dirs} ${curdir}/${dir})
      endif()
    endif()
  endforeach()
  set(${retval} ${list_of_dirs})
endmacro()

If I had such a macro, I could traverse my directory hierarchy
entirely in the top level file, without having to put traversal
directions in subdirectory CMakeLists.txt.

I suppose to describe to you the larger problem I'm trying to solve is
generating a solution file with project files for each of the 100
libraries (also generating a separate solution file for the samples
would be great), each of which has it's own unique preprocessor
definitions, libraries to link to, etc.  If I could do this by taking
advantage of the consistent directory structure rather than having to
maintain 100 CMake files, that would be great.

I have thought about using the source_group() command along with some
complicated regexes, but I haven't tried that path yet, so far
focusing only on the autogenerating approach.

Thank you.


More information about the CMake mailing list