Sorting source files and projects in folders with CMake and Visual Studio/Xcode

Sometimes Visual Studio and Xcode projects just get out of hand. The private project I’m working on has 130 subprojects, all in a single solution, that’s just too much to display in one window. And then I learnt that projects can actually be moved to folders, just like what is possible for files in a project (so you don’t have Source Files and Header Files, but something custom, for instance following the file hierarchy).

They are activated differently, and it’s sometimes not as straightforward, but it works great once it is set up. And as this works for Xcode projects and Visual Studio projects, I was really eager to sort out my Audio Toolkit main project, so it will be the basis of the tests here.

Sort files inside a project

So let’s start with sorting files inside a project. My personal preference is to have all files that are in the same folder in the same folder in a project as well, following the file system hierarchy. I’ve modified a macro I found online for this purpose:

MACRO(SOURCE_GROUP_BY_FOLDER target)
  SET(SOURCE_GROUP_DELIMITER "/")
  SET(last_dir "")
  SET(files "")
  FOREACH(file ${${target}_SRC} ${${target}_HEADERS})
    file(RELATIVE_PATH relative_file "${PROJECT_SOURCE_DIR}/${target}" ${file})
    GET_FILENAME_COMPONENT(dir "${relative_file}" PATH)
    IF (NOT "${dir}" STREQUAL "${last_dir}")
      IF (files)
        SOURCE_GROUP("${last_dir}" FILES ${files})
      ENDIF (files)
      SET(files "")
    ENDIF (NOT "${dir}" STREQUAL "${last_dir}")
    SET(files ${files} ${file})
    SET(last_dir "${dir}")
  ENDFOREACH(file)
  IF (files)
    SOURCE_GROUP("${last_dir}" FILES ${files})
  ENDIF (files)
ENDMACRO(SOURCE_GROUP_BY_FOLDER)

C++ files are stored in a variable named ${target}_SRC and headers in another called ${target}_HEADERS. All the files here will be sorted according to “${PROJECT_SOURCE_DIR}/${target}”. If target doesn’t exist, or if you want to create a different hierarchy, change this value.

The trick is managed through the SOURCE_GROUP command. It tells CMake to put one or more files in a specific folder inside a project. So here I used the file system hierarchy, but it is possible to sort the files by generation process, by type, by date…

Here is what it looks on ATKCore, compared to ATKDelay that hasn’t this macro:

Files hierarchy in Visual Studio
Files hierarchy in Visual Studio

Sort projects inside the solution

This is the part that I had more trouble finding on Internet. There seems to be pieces everywhere, but the documentation itself was not clear enough for me, so here we go.

To activate the folders in a solution, first this property has to be set:

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

Please note that this must be called before any target definition. Now each target can have some of its properties set. The one interesting here is FOLDER.

set_target_properties (ATKCore_static PROPERTIES
    FOLDER C++/static
)

For instance, the result in one of my solutions will be like this:

Project hierarchy in Visual Studio
Project hierarchy in Visual Studio

Of course, it makes sense when you have several hierarchies. A complete Audio Toolkit has Python, C++/static, C++/shared and tests as well.

Conclusion

On Linux, CMake generates directly Makefiles, and these don’t have a GUI behind. But for OS X and Windows developers, sorting and ordering files and projects makes it really easier to handle a project.

Buy Me a Coffee!
Other Amount:
Your Email Address:

2 thoughts on “Sorting source files and projects in folders with CMake and Visual Studio/Xcode”

  1. How can we have sub-libraries as sub-projects inside main project in XCode project navigator panel? In Xcode, with cmake, all sub-libraries comes under “Sources” folder of main xcodeproj.

Leave a Reply