您好(我正在使用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"
但我发现随着我的项目的增长,我开始需要更多的组织,这种方法不够动态。原因是如果我想将foo.h移动到一个新目录(比如include \ bar \ foo.h),我必须更改每个文件的每个包含。有没有办法让make实现这一目标。如果是这样,它也可以用于头文件依赖性。
作为旁注,我是makefile的新手。我甚至不确定它是否知道这些包含在那里,因为它们在代码中(实际上从我理解的不是)。那会让我陷入一个不幸的次要问题,这可以让我看到这些包括?如果不是可以改变它,它可以吗?随意回答你将如何处理这个问题,因为我有一种感觉,我将错误的方法放在文件中,而不是将它们链接到makefile中。
答案 0 :(得分:5)
编译器总是在寻找一些默认路径来查找.h文件。您可以添加路径。
例如gcc
采用包含路径的多个-I
参数。在你的foo.cpp
中:
#include "foo.h"
编译时说:
g++ -I../include foo.cpp -c [other options]
关于问题的第二部分:makefile
和对make
的调用通常不知道有关要编译的文件和项目的任何信息。但是,make中有几个默认变量和指令会产生这种印象:可能是,在您的环境中,您只需更改CFLAGS
或CPPFLAGS
变量即可添加-I
- 参数,它会工作。
答案 1 :(得分:2)
Patrick B已经很好地回答了如何使编译器知道从哪里包含,但不是以下几点:
作为旁注,我是makefile的新手。我甚至不确定它是否知道 这些包括在那里,因为它们在代码内(事实上来自 我所理解的不是)。那会让我感到不幸 次要问题,哪些可以看到这些包括?如果不是的话 可以改变它以便它可以吗?
不,make不明白您的源文件包含什么,或者它们如何依赖于其他文件[如果您使用C,C ++,Fortran,Pascal,ADA,Lisp,Cobol或者编程,也不会真正关心Haskell - 只要有一个“如果你有一个像这样的文件,并希望通过做某事的文件”文件之间的关系,make会为你排序。
有几种方法可以做到这一点。您可以手动添加:
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
请注意,makefiles在缩进是RELYING是标签。这篇文章使用空格,所以你需要“收看”收据。另请注意,在“正确”的makefile中,您可以从foo.o
等处制作foo.cpp
,并将所有不同的.o
文件链接在一起。这样,对于大型项目,编译速度会快一些。为了便于阅读,我简化了它。
也许我应该扩大一点:
gcc -MM
给出了正在“编译”的文件及其所有依赖项的列表(标准输出)。它实际上并没有编译代码(并且只要代码至少是SOMEWHAT)接近可编译,它将很乐意处理您的文件。
有关gcc -MM
及相关内容的详细信息,请查看GCC invocation文档。
$@
和$&^
是make
所谓的“自动变量” - 它们会扩展到“目标”(容易记住,因为它看起来有点像拍摄目标箭头在或类似)和“所有依赖”(这里没有视觉线索,我害怕 - 并且时不时地,我必须提醒自己)。查看here了解详情。