3

我可能很愚蠢,但我无法在我的 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 时,它会插入整个命令而不是结果,这会中断!

有任何想法吗?

皮特。

4

3 回答 3

5

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

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

TEST!=pwd
all:
    echo ${TEST}

将工作。解释很简单,请仔细阅读FreeBSD 的 man make,尤其是“VARIABLE ASSIGNMENTS”部分中的“Variable assignment modifiers” :

变量赋值修饰符

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

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

于 2016-12-30T11:02:51.807 回答
4

生成文件包含:

TEST = $(pwd);

all:
    echo $(TEST)

第一行将make变量中的值pwd加上分号分配给make变量TEST。然后,该规则呼应了这一点。我认为你忘记了这对和$(...)都很重要。假设您要回显命令的输出,然后使用双美元,因此将其扩展为一美元:makeshellpwdmake

TEST = $$(pwd)

all:
    echo $(TEST)

要将 shell 命令的输出转换为make变量,您必须使用 GNUmake扩展。有两个扩展在使用::=立即赋值,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
    

    这应该适用于make满足条件 1 的任何版本。

于 2013-03-23T11:52:34.913 回答
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
于 2013-03-23T11:45:40.027 回答