CXXFLAGSとCPPFLAGSの違い

2017年5月13日 オフ 投稿者: khws4v1

MakefileのCXXFLAGSとCPPFLAGSの違いについて。
名前が似ているだけあって混同してしまっていることがあるので念の為に書いとく。

実は2つの変数の違いは公式ドキュメントを見ると一瞬で分かるので読む。

CXXFLAGS

Extra flags to give to the C++ compiler.

 

CPPFLAGS

Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).

CXXFLAGSはC++コンパイラ(CXX)のオプション、CPPFLAGSはCプリプロセッサのオプションを意味している。
MakefileにCPPFLAGS = -std=c++11tと書くのは誤りで、CXXFLAGSを使わなければいけない。

試しにCXXFLAGSとCPPFLAGSで挙動が異なるMakefileを書いてみる。

#include <stdio.h>
void hello_c(void)
{
puts("Hello world in C.");
}
view raw hello-c.c hosted with ❤ by GitHub
#include <iostream>
void hello_cplusplus()
{
std::cout << "Hello world in C++." << std::endl;
}
extern "C" void hello_c(void);
void hello_cplusplus();
int main()
{
hello_c();
hello_cplusplus();
return 0;
}
view raw main.cpp hosted with ❤ by GitHub
CC = gcc
CFLAGS = -std=c99
CXX = g++
CPPFLAGS = -std=c++11
TARGET = example
SRCS = \
hello-c.c \
hello-cplusplus.cpp \
main.cpp \
OBJS = $(addsuffix .o, $(basename $(SRCS)))
$(TARGET): $(OBJS)
$(CXX) $^ -o $@
.PHONY: clean
clean:
$(RM) $(TARGET) $(OBJS)
CC = gcc
CFLAGS = -std=c99
CXX = g++
CXXFLAGS = -std=c++11
TARGET = example
SRCS = \
hello-c.c \
hello-cplusplus.cpp \
main.cpp \
OBJS = $(addsuffix .o, $(basename $(SRCS)))
$(TARGET): $(OBJS)
$(CXX) $^ -o $@
.PHONY: clean
clean:
$(RM) $(TARGET) $(OBJS)

実際に以下のコマンドでmakeする。

それぞれ実行した時の出力を見るとCXXFLAGSとCPPFLAGSの違いが出てくる。

CプリプロセッサはCとC++の両方で使われるため、CPPFLAGSはどちらのソースコードをコンパイルする時でも使われる。
CPPFLAGSをC++コンパイラのオプションと勘違いしてMakefileを書くと、CコンパイラにもC++コンパイラのオプションまで渡されてしまう。

ではCPPFLAGSの正しい使い方はと言うとインクルードパスを指定するのに使うそうだ。