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

新手上路,请多包涵

我有以下结构

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

主/CMakeLists.txt

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

ADD_SUBDIRECTORY(Dir)
ADD_EXECUTABLE(Main ${SOURCE})

Main/Dir/CmakeLists.txt

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

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

Main/Dir/CmakeLists.txt

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

SOURCE_GROUP(Dir FILES ${LOCAL_SOURCE})

我得到什么:

在此处输入图像描述

请帮助我解决这个问题。

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

原文由 Jai 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 651
1 个回答

有几种现成的或适应性强的解决方案可以模拟源树行为,例如在 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()

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

之所以我用我喜欢从 CMake 的 file() 命令文档中引用的所有源文件的专用列表替换您的 file(GLOB ...) 的原因:

我们不建议使用 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)

您将在示例中调用

assign_source_group(${source_list})

原文由 Florian 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题