makefile中的'$$directoryName'和'$(directoryName)'有什么区别

What is the difference between '$$directoryName' and '$(directoryName)' in makefile

我有两个 makefile

第一个:

dir = ../dir1
dis = ../dir2
test:
    $(MAKE) -C $(dir)

第二个:

DIRS = dir1 dir2 dir3

test:
    for dir in $(DIRS); do \
            if $(MAKE)  -C $$dir ; then \
                true; \
            else \
                exit 1; \
            fi; \
    done

为什么在 for 循环中我需要 $$dir 而在一个简单的食谱中我必须写 $(dir)

另一个问题: 我有另一个 makefile,其中有另一个 for 循环:

all clean dep depend print:
for dir in $(DIRS); do \
    if $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \
        true; \
    else \
        exit 1; \
    fi; \
done

行中的$@是什么意思

if $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \

我知道这是一个匹配规则目标文件名的自动变量。 这里的目标似乎是一个像取消这样的命令:

cancell:
    rm -rf *.o

一个是 makefile 变量,另一个是 shell 变量。 $(directoryName) 将由 make 解决,因为它正在阅读。对于 $$directoryName,make 将 $$ 转换为 $,并将其传递给 shell(因此 $$directoryName 变为 $directoryName)。 shell 将其扩展到其环境中的任何内容。

更详细一点:

如果在 make 中定义(在任何配方之外)

var := 1

那么var就是一个make变量。如果您随后致电

all:
    echo $(var)

然后 make 将配方扩展为 echo ../dir1 ,然后 将命令传递给 shell。另一方面,如果您这样做:

all:
    var=1; echo $$var

然后 make 将 var=1; echo $var 传递给 shell。 shell 将 var 设置为 1,然后打印出来。请注意,如果您尝试过:

all:
    var=1;
    echo $$var

然后配方将不会打印任何东西 -- 那是因为第一行是 shell 中的 运行,它将 var 设置为 1,然后退出.下一行运行s,它在一个新的shell中传递了echo $var,但是这个shell不知道var在之前的shell.

另外,如果你运行var=1;make,那么make在启动时会设置一个makefile变量var1。因此,在这种情况下,$(info $(var)) 将显示 1。

对于语法,在make中你可以做var := 1(带空格)。在 bash 中不能添加空格。在bash中,$var指的是变量var。在 make 中,$var 指的是 $v 后跟文字 ar。 (使您 必须 使用 {}() 来引用多字符变量)。在 bash 中,您可以使用 {},也可以不使用大括号($(var) 在 bash 中具有不同的含义)。

make 也有两个 flavors 变量,一个用 := 定义,一个用 =.

定义