Question

Is it possible to use makefile variables in prerequisites? My example below is a little backward, but should demonstrate what I'm trying to achieve:

objects_subsystem1 := $(patsubst %.c,%.o,$(wildcard ../src/ss1/*.c))
objects_subsystem2 := $(patsubst %.c,%.o,$(wildcard ../src/ss2/*.c))

all : subsystem1.elf subsystem2.elf

%.elf : $(objects_%)
    $(LD) $< -o $@

EDIT: I'm using GNU Make 3.80 so unfortunately SECONDEXPANSION is not available!

Was it helpful?

Solution

Yes, if you're using GNUMake:

.SECONDEXPANSION:
%.elf : $$(objects_%)
    $(LD) $< -o $@

EDIT:

As @bobbogo points out, there is a solution that does not require .SECONDEXPANSION. First, we spell out the rules:

objects_subsystem1 := $(patsubst %.c,%.o,$(wildcard ../src/ss1/*.c))
objects_subsystem2 := $(patsubst %.c,%.o,$(wildcard ../src/ss2/*.c))
objects_subsystem3 := $(patsubst %.c,%.o,$(wildcard ../src/ss3/*.c))

all : subsystem1.elf subsystem2.elf subsystem3.elf

subsystem1.elf : $(objects_subsystem1)
    $(LD) $< -o $@
subsystem2.elf : $(objects_subsystem2)
    $(LD) $< -o $@
subsystem3.elf : $(objects_subsystem3)
    $(LD) $< -o $@

Then we rearrange things a little:

objects_subsystem1 := $(patsubst %.c,%.o,$(wildcard ../src/ss1/*.c))
all : subsystem1.elf
subsystem1.elf : $(objects_subsystem1)
objects_subsystem2 := $(patsubst %.c,%.o,$(wildcard ../src/ss2/*.c))
all : subsystem2.elf
subsystem2.elf : $(objects_subsystem2)
objects_subsystem3 := $(patsubst %.c,%.o,$(wildcard ../src/ss3/*.c))
all : subsystem3.elf
subsystem3.elf : $(objects_subsystem3)

%.elf :
    $(LD) $< -o $@

Then we use the eval function:

define RULE_TEMPLATE
objects_subsystem$(1) := $(patsubst %.c,%.o,$(wildcard ../src/ss$(1)/*.c))
all : subsystem$(1).elf
subsystem$(1).elf : $$(objects_subsystem$(1))
endef

$(eval $(call RULE_TEMPLATE,1))
$(eval $(call RULE_TEMPLATE,2))
$(eval $(call RULE_TEMPLATE,3))

%.elf :
    $(LD) $< -o $@

Then finish up with a loop (if it's worth it):

define RULE_TEMPLATE
objects_subsystem$(1) := $(patsubst %.c,%.o,$(wildcard ../src/ss$(1)/*.c))
all : subsystem$(1).elf
subsystem$(1).elf : $$(objects_subsystem$(1))
endef

SUBSYSTEMS := 1 2 3 # this can be made automatic...

$(foreach sys,$(SUBSYSTEMS),$(eval $(call RULE_TEMPLATE,$(sys))))

%.elf :
    $(LD) $< -o $@
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top