diff --git a/Makefile b/Makefile
index ec9bc9d31ae23d70589b73f632bea28435f62169..0df2757190f5ab0416cee6942e3a8f8c2c2e9602 100644
--- a/Makefile
+++ b/Makefile
@@ -1,30 +1,10 @@
-ifeq (, $(__RIOTBUILD_FLAG))
-  all: welcome
-	@echo ""
-	@exit 1
-else
-  all:
-	mkdir -p $(BINDIR)
-	@for i in $(DIRS) ; do "$(MAKE)" -C $$i || exit 1; done ;
-endif
-
-DIRS = $(RIOTCPU)/$(CPU) core drivers sys
-
-ifneq (,$(filter embunit,$(USEMODULE)))
-	DIRS += tests/unittests/embunit/embUnit
-endif
+.all:
 
-ifneq (,$(filter embunit_textui,$(USEMODULE)))
-	DIRS += tests/unittests/embunit/textui
-endif
+.PHONY: all doc docclean welcome
 
-.PHONY: all clean doc docclean welcome
-
-clean:
-	@for i in $(DIRS) ; do "$(MAKE)" -C $$i clean || exit 1; done ;
-	-@if [ -d $(BINDIR) ] ; \
-	then rm -rf $(BINDIR) ; \
-	fi
+all: welcome
+	@echo ""
+	@exit 1
 
 doc:
 	"$(MAKE)" -BC doc/doxygen
diff --git a/Makefile.application b/Makefile.application
new file mode 100644
index 0000000000000000000000000000000000000000..5f1e1ae5893192fb74c10c7d3f4130910858c961
--- /dev/null
+++ b/Makefile.application
@@ -0,0 +1,13 @@
+MODULE = $(APPLICATION)
+
+DIRS += $(RIOTCPU)/$(CPU) $(RIOTBOARD)/$(BOARD)
+DIRS += $(RIOTBASE)/core $(RIOTBASE)/drivers $(RIOTBASE)/sys
+
+ifneq (,$(filter embunit,$(USEMODULE)))
+  DIRS += $(RIOTBASE)/tests/unittests/embunit/embUnit
+endif
+ifneq (,$(filter embunit_textui,$(USEMODULE)))
+  DIRS += $(RIOTBASE)/tests/unittests/embunit/textui
+endif
+
+include $(RIOTBASE)/Makefile.base
diff --git a/Makefile.base b/Makefile.base
index db9c68b9da5ff7e287259854dfcf42b71b9b5bf4..c2d547327fadfc49dc92048e7cd1a2059a951776 100644
--- a/Makefile.base
+++ b/Makefile.base
@@ -4,11 +4,20 @@ endif
 
 MODULE ?= $(shell basename $(CURDIR))
 
-all: $(BINDIR)$(MODULE).a
-	@for i in $(DIRS); do $(MAKE) -C $$i || exit 1; done;
+.PHONY: all ${DIRS:%=ALL--%} ${DIRS:%=CLEAN--%}
 
-clean::
-	@for i in $(DIRS); do $(MAKE) -C $$i clean; done;
+all: $(BINDIR)$(MODULE).a ..nothing
+
+..nothing:
+	@:
+
+clean:: ${DIRS:%=CLEAN--%}
+
+${DIRS:%=ALL--%}:
+	"$(MAKE)" -C ${@:ALL--%=%}
+
+${DIRS:%=CLEAN--%}:
+	"$(MAKE)" -C ${@:CLEAN--%=%} clean
 
 ASMSRC = $(wildcard *.s)
 ASSMSRC = $(wildcard *.S)
@@ -21,7 +30,8 @@ endif
 OBJ = $(SRC:%.c=$(BINDIR)$(MODULE)/%.o)
 DEP = $(SRC:%.c=$(BINDIR)$(MODULE)/%.d)
 
-$(BINDIR)$(MODULE).a: $(OBJ) $(ASMOBJ)
+$(BINDIR)$(MODULE).a: $(OBJ) $(ASMOBJ) ${DIRS:%=ALL--%}
+	@mkdir -p $(BINDIR)$(MODULE)
 	$(AD)$(AR) -rc $(BINDIR)$(MODULE).a $(OBJ) $(ASMOBJ)
 
 # pull in dependency info for *existing* .o files
diff --git a/Makefile.include b/Makefile.include
index 067d1e0456642e858035e1c19242259c452fbb8d..284d8bf525d143477080ef2f48cf78761950d2d6 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -1,4 +1,4 @@
-# Provide a shallow sanity check. You cannot call `make` in the root directory.
+# Provide a shallow sanity check. You cannot call `make` in a module directory.
 export __RIOTBUILD_FLAG := RIOT
 
 # set undefined variables
@@ -33,12 +33,14 @@ CPUDEF = $(shell echo $(CPU)|tr 'a-z' 'A-Z'|tr '-' '_')
 CFLAGS += -DBOARD_$(BB) -DCPU_$(CPUDEF)
 
 export CFLAGS
+export APPLICATION
 
 export BINDIRBASE ?= $(CURDIR)/bin
 export BINDIR ?= $(abspath $(BINDIRBASE)/$(BOARD))/
 
 ifeq ($(QUIET),1)
 	AD=@
+	MAKEFLAGS += --no-print-directory
 else
 	AD=
 endif
@@ -84,10 +86,8 @@ export ELFFILE ?= $(BINDIR)$(APPLICATION).elf
 export HEXFILE ?= $(ELFFILE:.elf=.hex)
 
 ## make script for your application. Build RIOT-base here!
-all: $(BINDIR)$(APPLICATION).a
-	@echo "Building application $(APPLICATION) for $(BOARD) w/ MCU $(MCU)."
-	"$(MAKE)" -C $(RIOTBOARD)/$(BOARD)
-	"$(MAKE)" -C $(RIOTBASE)
+all: ..build-message $(USEPKG:%=${BINDIR}%.a) $(APPDEPS)
+	"$(MAKE)" -C $(CURDIR) -f $(RIOTBASE)/Makefile.application
 ifeq (,$(RIOTNOLINK))
 ifeq ($(BUILDOSXNATIVE),1)
 	$(AD)$(LINK) $(UNDEF) -o $(ELFFILE) $(BASELIBS) $(LINKFLAGS) -Wl,-no_pie
@@ -98,14 +98,8 @@ endif
 	$(AD)$(OBJCOPY) $(OFLAGS) $(ELFFILE) $(HEXFILE)
 endif
 
-# string array of all names of c files in dir
-SRC = $(wildcard *.c)
-
-# string array of all names replaced .c with .o
-OBJ = $(SRC:%.c=${BINDIR}${APPLICATION}/%.o)
-
-$(BINDIR)$(APPLICATION).a: $(OBJ)
-	$(AD)$(AR) -rc $(BINDIR)$(APPLICATION).a $(OBJ)
+..build-message:
+	@echo "Building application $(APPLICATION) for $(BOARD) w/ MCU $(MCU)."
 
 # add extra include paths for packages in $(USEMODULE)
 export USEMODULE_INCLUDES =
@@ -119,7 +113,7 @@ INCLUDES += $(USEMODULE_INCLUDES_:%=-I%)
 
 # The `clean` needs to be serialized before everything else.
 ifneq (, $(filter clean, $(MAKECMDGOALS)))
-    $(OBJ) $(BASELIBS) $(USEPKG:%=$(RIOTBASE)/pkg/%/Makefile.include): clean
+    all $(BASELIBS) $(USEPKG:%=$(RIOTBASE)/pkg/%/Makefile.include): clean
 endif
 
 # include Makefile.includes for packages in $(USEPKG)
@@ -130,14 +124,6 @@ $(RIOTBASE)/pkg/%/Makefile.include::
 
 -include $(USEPKG:%=$(RIOTBASE)/pkg/%/Makefile.include)
 
-# pull in dependency info for *existing* .o files
--include $(OBJ:.o=.d)
-
-$(BINDIR)$(APPLICATION)/%.o: %.c $(APPDEPS) $(USEPKG:%=${BINDIR}%.a)
-	@echo; echo "Compiling.... $*.c"; echo
-	$(AD)mkdir -p "$(dir $@)"
-	$(AD)$(CC) $(CFLAGS) $(INCLUDES) -c "$<" -o "$@"
-
 $(USEPKG:%=${BINDIR}%.a):
 	@mkdir -p ${BINDIR}
 	"$(MAKE)" -C $(RIOTBASE)/pkg/$(patsubst ${BINDIR}%.a,%,$@)