I'm trying to check whether a variable is defined using ifndef/ifdef
, but I keep getting a not found
error from the execution. I'm using GNU Make 3.81
, and here is a snippet of what I have:
all: _images
$(call clean, .)
$(call compile, .)
@$(OPENER) *.pdf &
_images:
$(call clean, "images")
$(call compile, "images")
define clean
@rm -f ${1}/*.log ${1}/*.aux ${1}/*.pdf
endef
define compile
ifdef ${1}
dir = ${1}
else
dir = .
endif
ifdef ${2}
outdir = ${2}
else
outdir = ${1}
endif
@$(COMPILER) -output-directory ${outdir} ${dir}/*.tex
endef
And the exact error:
$ make
ifdef "images"
/bin/sh: 1: ifdef: not found
make: *** [_images] Error 127
Edit:
Considering Barmar comments, here goes the conclusions:
The contents of a define are shell command lines, not make directives; to break lines inside commands within a define block, the linebreak must be escaped -- with \; also, each block corresponding to one-liner commands is executed separately, each in a different shell execution, which means that, defining local variables won't work if the intention is to access the variable value in the next one-liner block.
Thanks tripleee for the nice work around.
You can combine the shell's facilities with Make's to get a fairly succinct definition.
define compile
@dir="${1}"; outdir="${2}"; outdir=$${outdir:-"$dir"}; \
$(COMPILER) -output-directory "$${outdir}" "$${dir:-.}/*.tex
The double-dollar is an escape which passes a single dollar sign to the shell. The construct ${variable:-value}
returns the value of $variable
unless it is unset or empty, in which case it returns value
. Because ${1}
and ${2}
are replaced by static strings before the shell evaluates this expression, we have to take the roundabout route of assigning them to variables before examining them.
This also demonstrates how to combine two "one-liners" into a single shell invocation. The semicolon is a statement terminator (basically equivalent to a newline) and the sequence of a backslash and a newline causes the next line to be merged with the current line into a single "logical line".
This is complex enough that I would recommend you omit the leading @
but I left it in just to show where it belongs. If you want silent operation, once you have it properly debugged, run with make -s
.