[makefile] Makefile의 현재 상대 디렉토리를 얻는 방법?

다음과 같이 앱 특정 디렉토리에 여러 개의 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그리고는 realpath3.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)