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

2skhul33  于 2022-11-11  发布在  其他
关注(0)|答案(4)|浏览(319)

我有以下结构

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

主目录/目录清单.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})
  • 主目录/目录清单.txt*
FILE(GLOB LOCAL_SOURCE
    "*.hpp"
    "*.cpp"
)
SET(SOURCE
    ${SOURCE}
    ${LOCAL_SOURCE}
    PARENT_SCOPE
)

SOURCE_GROUP(Dir FILES ${LOCAL_SOURCE})

"我得到的是“

关于这件事,请你帮帮我。

  • 我不想在具有筛选器的主目录中使用单个CmakeFile.txt
  • 实际结构是多层深嵌套结构。因此,请提出解决方案,将工作在任何级别的子目录
bq3bfh9z

bq3bfh9z1#

有几个现成的或可适应的解决方案可以模拟源树的行为,就像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()的文档,您必须为子目录提供双反斜杠。
我之所以将您的file(GLOB ...)替换为所有源文件的专用列表,原因是我喜欢引用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)

在示例中,您可以使用

assign_source_group(${source_list})
jtoj6r0c

jtoj6r0c2#

从CMake 3.8, the source_group command offers a TREE argument开始,递归搜索源文件的文件路径,并构造源文件组以匹配文件系统结构。现在,这提供了一个更干净的解决方案:

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

w9apscun3#

我想评论https://stackoverflow.com/users/3987854/squareskittles的回答,但我不能由于缺乏“声誉”?
不管怎么说,

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST})

工作起来像一个魅力,但我还需要设置这个:

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
xbp102n0

xbp102n04#

我知道使用CMAKE glob函数通常是不受欢迎的:Why is CMAKE glob evil,但在 my 的情况下,我发现它比显式命名每个文件更好。我想我会使用GLOB包括Florian的答案的修改版本。


# 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")

相关问题