Mike's Musings

Do you want code with that mongoose?

0

Generic Makefile

Earlier today I decided to start working on yet another side project, this time written in C++. Before I get into the meat of this post I thought I’d mention that I reinstalled my dev environment for C++, I use the MinGW port of the GCC for my compilier and would like to mention that the work they have done on their package manager mingw-get is really awesome it allowed me to get MinGW and MSYS up and running in no time with very little effort.

Once my dev environment was all setup again I went to set up my project only to find that somewhere along the way I had lost my generic all purpose Makefile, so after taking a little bit of time out to re-teach myself how to write a Makefile – from the best source that I know of – I recreated a makefile very similar to my original generic makefile. In an effort to not lose it again I thought I would share it with the world:

APPNAME = test
SRCDIR = src
OBJDIR = obj
BINDIR = bin

SRC = $(shell find $(SRCDIR) | grep .cc)
OBJ = $(patsubst $(SRCDIR)/%.cc, $(OBJDIR)/%.o, $(SRC))

.PHONEY: all clean init

all: clean $(APPNAME)

clean:
	rm -rfd $(OBJDIR) $(BINDIR)

init:
	mkdir $(OBJDIR) $(BINDIR)
	$(foreach DIR, $(patsubst $(SRCDIR)/%, $(OBJDIR)/%, $(shell find $(SRCDIR)/* -type d)), mkdir $(DIR))

$(APPNAME): init $(OBJ)
	$(CXX) -o $(BINDIR)/$(APPNAME).exe $(OBJ)

$(OBJDIR)/%.o: $(SRCDIR)/%.cc
	$(CXX) -c $< -o $@

To use this makefile you will need to run it from a POSIX like environment so it should work fine on Mac OSX and Linux but on Windows you will need something like MSYS or Cygwin, personally I use MSYS but that’s just a preference thing.

This makefile is intended to be a drop in start point for any C++ project, though it isn’t had to modify it for other languages. The following is the project structure that the makefile is designed to work with:

  • Project Root/
    • makefile
    • src/
      • source_file1.cc
      • source_file2.cc
      • subfolder1/
        • source_file3.cc
      • subfolder2/
        • source_file4.cc
        • source_file5.cc

It will pickup all of the source files in the subdirectories eliminating the need for a recursive makefile. I have never tested this makefile on a large project so I don’t know how well it would hold up, but I’m guessing if your project is getting big you would most likely be better off using something like Autotools or CMake.