Cómo establecer los filtros de Visual Studio para el subdirectorio nested usando cmake

Tengo la siguiente estructura

Main (dir) +-- CMakeLists.txt +-- File.cpp +-- File.hpp +-- Dir (dir) +-- CMakeLists.txt +-- File1.cpp +-- File1.hpp +-- File2.cpp +-- File2.hpp 

Main / CMakeLists.txt

 CMAKE_MINIMUM_REQUIRED (VERSION 2.8.11) PROJECT(Main) FILE(GLOB SOURCE "*.hpp" "*.cpp" ) ADD_SUBDIRECTORY(Dir) ADD_EXECUTABLE(Main ${SOURCE}) 

Principal / Dir / CmakeLists.txt

 FILE(GLOB LOCAL_SOURCE "*.hpp" "*.cpp" ) SET(SOURCE ${SOURCE} ${LOCAL_SOURCE} PARENT_SCOPE ) 

Se generó la siguiente estructura en Visual Studio
enter image description here

Lo que quiero:

enter image description hereenter image description here

Lo que probé:

Main / CMakeLists.txt

 CMAKE_MINIMUM_REQUIRED (VERSION 2.8.11) PROJECT(Main) FILE(GLOB LOCAL_SOURCE "*.hpp" "*.cpp" ) SET(SOURCE ${LOCAL_SOURCE} ) ADD_SUBDIRECTORY(Dir) SOURCE_GROUP(Main FILES ${LOCAL_SOURCE}) ADD_EXECUTABLE(Main ${SOURCE}) 

Principal / Dir / CmakeLists.txt

 FILE(GLOB LOCAL_SOURCE "*.hpp" "*.cpp" ) SET(SOURCE ${SOURCE} ${LOCAL_SOURCE} PARENT_SCOPE ) SOURCE_GROUP(Dir FILES ${LOCAL_SOURCE}) 

Lo que consigo:

enter image description here

Por favor ayúdenme con respecto a esto.

  • No quiero usar solo CmakeFile.txt en el directorio principal con filtros
  • La estructura real es muchas capas de estructura de anidación profunda. Por lo tanto, sugiera la solución que funcionará para cualquier sub-directorio de nivel

Existen varias soluciones listas para usar o adaptables para imitar un comportamiento de Árbol de origen como en Eclipse con CMake para Visual Studio (por ejemplo, ADD_SRC_SUBFOLDER DESTINATION_SRCS de Zobra o GroupSources de Luca).

Aquí está mi versión reducida para su caso de uso:

 cmake_minimum_required(VERSION 2.8.10) project(Main CXX) set( source_list "File.cpp" "File.hpp" "Dir/File1.cpp" "Dir/File1.hpp" "Dir/File2.cpp" "Dir/File2.hpp" ) add_executable(Main ${source_list}) foreach(source IN LISTS source_list) get_filename_component(source_path "${source}" PATH) string(REPLACE "/" "\\" source_path_msvc "${source_path}") source_group("${source_path_msvc}" FILES "${source}") endforeach() 

Consulte la documentación de source_group () que debe proporcionar a los subdirectorios con barras diagonales inversas dobles.

Por la razón por la que reemplacé su file(GLOB ...) con una lista dedicada de todos los archivos fuente que me gusta citar de la documentación del comando file () de CMake:

No recomendamos utilizar GLOB para recostackr una lista de archivos fuente de su árbol fuente. Si no cambia ningún archivo CMakeLists.txt cuando se agrega o elimina una fuente, el sistema de comstackción generado no puede saber cuándo solicitar la regeneración de CMake.

Y aquí está mi versión a prueba de fallas (que comprueba las rutas absolutas) para ser utilizada como una función:

 function(assign_source_group) foreach(_source IN ITEMS ${ARGN}) if (IS_ABSOLUTE "${_source}") file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source}") else() set(_source_rel "${_source}") endif() get_filename_component(_source_path "${_source_rel}" PATH) string(REPLACE "/" "\\" _source_path_msvc "${_source_path}") source_group("${_source_path_msvc}" FILES "${_source}") endforeach() endfunction(assign_source_group) 

Que llamarías en el ejemplo con

 assign_source_group(${source_list}) 

Sé que esto está usando la notoria función glob de CMAKE. ¿Por qué es tan malo el CMAKE glob , pero en mi caso podría ser mejor que nombrar explícitamente cada archivo. Pensé que incluiría una versión modificada de la respuesta de @ Florian usando GLOB.

 # This code sorts the project files as they appear in the root directory # Generate a list of all .c & .h files in the current directory and sub directores. file( GLOB_RECURSE source_list RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.c *.h ) foreach(source IN LISTS source_list) get_filename_component(source_path "${source}" PATH) string(REPLACE "/" "\\" source_path_msvc "${source_path}") source_group("${source_path_msvc}" FILES "${source}") endforeach() message(STATUS "Tree reorganized")