0
votes

Let's say I have this GNU makefile:

SOURCE = source1/a source2/b source3/c
BUILD  = build/a build/b build/c
BASE   = build/

$(BUILD): $(BASE)%: %
    install $< $@

So basically I have files in the directories source1, source2 and source3, which I want to regardlessly put into the build directory.

I want to accomplish this with a single static pattern rule. My naïve approach would be this:

$(BUILD): $(BASE)%: $(filter *%, $(SOURCE))
    install $< $@

This doesn't work. I know that filters are also denoted with percentage signs.

$(BUILD): $(BASE)%: $(wildcard */$(notdir %))
    install $< $@

This doesn't work either. But even if, this would still be non-satisfactory, as I might want to touch a new file source1/b, which would mess everything up.

How can I use the $(filter) function in GNU makefile static pattern rules? Or is there another approach to do accomplish this?

The hierarchy now looks like this:

source1/
        a
source2/
        b
source3/
        c
build/

I want it to look like this:

source1/
        a
source2/
        b
source3/
        c
build/
        a
        b
        c
2
If you have source1/b and source2/b, then what do you want to put into build/?Beta
I want to put a, b and c into build.hgiesel
Which b do you want to put into build/? You say that you might wish to introduce source/b in addition to source2/b, but you don't say what you want Make to do in that case.Beta
Oh, I'm so sorry, I misread your answer! I'd want to put source2/b into build, because it is in the $(SOURCE) variable. I think this problem can't be appropriately solved in make, so I would do that outside of make.hgiesel

2 Answers

2
votes

After reading a thousand Stackoverflow questions and the GNU make tutorial for hours, I finally got it working:

SOURCE = source1/a source2/b source3/c
TEST   = a b c
BUILD  = build/a build/b build/c
BASE   = build/
PERCENT = %

.SECONDEXPANSION:
$(BUILD): $(BASE)%: $$(filter $$(PERCENT)/$$*,$$(SOURCE))
    install $< $@

It's kinda hacky, but I'm happy with it. If anybody got any better idea, please let me know.

2
votes

You can do this with the VPATH variable:

SOURCE = source1/a source2/b source3/c
BUILD  = build/a build/b build/c
BASE   = build/

VPATH = source1 source2 source3

$(BUILD): $(BASE)%: %
    install $< $@

Or:

SOURCE = source1/a source2/b source3/c
BASE   = build/
BUILD  = $(addprefix $(BASE), $(notdir $(SOURCE)))

VPATH = $(dir $(SOURCE))

$(BUILD): $(BASE)%: %
    install $< $@