Macos 如何在makefile中追加文件路径
我在MacOS的makefile中使用了下面的示例代码来构建路径,但它总是不起作用Macos 如何在makefile中追加文件路径,macos,makefile,Macos,Makefile,我在MacOS的makefile中使用了下面的示例代码来构建路径,但它总是不起作用 all: ROOT=$(shell pwd) @echo $(ROOT) AGENT:=$(ROOT)/agent @echo $(AGENT) @mkdir -p $(AGENT) 它将输出为AGENT:=/AGENT,显然,AGENT变量没有扩展为ROOT这里有几个常见错误: 配方行在单独的shell中运行,您不能期望在一个shell中分配的shell变量仍然在另一个shell中定义 无
all:
ROOT=$(shell pwd)
@echo $(ROOT)
AGENT:=$(ROOT)/agent
@echo $(AGENT)
@mkdir -p $(AGENT)
它将输出为
AGENT:=/AGENT
,显然,AGENT
变量没有扩展为ROOT
这里有几个常见错误:
$(shell…
make函数:recipes已经是shell脚本了- Shell变量被分配为
(在var=xxx
周围没有空格),仅在配方中(好的,几乎只有)。它们是用=
或$var
扩展的,但从来没有用${var}
扩展,仍然几乎只在配方中$(var)
- Make变量被赋值为
或var:=xxx
(在var=xxx
或:=
周围有空格或没有空格),仅在配方之外(好吧,几乎仅限于此)。它们用=
或$(var)
展开,而不是在任何地方用${var}
展开。请注意,$var
和=
是不同的,但这超出了范围:=
ROOT
和AGENT
是make变量,使用:=
分配到任何配方之外,并且可以在任何地方使用,包括配方中。它们用$(var)
展开。在将配方传递给shell之前,make会将其展开为:
echo /some/where
echo /some/where/agent
mkdir -p /some/where/agent
每一行都将在一个单独的shell中执行,但这并不重要,因为它们之间没有shell变量传递
注意:如果您使用的是GNU make,则将定义CURDIR
make变量,并将其扩展为当前工作目录。无需使用pwd
,只需使用$(CURDIR)
而不是$(ROOT)
:
注意:如果ROOT
指向make文件的位置,并且如果使用-f
make选项从其他地方调用make,$(CURDIR)
不再工作,因为它指向调用make文件的位置,而不是make文件的位置。但您也可以通过以下方法获得正确的根目录
:
ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
在Makefile的最开始(在任何include
语句之前)
使用shell变量
仅使用shell语法和单行配方:
all:
@ROOT="`pwd`"; AGENT="$$ROOT"/agent; echo "$$ROOT"; echo "$$AGENT"; mkdir -p "$$AGENT"
ROOT
和AGENT
是shell变量,在配方内部分配有=
,仅在配方的同一行中可用。请注意,用于展开shell变量的双精度$
。在将结果传递给shell之前,需要它们来逃避make执行的第一次扩展。通过make进行扩展后,配方被传递到外壳,如下所示:
ROOT="`pwd`"; AGENT="$ROOT"/agent; echo "$ROOT"; echo "$AGENT"; mkdir -p "$AGENT"
(make将$$
扩展为$
并在那里停止)这就是您想要的。它在一个shell中执行,这就是shell变量从列表的一个命令传递到下一个命令的原因
如果您愿意,为了更好的可读性,您可以使用\
行继续符将配方拆分为几行,但仍然只有一个配方在一个shell中执行:
all:
@ROOT="`pwd`"; \
AGENT="$$ROOT/agent"; \
echo "$$ROOT"; \
echo "$$AGENT"; \
mkdir -p "$$AGENT"
这严格等同于另一种形式,只是更易于阅读。但它完全不同于:
all:
@ROOT="`pwd`"
@AGENT="$$ROOT/agent"
@echo "$$ROOT"
@echo "$$AGENT"
@mkdir -p "$$AGENT"
因为对于最后一个表单,5行由5个不同的shell执行。例如,当第二个shell运行时,由第一个shell分配的ROOT
shell变量不再定义,结果如下:
AGENT="/agent"
然后,这两条echo
行什么也不回显,只回显一条新行。最后您会得到一个错误,因为:
mkdir -p
无效。这里有几个常见错误:
$(shell…
make函数:recipes已经是shell脚本了- Shell变量被分配为
(在var=xxx
周围没有空格),仅在配方中(好的,几乎只有)。它们是用=
或$var
扩展的,但从来没有用${var}
扩展,仍然几乎只在配方中$(var)
- Make变量被赋值为
或var:=xxx
(在var=xxx
或:=
周围有空格或没有空格),仅在配方之外(好吧,几乎仅限于此)。它们用=
或$(var)
展开,而不是在任何地方用${var}
展开。请注意,$var
和=
是不同的,但这超出了范围:=
AGENT="/agent"
mkdir -p