GNU Make:在传递给 Shell 之前扩展模式
GNU Make: expand pattern before passing to Shell
我想使用 awk 脚本来确定在编译 FORTRAN 源文件之前必须编译哪些模块。我的项目的结构使得我可以通过 运行
获取提供模块的文件名
awk '=/use/{print gensub(",","","g", ) ".o"}' file.f90
在我要编译的文件上
但是,我的 make 命令
%.o: $(shell awk '$=/use/{print gensub(",","","g", $) ".o"}' /path/to/%.f90)
失败
awk: fatal: cannot open file `/path/to/%.f90' for reading: No such file or directory
所以 %.f90 没有得到扩展。为什么会这样,我该如何解决这个问题?
目标和先决条件中的变量和函数在解析 makefile 时扩展,而不是当 make 是 运行 makefile 时。但是,只有当 make 是 运行 生成文件时,模式规则才会扩展,试图构建与模式匹配的目标。因此,在扩展这些变量和函数时,您只有文字模式字符串,而不是将其扩展为真实文件名。
请参阅文档中的 How make reads a makefile。
有多种方法可以做到这一点。一种选择是使用 secondary expansion。但是请注意,您必须对正在转义的 $
进行两次转义!!
.SECONDEXPANSION:
%.o: $$(shell awk '$$$=/use/{print gensub(",","","g", $$$) ".o"}' /path/to/$$*.f90)
预计到达时间
您也可以完全不使用 .SECONDEXPANSION
,而是像这样使用 eval
:
%.o:
...
SRCS := $(wildcard *.f90)
OBJS := $(SRCS:%.f90=%.o)
$(foreach O,$(OBJS),\
$(eval $O: $(shell awk '$=/use/{print gensub(",","","g", $) ".o"}' $(O:%.o=%.f90))))
因为你没有给出一个实际的例子,我只是编造了 SRCS
和 OBJS
变量。也许你已经有类似的变量了。
我想使用 awk 脚本来确定在编译 FORTRAN 源文件之前必须编译哪些模块。我的项目的结构使得我可以通过 运行
获取提供模块的文件名awk '=/use/{print gensub(",","","g", ) ".o"}' file.f90
在我要编译的文件上
但是,我的 make 命令
%.o: $(shell awk '$=/use/{print gensub(",","","g", $) ".o"}' /path/to/%.f90)
失败
awk: fatal: cannot open file `/path/to/%.f90' for reading: No such file or directory
所以 %.f90 没有得到扩展。为什么会这样,我该如何解决这个问题?
目标和先决条件中的变量和函数在解析 makefile 时扩展,而不是当 make 是 运行 makefile 时。但是,只有当 make 是 运行 生成文件时,模式规则才会扩展,试图构建与模式匹配的目标。因此,在扩展这些变量和函数时,您只有文字模式字符串,而不是将其扩展为真实文件名。
请参阅文档中的 How make reads a makefile。
有多种方法可以做到这一点。一种选择是使用 secondary expansion。但是请注意,您必须对正在转义的 $
进行两次转义!!
.SECONDEXPANSION:
%.o: $$(shell awk '$$$=/use/{print gensub(",","","g", $$$) ".o"}' /path/to/$$*.f90)
预计到达时间
您也可以完全不使用 .SECONDEXPANSION
,而是像这样使用 eval
:
%.o:
...
SRCS := $(wildcard *.f90)
OBJS := $(SRCS:%.f90=%.o)
$(foreach O,$(OBJS),\
$(eval $O: $(shell awk '$=/use/{print gensub(",","","g", $) ".o"}' $(O:%.o=%.f90))))
因为你没有给出一个实际的例子,我只是编造了 SRCS
和 OBJS
变量。也许你已经有类似的变量了。