如何在Makefile中输入父目录?

ken*_*orb 3 shell makefile gnu-make

我有以下内容Makefile(GNU Make 3.81):

CWD:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

all:
        pwd
        cd "$(CWD)/.."
        pwd
        cd ".."
        pwd
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ make
pwd
/Users/kenorb/temp/foo
cd "/Users/kenorb/temp/foo/.."
pwd
/Users/kenorb/temp/foo
cd ".."
pwd
/Users/kenorb/temp/foo
Run Code Online (Sandbox Code Playgroud)

看来cd“通过 到父目录”..没有任何效果。

如何将当前工作目录更改为相对于Makefile文件的父目录?

眠りネ*_*ネロク 5

这个问题与规则配方的每一行都是在专用 shell 实例(即:新进程)中执行这一事实有关。因此,cd在一行中运行不会对另一行中的命令产生任何影响,因为这些命令是由不同的进程执行的。

更改配方的工作目录

您可以使用.ONESHELL(GNU Make 3.82 或更高版本)在单个相同的 shell 实例中运行配方的所有行:

CWD:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

.ONESHELL:
all:
        pwd
        cd "$(CWD)/.."
        pwd
        cd ".."
        pwd
Run Code Online (Sandbox Code Playgroud)

或者将所有命令保留在一行中:

CWD:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

all:
        pwd; cd "$(CWD)/.."; pwd; cd ".."; pwd
Run Code Online (Sandbox Code Playgroud)

工作目录的更改仅在该配方内生效。


请注意,更改调用的 shell 的 makefile 内的当前工作目录make是不可能的,因为这是一个进程的属性,并且make将执行的运行实例cd是另一个(子)进程。因此,它只会更改该子进程的工作目录。

这与您无法在不获取脚本的情况下通过执行脚本来更改 shell 的工作目录的原因相同:因为脚本在新的 shell 实例(即:子进程)中运行。