【问题标题】:get base variable in Makefile targets that are made from a list从列表中获取 Makefile 目标中的基本变量
【发布时间】:2017-12-14 03:09:46
【问题描述】:

我有一个 Makefile,它在自己的目录中管理多个 FPGA 构建。我有一个变量CS_FPGA_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_TARGET_FPGA_NAME。这似乎非常令人困惑。我需要添加许多具有不同前缀的此类目标。

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    不确定我是否了解所有详细信息,因为您的前缀没有出现在您的食谱中。因此,由于我看不出拥有其中几个的意义,我将假设目标比特流是install/<prefix><fpga>,而不是install/<fpga>。

    我还将使用稍微更面向 make 的方法,其中目标和先决条件是真实文件。例如,要复制您的比特流,将install/<prefix><fpga> 作为目标并以build/<fpga>/file.bit 作为先决条件更为自然。

    我还将install 添加为order-only prerequisite 和创建它的规则。

    回到您的主要问题:如果您使用 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_official_谢谢你的帮助!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多