####
# $Id: Makefile 119 2006-03-09 18:18:52Z gordon $

####
# operating system setup

# generic unix

CC               = gcc -std=c99
CXX              = g++
LD               = g++
AR               = ar

DEBUG_CCFLAGS    = -g -Wall
DEBUG_LDFLAGS    = -g

RELEASE_CCFLAGS  = -O3 -Wall -Werror
RELEASE_LDFLAGS  = 

APP_SUFFIX       =

OBJECT_SUFFIX    = .o

LIBRARY_SUFFIX   = .a
LIBRARY_CCFLAGS  = 
LIBRARY_LDFLAGS  =

SLIBRARY_PREFIX  = lib
SLIBRARY_SUFFIX  = .so
SLIBRARY_CCFLAGS = -fPIC
SLIBRARY_LDFLAGS = -shared

ARFLAGS = -r -csu

OS = $(shell uname)

ifeq ($(OS), Darwin)
SLIBRARY_SUFFIX = .dylib
SLIBRARY_LDFLAGS = -dynamiclib
endif

####
# assemble flags

ifdef APPLICATION
TARGET = $(APPLICATION)$(APP_SUFFIX)
else
ifdef STATIC_LIBRARY
TARGET = $(STATIC_LIBRARY)$(LIBRARY_SUFFIX)
else
ifdef SHARED_LIBRARY
TARGET = $(SLIBRARY_PREFIX)$(SHARED_LIBRARY)$(SLIBRARY_SUFFIX)
endif
endif
endif


ifdef TARGET

BUILD ?= debug

ifeq ($(BUILD), release)
CCFLAGS += $(RELEASE_CCFLAGS)
LDFLAGS += $(RELEASE_LDFLAGS)
BUILD_DIR = $(BASE_DIR)/release
else
CCFLAGS += $(DEBUG_CCFLAGS)
LDFLAGS += $(DEBUG_LDFLAGS)
BUILD_DIR = $(BASE_DIR)/debug
endif

ifeq ($(suffix $(TARGET)), $(LIBRARY_SUFFIX))
CCFLAGS += $(LIBRARY_CCFLAGS)
LDFLAGS += $(LIBRARY_LDFLAGS)
endif

ifeq ($(suffix $(TARGET)), $(SLIBRARY_SUFFIX))
CCFLAGS += $(SLIBRARY_CCFLAGS)
LDFLAGS += $(SLIBRARY_LDFLAGS)
endif

endif

####
# top-level build target

.PHONY: all build clean
.PHONY: subdirs $(SUBDIRS)

all: subdirs build

####
# subdirs

ifdef SUBDIRS
subdirs: $(SUBDIRS)
$(SUBDIRS):
	@echo "-->" $@
	@$(MAKE) -r -C $@ $(MAKECMDGOALS)
	@echo "<--"
else
subdirs:
endif

####
# build

ifdef TARGET

OBJ_DIR = .obj/$(BUILD)
OBJECTS = $(addprefix $(OBJ_DIR)/, $(addsuffix $(OBJECT_SUFFIX), $(basename $(SOURCES))))
OBJDEPS = $(join $(OBJECTS), $(addprefix :, $(SOURCES)))
OBJDIRS = $(addprefix $(OBJ_DIR)/, $(dir $(SOURCES)))

TARGET_MAKEFILE = .Makefile.$(TARGET).$(BUILD)

$(TARGET_MAKEFILE): $(BASE_DIR)/build/Makefile Makefile $(SOURCES) $(HEADERS)
	@echo "#" $(TARGET_MAKEFILE): $(OS) `date`                             > $(TARGET_MAKEFILE)
	@echo                                                                 >> $(TARGET_MAKEFILE)
	@echo $(OBJ_DIR)/%.o: %.c                                             >> $(TARGET_MAKEFILE)
	@echo "	"$(CC) $(CCFLAGS) $(INCLUDES) -c -o $$\@ $$\<                 >> $(TARGET_MAKEFILE)
	@echo                                                                 >> $(TARGET_MAKEFILE)
	@echo $(OBJ_DIR)/%.o: %.cpp                                           >> $(TARGET_MAKEFILE)
	@echo "	"$(CXX) $(CCFLAGS) $(INCLUDES) -c -o $$\@ $$\<                >> $(TARGET_MAKEFILE)
	@echo                                                                 >> $(TARGET_MAKEFILE)
	@echo "all: " $(BUILD_DIR)/$(TARGET)                                  >> $(TARGET_MAKEFILE)
	@echo                                                                 >> $(TARGET_MAKEFILE)
ifdef STATIC_LIBRARY
	@echo $(BUILD_DIR)/$(TARGET): $(OBJECTS)                              >> $(TARGET_MAKEFILE)
	@echo "	"$(AR) $(ARFLAGS) $$\@ $$\^                                   >> $(TARGET_MAKEFILE)
else
	@echo $(BUILD_DIR)/$(TARGET): $(OBJECTS)                              >> $(TARGET_MAKEFILE)
	@echo "	"$(LD) $(LDFLAGS) -o $$\@ $$\^ -L$(BUILD_DIR) $(LIBRARIES)    >> $(TARGET_MAKEFILE)
endif
	@echo                                                                 >> $(TARGET_MAKEFILE)
	@for i in $(OBJDEPS); do (echo "$$i" >> $(TARGET_MAKEFILE)); done
	@echo                                                                 >> $(TARGET_MAKEFILE)
	@echo "# DO NOT DELETE THIS LINE -- make depend depends on it."       >> $(TARGET_MAKEFILE)
	@makedepend $(INCLUDES) -- $(CCFLAGS) -- -f$(TARGET_MAKEFILE) -p$(OBJ_DIR)/ $(SOURCES) 2>/dev/null

build: $(TARGET_MAKEFILE)
	@mkdir -p $(OBJDIRS)
	@mkdir -p $(BUILD_DIR)
	@$(MAKE) --no-print-directory -r -f $(TARGET_MAKEFILE)

####
# clean

clean: subdirs
	@rm -f .Makefile.* $(GENERATED)
	rm -rf $(OBJ_DIR)
	rm -f $(BUILD_DIR)/$(TARGET)

else
build:
clean: subdirs
endif
