跨多个 Makefile 转义的环境变量
Environment variable escaping across multiple Makefiles
通过多级makefile传递和修改环境变量的正确方法是什么?具体来说,我使用 special $ORIGIN
RPATH value 在父 makefile 中设置 LDFLAGS
,并且我需要添加到某些子 makefile 中的变量。链接器需要文字字符串 $ORIGIN
,这不是要扩展的另一个变量。
Makefile
:
# default value for all children
export LDFLAGS = -Wl,-rpath='$$ORIGIN'
all:
env | grep LDFLAGS
$(MAKE) -f child1.mk
$(MAKE) -f child2.mk
child1.mk
:
# add an additional RPATH value
export LDFLAGS += -Wl,-rpath='$$ORIGIN/../..'
all:
env | grep LDFLAGS
child2.mk
:
all:
env | grep LDFLAGS
事情是这样的:
$ make
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make -f child1.mk
make[1]: Entering directory `/build/test'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='RIGIN' -Wl,-rpath='$ORIGIN/../..'
make[1]: Leaving directory `/build/test'
make -f child2.mk
make[1]: Entering directory `/build/test'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make[1]: Leaving directory `/build/test'
在 child1 输出中,'RIGIN'
是错误的,$$
似乎已被第二次评估。
documentation has this note about exports,这可能是相关的,但并没有真正解释如何避免它:
In both of these forms, the arguments to export
and unexport
are expanded, and so could be variables or functions which expand to a (list of) variable names to be (un)exported.
在顶级 Makefile "works" 中对 child1 使用 $$$$ORIGIN
,但对 child2 不使用 LDFLAGS
值并以 $$ORIGIN
结尾.
这是 Linux 下的 GNU Make 3.81。
我链接到的 RPATH post 有一个解决方法,但感觉这不是必需的:
LDFLAGS="-Wl,-rpath=XORIGIN/../lib" ./configure --prefix=/blabla/place
See the X
? That will be replaced by a dollar sign later when you run chrpath
on the resultant binaries.
这是一个工作示例,如何使用 bash
将 $ORIGIN
传递给多个级别的 makefile:
SHELL := /bin/bash
ifeq (${MAKELEVEL},0)
export LDFLAGS := -Wl,-rpath=`printf "%bORIGIN" "4"`
endif
all :
@echo MAKELEVEL=${MAKELEVEL} LDFLAGS=${LDFLAGS}
@if [[ ${MAKELEVEL} -lt 3 ]]; then ${MAKE}; fi
输出:
$ make --no-print-directory
MAKELEVEL=0 LDFLAGS=-Wl,-rpath=$ORIGIN
MAKELEVEL=1 LDFLAGS=-Wl,-rpath=$ORIGIN
MAKELEVEL=2 LDFLAGS=-Wl,-rpath=$ORIGIN
MAKELEVEL=3 LDFLAGS=-Wl,-rpath=$ORIGIN
或者,如果您使用 Linux,在没有 $ORIGIN
的情况下构建,然后使用 Exodus 进行 无痛重定位 Linux 二进制文件 – 以及所有他们的依赖关系——没有容器.
从表面上看,这似乎是 make 与环境变量集成时可能出现的意外错误。似乎每当 'make' 拾取环境变量时,它都会 'expand' 任何 '$v'(以及可能的其他构造)。
考虑这个非常简单的 makefile
all:
echo "V=$V"
env | grep V=
将 V 设置为 '$$SHELL' (bash export V='$$SHELL'),运行 make 将显示内部 'V'变量是/bin/bash,而环境变量是'$$SHELL'
echo "V=$SHELL"
V=/bin/bash
env | grep V=
V=$$SHELL
抛开这个问题是特性还是错误,您可以使用 $(value var) 函数来访问 "raw" 值。在 child 中使用:
# Append extra flags to env LDFLAGS, without 'expansion'
export LDFLAGS := $(value LDFLAGS) -Wl,-rpath='$$ORIGIN/../..'
您还可以设置 O
的附加变量以在附加到 LDFLAGS
之前扩展到相同的变量,这样即使 make
在 [= 中扩展 $O
16=],它仍然会导致 $ORIGIN
:
$ cat child1.mk
# add an additional RPATH value
O := $$O
LDFLAGS += -Wl,-rpath='$$ORIGIN/../..'
all:
env | grep LDFLAGS
输出:
$ make
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make -f child1.mk
make[1]: Entering directory '/home/raspy/so-62298900'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN' -Wl,-rpath='$ORIGIN/../..'
make[1]: Leaving directory '/home/raspy/so-62298900'
make -f child2.mk
make[1]: Entering directory '/home/raspy/so-62298900'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make[1]: Leaving directory '/home/raspy/so-62298900'
通过多级makefile传递和修改环境变量的正确方法是什么?具体来说,我使用 special $ORIGIN
RPATH value 在父 makefile 中设置 LDFLAGS
,并且我需要添加到某些子 makefile 中的变量。链接器需要文字字符串 $ORIGIN
,这不是要扩展的另一个变量。
Makefile
:
# default value for all children
export LDFLAGS = -Wl,-rpath='$$ORIGIN'
all:
env | grep LDFLAGS
$(MAKE) -f child1.mk
$(MAKE) -f child2.mk
child1.mk
:
# add an additional RPATH value
export LDFLAGS += -Wl,-rpath='$$ORIGIN/../..'
all:
env | grep LDFLAGS
child2.mk
:
all:
env | grep LDFLAGS
事情是这样的:
$ make
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make -f child1.mk
make[1]: Entering directory `/build/test'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='RIGIN' -Wl,-rpath='$ORIGIN/../..'
make[1]: Leaving directory `/build/test'
make -f child2.mk
make[1]: Entering directory `/build/test'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make[1]: Leaving directory `/build/test'
在 child1 输出中,'RIGIN'
是错误的,$$
似乎已被第二次评估。
documentation has this note about exports,这可能是相关的,但并没有真正解释如何避免它:
In both of these forms, the arguments to
export
andunexport
are expanded, and so could be variables or functions which expand to a (list of) variable names to be (un)exported.
在顶级 Makefile "works" 中对 child1 使用 $$$$ORIGIN
,但对 child2 不使用 LDFLAGS
值并以 $$ORIGIN
结尾.
这是 Linux 下的 GNU Make 3.81。
我链接到的 RPATH post 有一个解决方法,但感觉这不是必需的:
LDFLAGS="-Wl,-rpath=XORIGIN/../lib" ./configure --prefix=/blabla/place
See the
X
? That will be replaced by a dollar sign later when you runchrpath
on the resultant binaries.
这是一个工作示例,如何使用 bash
将 $ORIGIN
传递给多个级别的 makefile:
SHELL := /bin/bash
ifeq (${MAKELEVEL},0)
export LDFLAGS := -Wl,-rpath=`printf "%bORIGIN" "4"`
endif
all :
@echo MAKELEVEL=${MAKELEVEL} LDFLAGS=${LDFLAGS}
@if [[ ${MAKELEVEL} -lt 3 ]]; then ${MAKE}; fi
输出:
$ make --no-print-directory
MAKELEVEL=0 LDFLAGS=-Wl,-rpath=$ORIGIN
MAKELEVEL=1 LDFLAGS=-Wl,-rpath=$ORIGIN
MAKELEVEL=2 LDFLAGS=-Wl,-rpath=$ORIGIN
MAKELEVEL=3 LDFLAGS=-Wl,-rpath=$ORIGIN
或者,如果您使用 Linux,在没有 $ORIGIN
的情况下构建,然后使用 Exodus 进行 无痛重定位 Linux 二进制文件 – 以及所有他们的依赖关系——没有容器.
从表面上看,这似乎是 make 与环境变量集成时可能出现的意外错误。似乎每当 'make' 拾取环境变量时,它都会 'expand' 任何 '$v'(以及可能的其他构造)。
考虑这个非常简单的 makefile
all:
echo "V=$V"
env | grep V=
将 V 设置为 '$$SHELL' (bash export V='$$SHELL'),运行 make 将显示内部 'V'变量是/bin/bash,而环境变量是'$$SHELL'
echo "V=$SHELL"
V=/bin/bash
env | grep V=
V=$$SHELL
抛开这个问题是特性还是错误,您可以使用 $(value var) 函数来访问 "raw" 值。在 child 中使用:
# Append extra flags to env LDFLAGS, without 'expansion'
export LDFLAGS := $(value LDFLAGS) -Wl,-rpath='$$ORIGIN/../..'
您还可以设置 O
的附加变量以在附加到 LDFLAGS
之前扩展到相同的变量,这样即使 make
在 [= 中扩展 $O
16=],它仍然会导致 $ORIGIN
:
$ cat child1.mk
# add an additional RPATH value
O := $$O
LDFLAGS += -Wl,-rpath='$$ORIGIN/../..'
all:
env | grep LDFLAGS
输出:
$ make
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make -f child1.mk
make[1]: Entering directory '/home/raspy/so-62298900'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN' -Wl,-rpath='$ORIGIN/../..'
make[1]: Leaving directory '/home/raspy/so-62298900'
make -f child2.mk
make[1]: Entering directory '/home/raspy/so-62298900'
env | grep LDFLAGS
LDFLAGS=-Wl,-rpath='$ORIGIN'
make[1]: Leaving directory '/home/raspy/so-62298900'