EncryptedWatermelon
EncryptedWatermelon

Reputation: 5598

Makefile pattern match on multiple directories

I have a make target for *.abc files that need then trigger DIR/%.xyz. The problem is DIR is passed in as a list of directories. %.xyz is unique and exists only in one place. I've tried using a foreach without any luck. Any help would be much appreciated.

OtherDir:=dir1 dir2 dir3
${SOURCE_DIR}/%.abc: $(foreach dir, OtherDir, $(if ${dir}/%.xyz,,$(info Match found in ${dir}))

Edit - Found one possible solution. Instead of storing path to ${dir}/$*.xyz it is passed directly into the compile step. OtherDir:=dir1 dir2 dir3

${SOURCE_DIR}/%.abc:
    $(call status, Do the stuff)
    3rd_party_compile_tool $(foreach dir, ${OtherDir}, $(wildcard ${dir}/$*.xyz))

Upvotes: 0

Views: 706

Answers (2)

raspy
raspy

Reputation: 4261

The foreach that you wanted to do needs secondary expansion, so that it is evaluated when the stem (the % part) is set. Consider the following Makefile:

SOURCE_DIR := src
OtherDir := dir1 dir2 dir3

.SECONDEXPANSION:

$(SOURCE_DIR)/%.abc: $$(foreach dir,$(OtherDir),$$(wildcard $$(dir)/$$*.xyz))
        echo Making $@ from $^

with given file structure:

.
./dir1
./dir2
./dir2/foo.xyz
./dir3
./dir3/bar.xyz
./Makefile

it will match the appropriate prerequisite based on the stem:

$ make -s src/foo.abc src/bar.abc
Making src/foo.abc from dir2/foo.xyz
Making src/bar.abc from dir3/bar.xyz

Upvotes: 1

HardcoreHenry
HardcoreHenry

Reputation: 6387

So, for starters, the way you're trying to do things makes it sound like there's a flaw in your overall make design (specifically, if you have two %.xyz's with the same name in multiple directories, this will cause you issues -- and while you might not have any now, this is a sharp stick).

If you did want to do this, you could use a template/eval to generate a separate pattern rule for each of the dirs. Make will pick the first pattern that matches when trying to build %.abc.

OtherDir:=dir1 dir2 dir3

define abc_rule
${SOURCE_DIR}/%.abc: $(1)/%.xyz
    @3rd_party_compile_tool $^
endef

$(foreach dir,${OtherDir},$(eval $(call abc_rule,${dir})))

(notice that your updated posted solution will have issues due to dependencies).

Upvotes: 1

Related Questions