代码之家  ›  专栏  ›  技术社区  ›  Arkaik zx81

makefile在其依赖项中替换目标模式两次

  •  1
  • Arkaik zx81  · 技术社区  · 7 年前

    /
    ├── makefile
    └── doc/
        ├── makefile
        └── uml/
            ├── uml1/
            │   ├── uml1.plantuml
            |   └── res/
            |       ├── ressource1
            |       └── ressource2
            └── uml2/
                ├── uml2.plantuml
                └── res/
                    ├── ressource1
                    └── ressource2
    

    我的目标是为每个目录生成一个png图像 doc/uml build/doc/uml

    父makefile如下

    BUILD_PATH?=./build
    
    doc:
        ${MAKE} -C $@ $@ ADOC_OUTPUT_DIR=$(abspath ${BUILD_PATH}/doc)
    
    clean:
        rm -rf build
    
    .PHONY: doc clean
    

    子基文件如下

    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名称更好的方法来实现我的目标?

    3 回复  |  直到 7 年前
        1
  •  4
  •   MadScientist    7 年前

    你也可以使用 secondary expansion :

    .SECONDEXPANSION:
    ${UML_TARGETS}: ${UML_OUTPUT_DIR}/%.png : uml/$$*/$$*.plantuml
            plantuml $< -o $(@D)
    
        2
  •  1
  •   Renaud Pacalet    7 年前

    实际上,在您的情况下,不能使用静态模式规则。但你可以用 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))))
    
        3
  •  0
  •   l0b0    7 年前

    % s在 uml/%/%.plantuml 在文件系统中必须是唯一的,额外的目录不会添加任何东西来保持结果路径的唯一性- uml/foo/foo.plantuml uml/foo.plantuml . 我只想把下面的目录去掉 uml .