【问题标题】:How do the makefile and #include commands interact?makefile 和#include 命令如何交互?
【发布时间】:2014-04-30 09:44:47
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您似乎混合了两个不同的概念。 makefile 包含有关如何构建应用程序的说明,而源文件包含用于声明所需的头文件。

标签: c gcc compilation makefile


【解决方案1】:

一般来说是的。

#include 所做的只是包含,即直接粘贴到提到的文件中。由于标头 (.h) 文件通常只包含声明,但不包含 定义(即实际的函数实现),这还不够。

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

两者都需要,因为:

  • 尝试链接具有 #includes 但库不正确的程序将失败,并出现“未解析的符号”类型错误。
  • 如果没有正确的#includes,尝试调用您正在链接的库中的函数,将会产生“未声明的符号”警告或错误。

【讨论】:

  • 包含@JoachimPileborg 在此答案中对 OP 的评论中提到的上下文混淆的解释可能是个好主意。
【解决方案2】:

假设您有一个由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#include "bar.h"。另外,还有在某些情况下,最好使用 forward declaration int foo.h 并将指令放在 foo.c 中。如果您遇到问题,我们可以提供帮助。)

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

makefile 必须包含 一些东西,告诉 Make 在构建可执行文件时要使用哪些文件,可能像这样:

app: main.o foo.o
    $(CC) $^ -o $@

如果你在修改源文件后尝试这个,Make会正确编译main.ofoo.o,然后尝试链接它们,链接器会尖叫Bar类不完整,并且找不到bar_transform()的定义。

要将bar 合并到构建中,您只需将bar.o 添加到该先决条件列表中:

app: main.o foo.o bar.o
    ...

makefile 可以通过其他方式指定列表,所以如果您遇到问题,请向我们展示您的 makefile。此外,这并没有解决依赖关系处理的问题(例如,如果bar.h 已更改,则必须重新构建foo.o);这可能很容易解决,但我们必须查看 makefile。

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2013-02-21
    • 2013-06-03
    • 2012-10-31
    • 2012-02-20
    • 1970-01-01
    • 2021-09-16
    • 2022-01-18
    相关资源
    最近更新 更多