【问题标题】:GNU Make: expand pattern before passing to ShellGNU Make:在传递给 Shell 之前扩展模式
【发布时间】:2022-01-08 14:07:26
【问题描述】:

我想使用 awk 脚本来确定在编译 FORTRAN 源文件之前必须编译哪些模块。我的项目结构使得我可以通过运行获得提供模块的文件名

awk '$1=/use/{print gensub(",","","g", $2) ".o"}' file.f90

关于我要编译的文件。

但是,我的 make 命令

%.o: $(shell awk '$$1=/use/{print gensub(",","","g", $$2) ".o"}' /path/to/%.f90)

失败

awk: fatal: cannot open file `/path/to/%.f90' for reading: No such file or directory

所以 %.f90 不会被扩展。为什么会这样?我该如何解决这个问题?

【问题讨论】:

    标签: regex awk makefile gnu-make


    【解决方案1】:

    目标和先决条件中的变量和函数在解析 makefile 时展开,而不是在 make 运行 makefile 时展开。但是,模式规则仅在 make 运行 makefile 时才会扩展,试图构建与模式匹配的目标。因此,在这些变量和函数展开时,您只有文字模式字符串,而不是将其展开为真正的文件名。

    请参阅文档中的 How make reads a makefile

    有很多方法可以做到这一点。一种选择是使用secondary expansion。但是请注意,您必须双重转义您正在转义的$!!

    .SECONDEXPANSION:
    %.o: $$(shell awk '$$$$1=/use/{print gensub(",","","g", $$$$2) ".o"}' /path/to/$$*.f90)
    

    【讨论】:

    • 您将我的 %.f90 更改为 *.f90,因此它将匹配所有以 '.f90' 结尾的文件。那不是我想要的。当我构建 test.o 时,它应该在 test.f90 上运行此命令,而不是在所有以 .f90 结尾的文件上运行。但是,简单地将 $$*.f90 更改为 $$%.f90 是行不通的。
    • 你真的试过我写的东西看看它是否有效吗?你的说法不正确。我写了$$*.f90,它将减少为$*.f90$* 是自动变量,它扩展到规则的主干:这是% 的值。
    • 真的很抱歉!我确实对其进行了测试,但我的(更复杂的)Makefile 中还有另一个问题。现在我想我想通了大部分事情。谢谢!只是我没看错:正常情况下,% 和 $* 是一样的吗?
    • $* 是一个自动变量:gnu.org/software/make/manual/html_node/Automatic-Variables.html 但是,正如您在此处看到的,自动变量通常仅在配方中有效。因此,您在目标和先决条件中使用%,在配方中使用$*。二次扩展允许(一些)自动变量在扩展先决条件时也可见。
    猜你喜欢
    • 2017-09-26
    • 2011-10-04
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多