makefile 在其依赖项中两次替换目标模式
makefile substitute target pattern twice in its dependency
我有以下项目架构
/
├── makefile
└── doc/
├── makefile
└── uml/
├── uml1/
│ ├── uml1.plantuml
| └── res/
| ├── ressource1
| └── ressource2
└── uml2/
├── uml2.plantuml
└── res/
├── ressource1
└── ressource2
我的目标是为 doc/uml
中存在的每个目录生成一个 png 图像到 build/doc/uml
父makefile如下
BUILD_PATH?=./build
doc:
${MAKE} -C $@ $@ ADOC_OUTPUT_DIR=$(abspath ${BUILD_PATH}/doc)
clean:
rm -rf build
.PHONY: doc clean
而submakefile就是下面这个
ADOC_OUTPUT_DIR ?= build
UML_OUTPUT_DIR = ${ADOC_OUTPUT_DIR}/uml
UML = $(notdir $(wildcard uml/*))
UML_TARGETS = $(foreach uml, ${UML}, ${UML_OUTPUT_DIR}/${uml}.png)
doc: uml
uml: ${UML_OUTPUT_DIR} ${UML_TARGETS}
${UML_TARGETS}: ${UML_OUTPUT_DIR}/%.png : uml/%/%.plantuml
plantuml $< -o $(@D)
###################################
##### Directory creation part #####
###################################
${UML_OUTPUT_DIR}:
mkdir -p $@
.PHONY: doc uml ${UML_TARGETS} ${UML_OUTPUT_DIR}
但是当我用 make doc
启动它时它失败了
$ make doc
make -C doc doc ADOC_OUTPUT_DIR=/home/julien/test_uml/build/doc
make[1] : Entering directory « /home/julien/test_uml/doc »
make[1]: *** No rule to make target « uml/gui_state_diagram/%.plantuml », needed by « /home/julien/test_uml/build/doc/uml/gui_state_diagram.png ». Stop.
make[1] : Exiting directory « /home/julien/test_uml/doc »
makefile:12 : the recipe for target « doc » failed
make: *** [doc] Erreur 2
看来问题出在'%'不能在依赖项上被替换两次。
如果不修改项目架构,我找不到实现我的目标的方法(我想保持它与现在一样接近)
有没有办法将模式“%”替换两次?
有没有比尝试在目标依赖项中替换 uml 名称两次更好的方法来实现我的目标?
因为 uml/%/%.plantuml
中的两个 %
s 在文件系统中必须是唯一的,额外的目录在保持结果路径唯一性方面不会添加任何东西 - uml/foo/foo.plantuml
不是'它比 uml/foo.plantuml
更有用。我会简单地删除 uml
.
下的目录
确实,在您的情况下,您不能使用静态模式规则。但是你可以使用 the eval
function:
define MY_rule
${UML_OUTPUT_DIR}/$(1).png : uml/$(1)/$(1).plantuml
plantuml $$< -o $$(@D)
endef
$(foreach u,$(UML),$(eval $(call MY_rule,$(u))))
你也可以使用secondary expansion:
.SECONDEXPANSION:
${UML_TARGETS}: ${UML_OUTPUT_DIR}/%.png : uml/$$*/$$*.plantuml
plantuml $< -o $(@D)
我有以下项目架构
/
├── makefile
└── doc/
├── makefile
└── uml/
├── uml1/
│ ├── uml1.plantuml
| └── res/
| ├── ressource1
| └── ressource2
└── uml2/
├── uml2.plantuml
└── res/
├── ressource1
└── ressource2
我的目标是为 doc/uml
中存在的每个目录生成一个 png 图像到 build/doc/uml
父makefile如下
BUILD_PATH?=./build
doc:
${MAKE} -C $@ $@ ADOC_OUTPUT_DIR=$(abspath ${BUILD_PATH}/doc)
clean:
rm -rf build
.PHONY: doc clean
而submakefile就是下面这个
ADOC_OUTPUT_DIR ?= build
UML_OUTPUT_DIR = ${ADOC_OUTPUT_DIR}/uml
UML = $(notdir $(wildcard uml/*))
UML_TARGETS = $(foreach uml, ${UML}, ${UML_OUTPUT_DIR}/${uml}.png)
doc: uml
uml: ${UML_OUTPUT_DIR} ${UML_TARGETS}
${UML_TARGETS}: ${UML_OUTPUT_DIR}/%.png : uml/%/%.plantuml
plantuml $< -o $(@D)
###################################
##### Directory creation part #####
###################################
${UML_OUTPUT_DIR}:
mkdir -p $@
.PHONY: doc uml ${UML_TARGETS} ${UML_OUTPUT_DIR}
但是当我用 make doc
$ make doc
make -C doc doc ADOC_OUTPUT_DIR=/home/julien/test_uml/build/doc
make[1] : Entering directory « /home/julien/test_uml/doc »
make[1]: *** No rule to make target « uml/gui_state_diagram/%.plantuml », needed by « /home/julien/test_uml/build/doc/uml/gui_state_diagram.png ». Stop.
make[1] : Exiting directory « /home/julien/test_uml/doc »
makefile:12 : the recipe for target « doc » failed
make: *** [doc] Erreur 2
看来问题出在'%'不能在依赖项上被替换两次。
如果不修改项目架构,我找不到实现我的目标的方法(我想保持它与现在一样接近)
有没有办法将模式“%”替换两次?
有没有比尝试在目标依赖项中替换 uml 名称两次更好的方法来实现我的目标?
因为 uml/%/%.plantuml
中的两个 %
s 在文件系统中必须是唯一的,额外的目录在保持结果路径唯一性方面不会添加任何东西 - uml/foo/foo.plantuml
不是'它比 uml/foo.plantuml
更有用。我会简单地删除 uml
.
确实,在您的情况下,您不能使用静态模式规则。但是你可以使用 the eval
function:
define MY_rule
${UML_OUTPUT_DIR}/$(1).png : uml/$(1)/$(1).plantuml
plantuml $$< -o $$(@D)
endef
$(foreach u,$(UML),$(eval $(call MY_rule,$(u))))
你也可以使用secondary expansion:
.SECONDEXPANSION:
${UML_TARGETS}: ${UML_OUTPUT_DIR}/%.png : uml/$$*/$$*.plantuml
plantuml $< -o $(@D)