Makefile查询-C

4
这是我的考试题,我正在复习,但不知道为什么失去了分数。现在向教授提问已经太晚了,所以来这里寻求帮助。是我没有理解makefile的基础知识吗?这是问题:
“文件engine.c包括文件engine.h,文件engine.h包括文件temp.h。编写一个或多个makefile规则生成文件engine.o。”
这是我的答案:
engine.o: engine.c engine.h
    gcc -c engine.c

答案关键字说应该是:
engine.o: engine.c engine.h temp.h
    gcc -c engine.c 

但我不明白。 engine.c 的目标文件不依赖于 temp.h,是吗?engine.h 依赖它。如果我为 engine.h 编写另一个目标,我会处理 temp.h,但我现在没有。严格来说,关于 engine.o 的目标,我需要 temp.h 吗?


3
如果temp.h发生变化,engine.h需要重新构建吗?或者如果temp.h发生变化,engine.o需要重新构建吗? - user253751
引擎头文件 engine.h 对吧?最终应该是 engine.o 吧。 - move_slow_break_things
2
当你更新temp.h时,你需要对engine.h做什么?还有,你需要对engine.o做什么?(请记住,Make关心每个命令的输出 - 你编译engine.c,但从Make的角度来看,那是“对engine.o做了些什么”) - user253751
3
答案键是正确的。当 temp.h 发生变化时,您需要重新构建 engine.o — 因此告诉 Make,除非 engine.otemp.h(以及 engine.cengine.h)更新,否则它已过期。实际上,您可以从列表中省略 engine.c;Make 将推断出该依赖项。 - Jonathan Leffler
是的。但是希望今天的编译器可以为您完成这项工作,例如 gcc -M - el.pescado - нет войне
显示剩余3条评论
3个回答

2
假设temp.h的内容如下:
#pragma once

void temp_function(int x);

engine.h 的内容如下:

#pragma once
#include "temp.h"

void engine_function(int a, int b);

engine.c 的内容如下:

#include "engine.h"

void engine_function(int a, int b)
{
   temp_function(a+b);
}

假设由于某种原因,temp.h 的内容被更改为:

#pragma once

void temp_function(int x, int y);

假设temp_function在另一个文件中实现。
如果您不重新编译engine.c,那么engine.otemp_function的目标代码将与其所在文件中实现的函数的目标代码不匹配。结果会出现链接时错误。如果重新编译engine.c,则会出现编译时错误。
始终在编译时捕获错误比在链接时更好。
这是一个规则。
engine.o: engine.c engine.h temp.h

确保在更改temp.h时执行构建engine.o的命令,并捕获编译时错误。

1

回顾一下:

文件engine.c包含文件engine.h,而engine.h又包含文件temp.h

因此:

engine.c

#include "engine.h"

engine.h

#include "temp.h"

temp.h

/* nothing */

如果您修改了temp.h,那么您需要从其部分重新构建engine.o,因为其中一个部分最终是temp.h
当所有包含都完成后,代码实际上看起来像这样:
``` engine.c /* #include "engine.h" */ engine.h /* #include "temp.h" */ temp.h /* end of temp.h */ ... /* end of engine.h */ ... /* end of engine.c */ ```
事实上,如果您使用类似gcc -E engine.c > engine.i的命令,您可以自己查看。 -E选项在预处理阶段停止,将C源代码转换为无预处理器指令的C源代码。

1

engine.c依赖于engine.h,任何对engine.h的修改都可能对engine.c产生重大影响。

同样地,engine.h依赖于temp.h,任何对temp.h的修改都可能对engine.h产生重大影响,从而间接影响engine.c。

我们来看一个例子:

在temp.h中:

#define ID 1

在engine.h中。
#define ENGINE_ID ID

在engine.c中。
engineId = ENGINE_ID;

如果您修改了ID,但是在Makefile规则中是这样的:
engine.o: engine.c engine.h
gcc -c engine.c 

该文件将不会重新编译。但是使用 HTML 标签。
engine.o: engine.c engine.h temp.h
gcc -c engine.c 

文件将使用新的ID重新编译。

更改 temp.h 可能会改变编译 engine.c 的结果,而不影响 engine.h 中的内容 - 因此它对 engine.c 有直接影响,但对 engine.h 没有影响。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接