makefile assign命令

时间:2013-03-23 11:20:23

标签: makefile freebsd

我可能很蠢,但我不能在Makefile中做最基本的变量赋值。

TEST = $(pwd);

all:
    echo $(TEST)

当我在FreeBSD(v9.1)中运行Bash(v4.2.42)中的“make all”时,我得到:

echo

不知道我搞砸了什么。我也尝试使用$(shell ...)分配变量,结果相同。

如果我使用返回刻度(`),那么基本赋值可以工作,但它不存储结果,它存储命令。这打破了以下示例Makefile:

SERVERIP = `ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $$2}'`

all:
    echo $(SERVERIP)
    sed -e 's/%LISTENIP%/${SERVERIP}/g' test.conf > work/test.conf.tmp

结果是:

[pete@pete] ~/make
echo `ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $2}'`
10.128.28.151
sed -e 's/%LISTENIP%/`ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $2}'`/g' test.conf > work/test.conf.tmp
sed: 1: "s/%LISTENIP%/`ifconfig  ...": unescaped newline inside substitute pattern
*** [all] Error code 1

您可以看到基本变量赋值似乎有效,但是当您将结果插入到sed中时,它会插入整个命令而不是结果,这会中断!

有什么想法吗?

皮特。

3 个答案:

答案 0 :(得分:4)

makefile包含:

TEST = $(pwd);

all:
    echo $(TEST)

第一行将make变量pwd中的值加上分号添加到make变量TEST。然后规则回应了那个。我想,您忘了$(...)makeshell都很重要。假设您想要回显pwd命令的输出,那么使用双倍美元,make将其扩展为1美元:

TEST = $$(pwd)

all:
    echo $(TEST)

要将shell命令的输出转换为make变量,您必须使用GNU make扩展名。正在使用两个扩展::=立即赋值,用于在定义点而不是在使用点评估SERVERIP的值;和$(shell ...cmd...)用于运行shell命令并捕获其输出。

SERVERIP := $(shell ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $$2}')

all:
    echo ${SERVERIP}
    sed -e 's/%LISTENIP%/${SERVERIP}/g' test.conf > work/test.conf.tmp

这应该有效。关于sed正则表达式中的换行符的原始错误是奇怪的;反向标记应该已从ifconfig管道的输出中删除了尾随的换行符。但是,如果实际上有多行返回,那么您内部仍然会有换行符,从sed证明投诉的合理性。

这会产生投诉:

SERVERIP = `printf "%s\n" a b c`

all:
    echo $(SERVERIP)
    sed -e "s/%LISTENIP%/${SERVERIP}/g" test.conf > work/test.conf.tmp

这有效:

SERVERIP = `printf "%s\n" c`

all:
    echo $(SERVERIP)
    sed -e "s/%LISTENIP%/${SERVERIP}/g" test.conf > work/test.conf.tmp

由于您使用的是FreeBSD,因此您很可能没有GNU make。在这种情况下,您需要:

  1. 确保ifconfig命令管道仅生成一行输出。
  2. 使用make这样的命令:

    SERVERIP = `ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $$2}'`
    
    all:
        echo ${SERVERIP}
        sed -e "s/%LISTENIP%/${SERVERIP}/g" test.conf > work/test.conf.tmp
    

    如果符合条件1,则该版本适用于任何版本的make

答案 1 :(得分:1)

这是一个测试makefile,类似于你的。 ifconfig命令已放在$(shell ...)命令中,结果存储在SERVERIP中。

TOP:= $(shell pwd)
SERVERIP:= $(shell ifconfig en1 | grep -E 'inet.[0-9]' | awk '{ print $$2}')
LISTENIP:=240.12.4.63

all:
     echo $(SERVERIP)
     sed -e 's/$(LISTENIP)/$(SERVERIP)/g' test.conf > work/test.conf.tmp

答案 2 :(得分:1)

也许答案为时已晚,但我希望我能帮助(其他人)。

如果您不想安装GNU的make,可以使用!=

TEST!=pwd
all:
    echo ${TEST}

会奏效。解释非常简单,请仔细阅读FreeBSD's man make,尤其是 “VARIABLE ASSIGNMENTS”中的 “变量赋值修饰符” 部分:

  

变量赋值修饰符

     

可用于为变量赋值的五个运算符是   如下:......

     

!=展开值并将其传递给shell执行并执行                将结果分配给变量。结果中的任何换行符                用空格代替。