通过多个级别的makefile传递和修改环境变量的正确方法是什么?具体来说,我是使用LDFLAGS
在父Makefile中设置special $ORIGIN
RPATH value,并且需要在某些子Makefile中添加变量。链接器需要文字字符串$ORIGIN
,而不是要扩展的另一个变量。
$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
在child1输出中,$ 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'
不好,'RIGIN'
似乎已经被第二次评估。
$$
,可能是相关的,但并未真正说明如何避免它:
在这两种形式中,documentation has this note about exports和
export
的参数都被扩展,因此变量或函数也可以被扩展为要(不导出)变量名(列表)的变量或函数。
在顶层Makefile中使用unexport
对child1起作用,但对child2则不起作用,后者不会更改$$$$ORIGIN
值并以LDFLAGS
结尾。
这是Linux下的GNU Make 3.81。
我链接到的$$ORIGIN
有一种解决方法,但是感觉不需要这样做:
看到
LDFLAGS="-Wl,-rpath=XORIGIN/../lib" ./configure --prefix=/blabla/place
?稍后在生成的二进制文件上运行X
时,它将替换为美元符号。
这是一个有效的示例,如何使用chrpath
通过多个级别的makefile传递$ORIGIN
:
bash
输出:
SHELL := /bin/bash
ifeq (${MAKELEVEL},0)
export LDFLAGS := -Wl,-rpath=`printf "%bORIGIN" "\044"`
endif
all :
@echo MAKELEVEL=${MAKELEVEL} LDFLAGS=${LDFLAGS}
@if [[ ${MAKELEVEL} -lt 3 ]]; then ${MAKE}; fi
或者,如果您使用的是Linux,则在不使用$ 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
的情况下进行构建,然后使用$ORIGIN
进行Linux二进制文件及其所有依赖项的无痛重定位–无需容器。
从表面上看,这似乎与环境变量集成在一起可能是一个意外的错误。似乎每当环境变量被“ make”传递时,它都会“扩展”任何“ $ v”(以及可能的其他构造)。
考虑这个非常简单的makefile
Exodus
将V设置为'$$ SHELL'(bash导出V ='$$ SHELL'),然后运行make将显示内部的'V'变量为/ bin / bash,而环境变量为'$$ SHELL'
all:
echo "V=$V"
env | grep V=
附带问题,如果这是功能或错误,可以使用$(value var)函数访问“原始”值。在孩子中使用:
echo "V=$SHELL"
V=/bin/bash
env | grep V=
V=$$SHELL