M0M0
M0M0

Reputation: 226

GNU Make: expand pattern before passing to Shell

I want to use an awk script to figure out the which modules have to be compiled before I can compile a FORTRAN source file. My project is structured in a way that I can obtain the filenames that provide the modules by running

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

on the file I want to compile.

However, my make command

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

fails with

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

So %.f90 does not get expanded. Why is that the case and how can I solve that issue?

Upvotes: 0

Views: 457

Answers (1)

MadScientist
MadScientist

Reputation: 100946

Variables and functions in targets and prerequisites are expanded when the makefile is parsed, not when make is running the makefile. But, pattern rules are only expanded when make is running the makefile, trying to build a target that matches the pattern. So at the time these variables and functions are expanded, you only have the literal pattern string not its expansion into a real filename.

See How make reads a makefile in the docs.

There are a number of ways to do this. One option is using secondary expansion. However note you'll have to double-escape the $ you are escaping!!

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

ETA

You could alternatively not use .SECONDEXPANSION at all and instead use eval like this:

%.o:
        ...

SRCS := $(wildcard *.f90)
OBJS := $(SRCS:%.f90=%.o)

$(foreach O,$(OBJS),\
    $(eval $O: $(shell awk '$$1=/use/{print gensub(",","","g", $$2) ".o"}' $(O:%.o=%.f90))))

Since you didn't give an actual example I just made up SRCS and OBJS variables. Maybe you have similar variables already.

Upvotes: 2

Related Questions