假设您有一个名为file.c的文件。
file.c
包含header1.h
header1.h
包含header2.h
这是我对makefile的所有内容:
file.x: file.o
-gcc file.o -o file.x
file.o: file.c header1.h header2.h
-gcc file.c header1.h header2.h
我对如何处理header2.h包含header1.h时感到困惑。
这条线是多余的吗?或者显示依赖关系是不错的风格?
file.c header1.h header2.h
更新:我为这种混乱道歉。我已经恢复了我对这个问题所做的编辑。当前的makefile是我在Jonathan的答案所引用的原始问题中发布的那个。
答案 0 :(得分:2)
问题的原始版本包含makefile
中的以下行:
file.o: file.c header1.h header2.h
-gcc file.c header1.h header2.h
我的答案在修复之前解决了问题的原始版本。
请注意,编译行会生成可执行文件a.out
,除非编译器对象编译头文件。您应该在命令行中有-c
。
有几个问题:
在makefile
中,目标文件何时需要重建?
答案:当源文件或其中包含的某个标题发生变化时。
子公司问:这个依赖关系是什么意思:
file.o: file.c header1.h header2.h
子公司A:file.o
需要重建,如果源文件或其中包含的其中一个标题发生变化。
如果您规定:header1.h
取决于header2.h
,那么当您更改header1.h
时,header2.h
会发生什么?
答案:什么都没有。您本身不编译header1.h
。它是目标文件的变化。
如果您规定file.c
取决于header1.h
或header2.h
或两者,那么当您更改其中一个标题时,file.c
会发生什么?< / p>
答案:没有了。你不要改变file.c
;你再次重新编译目标文件。
因此,对象文件规则的依赖部分很好(在与自动依赖关系生成相关的限制内)。规则中没有必要说源文件依赖于头文件;实际上,源文件并不直接依赖于头文件。 (它间接依赖于它们,如果标题内容发生变化,那么有效代码不再是有效代码,在修复源代码之前不会编译任何东西。但这稍微偏离了主题。)
对依赖项进行硬编码是有问题的;他们改变了。另一方面,自动生成依赖关系是繁琐的。有GCC选项(例如-M
,-MM
,-MF
,-MG
,-MP
,-MQ
,-MD
,{{ 1}},-MMD
,-MT
- 这么丰富的选项告诉你这里有问题!)来帮助,GNU -H
有'条件包含'来包含依赖文件如果他们不存在而不存在干扰。这些可以帮助你。查找make
,makedepend
和相关命令,了解其他自动化方法。
忽略自动依赖关系生成,您的makefile可能显示为:
mkdep
FILES.o = file.o
file.x: ${FILES.o}
${CC} -o $@ ${CFLAGS} ${FILES.o}
file.o: file.c header1.h header2.h
将提供将make
编译为file.c
的命令。
当您的程序增长为使用file.o
时,您只需将other.o
添加到宏other.o
(这就是复数名称的原因)。您也可以添加依赖项信息。如果您也需要库,则可以向链接行添加选项:
FILES.o
请注意,库应该在目标文件之后。在目标文件之前列出库容易导致其他平台上的链接时失败,这会让那些试图构建软件的人感到恼火。