Automake/autotools 并使用“--dry-run”和“--always-make”进行 make

问题描述 投票:0回答:1

我最近切换到 VSCode 作为编辑器时偶然发现了一个问题。

我有几个项目拥有完整的(中型复杂+)自动工具 设置并且它们都工作正常。然而我发现 VSCode 的 makefile 插件为了初始化自身(并查找所有依赖项和目标)首先运行

make --dry-run --always-make

作为第一次初始化。这会抛出 makefile(或者实际上是 重新配置)进入无限循环重新运行“配置”(因为目标永远不会解析到磁盘)。

我也用尽可能小的 autoconf/automake 确认了这种行为 设置。我也可以理解为什么会发生这种情况(而且似乎使 有一种内部方法可以通过特殊的方法来发现这种确切的情况 变量 MAKE_RESTARTS 可用于检测循环 行为)

是否有已知的最佳实践解决方法?或者这两个选项结合起来是否有效? (在我陷入兔子洞提醒自己忘记了关于自动工具的神奇土地的所有细节之前,很高兴能有第二个意见)?

gnu-make autotools autoconf
1个回答
0
投票

问题

空运行 autoconf 项目时的无限循环是由于

GNU Make
的记录行为造成的。这不是一个错误,也不是特定于版本的行为:

  1. GNU Make 无条件地重制文件 makefile(定义为从中读取规则的文件,例如,给定语句“include blah.inc”,文件

    blah.inc
    是一个“makefile”)。 Remaking Makefiles 说“
    --dry-run
    不会阻止更新 makefile,因为过时的 makefile 会导致其他目标的错误输出

  2. Automake 创建规则,用于在

    Makefile.am
    更改时以及
    configure.ac
    更改时更新 Makefile。

  3. 在递归构建中,当 make 生成子 make 进程时,它不会通过

    --assume-old
    机制将“
    MAKEFLAGS
    ”参数传递给子 make。这在与子品牌通信选项

    中进行了描述

这三种行为共同保证了当加载项目时 vscode“Makefile Tools”扩展默认使用“

--dry-run
”时,autoconf+automake 项目将最终陷入无限循环。

解决方案

解决方案是更改命令行选项,如下(

settings.json
摘录):

"makefile.dryrunSwitches": [
        "--always-make",
        "--print-directory",
        "--dry-run",
        "--assume-old=Makefile",
        "Makefile",
        "all",
        "AM_MAKEFLAGS=--assume-old=Makefile Makefile"
],

如果使用 GUI,这些字符串中的每一个都必须出现在一行上。具体来说,

AM_MAKEFLAGS=--assume-old=Makefile Makefile
是一个参数。在 bash 命令行中,这将被引用为
AM_MAKEFLAGS="--assume-old=Makefile Makefile"

说明

--assume-old=Makefile
表示名为“Makefile”的文件(也是目标)将不会被考虑重制,尽管
--always-make
,根据避免编译

由于文件

Makefile
也是一个文件(即用于从中读取规则),因此尽管有“--dry-run”,它仍会被重新制作。除了
Makefile
之外,还可以通过将
all
指定为目标来覆盖此行为,如 Remaking Makefiles 中所述:“有时您可能实际上希望阻止甚至 makefile 的更新。您可以通过指定来做到这一点将 makefile 作为命令行中的目标以及将它们指定为 makefile。当将 makefile 名称显式指定为目标时,选项“-t”等确实适用于它们。

由于在递归构建中,

--assume-old
参数不会通过make自己的
MAKEFLAGS
环境变量机制传递给子make,因此
AM_MAKEFLAGS
变量用于执行覆盖此行为。这是有效的,因为 automake 项目会在每次 make 调用时添加此变量的值。

注 1. 如果您的项目在 Makefile.am 中定义了

AM_MAKEFLAGS
变量,则需要对其进行调整以包含所需的
--assume-old
咒语。一种方法是:

AM_MAKEFLAGS="--project-specific-make-flags $(DRYRUN_MAKEFLAGS)"

然后,在

DRYRUN_MAKEFLAGS="--assume-old=Makefile Makefile"
中使用
settings.json

注 2. 将“makefile.dryrunSwitches”设置放在哪个

settings.json
文件中很重要。如果您从事 autoconf 和 cmake 项目,您可能希望在每个项目的
settings.json
中都有它。我将其设置在用户级别,因为我只处理很少的 cmake 项目,然后我可以在项目级别覆盖。

注 3. 可以说,Makefile Tools 扩展中

makefile.dryrunSwitches
的默认设置是错误的,并且该扩展可以被认为是有错误的。但是,它并不声称与 automake 兼容,因此修复此问题需要添加 automake 兼容性。请参阅我的拉取请求#500

© www.soinside.com 2019 - 2024. All rights reserved.