makefile中的参数化配方?

时间:2014-04-16 04:19:54

标签: bash makefile

我有一个文件" ORIGINAL",如果更新,我想复制,修改和分发到驱动器上的几个地方。修改是通过一个小的bash脚本完成的,该脚本接受一个参数,每个生成的远程文件都有一个唯一的参数。

在我的Makefile中,我可以为每个参数使用单独的规则/配方,如下所示:

parameters = AWK BAT CAT DOG

$(DEST_FILE_AWK) : $(ORIGINAL)
    ./copyAndModify "AWK"     ## Creates $(ORIGINAL)_AWK, substed copy of ORIGINAL
    mv - f $(ORIGINAL)_AWK $(DEST_FILE_AWK)

$(DEST_FILE_BAT) : $(ORIGINAL)
    ./copyAndModify "BAT"     ## Creates $(ORIGINAL)_BAT, substed copy of ORIGINAL
    mv - f $(ORIGINAL)_BAT $(DEST_FILE_BAT)

DEST_FILE_AWKDEST_FILE_BAT的解除引用值彼此无关,但除此之外,上面的两个配方与参数的唯一区别完全相同,所以我可以&# 39; t帮助但希望将它们合并到一个具有多个目标规则行的超级规则/配方中。

但我无法实现这一目标。我已经在规则的目标部分尝试了各种foreach()和其他内容,但问题是无论如何,我都无法将参数的值输入到食谱部分。

有办法吗?

2 个答案:

答案 0 :(得分:0)

根据此处提供的信息,您可以做的最好(假设您正在使用GNU make)是一个eval / call组合。正如anishsane建议的那样,根据DEST_FILE_ *变量的值,可以做一些更简单的事情。

但这应该有效:

define COPY_TO_DEST
$$(DEST_FILE_$1) : $$(ORIGINAL)
        ./copyAndModify "$1"
        mv - f $$(ORIGINAL)_$1 $$@
endef

parameters = AWK BAT CAT DOG

$(foreach P,$(parameters),$(eval $(call COPY_TO_DEST,$P)))

答案 1 :(得分:0)

至少在gnu make中可以不用$(eval)来完成:)

  1. 从一个指定所有目标的配方开始,即目标列表在配方的左侧。假设我们有一个变量,其中包含所有这些目标的名称。

  2. 现在观察到,对于给定的配方, 函数和变量都将分别进行评估,因为它针对每个目标进行了扩展。回想一下,假设$@只是一个变量,并且将分别替换为每个目标。函数调用的行为相同。

  3. 提供类型列表和type:target对列表。我认为不需要像您一样将目标放到单独的变量中($(DEST_FILE_AWK)等)。

  4. TARGET_FOR_TYPE函数采用对和类型,并生成目标文件列表。

  5. TYPE函数计算的每个目标分配一次TYPE_FOR_TARGET变量。这样,重复的函数调用不会污染配方:)

请注意,DESTINATIONS列表包含纯文件名,没有任何进一步的间接引用。

types = AWK BAT
ORIGINAL = an_original
DESTINATIONS = \
    AWK:dest_for_awk \
    BAT:dest_for_bat

TARGET_FOR_TYPE = $(patsubst $(1):%,%,$(filter $(1):%,$(DESTINATIONS)))
TYPE_FOR_TARGET = $(patsubst %:$(1),%,$(filter %:$(1),$(DESTINATIONS)))

# Usage example for the functions above:
$(info type:   $(call TYPE_FOR_TARGET,dest_for_awk))
$(info target: $(call TARGET_FOR_TYPE,AWK))
$(info $())

DEST_FILES = $(foreach type,$(types),$(call TARGET_FOR_TYPE,$(type)))

all: $(DEST_FILES)

$(DEST_FILES) : TYPE=$(call TYPE_FOR_TARGET,$@)
$(DEST_FILES) : $(ORIGINAL)
    @echo ./copyAndModify $(TYPE)
    @echo mv - f $(ORIGINAL)_$(TYPE) $@