Archive for the ‘vs2010’ tag

Solution Folders with CMake (project_group())

with 5 comments

Update (2011.05.25): Native CMake support

In a frustrating case of less-than-intuitive usability, hard to locate documentation, and/or user error, the original post below on using Python to modify the Visual Studio solution to organize projects in folders is not necessary: CMake 2.8.3 does natively support solution folders.

The syntax is simple.  Here’s what I appended to the outer-most CMakeLists.txt in the Lx0 project to organize the sub-projects into folders (note – I have not tested this on any compiler other than VS2010 Professional):

#
# Organize projects into folders
#
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)

SET_PROPERTY(TARGET lxengine                PROPERTY FOLDER "Libs/LxEngine")
SET_PROPERTY(TARGET glgeom_benchmark        PROPERTY FOLDER "Libs/GLGeom")
SET_PROPERTY(TARGET glgeom_unittest         PROPERTY FOLDER "Libs/GLGeom")

SET_PROPERTY(TARGET sm_lx_cube_rain         PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_lx_cube_asteriods    PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_lxcanvas             PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_terrain              PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_raytracer            PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_lxcraft              PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_rasterizer           PROPERTY FOLDER "Samples/LxEngine")
SET_PROPERTY(TARGET sm_ogre_minimal         PROPERTY FOLDER "Samples/ThirdPartyLibs")
SET_PROPERTY(TARGET sm_v8_basic             PROPERTY FOLDER "Samples/ThirdPartyLibs")
SET_PROPERTY(TARGET cpp_smartptr            PROPERTY FOLDER "Samples/Cpp")

SET_PROPERTY(TARGET bm_lxvar                PROPERTY FOLDER "Benchmarks")
SET_PROPERTY(TARGET blendload               PROPERTY FOLDER "Sandbox")
SET_PROPERTY(TARGET elm_reference           PROPERTY FOLDER "Sandbox")
SET_PROPERTY(TARGET elm_function            PROPERTY FOLDER "Sandbox")
SET_PROPERTY(TARGET sandbox_shadergraph     PROPERTY FOLDER "Sandbox")
SET_PROPERTY(TARGET sb_fixedpoint           PROPERTY FOLDER "Sandbox")
SET_PROPERTY(TARGET ut_jsonparser           PROPERTY FOLDER "UnitTest")
SET_PROPERTY(TARGET ut_lx_vector            PROPERTY FOLDER "UnitTest")

 

Three parts worth noting:

  1. SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON) – for some reason you need to turn this feature on before you can use it (shouldn’t simply not using it be equivalent to it being off??)
  2. TARGET target name – as you might guess, after the name after the TARGET keyword should be the name of your executable or library as you define it elsewhere in the CMake project setup
  3. PROPERTY FOLDER “Folder/SubFolder” – use a forward slash to denote sub-folders

I’m hesitant to complain about tools I’ve done nothing to contribute to, but it is frustrating that CMake is an incredibly useful and powerful tool but is lacking in the usability department (e.g. unnecessarily unique syntax – why is this a TARGET PROPERTY and not a PROJECT_FOLDER() macro?, hard to track down / poorly organized documentation – I found this via a Google search that pointed me to a diff in the CMake git server such that I realized my earlier efforts were not also calling SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)).

CMake already supported exactly what I needed but it took non-trivial effort to just track down that it did!

Original Post (2010.12.16)

CMake supports the source_group() command for grouping files within a project. I like this feature as it maps well to how I organize projects conceptually.  CMake, however, appears to lack a means to create solution folders, i.e. folders for actually categorizing the projects themselves into a hierarchy.   With LxEngine, which has a lot of sub-projects – this would be a quite helpful feature for use with Visual Studio.  In other words, what is really desired (by me) is a project_group() CMake function.

In an effort to learn a tiny bit more Python – and to get the behavior I wanted (via a little less work than properly hacking the CMake sources to add project_group() functionality; though others have expressed interest and even possibly worked on such a feature, but as far as I can tell, it’s not yet a feature as of CMake 2.8.3), I put together a version 0.0 script for post-processing the Visual Studio 2010 solution file and inject the folder nesting that I want.  The result ends up with a project structure looking like this:

Solution Folders after post-processing

The script, as I mentioned, is definitely a version 0.0:

  • It’s not yet reusable
  • It’s hard-coded to the LxEngine project layout (but that’s easy to change)
  • It’s hard-coded to the Visual Studio 2010 file format
  • It’s low-quality Python code (apologies, I’m new to the language and just wanted to “get it to work”)
  • It’s a post-process rather than something CMake could invoke directly

However, it does work correctly – so if anyone wants to hack together their own temporary workaround to get solution folders/ project_group() functionality from CMake, feel free to use this code as a template.

The source is located here on github.

Update:

Despite the closed bug report on vtk.org, CMake 2.8.3 for windows does not appear to have a project_group() or project_folder() command.  Nor does setting a manual property via ‘set_property(TARGET mproject PROPERTY FOLDER “MyFolder”)’ seem to have any effect.  This is true even for the nightly build 2.8.3.20101215-g4bf09.  I am assuming from the comments in the bug that the changes must only exist in a branch and not the main line?

#
# Organize projects into folders
#
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
SET_PROPERTY(TARGET lxengine                PROPERTY FOLDER “Libs/LxEngine”)
SET_PROPERTY(TARGET glgeom_benchmark        PROPERTY FOLDER “Libs/GLGeom”)
SET_PROPERTY(TARGET glgeom_unittest         PROPERTY FOLDER “Libs/GLGeom”)
SET_PROPERTY(TARGET sm_lx_cube_rain         PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_lx_cube_asteriods    PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_lxcanvas             PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_terrain              PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_raytracer            PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_lxcraft              PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_rasterizer           PROPERTY FOLDER “Samples/LxEngine”)
SET_PROPERTY(TARGET sm_ogre_minimal         PROPERTY FOLDER “Samples/ThirdPartyLibs”)
SET_PROPERTY(TARGET sm_v8_basic             PROPERTY FOLDER “Samples/ThirdPartyLibs”)
SET_PROPERTY(TARGET cpp_smartptr            PROPERTY FOLDER “Samples/Cpp”)
SET_PROPERTY(TARGET bm_lxvar                PROPERTY FOLDER “Benchmarks”)
SET_PROPERTY(TARGET blendload               PROPERTY FOLDER “Sandbox”)
SET_PROPERTY(TARGET elm_reference           PROPERTY FOLDER “Sandbox”)
SET_PROPERTY(TARGET elm_function            PROPERTY FOLDER “Sandbox”)
SET_PROPERTY(TARGET sandbox_shadergraph     PROPERTY FOLDER “Sandbox”)
SET_PROPERTY(TARGET sb_fixedpoint           PROPERTY FOLDER “Sandbox”)
SET_PROPERTY(TARGET ut_jsonparser           PROPERTY FOLDER “UnitTest”)
SET_PROPERTY(TARGET ut_lx_vector            PROPERTY FOLDER “UnitTest”)

Written by arthur

December 16th, 2010 at 3:24 am