Reputation: 1925
I want to have a makefile that will take some strings as prefixes for some files (NAMES
) and from there work on the target and prerequisite file names. In the example below, for example, the idea would be to convert 2 a csv files (foo.csv
and bar.csv
) to tabular (although I'm just echoing the target and prerequisite).
NAMES = foo bar
PR = $(patsubst %,%.csv,$(NAMES))
TB = $(patsubst %,%.tsv,$(NAMES))
all: $(TB)
%.tsv: $(PR)
@echo $< $@
This prints:
foo.csv foo.tsv
foo.csv bar.tsv
So, it looks like that makefile is not expanding correctly the prerequisites in PR
as I would expect to see bar.csv bar.tsv
on the second line.
However, if I print $PR
and $TB
, both seem to be set properly:
$(info $$PR is [${PR}])
$(info $$TB is [${TB}])
# prints
$PR is [foo.csv bar.csv]
$TB is [foo.tsv bar.tsv]
Any idea how to get this working properly?
Note that I have both foo.csv
and bar.csv
files in the working directory.
Upvotes: 0
Views: 465
Reputation: 12899
The problem lies in the way you're using the built in variable $<
. If you expand the variables manually and rewrite the makefile it becomes...
NAMES = foo bar
PR = $(patsubst %,%.csv,$(NAMES))
TB = $(patsubst %,%.tsv,$(NAMES))
all: foo.tsv bar.tsv
%.tsv: foo.csv bar.csv
@echo $< $@
But $<
refers to the first prerequisite which is always foo.csv
regardless of the target.
One solution might be to use a scoped static pattern rule. So something like...
NAMES = foo bar
PR = $(patsubst %,%.csv,$(NAMES))
TB = $(patsubst %,%.tsv,$(NAMES))
all: $(TB)
# Tell make how to build a .tsv from a .csv but constrain the rule
# so that it only applies to .tsv files that are part of $(TB).
#
$(TB): %.tsv: %.csv
@echo 'building target [$@] with $$< = [$<]'
The above results in...
building target [foo.tsv] with $< = [foo.csv]
building target [bar.tsv] with $< = [bar.csv]
Upvotes: 2