我对makefile很新。我发现make文件中存在一个缺陷,导致列表中的文件从单个源文件而不是列表中的每个文件中复制。
首先,有一个子模型变量SUB_MODEL_LIST
,其中包含由空格分隔的0 1 2 3
。
以下是执行复制的细分:
$(TARGET_BIN_LIST_NEW) : $(TARGET_BIN_LIST)
@echo copying from $< to $@
$(call COPY, $(firstword $(TARGET_BIN_LIST)), $@)
TARGET_BIN_LIST_NEW
包含由空格分隔的新文件名,由以下内容组成:
file001.200 file001.201 file001.202 file001.203
和TARGET_BIN_LIST
包含现有文件名,由以下内容组成:
file001c.200 file001c.201 file001c.202 file001c.203
文件扩展名的最后一位是型号。 当我读到这个时,makefile运行:
@echo copying from $< to $@
$(call COPY, $(firstword $(TARGET_BIN_LIST)), $@)
但是,由于TARGET_BIN_LIST
功能,它总是使用firstword
中的第一个文件名。这会导致file001.200, file001.201, file001.202, file001.203
被创建,但它们都是file001c.200
的副本,它们应该是列表中各自文件的副本。每个文件都与代码的子模型版本有关。
我想解决这个问题就是使用word
函数。像这样:
$(TARGET_BIN_LIST_NEW) : $(TARGET_BIN_LIST)
@echo copying from $< to $@
$(call COPY, $(word $(sub), $(TARGET_BIN_LIST)), $@)
其中sub
是SUB_MODEL_LIST的元素,但我不确定它是如何工作的。以上是否分为4个单独的调用,或者可以将其视为可以具有sub
的增量值的循环
我还考虑过使用foreach循环:
$(foreach sub,$(SUB_MODEL_LIST),$(call COPY, $(word $(sub), $(TARGET_BIN_LIST)), $(word $(sub), $(TARGET_BIN_LIST_NEW)))
但我收到错误:
*** first argument to `word' function must be greater than 0. Stop.
好的,我试过了:
$(foreach sub,$(SUB_MODEL_LIST),$(call COPY, $(word $(sub)+1, $(TARGET_BIN_LIST)), $(word $(sub)+1, $(TARGET_BIN_LIST_NEW)))
但后来我收到了错误:
*** non-numeric first argument to `word' function. Stop.
现在我被卡住了。我希望尽可能保持现有的实现,但如果需要可以采用循环方法。
感谢您的帮助!
答案 0 :(得分:0)
你必须退后一步。你误解了它是如何工作的。在制定具有多个目标的显式规则时,完全相同,因为多次编写相同的规则,每个目标一次。所以这个:
$(TARGET_BIN_LIST_NEW) : $(TARGET_BIN_LIST)
@echo copying from $< to $@
$(call COPY, $(firstword $(TARGET_BIN_LIST)), $@)
如果TARGET_BIN_LIST_NEW
为file001.200 file001.201 file001.202 file001.203
且TARGET_BIN_LIST
为file001c.200 file001c.201 file001c.202 file001c.203
,则与撰写此内容相同:
file001.200 : file001c.200 file001c.201 file001c.202 file001c.203
...
file001.201 : file001c.200 file001c.201 file001c.202 file001c.203
...
file001.202 : file001c.200 file001c.201 file001c.202 file001c.203
...
file001.203 : file001c.200 file001c.201 file001c.202 file001c.203
...
因此,您可以清楚地看到,在运行每条规则时,$<
和$(firstword $(TARGET_BIN_LIST))
的值将是相同的(file001c.200
)。
是否真的出现这样的情况:每当fileXXXc.YYY
个文件发生变化时,您想重建所有fileXXX.YYY
个文件?这就是你的规则所做的事情,但根据食谱,它看起来并不像你想要的那样。
Make主要是编写一个规则来构建来自零个或多个先决条件的一个目标。如果您使用模式规则,则可以非常轻松地执行此操作:
all: $(TARGET_BIN_LIST_NEW)
file001.% : file001c.%
@echo copying from $< to $@
$(call COPY,$<,$@)
如果你的文件名可能有更复杂的命名约定,那么你需要更复杂的东西。
ETA:
由于您的命名惯例不适合制作模式规则功能,因此您必须做更高级的事情。您可以使用eval
生成规则,如下所示:
all: $(TARGET_BIN_LIST_NEW)
define TARGET_BIN_COPY
$(1) : $(basename $(1))c$(suffix $(1))
@echo copying from $$< to $$@
$$(call COPY,$$<,$$@)
endef
$(foreach T,$(TARGET_BIN_LIST_NEW),$(eval $(call TARGET_BIN_COPY,$T)))
# uncomment this for debugging
#$(foreach T,$(TARGET_BIN_LIST_NEW),$(info $(call TARGET_BIN_COPY,$T)))
答案 1 :(得分:0)
首先,感谢MadScientist帮助澄清其工作原理。
这个实现对我有用:
$(TARGET_BIN_LIST_NEW) : $(TARGET_BIN_LIST)
@echo copying from $(filter %$(suffix $@), $(TARGET_BIN_LIST)) to $@
$(call COPY, $(filter %$(suffix $@), $(TARGET_BIN_LIST)), $@)