Generic makefile for easily building 1 file programs

I’ve always found myself writing short little programs to test out an idea or learn how a language feature/bug works. Often they’re throw away programs, once finished they’re no longer needed. So often it ends up being test.c/test.cpp/test.java etc. But sometimes I like to keep it around so they’ll end up with a meaningful name i.e. I now have a lambda.cpp I used for trying out the new C++11 lambdas. So rather than always have to whip out a new makefile or copy/edit an old one I have this makefile which makes things a little easier. You just drop the makefile in place where you have file.cpp’s laying around and you can compile that single file.cpp with ‘make file’. As you can see I have it working on linux, osx, and windows.


$ cat - > hw.cpp
#include < iostream >
int main() {
std::cout < < "Hello, world!\n";
}

arch:/home/mkm/src/test
$ make hw
g++ -std=c++11 -Wall  hw.cpp -o hw

arch:/home/mkm/src/test
$ ./hw
Hello, world!

Here's the makefile


# generic 1 file makefile
# 2013/09/18 Mike Makuch
# This makefile will compile any single file.cpp file without modification
# by simply typing 'make file' without the .cpp eg;
#	file name	myprog.cpp
#	type:		make myprog
# Initially works for linux, osx, win7/vs2012,
# Written assuming gnu make

UNAME := $(shell uname -s)

.SUFFIXES:
	MAKEFLAGS += --no-builtin-rules

ifeq ($(UNAME), Linux)
CFLAGS = -std=c++11 -Wall 
CC = g++
COMPILE = $(CC) $(CFLAGS) $< -o $@
BINS = $(subst .cpp,,$(SRCS))
endif

ifeq ($(UNAME), Darwin)
CC = /opt/local/bin/g++-mp-4.7
CFLAGS = -std=c++11  -L/opt/local/lib -I/opt/local/include
COMPILE = $(CC) $(CFLAGS) $< -o $@
BINS = $(subst .cpp,,$(SRCS))
endif

ifneq (,$(findstring CYGWIN_NT,$(UNAME)))
CC=cl
CFLAGS=/O2 /nologo 
#LIBS=gdi32.lib user32.lib kernel32.lib shell32.lib winmm.lib opengl32.lib glu32.lib
LIBS=user32.lib kernel32.lib shell32.lib
COMPILE = cl /EHsc $?  /Fe$(subst .cpp,.exe,$?)  ;  rm $(OBJ)
OBJ = $(addsuffix .obj,$@)
BINS = $(subst .cpp,.exe,$(SRCS))
endif

SRCS = $(shell ls *.cpp)

% :	%.cpp
	$(COMPILE)

clean:
	rm -rf $(BINS) *.dSYM *.obj *.exe