2

您好(我使用的是 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 中以错误的方式解决这个问题。

4

2 回答 2

5

The compiler is always looking into some default paths to look for .h-files. You can add your path.

For example gcc takes multiple -I arguments which contain a path. In your foo.cpp you do:

#include "foo.h"

and when compiling you say:

g++ -I../include foo.cpp -c [other options]

.

Regarding the second part of your question: The makefile and the call to make does not normally know anything about the files to be compiled and about your project. However there are several default variables and directives in make which lead to that impression: It could be, that in your environment you only need to change the CFLAGS or CPPFLAGS variable to add the -I-argument and it will work.

于 2013-02-15T19:06:55.533 回答
2

Patrick B 已经很好地回答了如何让编译器知道从哪里包含,但不是以下位:

作为旁注,我是makefile的新手。我什至不确定它是否知道这些包含存在,因为它们在代码中(事实上据我了解它没有)。这将导致我遇到一个不幸的次要问题,即可以看到这些包括吗?如果不是,是否可以更改它以使其可以?

不,make 不了解您的源文件包含什么,或者它们如何依赖于其他文件只要文件之间存在“如果您有这样的文件,并且想要通过做某事来获得这样的文件”的关系,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

请注意,makefile 依赖于作为制表符的缩进。这篇文章使用了空格,因此您需要“标记”收据。另请注意,在“正确的”makefile 中,您将使用foo.ofoo.cpp,并将所有不同的.o文件链接在一起。这样,对于大型项目来说,编译会更快一些。为了便于阅读,我对其进行了简化。

也许我应该扩展一点:

gcc -MM给出正在“编译”的文件及其所有依赖项的列表(标准输出)。它实际上并不编译代码(只要代码至少有点)接近可编译,它会愉快地处理您的文件。

有关gcc -MM和相关的更多详细信息,请查看GCC 调用文档。

$@$&^是所谓的make“自动变量” - 它们扩展到“目标”(容易记住,因为它看起来有点像用于射击或类似的箭头的目标)和“所有依赖项”(这里没有视觉线索,我'恐怕——我不得不时不时地提醒自己)分别。在这里查看更多详细信息。

于 2013-02-15T19:21:32.753 回答