获取从列表生成的Makefile目标中的基变量

获取从列表生成的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

我有一个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

# 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
谢谢您的帮助!!