I've found many hand-made Makefiles that are very hard to read and modify; the reason: they use strange variable names to handle the compilation and linking of programs.

In case you don't know, there is a de facto standard in Makefile variable names when it comes to calling to the compiler. Here they are:

  • CC: Path to the C compiler. Sometimes set to cc or gcc. Never hardcode this to an absolute path, unless the value is being filled by the configure script.
  • CXX: Path to the C++ compiler. Sometimes set to c++ or g++. Follow the same rules as in the CC variable.
  • CPPFLAGS: Flags to be passed to the C/C++ preprocessor. More specifically, this contains all -D and -I flags.
  • CFLAGS: Flags to be passed to the C compiler. For example, -g, -Wall, etc. This does not include any of -D nor -I.
  • CXXFLAGS: Flags to be passed to the C++ compiler. Similar to CFLAGS.
  • LDFLAGS: Flags to be passed to the linker, except libraries. I.e., it can include -L or rpath flags.
  • LIBS: Libraries to link to. Usually in the form of -l flags.

Once you have all these variables set, there are some very simple rules to use them. Whenever you have to compile a C source file into an object, use the following form: $(CC) $(CPPFLAGS) $(CFLAGS) -o name.o -c name.c, and similary for C++ sources.

And when you have to link multiple objects into a single executable, use a call like: $(CC) $(LDFLAGS) -o name name1.o name2.o $(LIBS). Here you can see why libraries are not included in LDFLAGS.

Lastly, if you don't mind relying on the += operator, always use it to extend the value of all *FLAGS variables, so that the user can easily provide his own values in the environment.

Edit (December 11th): Corrected a variable name: CCFLAGS ought to be CFLAGS.