とあるエンジニアの備忘log
2012年2月12日日曜日
Linux Kernel の Makefile を解析する その1
Linux Kernel の Makefile がどういう仕組みになっているのか前から知りたいと思っていました。 O'REILLY の 「GNU Make」 という本の11章に Linux Kernel の makefile について少し解説があります。 もちろん makefile の仕組み全体は説明してないのですが、いくつかの興味深いトピックについて解説されていて、一読の価値があります。 まずはトップの Makefileの大枠から見てみます。 これは O'REILLY 本で解説されています。 トップのMakefileの100行目付近は以下のようになっています。(途中、あんまり関係ない部分は省略しています。) ifeq ($(KBUILD_SRC),) # OK, Make called in directory where kernel src resides # Do we want to locate output files in a separate directory? ifeq ("$(origin O)", "command line") KBUILD_OUTPUT := $(O) endif
# That's our default target when none is given on the command line PHONY := _all _all:
ifneq ($(KBUILD_OUTPUT),)
PHONY += $(MAKECMDGOALS) sub-make $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make @: sub-make: FORCE $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \ KBUILD_SRC=$(CURDIR) \ KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \ $(filter-out _all sub-make,$(MAKECMDGOALS)) # Leave processing to above invocation of make skip-makefile := 1 endif # ifneq ($(KBUILD_OUTPUT),) endif # ifeq ($(KBUILD_SRC),) # We process the rest of the Makefile if this is the final invocation of make ifeq ($(skip-makefile),) ぱっと見面食らうコードなので説明します。この部分は、 `KBUILD_OUTPUT` (`O`変数)を処理しています。 $ make O=
のようにすると、オブジェクトファイルなどの生成ファイルを `
` ディレクトリに出力するので、ソースツリーを汚さなくて済みます。 (make で指定できる変数については `Documentation/kbuild/kbuild.txt` に説明があります。) ifeq ("$(origin O)", "command line") KBUILD_OUTPUT := $(O) endif というコードにもあるように、出力ディレクトリは、環境変数 `KBUILD_OUTPUT` で与えることも コマンドラインで `O=` で与えることもできますが、 `O=` のほうが優先されます。 例えば、Linux のソースのトップで $ make O=/home/hoge/out piyo fuga と打ち込んだとします。 `KBUILD_SRC` は空で、 `KBUILD_OUTPUT` は空ではないので、上記コードを通ります。 make は `piyo` と `fuga` を構築するルールを見つけようとします。 $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make @: にルールが見つかります。(`MAKECMDGOALS` に `piyo` と `fuga` が入っているので) `piyo` と `fuga` は `sub-make` に依存することがわかります。 `@:` の部分は何もしません。 `sub-make`の構築ルールは以下です。 sub-make: FORCE $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \ KBUILD_SRC=$(CURDIR) \ KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \ $(filter-out _all sub-make,$(MAKECMDGOALS)) これは、 `-C $(KBUILD_OUTPUT)` でわかるように、出力ディレクトリへ移動して、再帰的に `make piyo fuga` を実行しています。 なお、 `skip-makefile` に `1` がセットされているので、 `ifeq ($(skip-makefile),)` 以下は見えていません。 トップの Makefile は1500行ほどありますが、残りの大半は `ifeq ($(skip-makefile),)` の中にいます。 再帰的に呼び出された make は `/home/hoge/out` で実行されます。 今度は `KBUILD_SRC=(Linuxソースのトップ)` がセットされていますので、上記箇所は通りません。 `skip-makefile` には何もセットされていないので、 `ifeq ($(skip-makefile),)` で囲まれているMakefileの本体部分が今回は見えます。 要するに、 - オブジェクトは make を実行したディレクトリ以下に作られる。 - 必ずしも、Linuxのソースコードのトップで make を実行する必要はない。(その場合、Linuxのソース位置がわかりませんので、 `KBUILD_SRC` 変数と `-f` の指定が必要です) という設計思想になっているんですね。 今回、トップのMakefileの一番外のネスト `ifeq ($(skip-makefile),)` 〜 について見てみました。 続きは[次回](/2012/02/linuxmakefile-2.html)。
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿