Как получить текущий каталог в вашем Makefile?



у меня есть несколько Makefiles в конкретных каталогах приложений, таких как это:



/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile


каждый Makefile включает a .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 для того, чтобы поместить двоичные файлы в соответствующие папки типов?

1545   11  

11 ответов:

функция оболочки.

можно использовать 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/.

код ниже будет работать для любого для Makefiles вызывается из любого каталога:

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) на самом деле является встроенной переменной. Это и есть место, где находится Makefileтекущий рабочий каталог, в котором, вероятно, находится Makefile, но не всегда.

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

см. приложение краткий справочник в http://www.gnu.org/software/make/manual/make.html

THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

Я пробовал многие из этих ответов, но на моей системе AIX с gnu make 3.80 мне нужно было сделать некоторые вещи старой школы.

получается, что 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 ../wherever / makefile
  • make-C ../ где бы то ни было
  • make-C ~ / wherever
  • cd ../ где бы то ни было; сделать

все Дайте мне wherever на current_dir и абсолютный путь к wherever на mkfile_dir.

собирая примеры, приведенные здесь, это дает полный путь к файлу makefile:

# Get the location of this makefile.
ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

мне нравится выбранный ответ, но я думаю, что было бы более полезно на самом деле показать его работу, чем объяснить его.

/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/]) используется для удаления задней косой черты.

пример для вашей справки, как показано ниже:

структура папок может быть так:

enter image description here

где есть два Makefiles, каждый, как показано ниже;

sample/Makefile
test/Makefile

теперь давайте посмотрим содержимое 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 !"

теперь выполните sample / Makefile, as;

cd sample
make

выход:

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'

объяснение заключается в том, что родительский/домашний каталог может храниться в флаге среды и может быть экспортирован, чтобы его можно было использовать во всех подкаталогах makefiles.

вот один-лайнер, чтобы получить абсолютный путь к вашей Makefile файл с использованием синтаксиса оболочки:

SHELL := /bin/bash
CWD := $(shell cd -P -- '$(shell dirname -- "")' && pwd -P)

а вот версия без оболочки на основе @0xff ответ:

CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))

проверьте его, напечатав его, например:

cwd:
        @echo $(CWD)

если переменная make содержит относительный путь ROOT_DIR

ROOT_DIR := ../../../

них, чтобы получить абсолютный путь просто использовать ниже метод.

ROOT_DIR := $(abspath $(ROOT_DIR))

его работа отлично в GNUMake...

обновление 2018/03/05 finnaly я использую это:


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

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

Он может быть выполнен правильно в относительном пути или абсолютном пути. Выполняется правильно, вызывается crontab. Выполняется корректно в другой оболочке.

показать пример, a.sh путь печати собственной личности.

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

старый: Я использую это:

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

Он может показать правильно, если выполняется в другой оболочке и другой каталог.

Comments

    Ничего не найдено.