Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake: how to create visual studio filters

I have already looked around (StackOverflow and more) and I'm trying to use cmake to generate Visual Studio filters. I have the following folders:

src/math  
src/import  
src/ui  

I would like to generate the filters like above.
math: contains all the cpp & h files in src/math
import: contains all the cpp & h files in src/import
ui: contains all the cpp & h files in src/ui

I have tried several solutions, but none seems to work!!!

Here is the last version of the code in CMakeList.txt:

set(VD_SRC "${VisualDesigner_SOURCE_DIR}/src/visualdesigner")

file(GLOB_RECURSE SRC_UI
    "${VD_SRC}/ui/*.cpp", "${VD_SRC}/ui/*.h")
file(GLOB_RECURSE SRC_IMPORT
    "${VD_SRC}/import/*.cpp",
    "${VD_SRC}/import/*.h")

source_group("ui"            FILES ${SRC_UI})
source_group("import"        FILES ${SRC_IMPORT})

Any help is welcomed!

like image 279
ClubberLang Avatar asked Nov 19 '15 15:11

ClubberLang


3 Answers

See How to set Visual Studio Filters for nested sub directory using cmake

Just be aware that

  • the source_group() command only works in combination with add_library() or add_executable() commands listing the same sources (the paths must match)
  • the source_group() command does not check if the file actually exists (so it takes anything you give it and during project file generation it tries to match the given source group file names against files used in the project)

I have given your code a try by adding a corresponding add_library() target and it works as expected (CMake 3.3.2 and VS2015):

set(VD_SRC "${VisualDesigner_SOURCE_DIR}/src/visualdesigner")

file(GLOB_RECURSE SRC_UI
    "${VD_SRC}/ui/*.cpp"
    "${VD_SRC}/ui/*.h"
)
file(GLOB_RECURSE SRC_IMPORT
    "${VD_SRC}/import/*.cpp"
    "${VD_SRC}/import/*.h"
)

add_library(VisalDesigner ${SRC_UI} ${SRC_IMPORT})

source_group("ui"            FILES ${SRC_UI})
source_group("import"        FILES ${SRC_IMPORT})

Results in

Solution Explorer with Filters

Here is a more generalized version taken from Visual Studio as an editor for CMake friendly project:

set(_src_root_path "${VisualDesigner_SOURCE_DIR}/src/visualdesigner")
file(
    GLOB_RECURSE _source_list 
    LIST_DIRECTORIES false
    "${_src_root_path}/*.c*"
    "${_src_root_path}/*.h*"
)

add_library(VisualDesigner ${_source_list})

foreach(_source IN ITEMS ${_source_list})
    get_filename_component(_source_path "${_source}" PATH)
    file(RELATIVE_PATH _source_path_rel "${_src_root_path}" "${_source_path}")
    string(REPLACE "/" "\\" _group_path "${_source_path_rel}")
    source_group("${_group_path}" FILES "${_source}")
endforeach()
like image 56
Florian Avatar answered Nov 19 '22 07:11

Florian


As of CMake 3.8, the source_group command offers a TREE argument to recursively search the files paths of your sources to structure the source groups to match your file system structure. Now, the solution is a lot cleaner, no need for looping:

set(VD_SRC "${VisualDesigner_SOURCE_DIR}/src/visualdesigner")
file(GLOB_RECURSE UI_IMPORT_MATH_SRCS
    "${VD_SRC}/ui/*.cpp"
    "${VD_SRC}/ui/*.h"
    "${VD_SRC}/import/*.cpp"
    "${VD_SRC}/import/*.h"
    "${VD_SRC}/math/*.cpp"
    "${VD_SRC}/math/*.h"
)

add_library(VisualDesigner ${UI_IMPORT_MATH_SRCS})

# Create the source groups for source tree with root at VD_SRC.
source_group(TREE ${VD_SRC} FILES ${UI_IMPORT_MATH_SRCS})

Also, check out the new PREFIX argument you can use with source_group if you find that useful.

Disclaimer: I advise against the use of GLOB (see here) wherever possible.

like image 3
Kevin Avatar answered Nov 19 '22 08:11

Kevin


I found it easier to do this and thought it might be helpful to others. Make sure you are using the latest version of CMAKE.

file(GLOB_RECURSE _source_list *.cpp* *.h* *.hpp*)
foreach(_source IN ITEMS ${_source_list})
    get_filename_component(_source_path "${_source}" PATH)
    string(REPLACE "${CMAKE_SOURCE_DIR}" "" _group_path "${_source_path}")
    string(REPLACE "/" "\\" _group_path "${_group_path}")
    source_group("${_group_path}" FILES "${_source}")
endforeach()
like image 4
Langerz Avatar answered Nov 19 '22 08:11

Langerz