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

How to set Visual Studio Filters for nested sub directory using cmake(如何使用 cmake 为嵌套子目录设置 Visual Studio 过滤器)

本文介绍了如何使用 cmake 为嵌套子目录设置 Visual Studio 过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下结构

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

Main/Dir/CmakeLists.txt

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

它在 Visual Studio 中生成了以下结构

It generated the following structure in Visual Studio

我想要的:

我的尝试:

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

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
  • 实际结构是多层深嵌套结构.所以请提出适用于任何级别子目录的解决方案

推荐答案

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

There are several ready to use or adaptable solutions out there to mimic a Source Tree behavior like in Eclipse with CMake for Visual Studio (e.g. ADD_SRC_SUBFOLDER DESTINATION_SRCS from Zobra or GroupSources from Luca).

这是我针对您的用例的简化版本:

Here is my reduced version for your use case:

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()的文档 你必须用双反斜杠给子目录.

See the documentation of source_group() that you have to give the sub-directories with double backslashes.

出于为什么我将您的 file(GLOB ...) 替换为我喜欢引用 CMake 的 file() 命令文档:

For the reason why I replaced your file(GLOB ...) with a dedicated list of all source files I like to quote from CMake's file() command documentation:

我们不建议使用 GLOB 从以下位置收集源文件列表你的源代码树.如果在源文件中没有 CMakeLists.txt 文件更改添加或删除然后生成的构建系统不知道何时要求 CMake 重新生成.

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.

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

And here is my fail-safe version (that checks for absolute paths) to be used as a function:

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

这篇关于如何使用 cmake 为嵌套子目录设置 Visual Studio 过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何使用 cmake 为嵌套子目录设置 Visual Studio 过滤器

基础教程推荐