如何构建具有多个相互依赖的子目录的 C++ 项目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6921695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I build a C++ project with multiple interdependent subdirectories?
提问by Daniel Bingham
I have a C++ project where I've used directories as more of an organizational element -- the way one might use packages in Java or directories in PHP. Directories are not intended to be self-sufficient elements, but rather just a way of organizing the whole of the project and keeping me from being overwhelmed by sources. How can I construct my CMakeLists.txt files to deal with this? Making the directories libraries doesn't seem to fit here, since they are all interdependent and not intended to be used that way.
我有一个 C++ 项目,我在其中使用目录作为更多的组织元素——人们可能使用 Java 中的包或 PHP 中的目录的方式。目录并不是自给自足的元素,而只是一种组织整个项目并防止我被来源淹没的方式。如何构建我的 CMakeLists.txt 文件来处理这个问题?制作目录库似乎不适合这里,因为它们都是相互依赖的,不打算以这种方式使用。
As a related issue, most of the examples I've seen of multiple subdirectories in CMake (and there aren't very many of those) have ignored or glossed over the issue of setting include_directories
, which is something I've been having trouble with. Short of combing my source files to determine which file depends on which and in what directory, is there anyway to just set all directories under /src/
as potential include directories and let CMake work out which ones are actually dependent?
作为一个相关的问题,我在 CMake 中看到的多个子目录的大多数示例(并且这些示例并不多)都忽略或掩盖了设置问题include_directories
,这是我一直遇到的问题。没有组合我的源文件来确定哪个文件依赖于哪个目录以及在哪个目录中,无论如何将所有目录设置/src/
为潜在的包含目录并让 CMake 计算出哪些实际上是依赖的?
Here's an example structure:
这是一个示例结构:
--src
--top1
--mid1
--bot1
--src1.cpp
--hdr1.h
--bot2
--src2.cpp
--hdr2.h
--mid2
--bot3
--src3.cpp
--src4.cpp
--hdr3.h
--top2
--mid3
--src5.cpp
--hdr4.h
So on and so forth. How can I structure my CMakeLists.txt
files to handle this sort of structure?
等等等等。我如何构建我的CMakeLists.txt
文件来处理这种结构?
采纳答案by sakra
Since the directory structure in your project is just there to keep your files organized, one approach is to have a CMakeLists.txt
that automatically finds all sources files in the src
directory and also adds all directories as include directories that have a header file in them. The following CMake file may serve as a starting point:
由于项目中的目录结构只是为了让文件井井有条,因此一种方法是使用CMakeLists.txt
自动查找目录中的所有源文件src
并将所有目录添加为包含头文件的目录。以下 CMake 文件可以作为起点:
cmake_minimum_required(VERSION 3.0)
project (Foo)
file(GLOB_RECURSE Foo_SOURCES "src/*.cpp")
file(GLOB_RECURSE Foo_HEADERS "src/*.h")
set (Foo_INCLUDE_DIRS "")
foreach (_headerFile ${Foo_HEADERS})
get_filename_component(_dir ${_headerFile} PATH)
list (APPEND Foo_INCLUDE_DIRS ${_dir})
endforeach()
list(REMOVE_DUPLICATES Foo_INCLUDE_DIRS)
add_executable (FooExe ${Foo_SOURCES})
target_include_directories(FooExe PRIVATE ${Foo_INCLUDE_DIRS})
The two file(GLOB_RECURSE ...
commands determine the set of source and header files. The foreach
loop computes the set of include directories from the list of all header files.
这两个file(GLOB_RECURSE ...
命令确定源文件和头文件的集合。该foreach
循环计算一组包含所有头文件的列表目录。
One drawback with computing the set of source files is that CMake will not automatically detect when new files are added to your source tree. You manually have to re-create your build files then.
计算源文件集的一个缺点是 CMake 不会自动检测何时将新文件添加到您的源代码树中。然后您必须手动重新创建构建文件。
回答by Guy Sirton
I'm not an expert on CMake but since there are no other answers I'll take a look at the documentaton and give it a go. Organizing source and include files in different directories is pretty much the norm.
我不是 CMake 的专家,但由于没有其他答案,我将查看文档并试一试。在不同目录中组织源文件和包含文件几乎是常态。
It looks like CMake allows you to give a list of include directories: http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories
看起来 CMake 允许您提供包含目录的列表:http: //www.cmake.org/cmake/help/cmake-2-8-docs.html#command: include_directories
So something like:
所以像:
include_directories("src/top1/mid1/bot1" "src/top1/mid1/bot2/" ... )
These are passed to the compiler so it can find the header files and will be passed for each of the source files. So any of your source files should be able to include any of the header files (which I think is what you're asking for).
这些被传递给编译器,以便它可以找到头文件,并将为每个源文件传递。因此,您的任何源文件都应该能够包含任何头文件(我认为这就是您所要求的)。
Similar to that you should be able to list all your source files in the add_executablecommand:
与此类似,您应该能够在add_executable命令中列出所有源文件:
add_executable(name "src/top1/mid1/bot1/src1.cpp" "src/top1/id1/bot2/src2.cpp" ...)
So this would be a naive way of getting everything to build. Each source file will be compiled and will look for headers in all those directories and then the object files will get linked together. Consider if there is any way of simplifying this such that you don't need so many include folders, maybe there are only a few common header files that need to be referenced by all source files. If things get more complex you can buiild sub-hierarchies into libraries etc. Also consider seperating source files and headers (e.g. in src and include).
所以这将是一种让一切都构建起来的幼稚方式。每个源文件都将被编译并在所有这些目录中查找头文件,然后将目标文件链接在一起。考虑是否有任何方法可以简化这一点,这样您就不需要这么多包含文件夹,也许只有几个公共头文件需要被所有源文件引用。如果事情变得更复杂,您可以将子层次结构构建到库等中。还可以考虑将源文件和头文件分开(例如在 src 和包含中)。