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

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

这就是我的目录结构现在的样子:

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

现在,我不知道我的Makefile应该如何…当.cpp文件和.h文件不在同一个目录下时,它似乎不工作。 任何人都可以指向我一个共同的目录结构与一个附带的Makefile,所以我不重新发明轮子?

分离.h文件的.cpp并不总是一个好的解决scheme。 一般来说,我把它们作为一个库(include和public header中的公共头与源代码)分开。

如果是图书馆,这个结构是好的。

 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指定编译的包含path

如果这是一个大项目,可以使用像autoconf / automakecmake这样的工具来构build一切。 这将缓解发展。

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

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

您只需在Makefilepath中使用:

 %.o : %.cpp 

用。。。来代替

 bin/%.o : %.cpp 

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

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

看一下gnu make手册 ,具体的章节8.3文件名的函数 ,以及之前的8.2函数stringreplace和分析

你可以做这样的东西:

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

 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 

等等。

如果你有很多的源文件,进一步细分你的源代码目录也是一个好主意。 例如,您的应用程序的核心function的一个子目录,一个用于GUI的子目录等等。

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

这样做也会迫使您避免在“模块”之间存在不必要的关系,这是良好的可重用代码的先决条件。

没有“好的目录结构”。 select一个你感觉舒适的结构并坚持下去。 有些人喜欢将源文件(头文件和实现文件)放在src/目录下,所以项目的根目录只有一个makefile,一个自述文件以及其他一些东西。 有些人喜欢在lib/目录下放置helper库,单元test/ doc/ etc下的test/src/test/下。

我还没有听到任何人将头文件和实现文件拆分成两个不同的目录。 就个人而言,我不喜欢将文件分割成很多目录。 我通常把我所有的源代码放在一个目录中,并把所有的文档放在另一个目录下。 如果我依靠良好的search工具,则不需要复杂的目录结构。

make可以处理makefile驻留在不同于source的目录下的那种结构。 唯一的是它会从makefile的目录中调用规则 – 编译器通常没有问题,编译在某个子目录下的源代码。 您不必在#include指定相对path; 只需指定包含编译器标志(gcc的-I标志等)的包含path。

如果您在阅读之前没有看到它,那么recursion会被认为是有害的 。

短小版本:尽pipe非常普遍,recursion式成语并不是最优的,随着项目变得越来越大,越来越复杂,越来越糟糕。 提出了一个替代scheme。

相关链接: 您的非recursion制作经验是什么?