makeアレコレ。via OpenJDK

ひとまずMakefileを読みます。makeをよく知らないので勉強しつつ

やりたいこと
クラスロードでVM.classやLauncher.classが使われるのは分かったけれど、コードを読むためにアタッチするjarに確信が持てないので、これらをビルドしているスクリプトを特定する。

makeファイルの作法として、再帰読み込みでmakeを実行するよりも、個別のmakeファイルを明示的にincludeすることが望ましい…らしい。OpenJDKのMakefileはまさにそのように書かれているので、数は多いけれど、たぶんきっと読みやすいハズ。(ホント?)

make文法の基本

  • 実行オプションが適用される優先順
  • ルールの書き方
    • 1行目: (ターゲット)コロン(依存ファイル)
    • 2行目〜: タブ文字(ルール)
  • 変数の定義には2種類ある
    • 再帰展開変数:「=」を使う。いわゆるdefineと同じ
    • 単純展開変数:「=:」を使う。shell関数を使うのにベンリ
  • 「@」で無効にしたechoは、-nオプションを付けたときだけ表示される

このあたりを参考にしています。

ところで、Makefileを読んでいると、二重コロンが頻繁に出てくるのだけれど

# What "all" means
all::
	@$(START_ECHO)

all:: sanity

ifeq ($(SKIP_FASTDEBUG_BUILD), false)
  all:: fastdebug_build
endif

ifeq ($(SKIP_DEBUG_BUILD), false)
  all:: debug_build
endif

all:: all_product_build 

all:: 
	@$(FINISH_ECHO)

これは、二重コロンルールの「個々に独立して」「上から順に」実行される性質を利用して、デフォルトターゲット(all)の振る舞いを定義してる、という理解でいいのかな。?

以下はOpenJDKのビルドファイルに関する覚書なので、"続きを読む"にしときます。


(★は大事そうなトコロ)

OpenJDKビルドディレクトリのルートにあるMakefile

ここでは、{opnejdk-build-dir}/make/common/shared/以下のMakefileをincludeしている。1つずつ確認する。

Defs-control.gmk

  • コンポーネントのトップディレクトリを定義する
  • Platform.gmkをincludeする
  • ビルド成果物のデフォルトの出力先を定義する
  • Defs.gmkをincludeする
  • make sanityを実行したときのログの出力場所を定義する :★
  • ビルド番号の調節
    • JDKのバージョン番号に数字以外が含まれていると、Windowsで上手く扱えないとかどーとか

Platform.gmk

  • JDKを含む)依存パッケージの必要バージョンを定義する
  • プラットフォームの情報を変数に設定する
  • ディスクの必要な空容量を定義する
  • 一時ディレクトリの場所を定義する
  • JVMのMax/Minメモリの値を設定する :★
    • ここでメモリが512MBytesに満たないと、make sanityのときスロービルドの警告が出る

SolarisLinuxWindowsのそれぞれについて、マシンからプラットフォーム情報を取得して変数に入れている。Windowsは記述が長い。Cygwinを使うか否かで分岐してるぽいし、ややこしいカンジ。

Defs.gmk

  • Defs-utils.gmkをincludeする
  • 依存パッケージのバージョンが(古すぎる|新しすぎる)のをチェックする
  • ビルド時に定義した環境変数が有効かチェックする
  • 出力先に定義したディレクトリが本当にあるかどうかチェックする
  • ビルドの種類(debugとかfastdebugとか)に応じたビルド名をつける
  • PrivateDefs.gmkがもしあればincludeする
  • プラットフォーム固有のDefs-hoge.gmkをincludeする
  • 認証局証明書(lib/security/cacerts)の有無をチェックする
    • ブート用JDKがOpenJDKかそうでないかで、挙動が異なる :★
  • ビルド成果物の出力先ディレクトリが書込み可能かチェックする

また、パラレルコンパイルというオプションがある。CPU数の2倍の値に設定する。

Defs-utils.gmk

  • 各プラットフォームのファイルシステムにおけるシェルの場所を定義する
  • 環境変数ANT_HOMEが有効かテストする
  • 他のMakefileからshell関数で呼び出すコマンド名の関数を定義する
    • プラットフォーム固有のフルパス+コマンド名という形式

Defs-solaris.gmk、Defs-windows.gmk

今回使わないので流し読み。

コンパイルアプローチのデフォルト(最適値)が、Solarisはparallelで、Windowsがnormalなのは、へぇという感じ。

Defs-windows.gmkは、Cygwinのための設定や、ディレクトリパスの対応で膨れ上がって、Defs-solarisの2倍くらい(500行以上)ある。

Defs-linux.gmk

(続く)