使用Makefile的大型C ++项目的最佳目录结构是什么?

使用Makefile的大型C ++项目的最佳目录结构是什么?

这是我目前的目录结构:

lib/ (class implementations *.cpp)
include/ (class definitions *.h)
tests/ (main.cpp for quick tests)

现在,我不确定我的Makefile应该是什么样子...当.cpp文件和.h文件不在同一目录中时,它似乎不起作用。 谁能指出我带有随附Makefile的通用目录结构,以便我不浪费时间?

Olivier Lalonde asked 2020-02-13T19:10:55Z
6个解决方案
57 votes

分隔.h文件的.cpp并不总是一个好的解决方案。 通常,当我将它们用作库时,我会将二者分开(包含源代码的include和private头中的公共头)。

如果它是一个库,则此结构可以。

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)

如果是应用程序

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)

使用标志-I $(PROJECT_BASE)/ include指定编译的包含路径

如果是一个大项目,最好使用诸如autoconf / automake或cmake之类的工具来构建所有内容。 它将简化发展。

Phong answered 2020-02-13T19:11:26Z
12 votes

如果源文件很多,最好进一步细分源目录。 例如,一个子目录用于应用程序的核心功能,一个子目录用于GUI等。

src/core
src/database
src/effects
src/gui
...

这样做还迫使您避免“模块”之间不必要的关系,这是编写精美且可重复使用的代码的先决条件。

Gnurou answered 2020-02-13T19:11:50Z
12 votes

没有特定或必需的目录结构。

您可以随时设置它。 您的问题很容易解决。 只需指示Makefile查看子目录或将编译后的对象放入子目录中即可,而不仅仅是使用当前目录。

您只需要在Makefile路径中使用:

%.o : %.cpp

用。。。来代替

bin/%.o : %.cpp

因此它将检查目录bin中的二进制文件是否存在,等等,您可以将其应用于编译文件的位置。

有多种方法可以添加/删除/修改源文件和目标文件的路径。

请查看gnu make手册,特别是第8.3节“文件名的功能”以及该节之前的“ 8.2字符串替换和分析的功能”。

您可以执行以下操作:

从当前目录中的源文件列表中获取对象列表:

OBJ     = $(patsubst %.cpp, %.o, $(wildcard *.cpp))

输出:

Application.o Market.o ordermatch.o

如果二进制对象位于子目录bin中,但源代码位于当前目录中,则可以将前缀bin应用于生成的目标文件:

OBJ     = $(addprefix bin/,$(patsubst %.cpp, %.o, $(wildcard *.cpp)))

输出:

bin/Application.o bin/Market.o bin/ordermatch.o

等等。

stefanB answered 2020-02-13T19:13:04Z
6 votes

没有“良好的目录结构”。 选择一个您喜欢的结构并坚持下去。 有些人喜欢将源文件(标头和实现文件)放在#include目录中,因此项目的根目录只包含makefile,自述文件和其他内容。 例如将帮助程序库放在-I目录下,将单元测试放在test/src/test/下,将文档放在doc/下等。

我还没有听说有人将头文件和实现文件分成两个不同的目录。 我个人不喜欢将文件拆分成多个目录。 我通常将所有源代码放在一个目录中,而所有文档都放在另一个目录中。 如果我仍然依靠良好的搜索工具,则无需复杂的目录结构。

make可以处理makefile所在目录与源目录不同的结构。 唯一的事情是它将从makefile的目录中调用规则-编译器通常在编译子目录中的源代码时没有问题。 您不必在#includes中指定相对路径; 只需使用编译器标志(gcc的-I标志等)指定包含路径即可。

wilhelmtell answered 2020-02-13T19:13:36Z
3 votes

如果您在阅读“递归使被认为有害”之前没有看过它。

简短的版本:尽管很常见,但递归的make惯用法并不理想,并且随着项目的扩大和复杂化而变得越来越糟。 提出了一种替代方案。

相关链接:您对非递归make有什么经验?

dmckee answered 2020-02-13T19:14:05Z
0 votes

这是一个老问题。 但是您可以将“干草叉项目”视为一般指南。

[https://github.com/vector-of-bool/pitchfork]。

一些文档在这里

kervin answered 2020-02-13T19:14:33Z
translate from https://stackoverflow.com:/questions/2360734/whats-a-good-directory-structure-for-larger-c-projects-using-makefile