Reputation: 7653
I have a Makefile which manages multiple FPGA builds in their own directory. I have a variable CS_FPGA_FETCH
which has the unique name of each fpga. (Many subfolders in my project are based on this name).
I would like a clean way to deal with adding a target for each FPGA. What I came up with is addprefix
and removing the prefix.
# Every FPGA
CS_FPGAS_FETCH := cs00 cs01 cs02 cs03 cs10 cs11 cs12 cs13 cs20 cs21 cs22 cs23 cs30 cs31 cs32 cs33
# this is a list of variables that has the words copy_official_ prefixed
# to all of the cs00, cs01
COPY_OFFICIAL_CS_TARGETS=$(addprefix copy_official_,$(CS_FPGAS_FETCH))
# because we use add prefix, we HAVE to strip it off
# this replases $(@) for guys with a prefix, so we can access the base variable inside the loop below
COPY_TARGET_FPGA_NAME=$(@:copy_official_%=%)
# this evaluates out to targets named:
# copy_official_cs00, copy_official_cs01 etc
$(COPY_OFFICIAL_CS_TARGETS):
@echo In $(@) target. Here i copy file $(COPY_TARGET_FPGA_NAME)
cp build/$(COPY_TARGET_FPGA_NAME)/file.bit install/$(COPY_TARGET_FPGA_NAME)
This method seems backwards to me. I need to create a COPY_TARGET_FPGA_NAME
for each prefix I want to use. This seems very confusing. I need to add many such targets all with different prefixes.
Upvotes: 0
Views: 101
Reputation: 29345
Not sure I understand all details because your prefix does not appear in your recipe. So, as I do not see the point in having several of them, I will assume that the destination bitstream is install/<prefix><fpga>
, not install/<fpga>
.
I will also use a slightly more make-oriented approach where targets and prerequisites are real files. To copy your bitstreams, for instance, it is more natural to have install/<prefix><fpga>
as target and build/<fpga>/file.bit
as prerequisite.
I also add install
as an order-only prerequisite and a rule to create it.
Back to your main question: if you use GNU make you can use foreach-eval-call
to iterate over lists and instantiate make constructs in each iteration:
# Every FPGA
CS_FPGAS_FETCH := cs00 cs01 cs02 cs03 cs10 cs11 cs12 cs13 cs20 cs21 cs22 cs23 cs30 cs31 cs32 cs33
# Every prefix
PREFIXES = copy_official_
.PHONY: all
# $(1): prefix
# $(2): FPGA name
define MY_rule
all: install/$(1)$(2)
install/$(1)$(2): build/$(2)/file.bit | install
@echo In $$@ target. Here i copy file $(2)
cp build/$(2)/file.bit $$@
endef
$(foreach p,$(PREFIXES),$(foreach f,$(CS_FPGAS_FETCH),$(eval $(call MY_rule,$(p),$(f)))))
install:
mkdir $@
Adapt to your needs but remember that the MY_rule
variable is expanded twice: one time by eval
and one more by make in its regular processing. So, some variables must be protected against the first expansion (thus the $$@
).
Upvotes: 2