前の関連記事:LibreOffice(20)makeについてちょっとお勉強 その1
最初のルールでターゲットをALLにすると、Makefileのすべてのターゲットが生成されると勘違いしていました、、、そうなんです、ALLは単に慣用句であってコマンドではないので先頭のルール以降は依存関係に基づいて必要なターゲットがあるルールが実行されるのでした。
先頭のルール以外のルールの書く順番は関係ない
ルールの順番に意味はありません。
GNU make 日本語訳(Coop編) - ルールの記述
先頭のルール以降は依存関係で要求されたものがターゲットになるルールが実行されていくのでルールが書かれている順番は関係ないということですね。
先頭のルールの依存関係がターゲットになっているルールを探し、そのルールの依存関係がターゲットになっているルールを探し、、、というふうにたどり、出発点になっているルールまで遡ります。
コマンドの実行はそのルールから始まります。
この順番がよく理解できていませんでした。
ALL:とあるときはすべてのルールが実行されるものと勘違いしていました。
前記事でそうではないと自分で書いているのですけどやってみないとわからないものですね。
パスの区切りはスラッシュ("/")?バックスラッシュ("\")?
Windowsを使っている私特有の悩みです。
バックスラッシュはブログを書く上でも¥が\になってしまっていつも悩みの種です。
ターゲットと依存関係ではスラッシュ、コマンドではバックスラッシュ、かと思ったのですがそうでもないようです。
ターゲットと依存関係ではスラッシュでなければならないようですが、コマンドはコマンドによってスラッシュとバックスラッシュが混在しています。
GNU make 日本語訳(Coop編) - ファイル名にワイルドカードを利用するにちょっとパスの区切りに言及した記述を見つけましたが、どこでどちらを使え、とはっきりした記述は見つけられませんでした。
FirstStepsのMakefileではsettings.mkでPS:=$(strip \ )と代入しておいて、$(subst /,$(PS),(/の入ったパス))で置換している部分がたくさんでてきます。
ターゲットと依存関係になる部分は逆に\を/に置換しています。
mkdir、del、cd、rdのコマンドの引数では/を\に置換しています。
javacやjaの引数のところは置換しておらずコマンドをみると/区切りのパスと\区切りのパスが混在しています。
(これは次に書いたようにWindows7 64bitでは/も\も両方使えるから問題ないだけかもしれません。)
PS:=$(strip \ )の":="は単純展開変数(Simply expanded variables)です。
DICOM(8)GDCM:バッチファイルの環境変数の即時展開と遅延展開ででてきたバッチファイルの即時展開と一緒ですね。
GNU make 日本語訳(Coop編) - 変数の二つの味に解説があります。
普通の"="を使うものは再帰展開変数(recursively expanded variable)といいます。
テキスト変形関数も2つでてきました。
$(strip string)
stringの前後の空白部分を削除し、文字列の内部にある一つ以上の空白文字(whitespace characters)を一文字のスペース(a single space)に置換してくれます。
$(subst from,to,text)
textという文章の本文の置換動作をしてくれます。つまり文章中にある全部のfromをtoに置換します。
GNU make 日本語訳(Coop編) -文字列を代入・分析する関数
Windows7 64bitではパスの区切りはスラッシュ("/")でもバックスラッシュ("\")でもよい
Windows7 64bitではバックスラッシュ("\")とスラッシュ("/")の両方使えることがわかりました。
今まで全然知りませんでした。
FirstStepsのMakefileのログをみていると"C:\Java\JDK17~1.0_1/bin/jar"というコマンドがコマンドウィンドウに渡されています。
1つのフルパスの中にバックスラッシュ("\")とスラッシュ("/")が混在しています。
Windows7 64bitのコマンドウィンドウでC:\Java\JDK17~1.0_1/bin/jarと打ち込むとちゃんとコマンドが実行されます。
C:/Java/JDK17~1.0_1/bin/jarでもできます。
cd c:/といったWindowsのコマンドの引数にも使えます。
ということでWindows7 64bitではバックスラッシュ("\")とスラッシュ("/")は同じように使えます。
FirstStepsのMakefileの$(subst /,$(PS),(/の入ったパス))の置換はWindows7 64bitでは不要な操作ですね。
折角置換しているのに"C:\Java\JDK17~1.0_1/bin/jar"という\と/が混在したパスが出てきてしまうのはバグでしょうか?
Windows7 64bitでは\も/も同じなので問題になりませんけど。
WindowsXPのコマンドウィンドウではcd c:/は動きませんでした。
cd c:\しか動きません。
ということはWindowsXPでFirstStepsのMakefileをMakeしようとすると
"C:\Java\JDK17~1.0_1/bin/jar"は
"C:\Java\JDK17~1.0_1\bin\jar"となるように修正しないといけないかもしれませんね。
jarの引数のパスにも/がでてきますけどこれも動かないかもしれませんね。
ターゲットに%が入っているルールは型ルール
型ルールはターゲット(のうち、正確には一つ)が"%"という文字を含んでいるという事以外は普通のルールと同じです。なんとシンプルでわかりやすい説明。
GNU make 日本語訳(Coop編) - 型ルールの定義と再定義
作り方も簡単で普通のルールのターゲットの抽象化したい部分を%とするだけです。
$(OUT_APP_CLASS)/%.class : %.java -$(MKDIR) $(subst /,$(PS),$(@D)) $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $<
FirstStepsのMakefileの最初にでてくる型ルールです。
変数を展開すると以下のようになります。
c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamplesにある拡張子classのファイルが要求されるとカレントディレクトリの拡張子javaの同名ファイルを使ってコマンドが実行されることになります。
66行目のmkdirの前にある"-"はmkdirでエラーがでてもそれを無視して次のコマンドを続けさせる記号です。
"$(@D)"と"$<"は自動変数というものです。
型ルールではターゲットや依存関係が抽象化されているので引用しにくいです。
そこで自動変数で引用します。
(2015.3.11追記。語幹%についての解説を追記しました。)
ターゲットにディレクトリ名が含まれるときの%にはディレクトリ名がファイル名に一致する部分の前に付加されたものになるので、$(basename $(notdir $*))でファイル名の部分だけ抜き出さないといけません。
これでFirstStepsのMakefileは全部読めるようになったと思います。
変数を展開すると以下のようになります。
c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples/%.class : %.java -mkdir $(subst /,\,$(@D)) "C:\Java\JDK17~1.0_1/bin/javac" -classpath "C:\PROGRA~2\LIBREO~1\URE\java\juh.jar;C:\PROGRA~2\LIBREO~1\URE\java\jurt.jar;C:\PROGRA~2\LIBREO~1\URE\java\ridl.jar;C:\PROGRA~2\LIBREO~1\URE\java\unoloader.jar;C:\PROGRA~2\LIBREO~1\program\classes\unoil.jar;c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples" -d c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamples $<
c:/LIBREO~1.1_S/WINexample.out/class/FirstStepsExamplesにある拡張子classのファイルが要求されるとカレントディレクトリの拡張子javaの同名ファイルを使ってコマンドが実行されることになります。
66行目のmkdirの前にある"-"はmkdirでエラーがでてもそれを無視して次のコマンドを続けさせる記号です。
コマンド行の本文の初め(先頭のタブの直後)に'-'と書けばそのコマンド行でのエラーを無視させることができます。'-'はシェルにコマンドを渡して実行させる前に削除されます。
GNU make 日本語訳(Coop編) - コマンド内エラー
"$(@D)"と"$<"は自動変数というものです。
型ルールではターゲットや依存関係が抽象化されているので引用しにくいです。
そこで自動変数で引用します。
$@"$*"はつまり"%"と一致します。
ルールのターゲットのファイル名。
$(@D)
ターゲットファイル名のディレクトリ部分の末尾のスラッシュを除去したもの。"$@"にスラッシュが含まれないとこの変数の値は"."になってしまいます。
$(@F)
ターゲットファイル名のディレクトリのないファイル部分。
$<
最初の依存関係の名前。
$*
暗黙のルールで一致した語幹。
GNU make 日本語訳(Coop編) - 自動変数
(2015.3.11追記。語幹%についての解説を追記しました。)
ターゲットにディレクトリ名が含まれるときの%にはディレクトリ名がファイル名に一致する部分の前に付加されたものになるので、$(basename $(notdir $*))でファイル名の部分だけ抜き出さないといけません。
'e%t'は'src/eat'というファイル名に'src/a'という語幹で一致します。
GNU make 日本語訳(Coop編) - 暗黙ルールの利用
これでFirstStepsのMakefileは全部読めるようになったと思います。
参考にしたサイト
GNU make 日本語訳(Coop編) - 目次
GNU Makeのマニュアルの日本語訳。
GNU make 日本語訳(Coop編) - ファイル名にワイルドカードを利用する
Windowsでは部位によりスラッシュ("/")とバックスラッシュ("\")を使い分けないといけません。
GNU make 日本語訳(Coop編) - 変数の二つの味
単純展開変数(:=)と再帰展開変数(=)。バッチファイルの即時展開と遅延展開のようなもの。
GNU make 日本語訳(Coop編) - 文字列を代入・分析する関数
$(strip string)、$(subst from,to,text)がでてきました。
GNU make 日本語訳(Coop編) - 型ルールの定義と再定義
ルールの抽象化。
GNU make 日本語訳(Coop編) - コマンド内エラー
コマンドの先頭に"-"をつければエラーを無視して次のコマンドへ進めます。
GNU make 日本語訳(Coop編) - 自動変数
型ルールではターゲットや依存関係が抽象化されているので自動変数で引用します。
GNU make 日本語訳(Coop編) - ルールの記述
先頭のルールだけ書く順番が関係します。
0 件のコメント:
コメントを投稿