5

我有一个具有以下结构的自动工具管理项目(此处为sscce tar.gz 包):

./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

...并且它仍然会被扫描并会触发依赖文件的重新编译。

所以,我的问题是:

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

1 回答 1

6

看看automake 手册。作为编译的副作用,依赖关系计算是在构建时完成的。依赖跟踪的历史可能对您来说也很有趣。请注意,此处的手册中有一个错误:它听起来像是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.
于 2012-07-22T23:17:11.573 回答