Fri*_*dFX 5 overriding makefile gnu-make target
我想创建一个 makefile 来包含在其他文件中,有点像“库”,我们称之为library.mak:
TARGET_FILES = a.txt b.txt c.txt d.txt
SRC_FOLDER = somewhere/else
.PHONY: all
all:
for target in ${TARGET_FILES} ; do \
echo -e "\nMaking $${target}:" ;\
${MAKE} ${MFLAGS} --no-print-directory $${target} ;\
done
.PHONY: ${TARGET_FILES}
${TARGET_FILES}:
cp ${SRC_FOLDER}/$@ $@
Run Code Online (Sandbox Code Playgroud)
这两条规则分别是为了制定全部目标,以及一个特定目标;使用默认规则(这是library.mak的目的)。
在名为 Makefile 的“用户 makefile”中,我想执行以下操作:
include library.mak
# special handling of c.txt
c.txt:
grep -v 'all except this' ${SRC_FOLDER}/$@ > $@
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,用户希望能够覆盖某些特殊情况的行为。warning: overriding recipe for target虽然这种方法有效,但它总是用令人恐惧的消息向用户打招呼warning: ignoring old commands for target,即使行为符合预期。
所以问题是:是否可以通过不同的方式来避免这些警告,或者是否有办法抑制它们?
该警告表示您覆盖了显式规则的配方。这确实是错误的。使用模式规则是有意义的,例如:%.txt: ${SRC_FOLDER}/%.txt。那么可以有一些明确的规则(c.txt: ${SRC_FOLDER}/c.txt)覆盖配方。当然,它不是 100% 相同,但是,我认为这不应该成为问题。无论如何,将明确的规则放入可重用文件中是一种犯罪。
接下来,您不断地使用不带先决条件的“假冒”和规则,即使您确实应该拥有它们。这不好。您正在尝试使“make”作为非分支 shell 脚本工作。这不仅效率低下,而且是一种滥用。基本上,make 可以被视为“shell 扩展”,能够“以复杂的方式在文件时间戳上进行分支”。如果您不需要它,则根本不要使用 make。
接下来,我认为完全没有理由进行递归 make。不管怎样,你要做的,我相信,没有它你也能做。即使你确实需要递归,也可以简单地写$(MAKE)。$(MFLAGS)不应该再使用(阅读此内容)。
PS 还有另一个(更灵活的)选项来定义参数化变量(宏)。例如:
define nl :=
endef
define myrule.text
$1: $2/$1
@cp $$< $$@
endef
myrule = $(eval $(foreach foo$0,$1,$(call myrule.text,$(foo$0),$2)$(nl)))
...
# user makefile
# for everything except c.txt call predefined macro
$(call myrule,$(filter-out c.txt,$(TARGET_FILES)),$(SRC_FOLDER))
# for c.txt only
c.txt: $(SRC_FOLDER)/c.txt
grep -v 'all except this' $< >$@
Run Code Online (Sandbox Code Playgroud)
但正如你所看到的,这是一个有点“神秘”的东西,我不想向初学者推荐它。