【问题标题】:I need a Makefile.am rule to update include file我需要一个 Makefile.am 规则来更新包含文件
【发布时间】:2020-07-18 23:54:51
【问题描述】:

我有一个Makefile.am,看起来像这样:

bin_PROGRAMS = prog

AM_CFLAGS = $(prog_CFLAGS)

prog_SOURCES = \
    data.h \
    src1.c \
    src2.c \
    ...
    src30.c

data.h 文件有时会根据特定条件由update_data.pl perl 脚本更新。我尝试将其添加到 Makefile.am 的末尾:

.PHONY: data.h
data.h:
    perl update_data.pl

但脚本永远不会运行。我确定我遗漏了一些简单的东西,但我就是想不通。

【问题讨论】:

  • 它永远不会运行,因为它没有先决条件,并且文件存在,所以它永远不会被 make 认为是过时的。通过比较文件的最后修改时间来制作作品。因此,您必须(a)每次都重新构建它,或者(b)找出一个或多个其他文件,如果更改,则意味着需要更新此标头。
  • 但是,正如 OP 所做的那样,将其标记为 .PHONY,应该会导致它每次都被重建,无论它是否已经存在,@MadScientist 不应该吗?
  • 不,请参阅gnu.org/software/make/manual/html_node/Phony-Targets.html。 “虚假目标不应该是真实目标文件的先决条件;如果是,则每次 make 更新该文件时都会运行其配方。只要虚假目标绝不是真实目标的先决条件,虚假目标只有当虚假目标是指定目标时才会执行目标配方。”
  • 是的,.PHONY 会这样做。不知怎的,我没有注意到这一点。奇怪,一定是就地避难失明。但是,只有当它被列为要构建的某些目标的先决条件时,它才会被重建。我不知道自动生成的输出会对prog_SOURCES 做什么,但如果它过滤掉.h 文件,并且不会将它们作为任何目标的先决条件,因为make 期望依赖生成来管理标题,然后它不会被重建。您可能必须在 .am 文件中明确将其标记为先决条件。

标签: gnu-make autotools automake


【解决方案1】:

由于您已经有一个data.h 文件,并且它不依赖于任何东西,make 认为没有什么可以更新它。

告诉make 始终重新创建文件并不是一个好方法。如果你想在更新脚本时重新生成它,你可以让它依赖于update_data.pl 文件。或者,如果它正在解析和转换数据文件,您可以让它依赖于数据文件(以及脚本)。

但是,如果您的构建不是密封的,并且内容取决于 make 无法知道的内容,那么就没有解决问题的好方法。

【讨论】:

    【解决方案2】:

    根据当前的 git 分支、HEAD 提交、树脏状态,我正在使用一些定义来更新头文件。

    可能有一些未捕获的极端案例,但它对我有用。希望能给你一些启发。

    CLEANFILES    += git-info.h
    BUILT_SOURCES += git-info.h.stamp
    git-info.h.stamp:
            echo "#ifndef GIT_INFO_H" > git-info.h.new
            echo "#define GIT_INFO_H" >> git-info.h.new
            echo "..." >> git-info.h.new
            echo "#endif" >> git-info.h.new
            if test -f git-info.h && cmp git-info.h.new git-info.h; then :; \
            else cat git-info.h.new > git-info.h; fi; \
            rm -f git-info.h.new
    

    注意事项:

    • 永远不会创建标记文件,因此该规则将始终是 在“make all”上执行(但不是在“make my-program”上)。

    • git-info.h 只有在实际发生变化时才会被触动。这 避免仅由更新的时间戳git-info.h 引起的重建 内容不做任何改动。

    • 为了减少git-info.h 更改时的重建工作,我 仅包含从单个生成的 git-info.h 标头 常规 C my_program_SOURCES 源文件 git-info.c 其中 然后定义了一些全局的char foo[] = FOO; 符号 然后将链接到最终的可执行文件。

    • git-info.o 文件将自动依赖于git-info.h, 当标头更改时,这将导致重建。

    【讨论】:

      【解决方案3】:

      这就是我最终让它工作的方式。使用$(shell) 可能不是最好的方法,但它确实有效。

      bin_PROGRAMS = prog
      
      AM_CFLAGS = $(prog_CFLAGS)
      
      update_data := $(shell ./update_data.pl > /dev/tty)
      
      prog_SOURCES = \
          data.h \
          src1.c \
          src2.c \
          ...
          src30.c
      

      【讨论】:

      • 您可以将$(shell) 的内容移动到GNUmakefile.in 中,该include Makefile 然后执行dummy := $(shell ...)。那么configure可以通过AC_CONFIG_FILES([GNUmakefile])生成GNUmakefile。然后,只要您运行 GNU make,$(shell ...) 就可以工作。这是$(shell ...) 工作的地方。使用非 GNU make,只有正常的 automake Makefiles 将处于活动状态。
      猜你喜欢
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 2014-03-05
      • 1970-01-01
      相关资源
      最近更新 更多