0

假设您有一个名为 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

更新:我为混乱道歉。我已恢复对问题所做的编辑。当前的生成文件是我在乔纳森的回答所指的原始问题中发布的文件。

4

1 回答 1

2

问题的原始版本在 中包含以下几行makefile

file.o: file.c header1.h header2.h
        -gcc file.c header1.h header2.h

在修复之前,我的回答解决了问题的原始版本。

请注意,a.out除非编译器反对编译头文件,否则编译行会生成可执行文件。你应该-c在命令行中。


几个问题:

  1. 在 amakefile中,目标文件何时需要重建?

    答:当源文件或它包含的标题之一发生更改时。

    附属Q:这个依赖线是什么意思:

    file.o: file.c header1.h header2.h
    

    附属 A:file.o如果源文件或其包含的头文件之一发生更改,则需要重建。

  2. 如果你规定:header1.h取决于header2.hheader1.h当你改变时会发生header2.h什么?

    答:没什么。header1.h你本身不编译。改变的是目标文件。

  3. 如果您规定file.c取决于header1.hheader2.h两者兼而有之,那么file.c当您更改其中一个标头时会发生什么?

    回答:又没有了。你没有改变file.c;您再次重新编译目标文件。

因此,您的目标文件规则的依赖部分很好(在与自动依赖生成相关的限制范围内)。说源文件依赖于标头的规则没有任何意义。实际上,源文件并不直接依赖于头文件。(它间接依赖于它们,因为如果标头内容发生更改,使得有效代码不再是有效代码,则在源代码修复之前不会编译任何内容。但这有点偏离主题。)

对依赖项进行硬编码是有问题的;他们改变了。另一方面,自动生成依赖项是繁琐的。有 GCC 选项(如-M, -MM, -MF, -MG, -MP, -MQ, -MD, -MMD, -MT, -H- 如此丰富的选项告诉您这里有问题!)可以提供帮助,并且 GNUmake有“条件包含”来包含依赖文件(如果它们存在),如果他们没有。这些可以提供帮助。查找makedependmkdep相关命令以获取其他自动化方式。


忽略自动依赖生成,您的 makefile 可能会显示:

FILES.o = file.o

file.x: ${FILES.o}
        ${CC} -o $@ ${CFLAGS} ${FILES.o} 

file.o: file.c header1.h header2.h

make将提供一个命令编译file.cfile.o.

当您的程序other.o也可以使用时,您只需添加other.o到宏FILES.o(这就是它是复数名称的原因)。你也可以添加依赖信息。如果您也需要库,则可以在链接行中添加选项:

LDFLAGS = -L/usr/local/lib
LDLIBS  = -llocal

FILES.o = file.o other1.o other2.o

file.x: ${FILES.o}
        ${CC} -o $@ ${CFLAGS} ${FILES.o} ${LDFLAGS} ${LDLIBS}

file.o: file.c header1.h header2.h

请注意,库应该在目标文件之后。在目标文件之前列出库很容易导致其他平台上的链接时失败,从而激怒那些试图构建您的软件的人。

于 2013-03-27T00:09:35.633 回答