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语法?你知道有什么解决办法吗?干得好,兄弟!很高兴看到这个
${…:-…}
被使用(:谢谢!