Programing

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

lottogame 2020. 5. 20. 07:46
반응형

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 $(lastword $(MAKEFILE_LIST))))

로 표시됩니다.

$ cd /home/user/

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

$ cd test; make Makefile 
/home/user/test

도움이 되었기를 바랍니다


GNU make를 사용하는 경우 $ (CURDIR)은 실제로 내장 변수입니다. 그것은이다 메이크 파일이있는 위치를 항상은 아니지만, 메이크 파일이 어디 아마도 현재 작업 디렉토리를 .

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

http://www.gnu.org/software/make/manual/make.html의 부록 A 빠른 참조를 참조하십시오.


THIS_DIR := $(dir $(abspath $(lastword $(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/])은 후행 슬래시를 제거하는 데 사용됩니다.


해결책은 여기에 있습니다 : https://sourceforge.net/p/ipt-netflow/bugs-requests-patches/53/

해결책은 다음과 같습니다. $ (CURDIR)

당신은 그것을 다음과 같이 사용할 수 있습니다 :

CUR_DIR = $(CURDIR)

## Start :
start:
    cd $(CUR_DIR)/path_to_folder

다음은 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)

다음과 같이 참조하십시오.

폴더 구조는 다음과 같습니다.

enter image description here

Where there are two Makefiles, each as below;

sample/Makefile
test/Makefile

Now, let us see the content of the Makefiles.

sample/Makefile

export ROOT_DIR=${PWD}

all:
    echo ${ROOT_DIR}
    $(MAKE) -C test

test/Makefile

all:
    echo ${ROOT_DIR}
    echo "make test ends here !"

Now, execute the sample/Makefile, as;

cd sample
make

OUTPUT:

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'

Explanation, would be that the parent/home directory can be stored in the environment-flag, and can be exported, so that it can be used in all the sub-directory makefiles.


Do yourself a huge favor and expect each make file to be run from the containing directory. No need to care about any paths whatsoever in any command.


update 2018/03/05 finnaly I use this:


shellPath=`echo $PWD/``echo ${0%/*}`

# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == '/' ] ; then
    shellPath=${shellPath2}
fi

It can be executed correct in relative path or absolute path. Executed correct invoked by crontab. Executed correct in other shell.

show example, a.sh print self path.

[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 /]# 

old: I use this:

MAKEFILE_PATH := $(PWD)/$({0%/*})

It can show correct if executed in other shell and other directory.

참고URL : https://stackoverflow.com/questions/18136918/how-to-get-current-relative-directory-of-your-makefile

반응형