【问题标题】:makefile patternrule with further wildcards in target file name在目标文件名中带有更多通配符的 makefile 模式规则
【发布时间】:2012-02-12 08:49:48
【问题描述】:

我需要创建一个特殊的 makefile 规则,最好用一个例子来解释。 也许我们用规则创建文件

%_test.pdf: %.tex
    pdflatex -jobname=%_test %.tex

%_result.pdf: %.tex
    pdflatex -jobname=%_result %.tex

它工作正常。只是想到有更多类似上面的模板,人们可能会想到一个通配符规则,如

%_WILDCARD.pdf: %.tex
    pdflatex -jobname=%_$(WILDCARD) %.tex

WILDCARD 由 make 决定。有没有可能建立这样的规则?

【问题讨论】:

    标签: makefile design-patterns wildcard


    【解决方案1】:

    我认为受到@eldar 和@andres 答案的启发,我得到了自己的解决方案

    .SECONDEXPANSION:
    %.pdf: $$(firstword $$(subst _, ,%))
        pdflatex -jobname=$* $+
    

    这正是我所需要的。这种方式的详细信息可以在GNU make manual找到。

    【讨论】:

      【解决方案2】:

      只需将您的目标合并到一个规则中,如下所示:

      %_test.pdf %_result.pdf : %.tex
          pdflatex -jobname=$(basename $@) $<
      

      更新。

      正如 Bastian 在 cmets 中所说,此解决方案不适用于模式规则。

      【讨论】:

      • 谢谢@eldar-abusalimov!听起来很有趣......但是 - 这会告诉 make,这两个文件都是由一次运行创建的,或者?请考虑只构建_result.pdf ...
      • @BastianEbeling 不,这告诉 make 两个目标具有相同的配方和先决条件模式,仅此而已。每个目标都将使用其自己的命令构建,其值为$@ 和$&lt;。只构建一个目标是可以的。
      • 好的@eldar-abusalimov,你能解释一下你的提议吗,它描述的行为与GNU make manual最后一段中给出的行为不同?此外,我可以用通配符替换下划线后面的那些东西吗?
      • @BastianEbeling,好吧,我建议这个是因为Multiple Targets in a Rule 章节。根据您提供的链接,它似乎不适用于模式规则。
      • @Beta,我只是尝试从xxx.tex 制作xxx_test.pdf 和xxx_result.pdf,它只构建第一个。对于后者,它说Nothing to be done for 'xxx_result.pdf'.
      【解决方案3】:

      您所要求的并非微不足道。您可能会得到满足您需求的东西,但这需要一些工作。

      为了清楚起见,(假设它有效)

      %_WILDCARD.pdf: %.tex
          pdflatex -jobname%_$(WILDCARD) %.tex
      

      会有一个规则,对于每个 .tex 文件,您将使用 WILDCARD 作为作业名称运行 pdflatex。因此,您可以键入: make doc_test.pdf 使用作业“doc_test”从 doc.tex 文件中获取 pdf。

      获得类似行为的一种方法是使用:

      # First get the names of all the .tex files
      TEX_FILE_NAMES := $(wildcard *.tex)
      
      #Find the names of the pdfs that could be made with those .tex files
      # Use the wildcard for the job-name instead of the file-name
      define PDF_Template
      $(1)_%.pdf: $(1).tex
          paflatex -jobname=$$@ $$<
      endef
      
      $(foreach TEX_FILE,$(TEX_FILE_NAMES),$(eval $(call PAF_TEMPLATE,$(basename $(TEX_FILE)))))
      

      然后运行它

      make doc_test.pdf
      

      我会继续声明我实际上并没有运行它,所以请原谅任何拼写错误。

      【讨论】:

        猜你喜欢
        • 2013-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-13
        相关资源
        最近更新 更多