The implicit make rule for compiling a C program is
%.o:%.c $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
$() syntax expands the variables. As both
CFLAGS are used in the compiler call, which you use to define include paths is a matter of personal taste. For instance if
foo.c is a file in the current directory
make foo.o CPPFLAGS="-I/usr/include" make foo.o CFLAGS="-I/usr/include"
will both call your compiler in exactly the same way, namely
gcc -I/usr/include -c -o foo.o foo.c
The difference between the two comes into play when you have multiple languages which need the same include path, for instance if you have
bar.cpp then try
make bar.o CPPFLAGS="-I/usr/include" make bar.o CFLAGS="-I/usr/include"
then the compilations will be
g++ -I/usr/include -c -o bar.o bar.cpp g++ -c -o bar.o bar.cpp
as the C++ implicit rule also uses the
This difference gives you a good guide for which to use – if you want the flag to be used for all languages put it in
CPPFLAGS, if it’s for a specific language put it in
CXXFLAGS etc. Examples of the latter type include standard compliance or warning flags – you wouldn’t want to pass
-std=c99 to your C++ compiler!
You might then end up with something like this in your makefile
CPPFLAGS=-I/usr/include CFLAGS=-std=c99 CXXFLAGS=-Weffc++