If I run the following makefile under GNU Make 3.81 / RHEL5:
all: A1B/C A1B/D A2B/C A2B/D
A%B/C A%B/D: E.%
#echo "Creating '$#' from '$^' with stem '$*'"
E.1 E.2:
#echo "Generate '$#'"
I get the following output:
Generate 'E.1'
Creating 'A1B/C' from 'E.1' with stem '1'
Generate 'E.2'
Creating 'A2B/C' from 'E.2' with stem '2'
Why are files A1B/D and A2B/D not generated?
(files with such names do not exist in my testcase)
If I specify the targets via the command line make states "Nothing to be done":
make A1B/C A1B/D A2B/C A2B/D
Generate 'E.1'
Creating 'A1B/C' from 'E.1' with stem '1'
make: Nothing to be done for `A1B/D'.
Generate 'E.2'
Creating 'A2B/C' from 'E.2' with stem '2'
make: Nothing to be done for `A2B/D'.
If I duplicate the implicit rule into their targets it works:
all: A1B/C A1B/D A2B/C A2B/D
A%B/C: E.%
#echo "Creating '$#' from '$^' with stem '$*'"
A%B/D: E.%
#echo "Creating '$#' from '$^' with stem '$*'"
E.1 E.2:
#echo "Generate '$#'"
Generate 'E.1'
Creating 'A1B/C' from 'E.1' with stem '1'
Creating 'A1B/D' from 'E.1' with stem '1'
Generate 'E.2'
Creating 'A2B/C' from 'E.2' with stem '2'
Creating 'A2B/D' from 'E.2' with stem '2'
According to the documentation this should not make a difference.
Thanks in advance.
Michael
You're not quite right about the documentation saying there's no difference. If you have a pattern rule with multiple targets (and you do), make assumes both will be made in a single execution of the recipe.
From the GNU make manual:
Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and recipe. If a pattern rule has multiple targets, make knows that the rule's recipe is responsible for making all of the targets. The recipe is executed only once to make all the targets.
You can confirm this behaviour for your case:
$ make -r -d
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Updating makefiles....
Considering target file `Makefile'.
Looking for an implicit rule for `Makefile'.
No implicit rule found for `Makefile'.
Finished prerequisites of target file `Makefile'.
No need to remake target `Makefile'.
Updating goal targets....
Considering target file `all'.
File `all' does not exist.
Looking for an implicit rule for `all'.
No implicit rule found for `all'.
Considering target file `A1B/C'.
File `A1B/C' does not exist.
Looking for an implicit rule for `A1B/C'.
Trying pattern rule with stem `1'.
Trying implicit prerequisite `E.1'.
Found an implicit rule for `A1B/C'.
Considering target file `E.1'.
File `E.1' does not exist.
Finished prerequisites of target file `E.1'.
Must remake target `E.1'.
Putting child 0x7fcad3c08440 (E.1) PID 34127 on the chain.
Live child 0x7fcad3c08440 (E.1) PID 34127
Generate 'E.1'
Reaping winning child 0x7fcad3c08440 PID 34127
Removing child 0x7fcad3c08440 PID 34127 from chain.
Successfully remade target file `E.1'.
Finished prerequisites of target file `A1B/C'.
Must remake target `A1B/C'.
Putting child 0x7fcad3c08710 (A1B/C) PID 34128 on the chain.
Live child 0x7fcad3c08710 (A1B/C) PID 34128
Creating 'A1B/C' from 'E.1' with stem '1'
Reaping winning child 0x7fcad3c08710 PID 34128
Removing child 0x7fcad3c08710 PID 34128 from chain.
Successfully remade target file `A1B/C'.
Considering target file `A1B/D'.
File `A1B/D' was considered already.
Considering target file `A2B/C'.
File `A2B/C' does not exist.
Looking for an implicit rule for `A2B/C'.
Trying pattern rule with stem `2'.
Trying implicit prerequisite `E.2'.
Found an implicit rule for `A2B/C'.
Considering target file `E.2'.
File `E.2' does not exist.
Finished prerequisites of target file `E.2'.
Must remake target `E.2'.
Putting child 0x7fcad3c08cd0 (E.2) PID 34129 on the chain.
Live child 0x7fcad3c08cd0 (E.2) PID 34129
Generate 'E.2'
Reaping winning child 0x7fcad3c08cd0 PID 34129
Removing child 0x7fcad3c08cd0 PID 34129 from chain.
Successfully remade target file `E.2'.
Finished prerequisites of target file `A2B/C'.
Must remake target `A2B/C'.
Putting child 0x7fcad3c08cd0 (A2B/C) PID 34130 on the chain.
Live child 0x7fcad3c08cd0 (A2B/C) PID 34130
Creating 'A2B/C' from 'E.2' with stem '2'
Reaping winning child 0x7fcad3c08cd0 PID 34130
Removing child 0x7fcad3c08cd0 PID 34130 from chain.
Successfully remade target file `A2B/C'.
Considering target file `A2B/D'.
File `A2B/D' was considered already.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
Notice these lines:
File `A1B/D' was considered already.
File `A2B/D' was considered already.
Related
So, I have a Makefile with 2 pattern rules, one of them is a terminal Match-Anything; the target is about.html (for example):
vpath %.md $(SOURCE_DIR)
HEADER := assets/navbar.part
%.html : %.md $(HEADER)
pandoc [...] $< -o $#
%::
cp $(SOURCE_DIR)/$# $#
If I execute make assets/navbar.part, and then make about.html (for example), everything works fine (navbar.part uses the match anything, and about.html uses the first rule). But if I try to make about.html without having navbar.part present, make does:
Find the prerequisite about.md
?? Gives up on fulfilling $(HEADER)
Tries to use the match anything rule to generate about.html
I was expecting that make would:
Find the prerequisite about.md
Make the prerequisite $(HEADER) using the match-anything rule
With all the prerequisites fulfilled, finally execute the first rule
From reading the debug trace, it seems like Make never really tries to fulfill the $(HEADER) prerequisite:
Considering target file 'about.html'.
File 'about.html' does not exist.
Looking for an implicit rule for 'about.html'.
Trying pattern rule with stem 'about'.
Trying implicit prerequisite 'about.md'.
Found prerequisite 'about.md' as VPATH '../website/about.md'
Trying rule prerequisite 'assets/navbar.part'.
Trying pattern rule with stem 'about.html'.
Found an implicit rule for 'about.html'.
Considering target file 'about.md'.
Finished prerequisites of target file 'about.md'.
No need to remake target 'about.md'; using VPATH name '../website/about.md'.
Finished prerequisites of target file 'about.html'.
Must remake target 'about.html'.
cp -f ../website/about.html about.html
Any ideas?
After digging the manual, I found section 10.8 that states:
For each pattern rule in the list:
Find the stem s, which is the nonempty part of t or n matched by the ‘%’ in the target pattern.
Compute the prerequisite names by substituting s for ‘%’; if the target pattern does not contain a slash, append d to the front of each prerequisite name.
Test whether all the prerequisites exist or ought to exist. (If a file name is mentioned in the makefile as a target or as an explicit prerequisite, then we say it ought to exist.)
Because the $(HEADER) does not meet the definition of ought to exist:
No file exists when the rule is tried
No rule with that explicit target exists
it fails; however, it suceeds if we try to make specifically $(HEADER), and then try to make about.html it suceeds, because by then $(HEADER) is an existing file.
I'm using GNU Make 4.0 to compile code on an IBM i system. Make is inexplicably choosing the wrong rule to build one type of object.
On this platform, program objects are built from modules, which are compiled from source code. There is also a convenience shortcut command that will create a program directly from a single piece of source code by creating a temporary module from the source code and then building a program from that. The problem I'm running into is that Make is using the shortcut command (crtbndrpg) instead of the two-step version (crtrpgmod + crtpgm), even though the target rule specifies that the program should be built from a module and not the shortcut.
There are two makefiles: a generic one that describes how to create IBM i objects, and a project-specific one that describes object dependencies for all items in this project and includes the generic one. My generic makefile looks like this (edited for simplicity):
# `IBMiMake`, a generic makefile that describes how to create IBM i objects.
OBJPATH := $(CURDIR)
override OBJPATH := $(shell echo "$(OBJPATH)" | tr '[:lower:]' '[:upper:]')
%.MODULE: %.RPGLE
$(eval crtcmd := crtrpgmod module($(OBJLIB)/$*) srcstmf('$<') $(CRTRPGMODFLAGS))
#system "$(crtcmd)" > $(LOGPATH)/$(notdir $<).log
%.PGM: %.RPGLE
$(eval crtcmd := crtbndrpg pgm($(OBJLIB)/$*) srcstmf('$<') $(CRTBNDRPGFLAGS))
system "$(crtcmd)" >$(LOGPATH)/$(notdir $<).log 2>&1
%.PGM:
$(eval crtcmd := crtpgm pgm($(OBJLIB)/$*) module($(basename $(filter %.MODULE,$(notdir $^)))) $(CRTPGMFLAGS))
system "$(crtcmd)" >$(LOGPATH)/$#.log 2>&1
The project-specific makefile looks like this (also edited for simplicity):
# `xpmake`, to create objects in this project.
ROOTDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
IBMIMAKE := $(ROOTDIR)/../SDE/IBMiMake
include $(IBMIMAKE)
# AB2001.B.MODULE -- CRTRPGMOD
AB2001.B.MODULE: AB2001.B.RPGLE
# AB2001.B.PGM -- CRTPGM
AB2001.B.PGM: AB2001.B.MODULE
To build the object in question:
bash-4.2$ make AB2001.B.PGM OBJPATH:='/qsys.lib/xp33make.lib' -f xp33make/xpmake -d --no-builtin-rules
What should happen: It should first create the module using the crtrpgmod command, which it does. It should then create the program using the crtpgm command. Instead of creating the program via crtpgm, however, it for some reason tries to use the crtbndrpg command to directly build the program from source code. The only thing I can think of is that perhaps Make is seeing AB2001.B.MODULE as an intermediate file and opting to bypass the crtrpgmod step. Could this be true? How do I get make to follow my rules and not try to overthink things?
Here is the output:
GNU Make 4.0
Built for powerpc-ibm-aix5.3.0.0
Copyright (C) 1988-2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Reading makefile 'xp33make/xpmake'...
Reading makefile '/home/SMEEP/Source/xp33make/../SDE/IBMiMake' (search path) (no ~ expansion)...
Updating makefiles....
Considering target file '/home/SMEEP/Source/xp33make/../SDE/IBMiMake'.
Looking for an implicit rule for '/home/SMEEP/Source/xp33make/../SDE/IBMiMake'.
No implicit rule found for '/home/SMEEP/Source/xp33make/../SDE/IBMiMake'.
Finished prerequisites of target file '/home/SMEEP/Source/xp33make/../SDE/IBMiMake'.
No need to remake target '/home/SMEEP/Source/xp33make/../SDE/IBMiMake'.
Considering target file 'xp33make/xpmake'.
Looking for an implicit rule for 'xp33make/xpmake'.
No implicit rule found for 'xp33make/xpmake'.
Finished prerequisites of target file 'xp33make/xpmake'.
No need to remake target 'xp33make/xpmake'.
Updating goal targets....
Considering target file 'AB2001.B.PGM'.
File 'AB2001.B.PGM' does not exist.
Looking for an implicit rule for 'AB2001.B.PGM'.
Trying pattern rule with stem 'AB2001.B'.
Trying implicit prerequisite 'AB2001.B.CLLE'.
Trying pattern rule with stem 'AB2001.B'.
Trying implicit prerequisite 'AB2001.B.RPGLE'.
Found an implicit rule for 'AB2001.B.PGM'.
Considering target file 'AB2001.B.RPGLE'.
Looking for an implicit rule for 'AB2001.B.RPGLE'.
No implicit rule found for 'AB2001.B.RPGLE'.
Finished prerequisites of target file 'AB2001.B.RPGLE'.
No need to remake target 'AB2001.B.RPGLE'; using VPATH name '/home/SMEEP/Source/xp33make/AB2001.B.RPGLE'.
Considering target file 'AB2001.B.MODULE'.
Looking for an implicit rule for 'AB2001.B.MODULE'.
Trying pattern rule with stem 'AB2001.B'.
Trying implicit prerequisite 'AB2001.B.C'.
Trying pattern rule with stem 'AB2001.B'.
Trying implicit prerequisite 'AB2001.B.CLLE'.
Trying pattern rule with stem 'AB2001.B'.
Trying implicit prerequisite 'AB2001.B.RPGLE'.
Found prerequisite 'AB2001.B.RPGLE' as VPATH '/home/SMEEP/Source/xp33make/AB2001.B.RPGLE'
Found an implicit rule for 'AB2001.B.MODULE'.
Pruning file '/home/SMEEP/Source/xp33make/AB2001.B.RPGLE'.
Pruning file '/home/SMEEP/Source/xp33make/AB2001.B.RPGLE'.
Finished prerequisites of target file 'AB2001.B.MODULE'.
Prerequisite '/home/SMEEP/Source/xp33make/AB2001.B.RPGLE' is older than target 'AB2001.B.MODULE'.
Prerequisite '/home/SMEEP/Source/xp33make/AB2001.B.RPGLE' is older than target 'AB2001.B.MODULE'.
No need to remake target 'AB2001.B.MODULE'; using VPATH name '/QSYS.LIB/XP33MAKE.LIB/AB2001.B.MODULE'.
Finished prerequisites of target file 'AB2001.B.PGM'.
Must remake target 'AB2001.B.PGM'.
system "crtbndrpg pgm(XP33MAKE/AB2001.B) srcstmf('/home/SMEEP/Source/xp33make/AB2001.B.RPGLE')" >/home/SMEEP/Source/xp33make/Logs/2016-11-14_11.42.55-Mon/AB2001.B.RPGLE.log 2>&1
Putting child 30016df0 (AB2001.B.PGM) PID 1155363 on the chain.
Live child 30016df0 (AB2001.B.PGM) PID 1155363
Reaping losing child 30016df0 PID 1155363
/home/SMEEP/Source/xp33make/../SDE/IBMiMake:476: recipe for target 'AB2001.B.PGM' failed
Removing child 30016df0 PID 1155363 from chain.
Your example is still difficult to read: creating a minimal example is usually best (that is, construct an example that uses touch etc. to create files, and doesn't depend on your environment).
Also, the use of $(eval ...) inside the recipe to create a make variable assignment is a bit confusing. Don't think that just because you do this in the recipe there's some kind of scoping involved: those variables are still globally assigned.
In any event, the problem is that you have two ways to build a target that matches %.PGM:
%.PGM: %.RPGLE
%.PGM:
You apparently want to use the second one, but if the stem of a matching pattern rule is has equal length (here both have the same stem, .PGM) then make will always choose the first pattern that you define so it will always choose the first one if it can.
So, it will always use crtbndrpg to build that target, as long as make can figure out how to build %.RPGLE, so that pattern rule will match.
I'm not sure if they're omitted in the simplifying process, but your explicit rules lack their recipes.
Pattern rules with no recipe mean canceling any existing implicit rules.
https://www.gnu.org/software/make/manual/html_node/Canceling-Rules.html
when using pdftk to extract pages in a Makefile, the pdftk command always get executed regardless of whether the prerequisite pdf file changed or not.
document.tex:
\documentclass[10pt]{article}
\begin{document}
Page one
\newpage
Page two
\end{document}
Make pdf file:
pdflatex document.tex
Makefile:
all: document page-one
document: document.tex
pdflatex $<
page-one: document
pdftk A=$<.pdf cat A1 output PageOne.pdf
Every time I do
make all
The pdftk command is executed. I would like to only extract the page if the parent document changed. Any ideas? Ultimately the pdflatex command would go in the Makefile as well but in order to highlight the problem I left it out.
Edit:
Please note, I changed the Makefile for clarity. And here are two runs as requested.
The first run produces
$ make -dRr page-one
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
Reading makefiles...
Reading makefile `Makefile'...
Updating makefiles....
Considering target file `Makefile'.
Looking for an implicit rule for `Makefile'.
No implicit rule found for `Makefile'.
Finished prerequisites of target file `Makefile'.
No need to remake target `Makefile'.
Updating goal targets....
Considering target file `page-one'.
File `page-one' does not exist.
Considering target file `document'.
File `document' does not exist.
Considering target file `document.tex'.
Looking for an implicit rule for `document.tex'.
No implicit rule found for `document.tex'.
Finished prerequisites of target file `document.tex'.
No need to remake target `document.tex'.
Finished prerequisites of target file `document'.
Must remake target `document'.
pdflatex document.tex
Putting child 0x0198c5c0 (document) PID 4347 on the chain.
Live child 0x0198c5c0 (document) PID 4347
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian)
entering extended mode
(./document.tex
LaTeX2e <2009/09/24>
Babel <v3.8l> and hyphenation patterns for english, usenglishmax, dumylang, noh
yphenation, ngerman, german, german-x-2009-06-19, ngerman-x-2009-06-19, loaded,
(/usr/share/texmf-texlive/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texmf-texlive/tex/latex/base/size10.clo)) (./document.aux) [1{/var/
lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] (./document.aux) )</usr/shar
e/texmf-texlive/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on document.pdf (2 pages, 13250 bytes).
Transcript written on document.log.
Reaping winning child 0x0198c5c0 PID 4347
Removing child 0x0198c5c0 PID 4347 from chain.
Successfully remade target file `document'.
Finished prerequisites of target file `page-one'.
Must remake target `page-one'.
pdftk A=document.pdf cat A1 output PageOne.pdf
Putting child 0x0198ea40 (page-one) PID 4348 on the chain.
Live child 0x0198ea40 (page-one) PID 4348
Reaping winning child 0x0198ea40 PID 4348
Removing child 0x0198ea40 PID 4348 from chain.
Successfully remade target file `page-one'.
And the second time:
$ make -dRr page-one
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
Reading makefiles...
Reading makefile `Makefile'...
Updating makefiles....
Considering target file `Makefile'.
Looking for an implicit rule for `Makefile'.
No implicit rule found for `Makefile'.
Finished prerequisites of target file `Makefile'.
No need to remake target `Makefile'.
Updating goal targets....
Considering target file `page-one'.
File `page-one' does not exist.
Considering target file `document'.
File `document' does not exist.
Considering target file `document.tex'.
Looking for an implicit rule for `document.tex'.
No implicit rule found for `document.tex'.
Finished prerequisites of target file `document.tex'.
No need to remake target `document.tex'.
Finished prerequisites of target file `document'.
Must remake target `document'.
pdflatex document.tex
Putting child 0x019ef5c0 (document) PID 4398 on the chain.
Live child 0x019ef5c0 (document) PID 4398
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian)
entering extended mode
(./document.tex
LaTeX2e <2009/09/24>
Babel <v3.8l> and hyphenation patterns for english, usenglishmax, dumylang, noh
yphenation, ngerman, german, german-x-2009-06-19, ngerman-x-2009-06-19, loaded.
(/usr/share/texmf-texlive/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texmf-texlive/tex/latex/base/size10.clo)) (./document.aux) [1{/var/
lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] (./document.aux) )</usr/shar
e/texmf-texlive/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on document.pdf (2 pages, 13250 bytes).
Transcript written on document.log.
Reaping winning child 0x019ef5c0 PID 4398
Removing child 0x019ef5c0 PID 4398 from chain.
Successfully remade target file `document'.
Finished prerequisites of target file `page-one'.
Must remake target `page-one'.
pdftk A=document.pdf cat A1 output PageOne.pdf
Putting child 0x019f1a40 (page-one) PID 4399 on the chain.
Live child 0x019f1a40 (page-one) PID 4399
Reaping winning child 0x019f1a40 PID 4399
Removing child 0x019f1a40 PID 4399 from chain.
Successfully remade target file `page-one'.
To get this Makefile working you have to specify existing targets, ie. real filenames (including the suffix). Moreover, you are creating a file called PageOne.pdf but check for a file called page-one which cannot be found.
That's more or less what you posted above:
...
Considering target file `page-one'.
File `page-one' does not exist.
Considering target file `document'.
File `document' does not exist.`
...
A working Makefile would look like
all: document.pdf page-one.pdf
document.pdf: document.tex
pdflatex $<
page-one.pdf: document.pdf
pdftk A=$< cat A1 output page-one.pdf
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
# ..
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?
I understand that an "explicit" pattern rule will take precedence on its implicit counterpart when its prerequisites can be made.
all: src/foo.o
src/%.o: makefile my_haeder.h src/%.c
echo Do something with those source files
If there is a typo for "my_header.h", the implicit rule for %.o will take precedence. Not only my recipe will not be executed, but touching the prerequisites will not trigger the rule. Actually it is the second point which is of interest for me.
The make documentation offers a verification using static pattern rules:
SET_OF_FILES=src/foo.o
all: src/foo.o
$(SET_OF_FILES): src/%.o: makefile my_haeder.h src/%.c
echo Do something with those source files
This results in:
gmake: *** No rule to make target `src/my_haeder.h', needed by `src/foo.o'. Stop.
Though a larger rule, that solution is nice, as long as I don't have to add a rule for which the stem could overlap:
SET_OF_FILES=src/foo.o src/subsrc/bar.o
all: src/foo.o
$(SET_OF_FILES): src/%.o: makefile my_header.h src/%.c
echo Do something with those source files
$(SET_OF_FILES): src/subsrc/%.o: makefile my_header.h src/subsrc/%.c
echo Do something with those other source files
Which results in:
makefile:8: target `src/foo.o' doesn't match the target pattern
makefile:9: warning: overriding commands for target `src/foo.o'
makefile:6: warning: ignoring old commands for target `src/foo.o'
makefile:9: warning: overriding commands for target `src/subsrc/bar.o'
makefile:6: warning: ignoring old commands for target `src/subsrc/bar.o'
The first message is here because I didn't bother $(filter)ing SET_OF_FILES. I don't know how to solve the next warnings, which for any reviewer would mean "something's wrong".
Is there another (more elegant) way to verify that the prerequisites are actually feasible, in order to avoid dropping the explicit pattern rule?
(using GNU Make 3.79.1 win32)
Add a separate rule to check for your prerequisites
all: prereqs src/foo.o
prereqs: Makefile my_header.h
src/%.o: src/%.c Makefile my_header.h
echo Do something with those source files
src/subsrc/%.o: src/subsrc/%.c Makefile my_header.h
echo Do something with those other source files
which will give you:
make
make: *** No rule to make target 'my_header.h', needed by 'prereqs'. Stop