我有几个makefile在应用程序特定的目录,像这样:

/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile

每个Makefile都在这个路径中包含一个.inc文件:

/project1/apps/app_rules.inc

app_rules内部。inc .我正在设置我想要在构建时放置二进制文件的目的地。我希望所有二进制文件都在它们各自的app_type路径中:

/project1/bin/app_typeA/

我尝试使用$(CURDIR),像这样:

OUTPUT_PATH = /project1/bin/$(CURDIR)

但相反,我得到了二进制文件埋在整个路径名,像这样:(注意冗余)

/project1/bin/projects/users/bob/project1/apps/app_typeA

我能做些什么来获得执行的“当前目录”,以便我可以知道app_typeX,以便将二进制文件放在各自的类型文件夹中?


当前回答

我尝试了许多这些答案,但是在我的AIX系统上,我需要使用gnu make 3.80做一些老派的事情。

最后一个词,abspath和realpath直到3.81才加入。:(

mkfile_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(shell cd $(shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))

正如其他人所说,它不是最优雅的,因为它调用了shell两次,而且它仍然有空格问题。

但由于我的路径中没有任何空间,无论我如何开始制作,它都适用于我:

Make -f ../where /makefile ./ make -C ../任意位置 make -C ~/where cd . . /的地方;使

都为我提供了current_dir的where和mkfile_dir的where的绝对路径。

其他回答

壳层函数。

您可以使用shell函数:current_dir = $(shell pwd)。 如果不需要绝对路径,也可以使用shell结合notdir: Current_dir = $(notdir $(shell pwd))。

更新。

给定的解决方案仅在从Makefile的当前目录运行make时有效。 正如@Flimm所指出的:

注意,这将返回当前工作目录,而不是Makefile的父目录。例如,如果您运行cd /;make -f /home/username/project/ makefile,则current_dir变量为/,而不是/home/username/project/。

下面的代码将适用于从任何目录调用的makefile:

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))

简单、正确、现代的方式:

对于GNU make >= 3.81,它是在2006年引入的

ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))

MAKEFILE_LIST在包含文件进入和退出作用域时发生变化。最后一项是当前文件。 lastword提取最后一项(Makefile名称,相对于pwd) Realpath是内置的,并从文件系统根解析为规范路径 Dir删除文件名,只留下目录。

更新2018/03/05 最后我用这个:


shellPath=`echo $PWD/``echo ${0%/*}`

# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == '/' ] ; then
    shellPath=${shellPath2}
fi

它可以在相对路径或绝对路径上正确执行。 由crontab调用的已执行正确。 在其他shell中执行正确。

显示示例,a.sh打印自路径。

[root@izbp1a7wyzv7b5hitowq2yz /]# more /root/test/a.sh
shellPath=`echo $PWD/``echo ${0%/*}`

# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == '/' ] ; then
    shellPath=${shellPath2}
fi

echo $shellPath
[root@izbp1a7wyzv7b5hitowq2yz /]# more /root/b.sh
shellPath=`echo $PWD/``echo ${0%/*}`

# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == '/' ] ; then
    shellPath=${shellPath2}
fi

$shellPath/test/a.sh
[root@izbp1a7wyzv7b5hitowq2yz /]# ~/b.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz /]# /root/b.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz /]# cd ~
[root@izbp1a7wyzv7b5hitowq2yz ~]# ./b.sh
/root/./test
[root@izbp1a7wyzv7b5hitowq2yz ~]# test/a.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz ~]# cd test
[root@izbp1a7wyzv7b5hitowq2yz test]# ./a.sh
/root/test/.
[root@izbp1a7wyzv7b5hitowq2yz test]# cd /
[root@izbp1a7wyzv7b5hitowq2yz /]# /root/test/a.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz /]# 

旧: 我用这个:

MAKEFILE_PATH := $(PWD)/$({0%/*})

如果在其他shell和其他目录下执行,可以显示正确。

下面是使用shell语法获取Makefile文件绝对路径的一行程序:

SHELL := /bin/bash
CWD := $(shell cd -P -- '$(shell dirname -- "$0")' && pwd -P)

下面是没有shell的版本,基于@0xff的答案:

CWD := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))

通过打印来测试,比如:

cwd:
        @echo $(CWD)

我尝试了许多这些答案,但是在我的AIX系统上,我需要使用gnu make 3.80做一些老派的事情。

最后一个词,abspath和realpath直到3.81才加入。:(

mkfile_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(shell cd $(shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))

正如其他人所说,它不是最优雅的,因为它调用了shell两次,而且它仍然有空格问题。

但由于我的路径中没有任何空间,无论我如何开始制作,它都适用于我:

Make -f ../where /makefile ./ make -C ../任意位置 make -C ~/where cd . . /的地方;使

都为我提供了current_dir的where和mkfile_dir的where的绝对路径。