make さんが "process_begin: CreateProcess((null), , ...)" とか言って爆死する件 - それと解
こんな単純な makefile があって、コマンドプロンプト(==窓)で make したとします。
default : hina.txt hina.txt : kana.txt move $< $@ kana.txt : echo kana > $@
c:\path\to\work>make echo kana > kana.txt move kana.txt hina.txt process_begin: CreateProcess((null), move kana.txt hina.txt, ...) failed. make (e=2): 指定されたファイルが見つかりません。 make: *** [hina.txt] Error 2
move でコケるとかどういうこちゃねん!
解決方法
失敗するコマンドに対して、makeの実行に影響を及ぼさない範囲でリダイレクト or 他のコマンドへのパイプ を混ぜましょう。何を混ぜ込むかはシーンによって異なるかと思いますが、例えば…
# コマンド結果を「じげんのはざま」へ そぉい! hina.txt : kana.txt move $< $@ > nul # 無駄に修飾してみる。無駄無駄無駄ァ!! hina.txt : kana.txt move $< $@ 9>&1 # 他のコマンドへパイプ。禁煙にはパイポ hina.txt : kana.txt move $< $@ | more # [追記]ぐぐったら cmd に投げるのも良しだった hina.txt : kana.txt cmd /c move $< $@
c:\path\to\work>make echo kana > kana.txt move kana.txt hina.txt 9>&1 1 個のファイルを移動しました。 c:\path\to\work>dir *.txt ドライブ C のボリューム ラベルは Windows です ボリューム シリアル番号は DEAD-BEEF です c:\path\to\work のディレクトリ 0548/02/14 14:08 7 hina.txt 1 個のファイル 7 バイト 0 個のディレクトリ 254,571,880,448 バイトの空き領域
うむ!
現象
少なからず、私が利用ている Gow に収録されている GNU make (v3.80 or v3.81) でこの現象が発生しています。
make -d すると解るのですが、特に修飾しなくとも正常に終了するコマンドは、CreateProcess() の第1・2引数共に適切なパラメータが渡されています。 この適切なパラメータは次の2種類の傾向が見受けられます。
- 該当コマンドのフルパス
- テンポラリに生成されたバッチファイルへのフルパス。 このバッチファイルは、ルールに記述されているコマンド1行がそのまま記述されていると思われ、それを実行することによりルールの1行を実行しているものと推測される。
失敗するコマンドについては、第1引数に null が指定され(ついでに、第2引数にコマンド1行がそのまま渡され) CreateProcess() に失敗しています。 今回の "move" は内部コマンドなので、そりゃ cmd かまさないと実行できないですよねぇ…と。
じゃぁ、どう回避するかと悩んだのですが、成功するコマンド・失敗するコマンドを比較した際に「成功する方はリダイレクト付いてるね…」と気づき、適当にリダイレクトかましたら実行できるように…! リダイレクトされていると強制的に「テンポラリのバッチを実行する形式」になり、結果 move が見つかるのでコマンドが成功する形になります。 …まぁそういう事してる場合は、素直に cmd に任せた方が実装が楽だったんだろうなぁ……(ぉ
ちなみに「失敗するコマンド」とか抽象的に書いてますが、おいらは今のところ "move" しか発見できてません! :-]
…ってか、何で move は失敗するのん…… copy とか echo とかの内部コマンドは成功してるのに………
ソース嫁。
トン!
つまる所
窓使いだったら nmake でも使ってろよって話ですねハイ