web-dev-qa-db-ja.com

CFLAGS vs CPPFLAGS

CFLAGS(またはC++の場合はCXXFLAGS)はコンパイラ用であり、CPPFLAGSはプリプロセッサで使用されることを理解しています。

しかし、私はまだ違いを理解していません。

#includeでインクルードされるヘッダーファイルのインクルードパスを指定する必要があります-#includeはプリプロセッサディレクティブであるため、プリプロセッサ(CPPFLAGS)のみが重要ですか?

どのような状況でコンパイラに追加のインクルードパスを与える必要がありますか?

一般に、プリプロセッサが必要なヘッダーファイルを見つけてインクルードする場合、なぜ追加のインクルードディレクトリについて通知する必要があるのですか? CFLAGSの用途は何ですか?

(私の場合、実際にはBOTHがプログラムのコンパイルを許可しているので、混乱を招きます... CFLAGSを使用できますまたは私の目標を達成するためのCPPFLAGS(少なくともautoconfコンテキストで)。何が得られますか?)

92
EBM

Cプログラムをコンパイルするための暗黙のmake規則は次のとおりです。

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

$()構文は変数を展開します。 CPPFLAGSCFLAGSの両方がコンパイラー呼び出しで使用されるため、インクルードパスの定義に使用するのは個人的な好みの問題です。たとえば、foo.cが現在のディレクトリ内のファイルである場合

make foo.o CPPFLAGS="-I/usr/include"
make foo.o CFLAGS="-I/usr/include"

どちらも、まったく同じ方法でコンパイラを呼び出します。つまり、

gcc -I/usr/include -c -o foo.o foo.c

同じインクルードパスを必要とする複数の言語がある場合、たとえばbar.cppがある場合は2つの違いが関係します。

make bar.o CPPFLAGS="-I/usr/include"
make bar.o CFLAGS="-I/usr/include"

その後、コンパイルは

g++ -I/usr/include -c -o bar.o bar.cpp
g++ -c -o bar.o bar.cpp

c ++の暗黙のルールもCPPFLAGS変数を使用するためです。

この違いは、使用する良いガイドを提供します-すべての言語にフラグを使用したい場合はCPPFLAGSに、特定の言語に使用したい場合はCFLAGSCXXFLAGSなど。後者のタイプの例には、標準準拠フラグまたは警告フラグが含まれます--std=c99をC++コンパイラに渡したくないでしょう!

メイクファイルで次のような結果になる可能性があります

CPPFLAGS=-I/usr/include
CFLAGS=-std=c99
CXXFLAGS=-Weffc++
144
Scott Wales

CPPFLAGSマクロは、#includeディレクトリを指定するために使用するマクロです。

CPPFLAGSCFLAGSは、make(1)ルールが前処理とコンパイルの両方を1つのコマンドに結合するため、どちらの場合でも機能します(したがって、両方のマクロがコマンドで使用されます)。

.という形式を使用する場合、#include "..."をinclude-directoryとして指定する必要はありません。また、標準コンパイラのインクルードディレクトリを指定する必要もありません。他のすべてのinclude-directoriesを指定する必要があります。

10
Steve Emmerson

暗黙の規則作成 の後です。

4