다음과 같이 앱 특정 디렉토리에 여러 개의 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
바이너리를 각 유형 폴더에 넣을 수있는 것을 알 수 있도록 실행의 “현재 디렉토리”를 얻으려면 어떻게해야 합니까?
답변
쉘 기능.
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))))
답변
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
도움이 되었기를 바랍니다
답변
GNU make를 사용하는 경우 $ (CURDIR)은 실제로 내장 변수입니다. Makefile 이 현재 작업 디렉토리 가있는 위치이며, 아마도 Makefile이있는 위치 일 수 있지만 항상 그런 것은 아닙니다 .
OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))
http://www.gnu.org/software/make/manual/make.html의 부록 A 빠른 참조를 참조하십시오.
답변
THIS_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
답변
나는이 답변 중 많은 것을 시도했지만 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))
다른 사람들이 말했듯이, 쉘을 두 번 호출 할 때 가장 우아하지는 않지만 여전히 공백 문제가 있습니다.
그러나 경로에 공백이 없으므로 시작 방법에 관계없이 작동합니다 make
.
- make -f ../whereever/makefile
- 어디든지 -C ../
- 어디든지 -C ~ /
- cd ../where; 하다
모든 줘 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
산출:
+ 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/])
은 후행 슬래시를 제거하는 데 사용됩니다.
답변
다음은 Makefile
쉘 구문을 사용 하여 파일의 절대 경로를 얻는 하나의 라이너입니다 .
SHELL := /bin/bash
CWD := $(shell cd -P -- '$(shell dirname -- "$0")' && pwd -P)
그리고 여기 @ 0xff 답변을 기반으로 쉘이없는 버전이 있습니다 .
CWD := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
다음과 같이 인쇄하여 테스트하십시오.
cwd:
@echo $(CWD)
