次のコマンドライン(メイクファイル内)を使用して、コンパイラからの詳細なエラーメッセージをPerlスクリプトを介してパイプし、人間が読める形式に簡略化します。
g++ -c source.cpp -o source.o 2>&1 | Perl /bin/gSTLFilt.pl
残念ながら、このアプローチは、g++
コマンドによって返されるエラー値を「マスク」します。 makeは、g++
コマンドが失敗したことを認識していません。これは、Perl
コマンドからのエラー結果だけが返されるためです。
出力をパイプし、元のエラー状態を保持する方法はありますか?
違いがある場合:GNU bash、バージョン2.04を実行しているMSYSコンソールでGNU Make 3.81およびg ++(GCC)3.4.5(mingw-Vista special r3)を使用しています。 Windows XPの.0(1)-release(i686-pc-msys)。
Shell sh.exe
が何を提供するかはわかりませんが(Windows実行可能ファイルにその名前を使用するシェルが複数あるため)、bash
などの場合は、$PIPESTATUS
を使用できます。アレイ。あなたの例では、あなたはそうするでしょう:
g++ -c source.cpp -o source.o 2>&1 | Perl /bin/gSTLFilt.pl
echo "${PIPESTATUS[0]}"
Bashにはオプションpipefail
があります:
The return status of a pipeline is the exit status of the last command,
unless the pipefail option is enabled. If pipefail is enabled, the
pipeline's return status is the value of the last (rightmost) command
to exit with a non-zero status, or zero if all commands exit success-
fully.
そう:
set -o pipefail && $GCC_COMMAND | $Perl_COMMAND
Makeは各行のサブシェル内のすべての行を実行します なので、gcc行の先頭に追加する必要があります。 makeにpipefail
が設定されたその1つのコマンドだけを実行させる方法はあるかもしれませんが、私にはわかりません。
追加Shell=/bin/bash
Makefile内( Makeはこれを使用する必要があります )
または試してください:
bash -o pipefail -c "$GCC_COMMAND | $Perl_COMMAND"
従来のシェルでは、パイプラインの最初のコマンドのステータスはスクリプトにまったく報告されません。 $?
では、最後のコマンドのステータスのみが使用可能です。
Bash≥3.0では、 パイプラインのどこかでエラーが発生した場合に停止する場合は、pipefail
オプションを使用します 。
g++ -c source.cpp -o source.o 2>&1 | Perl /bin/gSTLFilt.pl
より一般的には、bashでは、PIPESTATUS
配列は$?
を一般化して、最後のパイプラインのすべてのコマンドをカバーします。
$ (exit 1) | (exit 2) | (exit 3); echo ${PIPESTATUS[@]}
1 2 3
Zshにも同じ機能があり、配列のみがpipestatus
と呼ばれます。
% zsh -c '(exit 1) | (exit 2) | (exit 3); echo $pipestatus'
1 2 3
Bash(IIRCはmsysによってsh
として提供されるシェル)を想定する場合は、PIPESTATUS
を使用できます。そうでない場合は、パイプを介して終了ステータスをトップレベルシェルに渡すように調整し、通常の入力として使用する代わりに、入力の最後の行で読み取ったステータスでフィルタープログラムを終了させることができます。不器用ですが、便利な場合があります。
Makefileでは、一時ファイルを使用するのが比較的一般的です。ここでは、コンパイラメッセージをもう1つの中間ファイルとして扱います。
%.otmp %.g++-log: %.cpp
g++ -c $< -o $@tmp 2>&1 >$*.g++-log
%.o: %.otmp %.g++-log
Perl /bin/gSTLFilt.pl <$*.g++-log
mv $*.otmp $@