如何使用cmake为嵌套子目录设置Visual Studio过滤器

Jai*_*Jai 17 c++ cmake visual-studio visual-studio-2012

我有以下结构

Main (dir)
      +-- CMakeLists.txt
      +-- File.cpp
      +-- File.hpp
      +-- Dir (dir)
          +-- CMakeLists.txt
          +-- File1.cpp
          +-- File1.hpp
          +-- File2.cpp
          +-- File2.hpp
Run Code Online (Sandbox Code Playgroud)

主/的CMakeLists.txt

CMAKE_MINIMUM_REQUIRED (VERSION 2.8.11)
PROJECT(Main)
FILE(GLOB SOURCE
    "*.hpp"
    "*.cpp"
)

ADD_SUBDIRECTORY(Dir)
ADD_EXECUTABLE(Main ${SOURCE})
Run Code Online (Sandbox Code Playgroud)

主/ DIR /的CMakeLists.txt

FILE(GLOB LOCAL_SOURCE
    "*.hpp"
    "*.cpp"
)
SET(SOURCE
    ${SOURCE}
    ${LOCAL_SOURCE}
    PARENT_SCOPE
)
Run Code Online (Sandbox Code Playgroud)

它在Visual Studio中生成以下结构
在此输入图像描述

我想要的是:

在此输入图像描述 在此输入图像描述

我尝试了什么:

主/的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})
Run Code Online (Sandbox Code Playgroud)

主/ DIR /的CMakeLists.txt

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

SOURCE_GROUP(Dir FILES ${LOCAL_SOURCE})
Run Code Online (Sandbox Code Playgroud)

我得到了什么:

在此输入图像描述

请帮我解决这个问题.

  • 我不想在Main目录中使用具有过滤器的单个CmakeFile.txt
  • 实际结构是多层深嵌套结构.所以请建议适用于任何级别子目录的解决方案

Flo*_*ian 19

有几个随时可用或适应性强的解决方案来模仿源树行为,就像在Eclipse中使用CMake for Visual Studio(例如来自Zobra的ADD_SRC_SUBFOLDER DESTINATION_SRCS或来自Luca的GroupSources).

这是我的缩减版本用于您的用例:

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()
Run Code Online (Sandbox Code Playgroud)

请参阅source_group()的文档,您必须为子目录提供双反斜杠.

因为ADD_SRC_SUBFOLDER DESTINATION_SRCS我想用CMake的file()命令文档中引用的所有源文件的专用列表替换你的原因:

我们不建议使用GLOB从源树中收集源文件列表.如果在添加或删除源时没有更改CMakeLists.txt文件,则生成的构建系统无法知道何时请求CMake重新生成.

这是我的故障安全版本(检查绝对路径)用作函数:

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)
Run Code Online (Sandbox Code Playgroud)

您将在示例中调用哪个

assign_source_group(${source_list})
Run Code Online (Sandbox Code Playgroud)


squ*_*les 8

从CMake 3.8开始,该source_group命令提供了一个TREE参数,以递归方式搜索源文件的文件路径,以构造源组以匹配文件系统结构。现在,这提供了一种更清洁的解决方案:

project(Main)

set(SOURCE_LIST
    "File.cpp"
    "File.hpp"
    "Dir/File1.cpp"
    "Dir/File1.hpp"
    "Dir/File2.cpp"
    "Dir/File2.hpp"
)

add_executable(Main ${SOURCE_LIST})

# Create the source groups for source tree with root at CMAKE_CURRENT_SOURCE_DIR.
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST})
Run Code Online (Sandbox Code Playgroud)


小智 6

我想对/sf/users/279149811/的答案发表评论,但由于缺乏“声誉”而无法发表评论?

反正,

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST})
Run Code Online (Sandbox Code Playgroud)

就像一个魅力,但我还需要设置这个:

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
Run Code Online (Sandbox Code Playgroud)