我有几个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,以便将二进制文件放在各自的类型文件夹中?


当前回答

据我所知,这是唯一的答案,正确的空格:

space:= 
space+=

CURRENT_PATH := $(subst $(lastword $(notdir $(MAKEFILE_LIST))),,$(subst $(space),\$(space),$(shell realpath '$(strip $(MAKEFILE_LIST))')))

它本质上是通过将'\ '替换为'\ '来转义空格字符,这允许Make正确地解析它,然后它通过做另一个替换来删除makefile在MAKEFILE_LIST中的文件名,这样你就只剩下makefile所在的目录。虽然不是世界上最紧凑的东西,但它确实有效。

你最终会得到这样的结果,所有的空格都被转义了:

$(info CURRENT_PATH = $(CURRENT_PATH))

CURRENT_PATH = /mnt/c/Users/foobar/gDrive/P\ roje\ cts/we\ b/sitecompiler/

其他回答

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

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

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

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

从这里带走;

ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

显示为;

$ cd /home/user/

$ make -f test/Makefile 
/home/user/test

$ cd test; make Makefile 
/home/user/test
THIS_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))

如果您正在使用GNU make, $(CURDIR)实际上是一个内置变量。它是Makefile所在的位置,当前工作目录可能是Makefile所在的位置,但并不总是这样。

OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))

参见http://www.gnu.org/software/make/manual/make.html中的“附录A快速参考”

我喜欢选定的答案,但我认为实际展示它比解释它更有帮助。

/ 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/])用于去除后面的斜杠。