I am aware of LatexMk, but can't install that on the machine where I want to run pdflatex, so I need to write a Makefile of which %.pdf files are targets that depend on %.tex and the *.tex files that %.tex is inputting. For this I wrote the following:

%.pdf : %.tex $(shell perl -lne 'print "$$1\n" if /\\input{([\w-]+\.tex)}/' %.tex)

Now, I tested the regular expression and it seems to work fine, but the %.tex at the end isn't passed correctly, running make output.pdf gives me:

Can't open %.tex: No such file or directory.

How can I pass %.tex to the $(shell) command?

I'm using GNU make.

  • Your code does not look like make syntax. Are you sure about this code?
    – schily
    Commented Sep 20, 2015 at 22:28
  • @schily it's only the target line, but otherwise, yes.
    – user37050
    Commented Sep 20, 2015 at 22:28
  • This is not make syntax at all, but the text before the $ could be a SunPro-make enhancement that was introduced in Spring 1986: an implicit pattern matching rule. Such a rule may not be followed by everything you wrote starting with $ and the command line for the rule is missing.
    – schily
    Commented Sep 20, 2015 at 22:35
  • @schily %.pdf is the target, %.tex is the first dependency and $(shell ...) should create a further list with dependencies. That's what I learned here. I'm using GNU Make 3.81, and all this runs fine except that the final %.tex doesn't expand. Please provide reference for "This is not make syntax at all".
    – user37050
    Commented Sep 20, 2015 at 22:38
  • As mentioned already: this is not understood by make. $(shell ) is definitely illegal make syntax. Text like this is not permitted in a pattern matching rule and even a pattern matching rule is a SunPro-make enhancement already. See the POSIX make description for leal makesyntax: pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
    – schily
    Commented Sep 20, 2015 at 22:45

1 Answer 1


Probably what you're trying to do is better solved by creating a file listing dependencies, which you can then include from your Makefile. This is a common pattern in C and C++ makefiles.

SOURCES=foo.tex bar.tex

all: $(SOURCES:.tex=.pdf)

%.dep: %.tex
    perl -lne 'print "$*.pdf: $$1\n" if /\\input{([\w-]+\.tex)}/' <$< >$@

include $(SOURCES:.tex=.dep)

Recommended reading: Generating Prerequisites Automatically in the Make manual.

  • Tested and confirmed. My target line is now %.pdf: %.tex %.dep. Thanks!
    – user37050
    Commented Sep 21, 2015 at 11:22
  • This looks like valid make syntax ;-) but it still triggers a gmake problem I reported in 1998 and that is still not fixed. You will get a warning that the .dep file is missing even though there is a rule to make it.
    – schily
    Commented Sep 21, 2015 at 11:22
  • @Camil The target line should just be %.pdf: %.tex - the %.dep is implicitly a dependency of the Makefile. And inside each .dep file, you'll have foo.pdf: include1.tex etc. lines (I made a typo in my answer; now fixed). Commented Sep 21, 2015 at 11:24
  • Right, that looks better (and is hereby also confirmed to work). Thanks again!
    – user37050
    Commented Sep 21, 2015 at 11:27

You must log in to answer this question.