【问题标题】:How to fix Makefile error?如何修复 Makefile 错误?
【发布时间】:2017-03-13 01:03:34
【问题描述】:

我已经创建了一个 Makefile。现在,我收到以下错误:

  • clang:警告:brians_brain.o:“链接器”输入未使用
  • clang: 警告:cell.o: 'linker' 输入未使用
  • clang:警告:cell_grid.o:“链接器”输入未使用
  • 架构 x86_64 的未定义符号: “_List_Delete”,引用自: _main in brians_brain_cellular_automata.o “_List_Read”,引用自: _main in brians_brain_cellular_automata.o ld:未找到架构 x86_64 的符号 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) make: *** [brians_brain_cellular_automata] 错误 1

这是 Makefile:

brians_brain_cellular_automata: brians_brain_cellular_automata.o brians_brain.o cell.o cell_grid.o
    gcc -Wall brians_brain_cellular_automata.o brians_brain.o cell.o cell_grid.o

brians_brain_cellular_automata.o: brians_brain_cellular_automata.c brians_brain.o cell.o cell_grid.o
    gcc -Wall -c brians_brain_cellular_automata.c brians_brain.o cell.o cell_grid.o

brians_brain.o: brians_brain.c cell_grid.o cell.o list.o
    gcc -Wall -c brians_brain.c cell_grid.o cell.o list.o

cell_grid.o: cell_grid.c cell.o
    gcc -Wall -c cell_grid.c cell.o

cell.o: cell.c
    gcc -Wall -c cell.c

list.o: list.c cell.o
    gcc -Wall -c list.c cell.o

假设标签被正确使用。

最让我困惑的是这个 Makefile 今天早些时候工作。我在其中一个依赖项中输入了一些代码,它开始这样做。我恢复了这些更改,但我仍然收到这些错误。我做错了什么?

【问题讨论】:

  • 你确定这真的有效吗? -c 表示编译但不链接。因此,您的大多数规则都没有意义,因为 .o 文件用于链接,不应传递给 -c 命令行。
  • @kaylum 我明白你的意思。在这种情况下,创建所有目标文件,然后将它们正确链接在一起的最佳方法是什么?

标签: c makefile linker


【解决方案1】:

编译目标文件时,只需要传入源文件,不需要传入其他目标文件。在可执行文件中链接时使用对象文件。这就是警告的来源。

至于错误,您在链接可执行文件时没有包括list.o,也没有将其列为依赖项。因此,您会收到该文件中函数的“未定义引用”错误。

所以你的makefile应该是这样的:

brians_brain_cellular_automata: brians_brain_cellular_automata.o brians_brain.o cell.o cell_grid.o list.o
    gcc -Wall brians_brain_cellular_automata.o brians_brain.o cell.o cell_grid.o list.o

brians_brain_cellular_automata.o: brians_brain_cellular_automata.c 
    gcc -Wall -c brians_brain_cellular_automata.c

brians_brain.o: brians_brain.c
    gcc -Wall -c brians_brain.c

cell_grid.o: cell_grid.c
    gcc -Wall -c cell_grid.c

cell.o: cell.c
    gcc -Wall -c cell.c

list.o: list.c
    gcc -Wall -c list.c

由于每个目标文件的构建方式相同,因此您实际上可以使用通配符定义规则来编译目标文件:

brians_brain_cellular_automata: brians_brain_cellular_automata.o brians_brain.o cell.o cell_grid.o list.o
    gcc -Wall brians_brain_cellular_automata.o brians_brain.o cell.o cell_grid.o list.o

%.o: %.c
    gcc -Wall -c $<

使用此规则,brians_brain_cellular_automata 目标中引用的每个对象文件都将使用此规则构建。

【讨论】:

  • 你是最棒的。之前让我感到困惑的是确保一切都正确链接。例如,一些源文件依赖于其他源文件。
  • 请注意,Make 知道足以推断出 cell.o 是从 cell.c 创建的,而无需再次告知。它还具有将.c 文件编译成对应的.o 文件的内置规则;您只需要通过正确设置宏来适当地配置编译规则。这将使更改编译命令行变得更加容易。需要类似于第一段的内容;其余的不是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2011-10-18
  • 1970-01-01
  • 2015-12-04
  • 2016-11-17
  • 2011-07-24
  • 2021-05-10
相关资源
最近更新 更多