我在app特定目录中有几个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
以便将二进制文件放入各自的类型文件夹中?
答案 0 :(得分:220)
您可以使用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))))
答案 1 :(得分:114)
取自here;
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
显示为;
$ cd /home/user/
$ make -f test/Makefile
/home/user/test
$ cd test; make Makefile
/home/user/test
希望这有帮助
答案 2 :(得分:36)
如果您使用的是GNU make,$(CURDIR)实际上是一个内置变量。它是Makefile所在的位置 当前工作目录,这可能是Makefile的位置,但并不总是。
OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))
中的附录A快速参考
答案 3 :(得分:25)
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
答案 4 :(得分:5)
我尝试了很多这些答案,但在我的AIX系统上使用gnu make 3.80我需要做一些旧学校的事情。
事实证明,直到3.81才添加lastword
,abspath
和realpath
。 :(
mkfile_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(shell cd $(shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))
正如其他人所说的那样,并不是最优雅的,因为它会两次调用shell,而且它仍然存在空间问题。
但是由于我的路径中没有任何空格,无论我如何开始make
,它都适合我:
所有人wherever
为current_dir
提供wherever
,mkfile_dir
提供String emailAddress = "someone@somewhere.com";
hostServices.showDocument("mailto:" +
emailAddress +
"?Subject=This is my subject" +
"&body=Please see the details at this link: "
+ "http://myserver.com:8080/application/page.html?param1=SOMETHING¶m2=12345";
的绝对路径。
答案 5 :(得分:5)
我喜欢所选择的答案,但我认为实际展示它的工作比解释它更有帮助。
/tmp/makefile_path_test.sh
#!/bin/bash -eu
# Create a testing dir
temp_dir=/tmp/makefile_path_test
proj_dir=$temp_dir/dir1/dir2/dir3
mkdir -p $proj_dir
# Create the Makefile in $proj_dir
# (Because of this, $proj_dir is what $(path) should evaluate to.)
cat > $proj_dir/Makefile <<'EOF'
path := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
cwd := $(shell pwd)
all:
@echo "MAKEFILE_LIST: $(MAKEFILE_LIST)"
@echo " path: $(path)"
@echo " cwd: $(cwd)"
@echo ""
EOF
# See/debug each command
set -x
# Test using the Makefile in the current directory
cd $proj_dir
make
# Test passing a Makefile
cd $temp_dir
make -f $proj_dir/Makefile
# Cleanup
rm -rf $temp_dir
输出:
+ cd /tmp/makefile_path_test/dir1/dir2/dir3
+ make
MAKEFILE_LIST: Makefile
path: /private/tmp/makefile_path_test/dir1/dir2/dir3
cwd: /tmp/makefile_path_test/dir1/dir2/dir3
+ cd /tmp/makefile_path_test
+ make -f /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
MAKEFILE_LIST: /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
path: /tmp/makefile_path_test/dir1/dir2/dir3
cwd: /tmp/makefile_path_test
+ rm -rf /tmp/makefile_path_test
注意:函数$(patsubst %/,%,[path/goes/here/])
用于去除尾部斜杠。
答案 6 :(得分:0)
供您参考的示例,如下所示:
文件夹结构可能如下:
哪里有两个Makefile,每个都如下;
sample/Makefile
test/Makefile
现在,让我们看看Makefile的内容。
样品/生成文件
export ROOT_DIR=${PWD}
all:
echo ${ROOT_DIR}
$(MAKE) -C test
测试/生成文件
all:
echo ${ROOT_DIR}
echo "make test ends here !"
现在,执行sample / Makefile,as;
cd sample
make
输出:
echo /home/symphony/sample
/home/symphony/sample
make -C test
make[1]: Entering directory `/home/symphony/sample/test'
echo /home/symphony/sample
/home/symphony/sample
echo "make test ends here !"
make test ends here !
make[1]: Leaving directory `/home/symphony/sample/test'
说明,父/ home目录可以存储在environment-flag中,并且可以导出,以便可以在所有子目录makefile中使用。
答案 7 :(得分:0)
这是使用shell语法获取Makefile
文件的绝对路径的单行程序:
SHELL := /bin/bash
CWD := $(shell cd -P -- '$(shell dirname -- "$0")' && pwd -P)
这是基于@0xff answer的没有shell的版本:
CWD := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
通过打印来测试它,例如:
cwd:
@echo $(CWD)
答案 8 :(得分:0)
帮自己一个忙,希望每个make文件都可以从包含目录中运行。无需关心任何命令中的任何路径。
答案 9 :(得分:0)
解决方案在这里:https://sourceforge.net/p/ipt-netflow/bugs-requests-patches/53/
解决方案是:$(CURDIR)
您可以这样使用它:
CUR_DIR = $(CURDIR)
## Start :
start:
cd $(CUR_DIR)/path_to_folder
答案 10 :(得分:0)
据我所知,这是唯一可以正确使用空格的答案:
space:=
space+=
CURRENT_PATH := $(subst $(lastword $(notdir $(MAKEFILE_LIST))),,$(subst $(space),\$(space),$(shell realpath '$(strip $(MAKEFILE_LIST))')))
从本质上讲,它是通过用' '
代替'\ '
来转义空格字符而使Make能够正确解析它,然后通过进行另一次替换来删除MAKEFILE_LIST
中makefile的文件名。因此,您只剩下makefile所在的目录。这并不是世界上最紧凑的文件,但它确实可以工作。
您最终将得到这样的结果,其中所有空格均被转义:
$(info CURRENT_PATH = $(CURRENT_PATH))
CURRENT_PATH = /mnt/c/Users/foobar/gDrive/P\ roje\ cts/we\ b/sitecompiler/
答案 11 :(得分:-1)
更新2018/03/05 finnaly我用这个:
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和其他目录中执行,它可以显示正确。
答案 12 :(得分:-1)
如果make变量包含相对路径 ROOT_DIR
override func viewDidLoad() {
super.viewDidLoad()
let mainQueue = OperationQueue.main
NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot,
object: nil,
queue: mainQueue) { notification in
print("SCREENSHOT TAKEN")
}
}
获取绝对路径只需使用以下方法。
ROOT_DIR := ../../../
它在GNUMake中的工作正常......
答案 13 :(得分:-3)
Makefile中的一行应该足够了:
DIR := $(notdir $(CURDIR))