0
votes

Suppose I have a set of source files:

src/foo/file.abc
src/foo/otherfile.abc

that I want to do some operation on (for simplicity, let's just say copy) resulting in destination files in several different places:

dest/bar/file.xyz
dest/bar/otherfile.xyz
dest/baz/file.xyz
dest/baz/otherfile.xyz
dest/something/file.xyz
dest/something/otherfile.xyz

How do I express that dependency in a Makefile, so that updating the prerequisite file causes a recipe to recreate the target?

The GNU Make manual says "Wildcard expansion is performed by make automatically in targets and in prerequisites". Going by that, I would expect

dest/*/%.xyz : src/foo/%.abc
    install -d $< $@

to work, but it fails:

$ make -f test.mk dest/bar/file.xyz
make: *** No rule to make target `dest/bar/file.xyz'.  Stop.

Am I misunderstanding wildcard expansion in targets? Is there some better way to achieve what I'm after?

Environment: GNU Make 3.82.90
32-bit Cygwin

3

3 Answers

0
votes

It's not entirely clear what you're after. How about this:

dest/%.xyz:
    cp src/foo/$(notdir $*).abc $@

Now make -f test.mk dest/bar/file.xyz will copy src/foo/file.abc to dest/bar/file.xyz. Is that all you want it to do, or do you want it to copy the file to other destinations as well, or copy other files in the same operation, or what?

0
votes

Yes wildcard expansion is performed, as per the shell . If you don't have any destination files to begin with, the expansion will be to nothing. Make can't magically figure out what destination files you want.

So, you need to declare the destination files you want and proceed like this:

DEST_FILES := \
    dest/bar/file.xyz \
    dest/bar/otherfile.xyz \
    dest/baz/file.xyz \
    dest/baz/otherfile.xyz \
    dest/something/file.xyz \
    dest/something/otherfile.xyz \

.PHONY: all
all: $(DEST_FILES)

.SECONDEXPANSION:

$(DEST_FILES): %xyz: src/foo/$$(notdir $$*)abc Makefile
    cp $< $@
0
votes

I found a solution which relies on the GNU extension .SECONDEXPANSION, which is not ideal but better than nothing:

.SECONDEXPANSION:
dest/%.xyz : src/foo/$$(@F)
    install -D $< $@