Bash 使用ifdef和ifndef指令
我试图检查变量是否是使用Bash 使用ifdef和ifndef指令,bash,makefile,gnu-make,conditional-compilation,ifndef,Bash,Makefile,Gnu Make,Conditional Compilation,Ifndef,我试图检查变量是否是使用ifndef/ifdef定义的,但执行过程中不断出现notfound错误。我使用的是GNU Make 3.81,下面是我的一个片段: all: _images $(call clean, .) $(call compile, .) @$(OPENER) *.pdf & _images: $(call clean
ifndef/ifdef
定义的,但执行过程中不断出现notfound
错误。我使用的是GNU Make 3.81
,下面是我的一个片段:
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
确切的错误是:
$ make
ifdef "images"
/bin/sh: 1: ifdef: not found
make: *** [_images] Error 127
编辑:
考虑到Barmar的评论,以下是结论:
define的内容是shell命令行,而不是make指令;
要在定义块内的命令内打断行,必须转义换行符--;
此外,与一个线性命令相对应的每个块分别执行,每个块在不同的shell执行中执行,这意味着,如果打算访问下一个线性块中的变量值,则定义局部变量将不起作用
感谢tripleee所做的出色工作。您可以将shell的功能与Make的功能结合起来,以获得相当简洁的定义
define compile
@dir="${1}"; outdir="${2}"; outdir=$${outdir:-"$dir"}; \
$(COMPILER) -output-directory "$${outdir}" "$${dir:-.}/*.tex
双美元是一种逃避,它将一个美元符号传递给外壳。构造${variable:-value}
返回$variable
的值,除非它未设置或为空,在这种情况下,它返回值
。因为在shell计算这个表达式之前,${1}
和${2}
被静态字符串替换,所以我们必须采取迂回的方法,在检查变量之前将它们赋值给变量
这还演示了如何将两个“一行程序”组合到一个shell调用中。分号是一个语句终止符(基本上相当于一个换行符),反斜杠和换行的顺序会导致下一行与当前行合并为一个“逻辑行”
这非常复杂,我建议您省略前导的
@
,但我保留它只是为了显示它所属的位置。如果您希望执行静默操作,在正确调试后,使用make-s
运行define
的内容是shell命令行,而不是make
指令。我不知道,Barmar,谢谢!那么,除了define
之外,还有什么指令可以用来在makefile中创建“函数”吗?或者是否有任何方法可以进行ifdef/ifndef
比较?为什么不使用shell的if
命令?啊,刚刚明白了你的意思。我去看看,谢谢!Barmar,似乎我只能在一行中编写语句;当我使用多行时,它不能正确解析。不过我注意到所使用的shell是sh
,而不是bash
;这是一个sh
约束,还是由于makefile语法?你知道有什么解决办法吗?干得好,兄弟!很高兴看到这个${…:-…}
被使用(:谢谢!