autotools Makefile是否自动将包含的头文件视为依赖项?

时间:2012-07-22 19:26:55

标签: c makefile autotools automake

我有一个autotools管理的项目(sscce tar.gz package here),具有以下结构:

./main.c
./foo.c
./foo/foo.h

我的configure.ac是:

AC_INIT([foo], [1.0], [foo@bar.ba])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])

AC_OUTPUT

我的Makefile.am是:

bin_PROGRAMS = main
main_SOURCES = main.c foo.c foo.h

它编译并完美运行......但后来我注意到我的Makefile.am不正确。它声明我的主要代码取决于foo.h,但实际文件是foo/foo.h。我改变了它,编译按预期工作,就像以前一样:

bin_PROGRAMS = main
main_SOURCES = main.c foo.c foo/foo.h

然而,它让我想知道:当依赖关系错误时它是如何工作的?它工作得很好,我甚至可以编辑foo/foo.hmake将重新编译相关文件。实际上,我甚至可以从依赖项中删除头文件......

bin_PROGRAMS = main
main_SOURCES = main.c foo.c

...它仍会被扫描,会触发重新编译相关文件。

所以,我的问题是:

  • autotools生成的Makefile如何知道foo/foo.hmake调用期间要分析的依赖项?
  • 我应该将头文件添加到main_SOURCES变量吗?
  • 在第一种情况下,make不应该失败,因为我声明一个不存在的文件是依赖项?

1 个答案:

答案 0 :(得分:5)

查看automake manual。依赖计算在构建时完成,作为编译的副作用。 history of dependency tracking也可能对您有意义。请注意,这里的手册中有一个错误:它听起来像depcomp被无条件调用,但事实并非如此(configure时的测试检查编译器是否可以不使用它:参见@am__fastdepCC_TRUE@中的Makefile.in行。

所以会发生的事情是列出每个对象的依赖关系的文件存储在一个名为.deps的隐藏子目录中。这些文件初始为空,并在编译相应的源文件时被覆盖。 (对于gcc,这是通过-MD和相关标志完成的。)

您绝对应该在main_SOURCES变量中列出标题,这样Makefile会在您运行make dist(或者更好,make distcheck)时对其进行打包。

如果您列出一个不存在的标头,

make将不会失败,因为您实际上并未列出main_SOURCES行中的依赖项。 automake将处理该分配,然后写出构建main(仅依赖于目标文件)和各种目标文件(通过后缀规则)的规则。标题不是构建过程中任何内容的直接输入文件,因此您可以滑行。在示例项目上运行make dist会出现错误:

make: *** No rule to make target `foo.h', needed by `distdir'.  Stop.