对于使用 Makefile 的大型 C++ 项目,什么是好的目录结构?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2360734/
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
What's a good directory structure for larger C++ projects using Makefile?
提问by Olivier Lalonde
What's a good directory structure for larger C++ projects using Makefile ?
对于使用 Makefile 的大型 C++ 项目,什么是好的目录结构?
This is how my directory structure looks at the moment:
这是我的目录结构目前的样子:
lib/ (class implementations *.cpp)
include/ (class definitions *.h)
tests/ (main.cpp for quick tests)
Now, I'm not sure how my Makefile should look like... it doesn't seem to work when .cpp files and .h files aren't in the same directory. Could anyone point me to a common directory structure with an accompanying Makefile so that I don't reinvent the wheel ?
现在,我不确定我的 Makefile 应该是什么样子……当 .cpp 文件和 .h 文件不在同一目录中时,它似乎不起作用。谁能给我指出一个带有 Makefile 的通用目录结构,这样我就不会重新发明轮子了?
回答by Phong
Separating the .cpp of the .h file is not always a good solution. Generally I separate both of them when it is used as a library (public header in include and private header with the source code).
分离 .h 文件的 .cpp 并不总是一个好的解决方案。通常,当它用作库时,我将它们分开(包含源代码中的公共头和带有源代码的私有头)。
If it is a library, this structure is ok.
如果是库,这个结构就可以了。
lib/ (class implementations *.cpp .h)
include/ (class definitions *.h) <- Only those to be installed in your system
tests/ (main.cpp for quick tests)
doc/ (doxygen or any kind of documentation)
If it is a application
如果是应用程序
src/ (source for the application)
lib/ (source for the application library *.cpp *.hpp)
include/ (interface for the library *.h)
tests/ (main.cpp for quick tests) <- use cppunit for this part
doc/ (doxygen or any kind of documentation)
Use the flag -I$(PROJECT_BASE)/include to specify the include path for the compilation
使用标志 -I$(PROJECT_BASE)/include 指定编译的包含路径
If it is a big project, it can be good to use tool like autoconf/automakeor cmaketo build everything. It will ease the development.
如果它是一个大项目,最好使用autoconf/automake或cmake 之类的工具来构建所有内容。这将简化开发。
回答by Gnurou
If you have many source files, it may also be a good idea to further subdivide your source directory. For instance, one subdirectory for the core functionality of your application, one for the GUI, etc.
如果您有很多源文件,进一步细分您的源目录可能也是一个好主意。例如,一个用于应用程序核心功能的子目录,一个用于 GUI 等的子目录。
src/core
src/database
src/effects
src/gui
...
Doing so also forces you to avoid unneeded relationships between your "modules", which is a prerequisite to nice and reusable code.
这样做还会迫使您避免“模块”之间不必要的关系,这是获得良好和可重用代码的先决条件。
回答by stefanB
There is no one specific or required directory structure.
没有一种特定的或必需的目录结构。
You can set it up anyway you like. Your problem is simple to solve. Just instruct Makefile to look into subdirectories or put compiled objects into subdirectories instead of using just current directory.
您可以随意设置。你的问题很容易解决。只需指示 Makefile 查看子目录或将编译对象放入子目录,而不是仅使用当前目录。
You would just use in Makefile paths:
您只需在 Makefile 路径中使用:
%.o : %.cpp
replace with
用。。。来代替
bin/%.o : %.cpp
So it will check if binary file in directory bin
exists and so on, you can apply the same to locations where files are compiled.
因此它将检查目录中的二进制文件是否bin
存在等,您可以将其应用于编译文件的位置。
There are ways to add/remove/modify paths of source and object files.
有多种方法可以添加/删除/修改源文件和目标文件的路径。
Have a look at gnu make manual, specifically section 8.3 Functions for File Names,and the one before that 8.2 Functions for String Substitution and Analysis.
看看gnu make 手册,特别是8.3 文件名函数,以及之前的8.2 字符串替换和分析函数。
You can do stuff like:
您可以执行以下操作:
get a list of objects from list of source files in current directory:
从当前目录中的源文件列表中获取对象列表:
OBJ = $(patsubst %.cpp, %.o, $(wildcard *.cpp))
Output:
输出:
Application.o Market.o ordermatch.o
If binary objects are in subdirectory bin
but source code is in current directory you can apply prefix bin
to generated object files:
如果二进制对象在子目录中,bin
但源代码在当前目录中,您可以将前缀bin
应用于生成的对象文件:
OBJ = $(addprefix bin/,$(patsubst %.cpp, %.o, $(wildcard *.cpp)))
Output:
输出:
bin/Application.o bin/Market.o bin/ordermatch.o
And so on.
等等。
回答by wilhelmtell
There is no "good directory structure". Pick a structure you're comfortable with and stick to it. Some like placing source files (headers and implementation files) in a src/
directory, so the root directory of the project has nothing but a makefile, a readme and little else. Some like placing helper libraries under a lib/
directory, unittests under test/
or src/test/
, documentation under doc/
etc.
没有“好的目录结构”。选择一个你觉得舒服的结构并坚持下去。有些人喜欢将源文件(头文件和实现文件)放在一个src/
目录中,所以项目的根目录只有一个 makefile、一个自述文件和其他一些东西。有些喜欢将辅助库放在lib/
目录下,将单元测试放在test/
或下src/test/
,将文档放在doc/
等下。
I have yet to hear of anyone splitting header files and implementation files into two distinct directories though. Personally I don't like splitting files into directories much. I usually place all my source in a single directory and all the documentation in another directory. If I rely on good search tools anyway, there's no need for a complex directory structure.
不过,我还没有听说有人将头文件和实现文件分成两个不同的目录。我个人不太喜欢将文件拆分成目录。我通常将所有源代码放在一个目录中,将所有文档放在另一个目录中。如果无论如何我都依赖好的搜索工具,则不需要复杂的目录结构。
make can deal with the sort of structure where the makefile resides in a different directory than the source. The only thing is that it will invoke the rules from the directory of the makefile -- compilers usually have no problem compiling source that is in some subdirectory. You don't have to specify relative paths in your #include
s; just specify the include path with compiler flags (gcc's -I
flag etc).
make 可以处理 makefile 与源文件所在目录不同的结构类型。唯一的问题是它会从 makefile 的目录中调用规则——编译器通常在编译某个子目录中的源代码时没有问题。您不必在#include
s 中指定相对路径;只需使用编译器标志(gcc 的-I
标志等)指定包含路径。
回答by dmckee --- ex-moderator kitten
If you haven't seen it before read Recursive Make Considered Harmful.
如果您在阅读Recursive Make Considered Harmful之前还没有看过它。
Short, short version:Though very common the recursive make idiom is less than optimal and gets ever worse as projects grow larger and more complicated. An alternative is presented.
简短的版本:虽然很常见,但递归 make 习惯用法不是最佳的,并且随着项目变得越来越大和越来越复杂而变得越来越糟。提出了一种替代方案。
Related link: What is your experience with non-recursive make?
相关链接:您对非递归 make 的体验如何?
回答by kervin
This is an old question. But you can consider the Pitchfork Project as a general guide.
这是一个老问题。但是您可以将 Pitchfork 项目视为一般指南。
https://github.com/vector-of-bool/pitchforkfor the project.
该项目的https://github.com/vector-of-bool/pitchfork。
Some Documentation here
一些文档在这里