Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make always remakes PHONY static rule targets

Tags:

makefile

latex

I've been scratching my head for about an hour now, and Google has proved of limited use. I have a Makefile for a report which contains graphs. The graphs are represented by .plot files inside the directory graphs/, and gnuplot is used to generate .tex and .eps files from them. ps2pdf is then used to generate a pdf from the .eps, and finally an \include command inside report.tex includes the graph .tex into the document, which again includes the graph .pdf to put the graph in the final report.pdf.

I have a Makefile which builds everything correctly, but for some reason, make insists on remaking report.pdf every time I run make. A read through the ouput of make -d reveals that Make says: "Must remake target mp-int-2.4-ni'." and "Must remake targetmp-int-2.4-i'." every run, but these are declared as PHONY, and thus shouldn't be remade unless something they depend on has change. Or at least so I thought?

Any thoughts on what might be causing this and how I might avoid having to remake the final pdf every time?

Makefile

GRAPHS := mp-int-2.4-ni mp-int-2.4-i

.PHONY : $(GRAPHS)
.PRECIOUS : graphs/%.pdf

report.pdf: report.tex $(GRAPHS)
    # ...

$(GRAPHS): %: graphs/%.pdf graphs/%.tex

graphs/%.pdf: graphs/%.eps
    # ...

graphs/%.tex graphs/%.eps: graphs/%.plot
    # ...

make -d after make has already been run

$ make -d | grep -Ev "Trying|Reject|Avoid|intermediate"
Considering target file `report.pdf'.
  Considering target file `report.tex'.
   Looking for an implicit rule for `report.tex'.
   No implicit rule found for `report.tex'.
   Finished prerequisites of target file `report.tex'.
  No need to remake target `report.tex'.
  Considering target file `mp-int-2.4-i'.
   File `mp-int-2.4-i' does not exist.
    Considering target file `graphs/mp-int-2.4-i.pdf'.
     Looking for an implicit rule for `graphs/mp-int-2.4-i.pdf'.
     Found an implicit rule for `graphs/mp-int-2.4-i.pdf'.
       Considering target file `graphs/mp-int-2.4-i.plot'.
        Looking for an implicit rule for `graphs/mp-int-2.4-i.plot'.
        No implicit rule found for `graphs/mp-int-2.4-i.plot'.
        Finished prerequisites of target file `graphs/mp-int-2.4-i.plot'.
       No need to remake target `graphs/mp-int-2.4-i.plot'.
     Finished prerequisites of target file `graphs/mp-int-2.4-i.pdf'.
     Prerequisite `graphs/mp-int-2.4-i.eps' of target `graphs/mp-int-2.4-i.pdf' does not exist.
    No need to remake target `graphs/mp-int-2.4-i.pdf'.
    Considering target file `graphs/mp-int-2.4-i.tex'.
     Looking for an implicit rule for `graphs/mp-int-2.4-i.tex'.
     Found an implicit rule for `graphs/mp-int-2.4-i.tex'.
      Pruning file `graphs/mp-int-2.4-i.plot'.
      Pruning file `graphs/mp-int-2.4-i.plot'.
     Finished prerequisites of target file `graphs/mp-int-2.4-i.tex'.
     Prerequisite `graphs/mp-int-2.4-i.plot' is older than target `graphs/mp-int-2.4-i.tex'.
    No need to remake target `graphs/mp-int-2.4-i.tex'.
   Finished prerequisites of target file `mp-int-2.4-i'.
  Must remake target `mp-int-2.4-i'.
  Successfully remade target file `mp-int-2.4-i'.
  Considering target file `mp-int-2.4-ni'.
   File `mp-int-2.4-ni' does not exist.
    Considering target file `graphs/mp-int-2.4-ni.pdf'.
     Looking for an implicit rule for `graphs/mp-int-2.4-ni.pdf'.
     Found an implicit rule for `graphs/mp-int-2.4-ni.pdf'.
       Considering target file `graphs/mp-int-2.4-ni.plot'.
        Looking for an implicit rule for `graphs/mp-int-2.4-ni.plot'.
        No implicit rule found for `graphs/mp-int-2.4-ni.plot'.
        Finished prerequisites of target file `graphs/mp-int-2.4-ni.plot'.
       No need to remake target `graphs/mp-int-2.4-ni.plot'.
     Finished prerequisites of target file `graphs/mp-int-2.4-ni.pdf'.
     Prerequisite `graphs/mp-int-2.4-ni.eps' of target `graphs/mp-int-2.4-ni.pdf' does not exist.
    No need to remake target `graphs/mp-int-2.4-ni.pdf'.
    Considering target file `graphs/mp-int-2.4-ni.tex'.
     Looking for an implicit rule for `graphs/mp-int-2.4-ni.tex'.
     Found an implicit rule for `graphs/mp-int-2.4-ni.tex'.
      Pruning file `graphs/mp-int-2.4-ni.plot'.
      Pruning file `graphs/mp-int-2.4-ni.plot'.
     Finished prerequisites of target file `graphs/mp-int-2.4-ni.tex'.
     Prerequisite `graphs/mp-int-2.4-ni.plot' is older than target `graphs/mp-int-2.4-ni.tex'.
    No need to remake target `graphs/mp-int-2.4-ni.tex'.
   Finished prerequisites of target file `mp-int-2.4-ni'.
  Must remake target `mp-int-2.4-ni'.
  Successfully remade target file `mp-int-2.4-ni'.
 Finished prerequisites of target file `report.pdf'.
 Prerequisite `report.tex' is older than target `report.pdf'.
 Prerequisite `mp-int-2.4-i' of target `report.pdf' does not exist.
 Prerequisite `mp-int-2.4-ni' of target `report.pdf' does not exist.
Must remake target `report.pdf'.

Working Makefile after answer from Etan Reisner below:

GRAPHS := mp-int-2.4-i mp-int-2.4-ni
GRAPHS_WD := $(addprefix graphs/,$(GRAPHS))
REAL_GRAPHS := $(addsuffix .pdf,$(GRAPHS_WD)) $(addsuffix .tex,$(GRAPH_SWD))

.PHONY : clean

report.pdf: report.tex $(REAL_GRAPHS)
    # ...

graphs/%.pdf: graphs/%.eps
    # ..

graphs/%.tex graphs/%.eps: graphs/%.plot
    # ..
like image 317
Jon Gjengset Avatar asked Jul 30 '13 14:07

Jon Gjengset


People also ask

What kind of targets should have a phony directive in the Makefile?

A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.

What is the purpose of .phony in a Makefile?

PHONY: allows to declare phony targets, so that make will not check them as actual file names: it will work all the time even if such files still exist.

What is a make target?

A 'make target' is basically a file that you want rebuilt. Make can't divine what you want built, so you have to tell it, implicitly or explicitly, what it should build.

What does all do in Makefile?

This means that when you do a "make all", make always thinks that it needs to build it, and so executes all the commands for that target. Those commands will typically be ones that build all the end-products that the makefile knows about, but it could do anything.


1 Answers

A PHONY rule is one that you have told make doesn't correspond to an actual file so it isn't checking for the files to exist and so it always assumes the rule needs to run and so report.pdf has prerequisites that are newer (which is what that output is telling you).

The make documentation says "A phony target should not be a prerequisite of a real target file; if it is, its recipe will be run every time make goes to update that file." [ref]

What was your purpose in marking those files as PHONY?

like image 65
Etan Reisner Avatar answered Oct 27 '22 11:10

Etan Reisner