Search code examples
buildmakefilebuild-processgnu-make

Multiple wildcards in GNU Makefile Pattern


My filetree looks somewhat like this:

Makefile
src/foo/foo.c
src/bar/bar.c
build/bin/
build/libs/

Each sub-directory contains other files related to the source, so i want some structure. Since i have many foos and even more bars, i thought of a pattern rule:

PROGS=foo bar

all : $(PROGS)

% :: src/%/%.c
    @echo $@ $<

Unfortunately make does not recognize this as a valid pattern:

make: *** No rule to make target `foo', needed by `all'.  Stop.

However, If I keep all files in just the src/ directory, a single % works as expected:

% :: src/%.c
    @echo $@ $<

Output:
foo src/foo
bar src/bar

Is there a way to do this without giving up the structure?


Solution

  • Use vpath:

    PROGS=foo bar
    
    all : $(PROGS)
    
    % : %.c
        @echo $@ $<
    
    vpath %.c src/foo src/bar
    

    And if you want to put the binaries in build/bin/,

    PROGS = build/bin/foo build/bin/bar
    
    all : $(PROGS)
    
    build/bin/% : %.c
        @echo $@ $<
    
    vpath %.c src/foo src/bar