Command


POINT
[.] Command とは 1 行の ShellScript make は一行ごとに subshellに渡す
既定 shell == /bin/sh ENV:SHELL の影響をうける POINT
[.] SubShell にわたさないで Make 自身が実行する場合もある Shell の特殊文字 ( wildcard , redirect )の有無が判定基準 fork/exec などの重い処理が不要になる



Command 構文解析


POINT
Make が Command と認識する箇所 Target に続く "最初の文字が Tab" から始まる
Command を Target 直後以外の場所から読むと 次のエラーがでる # CommandLine が最初の Target 以前に置かれています # POINT [.] Target の文脈以外で CommandLine が見つかりました が正しい POINT [.] Command 以外の行がみつかると Command 解析モードがとまる 先頭に tab がなくなった時点で 解析 mode 終了
[tab]XXX ... <-> cmdline>XXX...
Script として make に解釈されるもの( 以下のものは SKIP ) POINT [.] Command Mode では以下も Command 扱いになる
[.] 空行 [.] Comment [.] 条件判断命令( ifdef, ifeq ) -> Make の設計として必要だったと思う [.] include
POINT [.] CommandLIne 中の 組み込み関数の置換結果は有効な ShellCommand | VOID
longcommand: @echo line 2 # shell Comment # make Comment ( no tab ) # make Comment @echo line 11 ifdef COMSPEC @echo env is Windows endif # Command としての warning # warning は置換結果は 空 -> 空文字列 が Shell に渡る # # echo より warning による出力が先に表示される # ( Make が Command 内部の展開を先にするから ) # $(warning keikoku) #



長い Command


[.] 各 Command は別々 sub Shell に渡される 複数行を同時に渡すには \ をつかう [\] : 行継続をあらわす POINT [.] 複数行の CommandLine は \ && ; でつなぐ POINT define macro を CommandLine に配置したとき 各行に TAB がおかれる
# 一連の Shell Command を "cmd" マクロにまとめる define cmd cd src;\ ls endef # [tab] がはいった状態になる definetest: $(cmd)
# d に対する参照を escape する ERROR $d : make が置換する OK $$d
# 中間 file は消去 .INTERMEDIATE: filelist ll:=foo bar goo # [\] により 1 行に連結されて Shell にわたるので # [;] を忘れないこと filelist: for d in $(ll); \ do \ echo $$d; \ # shell の [$d] として渡すため [$$d] とする done
# File 数が少ないなら make 関数を利用するのもあり # filelist: echo $(addsuffix /*.java,$(COMPILATION_DIRS)) > $@ # cd などは \ をつけないと意味なし # TAGS: cd src; \ ctags --recusrse # さらに 結果をみる # # TAGS: cd src && \ ctags --recusrse
POINT [.] define の CommandLine での展開も注意が必要 展開された 各行は 別の SubShell に渡る


Command 修飾子


POINT [.] Command は Prefix をおくことで動作を変更できる [.] Prefix は各行単位でする
@ : Command を非表示 - : Command の ERROR を無視 + : -n でも Command を実行
@: cmd silent .SILENT. tgt QUIET:=@ # -s( --silent ) option で全 Command を Log OFF # make -s # QUIET という変数で ON/OFF をできるようにする # Reset するなら CommandLine から Reset する # # shell> make QUIET= test # QUIET := @ test: $(QUIET)echo "test ..." echo "aaa" POINT [.] Make が Command を実行するとき, その Program の StatusCode をチェックする [.] 0 以外を返す( 失敗 )なら, Make はそこで処理を中断
make が 終了 status を無視して処理を継続 # CommandLine から一括で shell> make -i( --ignore-errors ) # Target 指定 .IGNORE : test # Command ごとに test: $(QUIET)echo "test ..." -rm noExistFile echo "aaa" +: -n でも cmd 実行
]