【问题标题】:GNU make: mixing the $(file) function with external toolsGNU make:将 $(file) 函数与外部工具混合
【发布时间】:2022-01-23 00:30:25
【问题描述】:

以下示例直接来自 GNU make 手册:

program: $(OBJECTS)
        $(file >$@.in,$^)
        $(CMD) $(CMDFLAGS) @$@.in
        @rm $@.in

这非常有效。但是,如果我颠倒 $(file) 和外部工具的顺序,行为仍然相同:首先执行 $(file),然后才执行外部工具。

是否可以在配方中调用外部工具,在工具成功完成后,使用 $(file) 处理日志并创建更多文件?

外部工具是生成一组未知文件的代码生成器。配方应该解析日志文件并创建包含文件。与 echo/$(shell) 一起使用,但这受系统命令行长度的限制。使用单独的规则当然可以,但可以在同一个配方中完成吗?

【问题讨论】:

  • “可能”是一个强词。在执行配方时,设置依赖图和变量。无法将它们添加到 current 调用中。但是您应该能够让该工具生成一个包含生成的依赖项的 makefile,然后递归调用它。
  • 嗨 Andreas,实际上您可以使用 GNU make 来做到这一点,请参阅我的另一个问题,例如:stackoverflow.com/questions/70398930/…。当前版本使用 echo 创建包含,这就是我要转换为使用 $(file) 的内容。速度更快,不受系统命令行长度限制。

标签: makefile gnu-make


【解决方案1】:

GNU make 在开始调用配方中的任何命令之前,总是会预先扩展整个配方中的所有变量和函数。因此,您不能让$(file ...) 函数(例如)对在同一配方中运行某些命令的结果进行操作。

所以对你的问题的简短回答是否定的,它不能按照你想要的方式在一个食谱中完成。

【讨论】:

  • 谢谢,明白了。
【解决方案2】:

如果您使用 $(shell ) 而不是直接将其放入配方中运行 shell 命令,这是可能的。我一直在使用以下包装器,它检查错误代码并丢弃结果:

# Same as `$(shell ...)`, but triggers a error on failure.
ifeq ($(filter --trace,$(MAKEFLAGS)),)
override safe_shell = $(shell $1)$(if $(filter-out 0,$(.SHELLSTATUS)),$(error Unable to execute `$1`, status $(.SHELLSTATUS)))
else
override safe_shell = $(info Shell command: $1)$(shell $1)$(if $(filter-out 0,$(.SHELLSTATUS)),$(error Unable to execute `$1`, status $(.SHELLSTATUS)))
endif

# Same as `safe_shell`, but discards the output and expands to a single space.
override safe_shell_exec = $(call space,$(call safe_shell,$1))

然后$(CMD) $(CMDFLAGS) @$@.in 变为$(call safe_shell_exec,$(CMD) $(CMDFLAGS) @$@.in)

【讨论】:

  • 好主意,谢谢!有用。不幸的是,控制台输出不起作用......或者是否可以以某种方式将输出从工具重定向到控制台? $(shell) 捕获输出,它不会发送到控制台。
  • @vjalle 我不确定。您可以尝试将输出重定向到标准错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
相关资源
最近更新 更多