web-dev-qa-db-ja.com

共通GNU makefileディレクトリパス

共通のメイクファイルを使用して、いくつかのビルド情報を統合しようとしています。私の問題は、異なるサブディレクトリレベルからそのmakefileを使用することです。これにより、作業ディレクトリの値(pwd)が予測不能になります。例えば:

_# Makefile.common
TOP := $(Shell pwd)
COMPONENT_DIR := $(TOP)/component
COMPONENT_INC := $(COMPONENT_DIR)/include
COMPONENT_LIB := $(COMPONENT_DIR)/libcomponent.a
_

そのように、サブディレクトリから_Makefile.common_を含めると、$(TOP)ディレクトリが正しくなくなり、他のすべてがそれに続きます。

_# other_component/Makefile
include ../Makefile.common
# $(COMPONENT_LIB) is incorrectly other_component/component
_

_Makefile.common_を取得して、より気まぐれなpwdの代わりに独自のディレクトリパスを使用する最良の方法は何ですか?

48
cdleary

次のように、 MAKEFILE_LIST変数 を使用できるはずです。

# This must be the first line in Makefile.common
TOP := $(dir $(lastword $(MAKEFILE_LIST)))

ドキュメントから:

Makeは、MAKEFILES変数、コマンドライン、デフォルトファイル、またはincludeディレクティブから取得したものを含むさまざまなメイクファイルを読み取るときに、それらの名前がMAKEFILE_LIST変数に自動的に追加されます。 makeは、makeが解析を開始する直前に追加されます。つまり、メイクファイルが最初に行うことは、この変数の最後のワードを調べることである場合、現在のメイクファイルの名前になります。ただし、現在のメイクファイルがインクルードを使用すると、最後のWordがインクルードされたばかりのメイクファイルになります。

68
JesperE

別の依存関係(つまり、realpathバイナリ)が追加されるため、これは良いスタイルではありません。ユースケースに応じて、それが許容される場合があります。

ROOT_DIR := $(Shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

Realpathがインストールされていない場合:

$ Sudo apt-get install realpath # on debian and derivatives

編集:=の代わりに=を使用してください。後者はmakeに遅延バインディングを使用させ、MAKEFILE_LISTは後で含まれます。

9
Bill

やってみましたか:

# Makefile.common
TOP ?= $(Shell pwd)
COMPONENT_DIR := $(TOP)/component
COMPONENT_INC := $(COMPONENT_DIR)/include
COMPONENT_LIB := $(COMPONENT_DIR)/libcomponent.a

# other_component/Makefile
TOP ?= ..
include ../Makefile.common

?=構文を使用すると、TOPが既に設定されている場合、TOPが再定義されなくなります。 makeを呼び出すときにツリー内のどこにいるかに基づいて、適切な値に設定できます。 GNU makeを使用してからしばらく時間が経過したため、これが機能しないか、微調整が必​​要になる可能性があります。

2
tvanfosson

common.mkに一般的なものを書くだけです。次に、common.mkを入れます。これは、makeがinclude common.mkステートメントを検出したときに検索するデフォルトのフォルダーです。

一般的なフォルダーのヘルプを参照してください。 common.mkをホームフォルダーに入れて、任意のフォルダーからmake -I$HOMEと入力することもできます。

各サブフォルダーのMakefile内で、単純に

include common.mk

それだけです。パスと移動を心配する必要はありません。

1
Robert H