etheranger
etheranger

Reputation: 1273

Wildcard expansion in makefile targets

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

Upvotes: 1

Views: 1359

Answers (3)

etheranger
etheranger

Reputation: 1273

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 $< $@

Upvotes: 1

Mark Galeck
Mark Galeck

Reputation: 6385

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 $< $@

Upvotes: 0

Beta
Beta

Reputation: 99094

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?

Upvotes: 0

Related Questions