Cmake: как создавать визуальные студийные фильтры

Я уже посмотрел вокруг (Qaru и более), и я пытаюсь использовать cmake для генерации фильтров Visual Studio. У меня есть следующие папки:

src/math  
src/import  
src/ui  

Я хотел бы создать фильтры, как указано выше.
math: содержит все cpp & h файлы в src/math
import: содержит все cpp & h файлы в src/import
ui: содержит все cpp & h файлы в src/ui

Я пробовал несколько решений, но ни одно из них не работает !!!

Вот последняя версия кода в 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})

Любая помощь приветствуется!

Ответ 1

См. Как установить фильтры Visual Studio для вложенной подкаталога с помощью cmake

Просто имейте в виду, что

  • команда source_group() работает только в сочетании с add_library() или add_executable(), перечисляя одни и те же источники (пути должны совпадать)
  • команда source_group() не проверяет, действительно ли файл существует (поэтому он берет все, что вы ему даете, и при создании файла проекта он пытается сопоставить имена файлов исходной группы с файлами, используемыми в проекте).

Я попробовал ваш код, добавив соответствующий целевой объект add_library(), и он работает как ожидалось (CMake 3.3.2 и 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})

Результаты в

Обозреватель решений с фильтрами

Вот более обобщенная версия, взятая из Visual Studio в качестве редактора для проекта, совместимого с CMake:

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()

Ответ 2

Мне было проще это сделать, и я подумал, что это может быть полезно для других. Убедитесь, что вы используете последнюю версию 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()

Ответ 3

Начиная с CMake 3.8, команда source_group предлагает аргумент TREE для рекурсивного поиска путей к файлам ваших источников для структурирования групп источников в соответствии со структурой вашей файловой системы. Теперь решение намного чище, не нужно зацикливаться:

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})

Кроме того, ознакомьтесь с новым аргументом PREFIX, который вы можете использовать с source_group, если сочтете это полезным.

Отказ от ответственности: я рекомендую не использовать GLOB (см. Здесь), где это возможно.

Ответ 4

Для тех, кто хочет создать их в разделах "Заголовочные файлы" и "Исходные файлы":

Вы можете использовать source_group. Вот конкретный пример.

Предположим, у вас есть структура каталогов, как:

|-include
    | some.h
    |-sub
       | someother.h 
|-src
   | some.cpp
   |-sub
      |-someother.cpp

Соберите файлы (некоторые люди, включая документацию, не одобряют использование GLOB, но я оставляю это для вас, вы можете перечислить их по одному, если хотите, хотя я считаю, что GLOB просто прекрасен много раз):

file(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB HEADER_FILES_SUB "${CMAKE_CURRENT_SOURCE_DIR}/include/sub/*.h")
file(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
file(GLOB SOURCE_FILES_SUB "${CMAKE_CURRENT_SOURCE_DIR}/src/sub/*.h")

# Setup your library or executable:
add_library(MY_LIB ${HEADER_FILES} ${HEADER_FILES_SUB}
                   ${SOURCE_FILES} ${SOURCE_FILES_SUB})

# Here the important part ("Header Files" and "Source Files" are literals.)
source_group("Header Files\\sub" ${HEADER_FILES_SUB})
source_group("Source Files\\sub" ${SOURCE_FILES_SUB})