LibreOffice(20)makeについてちょっとお勉強 その1

2014-02-08

旧ブログ

t f B! P L

前の関連記事:LibreOffice(19)Javaの例をmakeする


makeについてちょっと調べてみるとわかりやすい資料を見つけたのでMakefileが何をしているのかみてみます。

エラーメッセージは問題なし


C:\Program Files (x86)\LibreOffice 4\sdk\examples\DevelopersGuide\FirstSteps\Makefile(以下FirstStepsのMakefileといいます)をmakeしてコマンドウィンドウに出力された結果を見てみると最初にエラーメッセージがでてきます。

C:\Program Files (x86)\LibreOffice 4\sdk\examples\DevelopersGuide\FirstStepsのMakefileをmakeしますか?(y/n)y
'..' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。
mkdir c:\LIBREO~1.1_S\WINexample.out\class\FirstStepsExamples
mkdir c:\LIBREO~1.1_S\WINexample.out\class\FirstStepsExamples

ほかにもいろいろエラーがでてきます。

makeについてちょっとお勉強したところこれらのエラーは致命的なものではなく、コンパイルはちゃんとされているという結論に達しました。

makeについてはGNU make 日本語訳(Coop編) - 目次に日本語マニュアルがあります。

機能がたくさんあるのでマニュアルも膨大です。

でも具体的な例がたくさん載っているのでとてもわかりやすいです。

コマンドウィンドウにでてくるメッセージはほとんどがmakeからのコマンドを受け取ったWindowsのコマンドウィンドウが出しているものです。

make自身が出しているメッセージは行頭にmingw32-make: とついています。

これらのメッセージがMakefileのどの部分から出されているのかFirstStepsのMakefileの内容を見ていきます。

そんなに難しい機能は使われていないのでGNU make 日本語訳(Coop編) - Makefile入門を読めばだいたい読めるようになります。

Makefileでタブから始まる行がコマンドウィンドウに渡されるコマンド


makeからWindowsのコマンドウィンドウに出されるコマンドはMakefileで行頭にタブがあるものです。

ターゲット  : 依存関係
        コマンド
        ...

GNU make 日本語訳(Coop編) - ルールの構文

この2行目の先頭は空白ではなくタブにしないといけません。

この組み合わせをルールといいます。

この2行目以降のタブに続くコマンドがコマンドウィンドウで実行されます。

ターゲットにはコマンドを実行の出力結果のファイル名を書きます。

依存関係にはターゲットの材料(ソース)になるファイル名を書きます。

普通はターゲットにコンパイル後のファイル名、依存関係にソースファイル名が来ることになると思います。

Makeはターゲット(出力結果)と依存関係(ソース)の更新日時を比較してターゲット(出力結果)の方が依存関係(ソース)より古いとコマンドを実行してターゲット(出力結果)を更新します。

こうすることによって複数のソースファイルをコンパイルしたいときに、ソースファイルが更新されたものだけをコンパイルすることができます。

うまい仕組みになっていますねぇ。

変数名=データ、で変数に代入。$(変数名)で展開。環境変数もそのまま引き継げる。


FirstStepsのMakefileではまず最初にC:\Program Files (x86)\LibreOffice 4\sdk\settingsにあるsettings.mkとstd.mkを読み込んでいます。

これらではOSに合わせた変数定義をたくさんしています。

タブで始まる行はひとつもありません。¥(\と同じ)で終わる行の次の行は単に前の行の続きです。
新しい行が後に続くバックスラッシュ("\")を挿入することで長い行を分割することができますが、makeはmakefileの行の長さに制限を設けているわけではないので、別に分割は必要というわけではありません。
GNU make 日本語訳(Coop編) - ルールの構文
驚いたのはsetsdkenv_windows.batを使って設定した変数がそのままの変数名で$(変数名)で展開できること。
makeがはじめに起動したときに調べる環境変数はどれも同じ変数名と値を持ったmake用の変数に変形されます。
GNU make 日本語訳(Coop編) - 環境からの変数
setsdkenv_windows.batでPATHに設定しない変数もたくさん設定していた意味がここでわかります。

ターゲットがファイル名でないときは .PHONY: ターゲット と書いておく


settings.mkとstd.mkを読み込んだ後Makefileに戻ってきて#Tagetsから後にようやく最初のルールが出てきます。(以下表示の関係でコマンドの前はタブでなく空白に置換しています。)
# Targets
.PHONY: ALL
ALL : \
 $(EXAMPLE_NAME)
.PHONY: ALLというのは次にでてくるALLというターゲットがファイル名を表すものではないということをmakeに教えるものです。(GNU make 日本語訳(Coop編) - 偽りのターゲット(Phony)

最初のルールで最終目的(ゴール)を指定する


60行目の最後の\は次行とつながっているという意味ですので繋げると以下のようになります。
# Targets
.PHONY: ALL
ALL : $(EXAMPLE_NAME)
ALLを出力結果、$(EXAMPLE_NAME)をソースとすると、ALL : $(EXAMPLE_NAME)は$(EXAMPLE_NAME)を元にALLを作りなさいという意味になります。

ALLを作るためにはその元になる$(EXAMPLE_NAME)を作らないといけないので、それが転じてこれは$(EXAMPLE_NAME)を作りなさいという意味になります。

ALLというターゲットはGNU make 日本語訳(Coop編) - 慣習的なMekifileにあるように単に慣用句なのでALLでなくてもZenbuとしてもちゃんと動作します。
# Targets
.PHONY: Zenbu
Zenbu : $(EXAMPLE_NAME)
$(EXAMPLE_NAME)は展開するとFirstStepsExamplesになります。

このFirstStepsExamplesはどこで作られるのかというと86行目にようやくでてきます。
$(EXAMPLE_NAME) : $(APP1_JAR) $(APP2_JAR) $(APP3_JAR)
86行目をechoで書き出してみたのが以下です。
FirstStepsExamples : c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples/FirstUnoContact.jar c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples/FirstLoadComponent.jar c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples/HelloTextTableShape.jar
結局この3つのjarファイルを作りなさいということになるのです。

とてもまどろっこしいですね。慣習なので慣れるしかないです。
# Targets
.PHONY: ALL
ALL : \
 $(EXAMPLE_NAME)
を全部削って86行目を移動させてきて
$(EXAMPLE_NAME) : $(APP1_JAR) $(APP2_JAR) $(APP3_JAR)
と置き換えても同じ結果になります。

(2015.6.12追記偽りのターゲット(Phony)に「フォニーターゲットは本物のターゲットファイルの依存関係にすべきではありません。そうしてしまうとmakeがファイル更新をする度に実行することになります。」と書いてあるので偽りのターゲットの依存関係にファイル名をもってくるのはよくないようです。)

# Targets
.PHONY: ALL
ALL : \
 $(APP1_JAR)
とするとAPP1_JARのc:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples/FirstUnoContact.jarだけ作成されます。
makefile内の最初のルールにいくつかのターゲットがあるなら、ルール内のリスト全てじゃなく最初のターゲットだけがデフォルトのゴールになります
GNU make 日本語訳(Coop編) - ゴールを指定する引数

最初のルールがそれだけで完結してしまうものであればそこで終わってしまいます。

そこで最終目的(ゴール)を指定するルールはMakefileの中で一番最初にでてくるルールに書かないといけません。

参考にしたサイト


GNU make 日本語訳(Coop編) - 目次
GNU Makeのマニュアルの日本語訳。

GNU make 日本語訳(Coop編) - Makefile入門
ルール、変数、暗黙のルール、偽りのターゲット

GNU make 日本語訳(Coop編) - ルールの構文
ルールの詳解。

GNU make 日本語訳(Coop編) - 環境からの変数
コマンドウィンドウでバッチファイルで設定した変数をそのままMakefileで引き継げます。

GNU make 日本語訳(Coop編) - 偽りのターゲット(Phony)
ファイル名以外のターゲットのときに使う方法

GNU make 日本語訳(Coop編) - 慣習的なMekifile
ALL、clean、installなどは慣用句になっています。

GNU make 日本語訳(Coop編) - ゴールを指定する引数
最初のターゲットだけがデフォルトのゴールになります。

次の関連記事:LibreOffice(21)makeについてちょっとお勉強 その2

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ