正常に機能するMakefileを作成しました。私は調査中のその部分を投稿しています:
BUILD_PRINT = @echo -e "\e[1;34mBuilding $<\e[0m"
COMPILE_cpp = $(CXX) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
%.o : %.cpp
$(BUILD_PRINT)
$(COMPILE_cpp)
.SUFFIXES: .o .cpp
外部ツール(colorgccやCMakeなど)を使用せずにコンパイラーによって与えられた警告とエラーを強調したいと思います。私はそれをハッキングするための良い方法は「bashスクリプトトリック」を経由することだと思った。 make出力で警告行とエラー行を強調表示するにはどうすればよいですか? 私は以下を試しました:
pathpat="(/[^/]*)+:[0-9]+"
ccred=$(echo -e "\033[0;31m")
ccyellow=$(echo -e "\033[0;33m")
ccend=$(echo -e "\033[0m")
BUILD_PRINT = @echo -e "\e[1;34mBuilding $<\e[0m"
COMPILE_cpp = $(CXX) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
%.o : %.cpp
$(BUILD_PRINT)
$(COMPILE_cpp) 2>&1 | sed -e "/[Ee]rror[: ]/ s%$pathpat%$ccred&$ccend%g" -e "/[Ww]arning[: ]/ s%$pathpat%$ccyellow&$ccend%g" echo "${PIPESTATUS[0]}"
.SUFFIXES: .o .cpp
しかし、それは機能していません。次の出力が表示されます
Building main.cpp
g++ -o main.o -c main.cpp 2>&1 | sed -e "/[Ee]rror[: ]/ s%athpat%cred&cend%g" -e "/[Ww]arning[: ]/ s%athpat%cyellow&cend%g" echo ""
sed: can't read echo: No such file or directory
sed: can't read : No such file or directory
前もって感謝します!
うまくいきました。
まず、@ EtanReisnerと@riciに感謝します。これがコードです:
_BUILD_PRINT = \e[1;34mBuilding $<\e[0m
COMPILE_cpp = $(CXX) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
COMPILE_cpp_OUT=$$($(COMPILE_cpp) 2>&1 | sed -e 's/error/\\\e[1;31merror\\\e[0m/g' -e s/warning/\\\e[1;33mwarning\\\e[0m/g')
%.o : %.cpp
@echo -e "$(BUILD_PRINT)\n$(COMPILE_cpp)\n$(COMPILE_cpp_OUT)"
.SUFFIXES: .o .cpp
_
_make -j
_を使用して並列ビルドを起動すると、ビルドされた各ファイルに対してすべての出力(コマンド文字列と警告/エラー)が一貫してグループ化されるため、すべてのコマンドは1つのecho
によって呼び出されます。
$(BUILD_PRINT)
は、現在ビルドされているファイルのパスを出力するだけです。
$(COMPILE_cpp)
は、コンパイラの文字列を出力するので、すべてのフラグ/依存関係/その他を含むコマンドを表示できます...
$(COMPILE_cpp_OUT)
は、コンパイラの出力を保存し、sed
コマンドを使用して関連するWordの色を変更します。
Makeコンテキストでは、次の行はシェルでのように動作しません。
_ccred=$(echo -e "\033[0;31m")
ccyellow=$(echo -e "\033[0;33m")
ccend=$(echo -e "\033[0m")
_
シェルでは、それらはエコーされた出力をそれらの変数に入れます。 makeは、存在しないecho
コマンドを実行しようとし、最終的に空の変数を作成します。
これらの行は
ccred=$(Shell echo -e "\033[0;31m")
は、シェルを介してコマンドを実行し、出力を格納して、本文で$(ccred)
として使用しますccred=\033[0;31m
_は、文字列を変数に格納し、本体で$$(echo -e '$(ccred)')
として使用しますccred=echo -e "\033[0;31m"
_コマンドを変数に格納し、本体で$$($(ccred)
として使用します最初のオプションと2番目のオプションのどちらでも問題ない可能性があります。 (使用する := の代わりに = 最初のオプションでは、ccred
が使用されるたびではなく、makeの解析時に、makeがechoコマンドを1回だけ実行するようにします。)
makeとShell変数は接頭辞sigilを共有します $。したがって、makeコンテキストでシェル変数を使用するには、エスケープする必要があります。 $ シェルのコンテキストでは $$。したがって、_s%$pathpat%$ccred&$ccend%g
_は_s%$$pathpat%$$ccred&$$ccend%g
_などである必要があります。
Makeルール本体の各行は、個別のシェルコマンドとして実行されます。そのため、コマンドは相互に対話できません。したがって、_echo "${PIPESTATUS[0]}"
_のような構造を意味のある形で使用するには、make内の同じコマンドラインにある必要があります。そのため、そのパターンルールのコンパイル行は$(COMPILE_cpp) 2>&1 | sed ...; echo "${PIPESTATUS[0]}"
である必要があります。
ただし、コンパイルで終了ステータスをエコーする必要がないので、それでも期待どおりの結果は得られないため、代わりに_; exit "${PIPESTATUS[0]}"
_を使用することをお勧めします。