makefile和#include命令如何交互?

时间:2014-04-30 09:44:48

标签: c gcc compilation makefile

这听起来很明显,但我无法清楚知道如何管理Makefile和#include命令。

据我所知,#include用于 - 根据其名称 - 通过指示其标题(.h)文件名来包含库文件。它们可以位于程序文件夹中或某些标准库目录中。 makefile指定在编译可执行文件时必须将哪些文件和包放在一起。

假设我想将我创建的源文件(.c.h)添加到现有程序中。我是否必须同时#include并将它们添加到makefile中?

编辑 - 附加问题:如果我将一个源文件放在makefile中但忘记#include它,我会收到错误还是不会被使用?

2 个答案:

答案 0 :(得分:3)

是的,总的来说。

所有#include确实包括,即字面上粘贴在上述文件中。由于标题(.h)文件通常只包含声明,但不包含定义(即实际的函数实现),这还不够。

这就是为什么您通常必须通过Makefile与链接器进行交互,以告诉它将您的程序链接到哪些其他库。

两者都是必需的,因为:

  • 尝试链接具有#include但没有正确库的程序将失败,其中包含"未解析的符号" -type错误。
  • 尝试调用您正在链接的库中的函数,但没有正确的#include将生成"未声明的符号"警告或错误。

答案 1 :(得分:1)

假设您有一个由main.cfoo.cfoo.h和构建程序的makefile组成的现有程序。并且假设您要添加bar.cbar.h

任何需要条形码的东西都必须告诉编译器在哪里找到它。否则,如果Foo类有Bar成员,main()调用bar_transform(),则编译器会尖叫说它不知道你在说什么关于。因此foo.hmain.c必须包含此行:

#include "bar.h"

(这里的模式有点微妙。请注意foo.c可能需要此指令,因为它有#include "foo.h",而foo.h有{ {1}}。此外,在某些情况下,最好使用前向声明 int #include "bar.h"并将指令放在foo.h中。如果您遇到问题这个,我们可以帮忙。)

现在代码是正确的。我们可以编译它并生成foo.cmain.ofoo.o。我们只需要正确链接它们。

makefile必须包含某些,它告诉生成构建可执行文件时要使用的文件,可能是这样的:

bar.o

如果在修改源文件后尝试此操作,Make会正确编译app: main.o foo.o $(CC) $^ -o $@ main.o,然后尝试链接它们,链接器会尖叫foo.o类不完整,它找不到Bar的定义。

要在构建中合并bar_transform(),您只需要将bar添加到该先决条件列表中:

bar.o

makefile可以通过其他方式指定列表,因此如果遇到问题,请向我们展示您的makefile。此外,这并未解决依赖项处理的问题(例如,如果app: main.o foo.o bar.o ... 已更改,则必须知道必须重建foo.o);这可能很容易修复,但我们必须看到makefile。