获取从列表生成的Makefile目标中的基变量
我有一个Makefile,它在自己的目录中管理多个FPGA构建。我有一个变量获取从列表生成的Makefile目标中的基变量,makefile,gnu-make,Makefile,Gnu Make,我有一个Makefile,它在自己的目录中管理多个FPGA构建。我有一个变量CS\u FPGA\u FETCH,它具有每个FPGA的唯一名称。(我的项目中的许多子文件夹都基于此名称) 我想要一个干净的方法来处理为每个FPGA添加一个目标。我想到的是addprefix并删除前缀 # Every FPGA CS_FPGAS_FETCH := cs00 cs01 cs02 cs03 cs10 cs11 cs12 cs13 cs20 cs21 cs22 cs23 cs30 cs31 cs32 cs33
CS\u FPGA\u FETCH
,它具有每个FPGA的唯一名称。(我的项目中的许多子文件夹都基于此名称)
我想要一个干净的方法来处理为每个FPGA添加一个目标。我想到的是addprefix
并删除前缀
# 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)
在我看来,这种方法似乎是落后的。我需要为我要使用的每个前缀创建一个
COPY\u TARGET\u FPGA\u NAME
。这似乎很令人困惑。我需要添加许多这样的目标,所有这些目标都有不同的前缀。我不确定我是否了解所有细节,因为您的前缀没有出现在您的配方中。因此,由于我看不到拥有其中几个的意义,我将假设目标比特流是install/
,而不是install/
我还将使用一种稍微面向make的方法,其中目标和先决条件是真实的文件。例如,要复制位流,更自然的做法是将install/
作为目标,将build//file.bit
作为先决条件
我还添加了install
,作为一个示例和创建它的规则
回到您的主要问题:如果您使用GNU make,您可以使用foreach eval call
在每次迭代中迭代列表并实例化make构造:
# 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 $@
根据您的需要进行调整,但请记住,
MY_rule
变量扩展了两次:一次扩展为eval
,另一次扩展为make。因此,某些变量必须针对第一次扩展进行保护(因此$$@
)。我不确定我是否了解所有细节,因为您的前缀没有出现在您的配方中。因此,由于我看不到拥有其中几个的意义,我将假设目标比特流是install/
,而不是install/
我还将使用一种稍微面向make的方法,其中目标和先决条件是真实的文件。例如,要复制位流,更自然的做法是将install/
作为目标,将build//file.bit
作为先决条件
我还添加了install
,作为一个示例和创建它的规则
回到您的主要问题:如果您使用GNU make,您可以使用foreach eval call
在每次迭代中迭代列表并实例化make构造:
# 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 $@
根据您的需要进行调整,但请记住,
MY_rule
变量扩展了两次:一次扩展为eval
,另一次扩展为make。因此,某些变量必须防止第一次扩展(因此$$@
)。前缀是copy\u official\u
感谢您的帮助!!前缀是copy\u official\u
谢谢您的帮助!!