2

我正在尝试检查是否使用 定义了变量ifndef/ifdef,但我不断收到not found执行错误。我正在使用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 的出色工作。

4

1 回答 1

4

您可以将 shell 的功能与 Make 结合起来以获得相当简洁的定义。

define compile
        @dir="${1}"; outdir="${2}"; outdir=$${outdir:-"$dir"}; \
        $(COMPILER) -output-directory "$${outdir}" "$${dir:-.}/*.tex

double-dollar 是一种将单个美元符号传递给 shell 的转义。该构造${variable:-value}返回 的值,$variable除非它未设置或为空,在这种情况下它返回value。因为在 shell 计算这个表达式之前${1}and${2}被静态字符串替换,我们必须在检查它们之前采取迂回的路线将它们分配给变量。

这也演示了如何将两个“单行”组合成一个 shell 调用。分号是语句终止符(基本上相当于换行符),反斜杠和换行符的序列导致下一行与当前行合并为单个“逻辑行”。

这很复杂,我建议你省略前导@,但我把它留在里面只是为了显示它所属的位置。如果您想要静默操作,一旦您对其进行了正确调试,请使用make -s.

于 2013-01-13T13:20:15.007 回答