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

查看:1115
本文介绍了如何使用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 b $ b ADD_EXECUTABLE(Main $ {SOURCE})

Main / Dir / CmakeLists.txt

  FILE(GLOB LOCAL_SOURCE 
* .hpp
* .cpp

SET(SOURCE
$ {SOURCE}
$ {LOCAL_SOURCE}
PARENT_SCOPE

它在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(主文件$ {LOCAL_SOURCE})
ADD_EXECUTABLE(主$ {SOURCE})

Main / Dir / CmakeLists.txt b

  FILE(GLOB LOCAL_SOURCE 
* .hpp
* .cpp

SET SOURCE
$ {SOURCE}
$ {LOCAL_SOURCE}
PARENT_SCOPE


SOURCE_GROUP(目录文件$ {LOCAL_SOURCE})

我得到的东西





请帮我解决这个问题。 / p>


  • 我不想在具有过滤器的主目录中使用单个cmakeFile

  • 实际结构是多层深嵌套结构。所以请建议我的解决方案,它将在任何级别的子目录下工作


解决方案

使用或适应性解决方案来模仿源代码树行为像Eclipse中的CMake for Visual Studio(例如来自Zobra的ADD_SRC_SUBFOLDER DESTINATION_SRCS 或来自Luca的 GroupSources )。



这是我的简化版本,用于您的使用案例:

  cmake_minimum_required .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(),您必须给子目录添加双反斜杠。



用所有源文件的专用列表替换您的文件(GLOB ...)我想引用从CMake的 file()命令文档:


我们不建议使用GLOB从
源代码树中收集源文件列表。如果没有CMakeLists.txt文件更改,当源是
添加或删除,那么生成的构建系统无法知道什么时候
要求CMake重新生成。


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

 code>函数(assign_source_group)
foreach(_source IN ITEMS $ {ARGN})
if(IS_ABSOLUTE$ {_ source})
文件(RELATIVE_PATH _source_rel$ {CMAKE_CURRENT_SOURCE_DIR} $ {_ source})
else()
set(source_rel$ {_ source})
endif()
get_filename_component(_source_path$ {_ source_rel} )
string(REPLACE/\\_source_path_msvc$ {_ source_path})
source_group($ {_ source_path_msvc}FILES$ {_ source})
endforeach ()
endfunction(assign_source_group)

>

  assign_source_group($ {source_list})


I have following structure

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
)

It generate following structure in Visual Studio

what i want ?

What i tried ?

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

What i get

Please help me regarding this.

  • I do not want to use single cmakeFile in Main directory having filters
  • Actual structure is many layer deep nesting structure. So please suggest me solution which will work for any level sub directory

解决方案

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

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

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:

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)

Which you would call in the example with

assign_source_group(${source_list})

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆