【问题标题】:Does autotools Makefile automatically consider included header files as dependencies?autotools Makefile 是否自动将包含的头文件视为依赖项?
【发布时间】:2012-07-21 03:29:46
【问题描述】:

我有一个由 autotools 管理的项目(ssccetar.gz 包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

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

所以,我的问题是:

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

【问题讨论】:

  • 出于好奇,您是否省略了一些细节? -I$(srcdir)/foo 是如何进入 CPPFLAGS 的?
  • @WilliamPursell 好吧,我省略了我的 real 场景的一些细节,但下面的示例按预期编译。在这种情况下,不需要-I$(srcdir)/foo,因为foo.cmain.c 都包含目录名称为:#include "foo/foo.h" 的文件,如here 所示。

标签: c makefile autotools automake


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2017-04-30
    • 2016-10-13
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多