bol*_*ing 183 makefile working-directory gnu-make
我在app特定目录中有几个Makefile,如下所示:
/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile
Run Code Online (Sandbox Code Playgroud)
每个Makefile在此路径中包含一个.inc文件:
/project1/apps/app_rules.inc
Run Code Online (Sandbox Code Playgroud)
在app_rules.inc里面我正在设置我希望在构建时放置二进制文件的目的地.我希望所有二进制文件都在各自的app_type路径中:
/project1/bin/app_typeA/
Run Code Online (Sandbox Code Playgroud)
我尝试过使用$(CURDIR),像这样:
OUTPUT_PATH = /project1/bin/$(CURDIR)
Run Code Online (Sandbox Code Playgroud)
但相反,我把二进制文件埋在整个路径名中,如下所示:( 注意冗余)
/project1/bin/projects/users/bob/project1/apps/app_typeA
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能获得执行的"当前目录",这样我才能知道app_typeX为了将二进制文件放在各自的类型文件夹中?
Nik*_*pov 240
你可以使用shell功能:current_dir = $(shell pwd).或者shell结合使用notdir,如果你不需要绝对路径:
current_dir = $(notdir $(shell pwd)).
给定解决方案仅在make从Makefile的当前目录运行时才有效.
正如@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))))
Run Code Online (Sandbox Code Playgroud)
sle*_*cal 123
从这里开始 ;
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
Run Code Online (Sandbox Code Playgroud)
显示为;
$ cd /home/user/
$ make -f test/Makefile
/home/user/test
$ cd test; make Makefile
/home/user/test
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
Tzu*_*ong 41
如果您使用的是GNU make,$(CURDIR)实际上是一个内置变量.它是Makefile驻留 当前工作目录的位置,可能是Makefile所在的位置,但并非总是如此.
OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))
Run Code Online (Sandbox Code Playgroud)
请参阅http://www.gnu.org/software/make/manual/make.html中的附录A快速参考
小智 26
THIS_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
Run Code Online (Sandbox Code Playgroud)
Sta*_*dog 25
对于 GNU make >= 3.81,于 2006 年推出
ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
Run Code Online (Sandbox Code Playgroud)
MAKEFILE_LIST当包含文件进入和超出范围时进行更改。最后一项是当前文件。
lastword选取最后一项(Makefile 名称,相对于pwd)
realpath内置于make,并解析为来自文件系统根的规范路径
dir删除文件名,只留下目录。
注意:结果ROOT_DIR将包括尾随路径分隔符(例如,nix 上的“/”或 Windows 上的“\”)
我尝试了许多这些答案,但是在带有gnu make 3.80的AIX系统上,我需要做一些旧的事情。
原来是lastword,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))
Run Code Online (Sandbox Code Playgroud)
就像其他人所说的那样,它不是最优雅的,因为它两次调用了shell,并且仍然存在空格问题。
但是由于我的路径中没有空格,所以无论我如何开始,它都对我有用make:
所有给我wherever的current_dir和绝对路径wherever的mkfile_dir。
我喜欢选择的答案,但我认为实际展示它比解释它会更有帮助。
/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
Run Code Online (Sandbox Code Playgroud)
输出:
+ 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
Run Code Online (Sandbox Code Playgroud)
注意:该功能$(patsubst %/,%,[path/goes/here/])用于去除斜杠。