我有以下结构
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})
主要/风向/的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(Main FILES ${LOCAL_SOURCE})
ADD_EXECUTABLE(Main ${SOURCE})
主/风向/的CMakeLists.txt
FILE(GLOB LOCAL_SOURCE
"*.hpp"
"*.cpp"
)
SET(SOURCE
${SOURCE}
${LOCAL_SOURCE}
PARENT_SCOPE
)
SOURCE_GROUP(Dir FILES ${LOCAL_SOURCE})
我得到了什么:
请帮我解决这个问题。
答案 0 :(得分:17)
有几个随时可用或适应性强的解决方案来模仿源树行为,就像在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})
答案 1 :(得分:1)
我知道这是使用臭名昭著的CMAKE glob函数Why is CMAKE glob evil,但是在 my 的情况下,这可能比显式命名每个文件更好。我想我会使用GLOB包括@Florian答案的修改版本。
{"defense"=>
[{:id=>30,
:source=>"Hacker News",
:title=>
"China-based campaign breached satellite, defense companies: Symantec",
:link=>
"https://www.reuters.com/article/us-china-usa-cyber/china-based-campaign-breached-satellite-defense-companies-symantec-idUSKBN1JF2X0"}]}
答案 2 :(得分:1)
从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})
答案 3 :(得分:1)
我想评论https://stackoverflow.com/users/3987854/squareskittles的答案,但是由于缺乏“声誉”而无法发表我的看法?
反正
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST})
就像一个饰物一样工作,但我还需要进行以下设置:
set_property(GLOBAL PROPERTY USE_FOLDERS ON)