GNU makeを使用してC++コードをコンパイルしています。コンパイルをカスタマイズ可能にする方法を理解したいと思います。
CFLAGS
、CCFLAGS
、およびCXXFLAGS
がこの目的に使用されることをさまざまな場所で読みました。それで、それらをどのように使うべきですか?コンパイラーに追加のコマンドライン引数がある場合、それらをCFLAGS
に追加するか、先頭に追加する必要がありますか?一般的な慣行はありますか?
なぜ3つの異なる変数なのでしょうか? CコンパイラはCFLAGS
とCCFLAGS
を取得するはずですが、C++コンパイラはCFLAGS
とCXXFLAGS
を取得する必要があります。
人間のユーザーはこれらの変数を設定することになっていますか?自動ツール(automake
、autoconf
など)はそれらを設定しますか?私が使用することになっているLinuxシステムは、これらの変数のいずれも定義していません-これは典型的なものですか?
現在、私のMakefileは次のようになっていますが、少し汚い気がします。
ifdef code_coverage
GCOV_FLAG := -fprofile-arcs -ftest-coverage
else
GCOV_FLAG :=
endif
WFLAGS := -Wall
INC_FLAGS := -Istuff -Imore_stuff -Ietc
CCFLAGSINT := -O3 $(WFLAGS) $(INC_FLAGS) $(CCFLAGS)
... (somewhere in the makefile, the command-line for compilation looks like this)
$(CC) $(CCFLAGSINT) -c $< -o $@
... (somewhere in the makefile, the command-line for linking looks like this)
$(CC) $(GCOV_FLAG) $(CCFLAGSINT) $(OBJLIST) $(LDFLAGS) -o $@
ここにはバグがないと確信しています。 Makefileは非常にうまく機能します。しかし、慣例に反するものはありますか(CCFLAGSINT
など-代わりにCCFLAGS
を上書きするだけですか?またはCXXFLAGS
?FUD!)
非常に多くの質問でごめんなさい。あなたは明らかにそれらすべてに答えるわけではありませんが、答えがこれらの設定の背後にある一般的なアイデアを理解するのに役立つことを願っています。
お気づきのとおり、これらはMakefile {マクロまたは変数}であり、コンパイラオプションではありません。一連の規則を実装します。 (マクロはそれらの古い名前であり、今でも一部で使用されています。GNU make docはそれらを変数と呼びます。)
名前が重要な唯一の理由は、デフォルトのmakeルールであり、make -p
、それらのいくつかを使用します。
独自のルールをすべて作成すると、独自のマクロ名をすべて選択できるようになります。
Vanilla gnu makeには、CCFLAGSのようなものはありません。 CFLAGS
、CPPFLAGS
、およびCXXFLAGS
があります。 Cコンパイラの場合はCFLAGS
、C++の場合はCXXFLAGS
、両方の場合はCPPFLAGS
。
両方にCPPFLAGS
があるのはなぜですか?従来は、プリプロセッサフラグ(-D
、-U
)およびcとc ++の両方がそれらを使用します。さて、全員がcとc ++の同じ定義環境を望んでいるという仮定は疑わしいかもしれませんが、伝統的です。
追伸 James Moore で述べたように、一部のプロジェクトでは、Cプリプロセッサへのフラグではなく、C++コンパイラへのフラグにCPPFLAGSを使用しています。 Android NDK、1つの大きな例です。
による GNU make
マニュアル:
CFLAGS:Cコンパイラに与える追加のフラグ。
CXXFLAGS:C++コンパイラーに与える追加のフラグ。
CPPFLAGS:Cプリプロセッサーおよびそれを使用するプログラム(CおよびFortranコンパイラー)に与える追加フラグ。
src: https://www.gnu.org/software/make/manual/make.html#index-CFLAGS
注:PPはPreProcessor(プラスプラスではない)を表します。
CPP:Cプリプロセッサを実行するためのプログラム。結果は標準出力に出力されます。デフォルトは「$(CC)-E」です。
これらの変数は、make
の暗黙のルールによって使用されます
Cプログラムのコンパイル
n.oは、n.cから次の形式のレシピで自動的に作成されます。
「$(CC)$(CPPFLAGS)$(CFLAGS)-c」。C++プログラムのコンパイル
n.oは、n.cc、n.cpp、またはn.Cから次の形式のレシピで自動的に作成されます。
「$(CXX)$(CPPFLAGS)$(CXXFLAGS)-c」。
C++ソースファイルには、「。C」の代わりに接尾辞「.cc」を使用することをお勧めします。
src: https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
そして、最小限の例として Mizuxが言った を作るだけです:
main_c.c
#include <stdio.h>
int main(void) {
puts("hello");
}
main_cpp.cpp
#include <iostream>
int main(void) {
std::cout << "hello" << std::endl;
}
次に、Makefile
なしで:
make CFLAGS='-g -O3' CXXFLAGS='-ggdb3 -O0' CPPFLAGS='-DX=1 -DY=2' main_c main_cpp
実行:
cc -g -O3 -DX=1 -DY=2 main_c.c -o main_c
g++ -ggdb3 -O0 -DX=1 -DY=2 main_cpp.cpp -o main_cpp
そのため、次のことを理解しています。
make
には、main_c
およびmain_cpp
からmain_c.c
およびmain_cpp.cpp
を作成する暗黙のルールがありました.c
コンパイルの暗黙的なルールの一部として使用されました.cpp
コンパイルの暗黙ルールの一部として使用されましたこれらの変数は、makeの暗黙のルールでのみ自動的に使用されます。コンパイルが独自の明示的なルールを使用した場合、次のようにこれらの変数を明示的に使用する必要があります。
main_c: main_c.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $<
main_cpp: main_c.c
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
暗黙のルールに同様の影響を与えるため。
必要に応じてこれらの変数に名前を付けることもできます。ただし、Makeはすでに暗黙のルールでそれらを魔法のように扱っているため、適切な名前を選択します。
Ubuntu 16.04でテスト済み、GNU Make 4.1。