tags:

views:

11

answers:

1

Consider the following Makefile

COMP = compiler

OBJECTS =   file1 \
        file2 \
        file3 \
        file4 \
        file5_suffix \
        file6 \
        file7 \
        file8 \
        file9_suffix \
        file10

all:    $(OBJECTS) 
        $(COMP) $(OBJECTS) -o bin/executable_suffix

Is there an easy way to compile multiple executables for different values of suffix? For example, the equivalent of

COMP = compiler

OBJECTS1 =  file1 \
        file2 \
        file3 \
        file4 \
        file5_s1 \
        file6 \
        file7 \
        file8 \
        file9_s1 \
        file10

OBJECTS2 =  file1 \
        file2 \
        file3 \
        file4 \
        file5_s2 \
        file6 \
        file7 \
        file8 \
        file9_s2 \
        file10

all:    $(OBJECTS1) $(OBJECTS2) 
        $(COMP) $(OBJECTS1) -o bin/executable_s1
        $(COMP) $(OBJECTS2) -o bin/executable_s2

but without redefining the whole list of objects? In the real life case I am dealing with, there might be 50+ objects and a dozen binaries to build, with only small changes between the object list each time, so it would be nice not to have to list all the objects each time.

A: 

This will do it. It can be made more elegant if there are more restrictions you can put on the variations.

COMP = compiler

OBJECTS =  file1 \
    file2 \
    file3 \
    file4 \
    file5 \
    file6 \
    file7 \
    file8 \
    file9 \
    file10

# This isn't terribly elegant, but it is quite general.
# If the variations you have in mind are more regular, such as
# changing only file5 and file9 for all executables, then there
# are tidier ways to do it.
OBJECTS1 := $(OBJECTS)
OBJECTS1 := $(patsubst file5,file5_s1,$(OBJECTS1))
OBJECTS1 := $(patsubst file9,file9_s1,$(OBJECTS1))

OBJECTS2 := $(OBJECTS)
OBJECTS2 := $(patsubst file5,file5_s2,$(OBJECTS2))
OBJECTS2 := $(patsubst file9,file9_s2,$(OBJECTS2))

all: bin/executable_s1 bin/executable_s2

# It looks a little clumsy to include the path in the target,
# but the idea is that the target should be what it's actually making,
# which is bin/executable_s1, not executable_s1.

bin/executable_s1: $(OBJECTS1)
bin/executable_s2: $(OBJECTS2)

bin/executable_%:
    $(COMP) $^ -o $@
Beta