代码之家  ›  专栏  ›  技术社区  ›  Gergely

make无法识别Makefile中的目标

  •  0
  • Gergely  · 技术社区  · 4 年前

    我经历了以下事情:

    $ cat Makefile
    POLYSCRIPTER=${HOLDIR}/Manual/Tools/polyscripter
    UMAP=${HOLDIR}/Manual/Tools/umap
    
    all:    tactics.pdf
    
    %.tex:  %.stex
            ${POLYSCRIPTER} ${UMAP} <%.stex >%.tex
    
    tactics.pdf:    %.tex
            pdflatex tactics.tex
            bibtex tactics
            pdflatex tactics.tex
            pdflatex tactics.tex
    
    
    clean:
            rm tactics.{aux,bbl,blg,log,pdf,tex,ui,uo}
    $ make
    make: *** No rule to make target '%.tex', needed by 'tactics.pdf'.  Stop.
    

    有一个%.tex目标。我做错了什么?

    这是GNU Make 4.3。

    更新:我想表达的是:从相应的%.stex文件创建任何%.tex文件,然后从latexing tactist.tex生成包含所有%/tex文件的tactiss.pdf。

    更新2:我编辑了一行,学习如何引用依赖关系和目标:

    ${POLYSCRIPTER} ${UMAP} <$< >$@                   
    
    1 回复  |  直到 4 年前
        1
  •  1
  •   MadScientist    4 年前

    模式规则是告诉make如何构建目标的模板。它没有为make提供要构建的目标列表:它只是构建目标的配方。所以这个模式规则:

    %.tex:  %.stex
    

    不告诉make“走出文件系统并找到所有匹配的文件” %.stex 这可能会变成 .tex 它告诉make,“嘿,如果你发现出于某种原因,你想建立一个与模式匹配的目标 %.tex 那么,这里有一种方法可以构建它”。

    另一方面,这:

    tactics.pdf:    %.tex
    

    这根本不是一个模式规则。模式规则 必须 有一个 % 在目标名称中。这是一个直接的显式规则,恰好依赖于一个名为的文件,字面意思是 %.tex .Make不知道如何构建名为的文件 %.tex (因为没有按字面意思命名的文件 %.stex 因此,您上面定义的模式规则不适用)。

    你可以这样做:

    tactics.pdf: *.tex
    

    使用shell globbing。这更接近,因为它告诉生成一组 .tex 要构建的文件。但这也行不通,因为当你第一次跑步时,不要 .tex 文件存在!因此,此表达式将与任何文件都不匹配,您将拥有一组空的先决条件。

    您需要做的是(1)找到要构建的所有源文件:

    STEX := $(wildcard *.stex)
    

    然后(2)将其转换为要构建的目标集:

    TEX := $(patsubst %.stex,%.tex,$(STEX))
    

    然后(3)列出这些目标作为PDF文件的先决条件:

    tactics.pdf: $(TEX)
    

    现在,make将使用您的模式规则来确定如何构建这些 .tex 文件夹。