Search code examples
makefilefindlatexgnu-makemingw-w64

Makefile with find command results in error "paths must precede expression"


I have the following Makefile which should find all .tex files starting with prefix "slides" and then compile all these latex files:

TSLIDES = $(shell find . -maxdepth 1 -iname 'slides*.tex' -printf '%f\n')
TPDFS = $(TSLIDES:%.tex=%.pdf)

all: $(TPDFS)

$(TPDFS): %.pdf: %.tex
    latexmk -pdf $<

However, I keep getting the error messages (I am pretty sure it used to work and am very confused why I am getting this error now...)

/usr/bin/find: paths must precede expression: `slides01-intro.tex'
/usr/bin/find: possible unquoted pattern after predicate `-iname'?

In the manual, I found this

NON-BUGS         

   Operator precedence surprises
   The command find . -name afile -o -name bfile -print will never print
   afile because this is actually equivalent to find . -name afile -o \(
   -name bfile -a -print \).  Remember that the precedence of -a is
   higher than that of -o and when there is no operator specified
   between tests, -a is assumed.

   “paths must precede expression” error message
   $ find . -name *.c -print
   find: paths must precede expression
   Usage: find [-H] [-L] [-P] [-Olevel] [-D ... [path...] [expression]

   This happens because *.c has been expanded by the shell resulting in
   find actually receiving a command line like this:
   find . -name frcode.c locate.c word_io.c -print
   That command is of course not going to work.  Instead of doing things
   this way, you should enclose the pattern in quotes or escape the
   wildcard:
   $ find . -name '*.c' -print
   $ find . -name \*.c -print

But this does not help in my case as I have used quotes to avoid shell expansion. Any idea how I can fix this (I have also tried TSLIDES = $(shell find . -maxdepth 1 -iname 'slides*.tex' in the first line of my Makefile but it exits with the same error?

EDIT: I am on windows and use the git bash (which is based on mingw-64).


Solution

  • You should always make very clear up-front in questions using Windows, that you're using Windows. Running POSIX-based tools like make on Windows always requires a bit of extra work. But I'm assuming based on the mingw-w64 label that you are, in fact, on Windows.

    I tried your example on my GNU/Linux system and it worked perfectly. My suspicion is that your version of GNU make is invoking Windows cmd.exe instead of a POSIX shell like bash. In Windows cmd.exe, the single-quote character ' is not treated like a quote character.

    Try replacing your single quotes with double-quotes " and see if it works:

    TSLIDES = $(shell find . -maxdepth 1 -iname "slides*.tex" -printf "%f\n")
    

    I'm also not sure if the \n will be handled properly. But you don't really need it, you can just use -print (or even, in GNU find, leave it out completely as it's the default action).

    I'm not a Windows person so the above might not help but it's my best guess. If not please edit your question and provide more details about the environment you're using: where you got your version of make, where you're running it from, etc.