Organizing Projects With vpath

Tags:

GNU Make's vpath directive lets me easily build a “debug” and a “release” form of my project from the same source in completely independent workspaces but using the same source code and the same Makefile.

When I start a new programming project, say a C++ class library, I typically start by creating the following directories, all of which I ultimately put under version control (e.g., CVS or Subversion):

  • doc: where I build my Doxygen documentation from my embedded documentation (in my .h files).
  • include: where I put all my class interface definitions.
  • src: where I put my class implementation files (i.e., the .cpp files), and my Makefile.
  • tests: where I put my regression test programs for my library classes.

In addition to the above directories I also create a pair in which to build my project, obj_d for the debug version, obj for the optimized/release version. Nothing that gets produced in these directories will go under version control. Finally, I create symbolic link from the Makefile in the src directory in both:

$ cd src
$ mkdir ../obj ../obj_d
$ ln -s ./Makefile ../obj/
$ ln -s ./Makefile ../obj_d/

GNU Make's vpath directive identifies alternative locations for various file types. In my src/Makefile I put the following vpath directives:

vpath %.h ../include
vpath %.cpp ../src

These settings tell GNU Make to look in ../include for .h files and in ../src for .cpp files. This allows me to use the same Makefile in obj, obj_d, or even src, although prefer to keep my generated content separate from my version-controlled content.

The vpath directive makes it easy to keep multiple versions of the project built and up-to-date. It also makes it easy to keep the generated code separate from the source code, which makes clean-up simpler. To remove all my temporary and intermediate files all I need to do is remove the entire obj (or obj_d) directory.