diff --git a/Makefile b/Makefile
index 74974ff67f377216b4bdaef7998b558f25d3d31b..b66b85f98a584703d95834020fa4600250d5ef15 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,11 @@ export BIN_DIR	= bin
 export SRC_DIR	= src
 export UTIL_DIR	= src/utils
 export CXX		= g++
+ifeq ($(DEBUG),1)
+export CXXFLAGS = -Wall -O0 -g -fno-inline -fkeep-inline-functions -D_FILE_OFFSET_BITS=64 -fPIC -DDEBUG -D_DEBUG
+else
 export CXXFLAGS = -Wall -O2 -D_FILE_OFFSET_BITS=64 -fPIC
+endif
 export LIBS		= -lz
 export BT_ROOT  = src/utils/BamTools/
 
@@ -74,25 +78,7 @@ UTIL_SUBDIRS =	$(SRC_DIR)/utils/bedFile \
 BUILT_OBJECTS = $(OBJ_DIR)/*.o
 
 
-all: gitversion
-	[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
-	[ -d $(BIN_DIR) ] || mkdir -p $(BIN_DIR)
-	
-	@echo "Building BEDTools:"
-	@echo "========================================================="
-	
-	@for dir in $(UTIL_SUBDIRS); do \
-		echo "- Building in $$dir"; \
-		$(MAKE) --no-print-directory -C $$dir; \
-		echo ""; \
-	done
-
-	@for dir in $(SUBDIRS); do \
-		echo "- Building in $$dir"; \
-		$(MAKE) --no-print-directory -C $$dir; \
-		echo ""; \
-	done
-
+all: print_banner $(OBJ_DIR) $(BIN_DIR) gitversion $(UTIL_SUBDIRS) $(SUBDIRS)
 	@echo "- Building main bedtools binary."
 	@$(CXX) $(CXXFLAGS) -c src/bedtools.cpp -o obj/bedtools.o -I$(UTIL_DIR)/version/
 	@$(CXX) $(LDFLAGS) $(CXXFLAGS) -o $(BIN_DIR)/bedtools $(BUILT_OBJECTS) -L$(UTIL_DIR)/BamTools/lib/ -lbamtools $(LIBS)
@@ -106,14 +92,34 @@ all: gitversion
 
 .PHONY: all
 
+print_banner:
+	@echo "Building BEDTools:"
+	@echo "========================================================="
+.PHONY: print_banner
+
+# make the "obj/" and "bin/" directories, if they don't exist
+$(OBJ_DIR) $(BIN_DIR):
+	@mkdir -p $@
+
+
+# One special case: All (or almost all) programs requires the BamTools API files to be created first.
+.PHONY: bamtools_api
+bamtools_api:
+	@$(MAKE) --no-print-directory --directory=$(BT_ROOT) api
+$(UTIL_SUBDIRS) $(SUBDIRS): bamtools_api
+
+
+# even though these are real directories, treat them as phony targets, forcing to always go in them are re-make.
+# a future improvement would be the check for the compiled object, and rebuild only if the source code is newer.
+.PHONY: $(UTIL_SUBDIRS) $(SUBDIRS)
+$(UTIL_SUBDIRS) $(SUBDIRS): $(OBJ_DIR) $(BIN_DIR)
+	@echo "- Building in $@"
+	@$(MAKE) --no-print-directory --directory=$@
+
 clean:
-	@echo "Cleaning up."	
+	@$(MAKE) --no-print-directory --directory=$(BT_ROOT) clean_api
+	@echo " * Cleaning up."
 	@rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
-	@rm -Rf $(BT_ROOT)/lib
-	@rm -f $(BT_ROOT)/src/api/*.o
-	@rm -f $(BT_ROOT)/src/api/internal/*/*.o
-	@rm -Rf $(BT_ROOT)/include
-
 .PHONY: clean
 
 test: all
diff --git a/src/utils/BamTools/Makefile b/src/utils/BamTools/Makefile
index 451c242ee16c2f82da7371e8cd37b8b83c889ee2..28c5a93fb7627dbe2358ac3cee995be78e6a461c 100644
--- a/src/utils/BamTools/Makefile
+++ b/src/utils/BamTools/Makefile
@@ -55,15 +55,6 @@ all: $(LIBRARY)
 .PHONY: all
 
 $(LIBRARY): $(OBJECTS)
-	[ -d lib ] || mkdir -p lib
-	[ -d include ] || mkdir -p include
-	[ -d include/api ] || mkdir -p include/api
-	[ -d include/shared ] || mkdir -p include/shared
-
-	@cp src/api/*.h include/api
-	@cp src/shared/*.h include/shared
-
-
 	@echo " * linking $(LIBRARY)"
 	ar cr $@ $^
 	-ranlib $@
@@ -71,3 +62,18 @@ $(LIBRARY): $(OBJECTS)
 $(OBJECTS): $(SOURCES)
 	@echo " * compiling" $(*F).cpp
 	@$(CXX) -c $(*D)/$(*F).cpp $(LDFLAGS) $(CXXFLAGS) $(INCLUDES) -o $(*D)/$(*F).o
+
+.PHONY: api
+api:
+	@echo " * Creating BamTools API"
+	@mkdir -p lib
+	@mkdir -p include
+	@mkdir -p include/api
+	@mkdir -p include/shared
+	@cp src/api/*.h include/api
+	@cp src/shared/*.h include/shared
+
+.PHONY: clean_api
+clean_api:
+	@echo " * Cleaning-up BamTools API"
+	@rm -rf ./lib ./src/api/*.o ./src/api/internal/*/*.o ./include