你好(我正在使用Windows,mingw g ++编译器和mingw32-make)
为了概括我的问题,我想学习如何编写一个c ++源文件,如下所示:
假设foo.cpp依赖于foo.h,其中foo.cpp在src \中,foo.h在include \
// foo.cpp
#include "foo.h"
通常我会这样写
//foo.cpp
#include "..\include\foo.h"
但是我发现,随着我的项目的发展,我开始需要更多的组织,这种方法不够dynamic。 原因是如果我想将foo.h移动到新目录(比如include \ bar \ foo.h),我必须改变每个文件的每个包含。 有没有办法做到这一点。 如果是这样的话,那么头文件依赖关系也可以这样做。
作为一个方面说明,我是新的makefile。 我甚至不确定它是否知道这些包含在那里,因为它们在代码中(实际上从我所理解的不)。 那会导致我一个不幸的第二个问题,这是否能够使这些包括? 如果没有,是否有可能改变它,以便它可以? 随意回答你将如何解决这个问题,因为我有一种感觉,我把这个错误的方式放在文件中,而不是把它们链接到makefile中。
编译器一直在寻找一些默认路径来查找.h文件。 你可以添加你的路径。
例如gcc
需要多个包含路径的-I
参数。 在你的foo.cpp
你可以:
#include "foo.h"
编译时你说:
g++ -I../include foo.cpp -c [other options]
。
关于你的问题的第二部分: makefile
和make
的调用通常不知道要编译的文件和你的项目。 但是make中有几个默认变量和指令会导致这种印象:在您的环境中,您可能只需要更改CFLAGS
或CPPFLAGS
变量以添加-I
即可。
Patrick B已经很好地回答了如何使编译器知道从哪里来,但不是以下几点:
作为一个方面说明,我是新的makefile。 我甚至不确定它是否知道这些包含在那里,因为它们在代码中(实际上从我所理解的不)。 那会导致我一个不幸的第二个问题,这是否能够使这些包括? 如果没有,是否有可能改变它,以便它可以?
不,make不理解你的源文件包含什么,或者它们如何依赖于其他文件[也不在乎你是否用C,C ++,Fortran,Pascal,ADA,Lisp,Cobol或Haskell编程只要有一个“如果你有一个这样的文件,并希望通过做一些文件之间的文件,文件之间的关系”,将会为你排序。
有几种方法可以做到这一点。 您可以手动添加:
foo.cpp: foo.h
或者你可以使用一个依赖文件作为你的包含文件,让make
自动创建它,例如:
SOURCES = foo.cpp # Add any further source files here. INCLUDES = -I../includes # Add other include directories if needed. CFLAGS += ${INCLUDES} TARGET = foo.exe # in Windows. Just foo in linux/MacOS. all: ${TARGET} deps.mk ${TARGET}: ${SOURCES} gcc -O $@ $^ desp.mk: ${SOURCES} gcc -MM ${INCLUDES} $^ > $@ include deps.mk
请注意,makefile依赖缩进作为选项卡。 这篇文章使用空格,所以你需要“tabify”收件人。 另外请注意,在一个“正确的”makefile中,你可以从foo.cpp
等创建foo.o
,并将所有不同的.o
文件链接在一起。 这样,对于大型项目来说,编译速度要快一些。 我已经简化了它的可读性。
也许我应该扩大一点:
gcc -MM
给出了正在被“编译”的文件列表(标准输出)以及所有依赖项。 它实际上并没有编译代码(只要代码至少是SOMEWHAT)接近于可编译,它将愉快地处理您的文件。
有关gcc -MM
和相关的更多细节,请看GCC调用文档。
$@
和$&^
是调用“自动变量”的东西 – 它们扩展到“目标”(容易记住,因为它看起来有点像射箭或类似的目标)和“所有依赖”这里的视觉线索,我害怕 – 而且每隔一段时间,我都要提醒自己)。 看看这里的更多细节。