web-dev-qa-db-ja.com

Makefileの現在の相対ディレクトリを取得する方法

私はこのようにアプリ固有のディレクトリにいくつかのMakefileを持っています。

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

各Makefileは、このパスに1レベル上の.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だけを知ることができるように、実行の「カレントディレクトリ」を取得するにはどうすればいいですか。 ?

166

シェル関数.

あなたは Shell function:current_dir = $(Shell pwd)を使うことができます。絶対パスが必要ない場合は、 Shell と組み合わせたnotdircurrent_dir = $(notdir $(Shell pwd))

更新。

与えられた解決策は、Makefileの現在のディレクトリからmakeを実行している場合にのみ機能します。
@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))))
223
Nikolai Popov

ここから から取ったように ;

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

お役に立てれば

115
sleepycal

GNU makeを使用している場合、$(CURDIR)は実際には組み込み変数です。それは makefileが存在する場所現在の作業ディレクトリ。おそらくMakefileが置かれている場所ですが、必ずしもそうとは限りません。

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

http://www.gnu.org/software/make/manual/make.html の付録Aクイックリファレンスを参照してください。

36
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
25
momo

私はこれらの答えの多くを試したが、gnu make 3.80を使った私のAIXシステムで、私はいくつかのことを古い学校でやる必要があった。

lastwordabspathrealpathは3.81まで追加されていませんでした。 :(

mkfile_path := $(Word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(Shell cd $(Shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))

他の人が言っているように、シェルを2回呼び出すので最もエレガントではありませんが、それでもスペースの問題があります。

しかし、私は自分のパスにスペースがないので、makeを始めた方法に関係なくそれは私のために働きます。

  • make -f ../wherever/makefile
  • 作る-C ../どこでも
  • -C〜/どこでも
  • cd ../どこでも;作る

current_dirにはwhereverを、mkfile_dirにはwhereverへの絶対パスを教えてください。

5
Jesse Chisholm

私は選ばれた答えが好きです、しかし、私はそれを説明するより実際にそれを働かせることを示すことがより役に立つと思います。

/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/])は末尾のスラッシュを削除するために使用されます。

5
Bruno Bronosky

ここにある解決策: https://sourceforge.net/p/ipt-netflow/bugs-requests-patches/53/

解決策は:$(CURDIR)

次のように使用できます。

CUR_DIR = $(CURDIR)

## Start :
start:
    cd $(CUR_DIR)/path_to_folder
2
Soma Bini

下記のようにあなたの参照のための例:

フォルダ構造は次のようになります。

enter image description here

2つのMakefileがあり、それぞれ以下の通りです。

sample/Makefile
test/Makefile

それでは、Makefileの内容を見てみましょう。

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を実行してください。

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'

説明として、親/ホームディレクトリは環境フラグに格納し、エクスポートすることができるため、すべてのサブディレクトリmakeファイルで使用できます。

0
parasrish

これは、シェル構文を使用して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)
0
kenorb

Make変数に相対パスが含まれている場合はROOT_DIR

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

絶対パスを取得するには、以下のメソッドを使用してください。

ROOT_DIR := $(abspath $(ROOT_DIR))

その仕事はGNUMakeで大丈夫です...

0
Jerry

自分自身を大いに支持し、それぞれのmakeファイルがそれを含んでいるディレクトリから実行されることを期待してください。どのコマンドでも、パスを気にする必要はありません。

0