diff --git a/Makefile.buildtests b/Makefile.buildtests
index 9df9d455bff5031347c8baef8ded76fed5f35c9a..f87a19cfacb84367726fa0eb6f9b2c5d59638a31 100644
--- a/Makefile.buildtests
+++ b/Makefile.buildtests
@@ -45,52 +45,57 @@ buildtest:
 	APP_RETRY=0; \
 	rm -rf "$$BINDIRBASE"; \
 	for BOARD in $$($(MAKE) -s info-boards-supported); do \
-	  RIOTNOLINK=$$(echo $(BOARD_INSUFFICIENT_RAM) | grep $${BOARD} 2>&1 >/dev/null && echo 1); \
-	  ${COLOR_ECHO} -n "Building for $${BOARD} "; \
-	  [ -n "$${RIOTNOLINK}" ] && ${COLOR_ECHO} -n "(no linking) "; \
-	  for NTH_TRY in 1 2 3; do \
-	    ${COLOR_ECHO} -n ".. "; \
-	    LOG=$$(env -i \
-	        HOME=$${HOME} \
-	        PATH=$${PATH} \
-	        BOARD=$${BOARD} \
-	        CCACHE=$${CCACHE} \
-	        CCACHE_DIR=$${CCACHE_DIR} \
-	        CCACHE_BASEDIR=$${CCACHE_BASEDIR} \
-	        RIOTBASE=$${RIOTBASE} \
-	        RIOTBOARD=$${RIOTBOARD} \
-	        RIOTCPU=$${RIOTCPU} \
-	        BINDIRBASE=$${BINDIRBASE} \
-	        RIOTNOLINK=$${RIOTNOLINK} \
-	        RIOT_VERSION=$${RIOT_VERSION} \
-	        $(MAKE) -j$(NPROC) 2>&1) ; \
-	    if [ "$${?}" = "0" ]; then \
-	      ${COLOR_ECHO} "${COLOR_GREEN}success${COLOR_RESET}"; \
-	    elif [ -n "$${RIOT_DO_RETRY}" ] && [ "$${APP_RETRY}" -lt "3" ] && [ $${NTH_TRY} != 3 ]; then \
-	      ${COLOR_ECHO} -n "${COLOR_PURPLE}retrying${COLOR_RESET} "; \
-	      continue; \
-	    else \
-	      ${COLOR_ECHO} "${COLOR_RED}failed${COLOR_RESET}"; \
-	      echo "$${LOG}" | grep -v -E '^make(\[[[:digit:]]])?:'; \
-	      APP_RETRY=`expr $${APP_RETRY} + 1`; \
-	      BUILDTESTOK=false; \
-	    fi; \
-	    break; \
-	  done; \
-	  env -i \
-	    HOME=$${HOME} \
-	    PATH=$${PATH} \
-	    BOARD=$${BOARD} \
-	    CCACHE=$${CCACHE} \
-	    CCACHE_DIR=$${CCACHE_DIR} \
-	    CCACHE_BASEDIR=$${CCACHE_BASEDIR} \
-	    RIOTBASE=$${RIOTBASE} \
-	    RIOTBOARD=$${RIOTBOARD} \
-	    RIOTCPU=$${RIOTCPU} \
-	    BINDIRBASE=$${BINDIRBASE} \
-	    RIOTNOLINK=$${RIOTNOLINK} \
-	    RIOT_VERSION=$${RIOT_VERSION} \
-	    $(MAKE) clean-intermediates 2>&1 >/dev/null || true; \
+		RIOTNOLINK=$$(echo $(BOARD_INSUFFICIENT_RAM) | grep $${BOARD} 2>&1 >/dev/null && echo 1); \
+		${COLOR_ECHO} -n "Building for $${BOARD} "; \
+		[ -n "$${RIOTNOLINK}" ] && ${COLOR_ECHO} -n "(no linking) "; \
+		for NTH_TRY in 1 2 3; do \
+			${COLOR_ECHO} -n ".. "; \
+			LOG=$$(env -i \
+					HOME=$${HOME} \
+					PATH=$${PATH} \
+					BOARD=$${BOARD} \
+					CCACHE=$${CCACHE} \
+					CCACHE_DIR=$${CCACHE_DIR} \
+					CCACHE_BASEDIR=$${CCACHE_BASEDIR} \
+					RIOTBASE=$${RIOTBASE} \
+					RIOTBOARD=$${RIOTBOARD} \
+					RIOTCPU=$${RIOTCPU} \
+					BINDIRBASE=$${BINDIRBASE} \
+					RIOTNOLINK=$${RIOTNOLINK} \
+					RIOT_VERSION=$${RIOT_VERSION} \
+					$(MAKE) -j$(NPROC) 2>&1) ; \
+			if [ "$${?}" = "0" ]; then \
+				${COLOR_ECHO} "${COLOR_GREEN}success${COLOR_RESET}"; \
+				if [ -n "$${BUILDTEST_VERBOSE}" ]; then \
+					echo "$${LOG}" | tail -n +2 | head -n -2 | grep -v -E '^Building application|^\"make|^patching' | awk 'NF'; \
+				fi; \
+			elif [ -n "$${RIOT_DO_RETRY}" ] && [ "$${APP_RETRY}" -lt "3" ] && [ $${NTH_TRY} != 3 ]; then \
+				${COLOR_ECHO} -n "${COLOR_PURPLE}retrying${COLOR_RESET} "; \
+				continue; \
+			else \
+				${COLOR_ECHO} "${COLOR_RED}failed${COLOR_RESET}"; \
+				if [ -n "$${BUILDTEST_VERBOSE}" ]; then \
+					echo "$${LOG}" | grep -v -E '^\"make'; \
+				fi; \
+				APP_RETRY=`expr $${APP_RETRY} + 1`; \
+				BUILDTESTOK=false; \
+			fi; \
+			break; \
+		done; \
+		env -i \
+			HOME=$${HOME} \
+			PATH=$${PATH} \
+			BOARD=$${BOARD} \
+			CCACHE=$${CCACHE} \
+			CCACHE_DIR=$${CCACHE_DIR} \
+			CCACHE_BASEDIR=$${CCACHE_BASEDIR} \
+			RIOTBASE=$${RIOTBASE} \
+			RIOTBOARD=$${RIOTBOARD} \
+			RIOTCPU=$${RIOTCPU} \
+			BINDIRBASE=$${BINDIRBASE} \
+			RIOTNOLINK=$${RIOTNOLINK} \
+			RIOT_VERSION=$${RIOT_VERSION} \
+			$(MAKE) clean-intermediates 2>&1 >/dev/null || true; \
 	done; \
 	$${BUILDTESTOK}
 endif # BUILD_IN_DOCKER
diff --git a/Makefile.docker b/Makefile.docker
index 4a741c173f79f73094b1e22da8622d562aa0eb27..1ee2657a9728cf6c9c44e3c1601bd7655a7b2997 100644
--- a/Makefile.docker
+++ b/Makefile.docker
@@ -42,6 +42,7 @@ export DOCKER_ENV_VARS = \
   SIZE \
   UNDEF \
   BUILDTEST_MCU_GROUP \
+  BUILDTEST_VERBOSE \
   #
 
 # Find which variables were set using the command line or the environment and
diff --git a/dist/tools/compile_test/compile_test.py b/dist/tools/compile_test/compile_test.py
index 9cc83e1b1d87a5fda69fe4b078f3bfbf7f603141..8202c0f954bd450b99358158cc821b65b3017899 100755
--- a/dist/tools/compile_test/compile_test.py
+++ b/dist/tools/compile_test/compile_test.py
@@ -2,6 +2,7 @@
 # -*- coding: utf-8 -*-
 
 # Copyright (C) 2014  René Kijewski  <rene.kijewski@fu-berlin.de>
+# Copyright (C) 2015  Philipp Rosenkranz  <philipp.rosenkranz@fu-berlin.de>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -24,23 +25,17 @@ from itertools import groupby
 from os import devnull, environ, listdir
 from os.path import abspath, dirname, isfile, join
 from subprocess import CalledProcessError, check_call, check_output, PIPE, Popen
-from sys import exit, stdout, argv
-
-riotbase = environ.get('RIOTBASE') or abspath(join(dirname(abspath(__file__)), '../' * 3))
-
-if len(argv) > 1:
-    base_branch = argv[1]
-    diff_files = check_output(('git', 'diff', '--name-only', base_branch, 'HEAD'))
-    diff_files = set(diff_files.split())
-else:
-    base_branch = ''
-
-null = open(devnull, 'w', 0)
-
-success = []
-failed = []
-skipped = []
-exceptions = []
+from sys import exit, stdout, argv, exc_info
+from StringIO import StringIO
+from itertools import tee
+
+class Termcolor:
+    red = '\033[1;31m'
+    green = '\033[1;32m'
+    yellow = '\033[1;33m'
+    blue = '\033[1;34m'
+    purple = '\033[1;35m'
+    end = '\033[0m'
 
 def is_tracked(application_folder):
     if not isfile(join(application_folder, 'Makefile')):
@@ -53,33 +48,47 @@ def is_tracked(application_folder):
     else:
         return True
 
-def get_lines(readline, prefix):
+def get_results_and_output_from(fd):
+    results_prefix = 'Building for '
+    output_prefix = 'Building application '
+    prev_results = False
+    result = ['']
+    output = StringIO()
     while 1:
-        result = readline()
-        if not result:
+        line = fd.readline()
+        if not line:
+            if prev_results:
+                yield (' .. '.join(result[:-1]), result[-1], output)
             break
-        elif not result.startswith(prefix):
-            continue
-
-        result = result[len(prefix):].rstrip().split(' .. ')[::-1]
-        if (len(result) > 1) and ('success' in result[0] or 'failed' in result[0]):
-            stdout.write('.')
-            stdout.flush()
-            yield (' .. '.join(result[:-1]), result[-1])
+        elif line.startswith(results_prefix):
+            read_more_output = False
+            if prev_results:
+                yield (' .. '.join(result[:-1]), result[-1], output)
+            prev_results = True
+            result = line[len(results_prefix):].rstrip().split(' .. ')[::-1]
+            if (len(result) > 1) and ('success' in result[0] or 'failed' in result[0]):
+                stdout.write('.')
+                stdout.flush()
+        elif line.startswith(output_prefix):
+            output = StringIO()
+            output.write(line)
+            read_more_output = True
+        elif read_more_output:
+            output.write(line)
 
 def _get_common_user(common):
     return [f for f in check_output(r'grep -l "{}" cpu/*/Makefile* boards/*/Makefile*'.format(common),
-            shell=True).split() if "common" not in f]
+            shell=True).split() if 'common' not in f]
 
 def _get_boards_from_files(files):
     boards = set()
-    if any("boards/" in s for s in files):
+    if any('boards/' in s for s in files):
         for f in files:
-            if "boards/" not in f:
+            if 'boards/' not in f:
                 continue
-            board = re.sub(r"^boards/([^/]+)/.*$", r"\1", f)
+            board = re.sub(r'^boards/([^/]+)/.*$', r'\1', f)
 
-            if "common" in board:
+            if 'common' in board:
                 boards |= _get_boards_from_files(_get_common_user(board))
             else:
                 boards |= { board }
@@ -89,14 +98,14 @@ def _get_boards_from_files(files):
 def _get_cpus_from_files(files):
     cpus = set()
 
-    if any("cpu/" in s for s in files):
+    if any('cpu/' in s for s in files):
         for f in files:
-            if "cpu/" not in f:
+            if 'cpu/' not in f:
                 continue
 
-            cpu = re.sub(r"^cpu/([^/]+)/.*", r"\1", f)
+            cpu = re.sub(r'^cpu/([^/]+)/.*', r'\1', f)
 
-            if "common" in cpu:
+            if 'common' in cpu:
                 cpus |= _get_cpus_from_files(_get_common_user(cpu))
             else:
                 cpus |= { cpu }
@@ -108,8 +117,8 @@ def is_updated(application_folder, subprocess_env):
         if base_branch == '':
             return True
 
-        if ".travis.yml" in diff_files or \
-           any("dist/" in s for s in diff_files):
+        if '.travis.yml' in diff_files or \
+           any('dist/' in s for s in diff_files):
             return True
 
         boards_changes = set()
@@ -125,7 +134,7 @@ def is_updated(application_folder, subprocess_env):
             app_files = set()
 
             for board in boards_changes:
-                env = { "BOARD": board }
+                env = { 'BOARD': board }
                 env.update(subprocess_env)
                 tmp = check_output(('make', 'info-files'), stderr=null,
                                          cwd=application_folder, env=env)
@@ -142,59 +151,123 @@ def is_updated(application_folder, subprocess_env):
     except CalledProcessError as e:
         return True
 
-for folder in ('examples', 'tests'):
-    print('Building all applications in: \033[1;34m{}\033[0m'.format(folder))
+def build_all():
+    riotbase = environ.get('RIOTBASE') or abspath(join(dirname(abspath(__file__)), '../' * 3))
+    for folder in ('examples', 'tests'):
+        print('Building all applications in: {}'.format(colorize_str(folder, Termcolor.blue)))
 
-    applications = listdir(join(riotbase, folder))
-    applications = filter(lambda app: is_tracked(join(riotbase, folder, app)), applications)
-    applications = sorted(applications)
+        applications = listdir(join(riotbase, folder))
+        applications = filter(lambda app: is_tracked(join(riotbase, folder, app)), applications)
+        applications = sorted(applications)
 
-    subprocess_env = environ.copy()
-    subprocess_env['RIOT_DO_RETRY'] = '1'
+        subprocess_env = environ.copy()
+        subprocess_env['RIOT_DO_RETRY'] = '1'
+        subprocess_env['BUILDTEST_VERBOSE'] = '1'
 
-    for nth, application in enumerate(applications, 1):
-        stdout.write('\tBuilding application: \033[1;34m{}\033[0m ({}/{}) '.format(application, nth, len(applications)))
-        stdout.flush()
-        try:
-            if not is_updated(join(riotbase, folder, application), subprocess_env):
-                print("\033[1;33m(skipped)\033[0m")
-                skipped.append(application)
-                continue
-            subprocess = Popen(('make', 'buildtest'),
-                               bufsize=1, stdin=null, stdout=PIPE, stderr=null,
-                               cwd=join(riotbase, folder, application),
-                               env=subprocess_env)
+        for nth, application in enumerate(applications, 1):
+            stdout.write('\tBuilding application: {} ({}/{}) '.format(colorize_str(application, Termcolor.blue), nth, len(applications)))
+            stdout.flush()
+            try:
+                if not is_updated(join(riotbase, folder, application), subprocess_env):
+                    print(colorize_str('(skipped)', Termcolor.yellow))
+                    skipped.append(application)
+                    continue
+                subprocess = Popen(('make', 'buildtest'),
+                                   bufsize=1, stdin=null, stdout=PIPE, stderr=null,
+                                   cwd=join(riotbase, folder, application),
+                                   env=subprocess_env)
+
+                results, results_with_output = tee(get_results_and_output_from(subprocess.stdout))
+                results = groupby(sorted(results), lambda (outcome, board, output): outcome)
+                results_with_output = filter(lambda (outcome, board, output): output.getvalue(), results_with_output)
+                failed_with_output = filter(lambda (outcome, board, output): 'failed' in outcome, results_with_output)
+                success_with_output = filter(lambda (outcome, board, output): 'success' in outcome, results_with_output)
+                print()
+                for group, results in results:
+                    print('\t\t{}: {}'.format(group, ', '.join(sorted(board for outcome, board, output in results))))
+                returncode = subprocess.wait()
+                if success_with_output:
+                    warnings.append((application, success_with_output))
+                if returncode == 0:
+                    success.append(application)
+                else:
+                    failed.append(application)
+                    errors.append((application, failed_with_output))
+            except Exception, e:
+                print('\n\t\tException: {}'.format(e))
+                exceptions.append(application)
+            finally:
+                try:
+                    subprocess.kill()
+                except:
+                    pass
+
+def colorize_str(string, color):
+    return '%s%s%s' % (color, string, Termcolor.end)
+
+def print_output_for(buf, name, color):
+    if buf:
+        print('%s:' % name)
+        for application, details in buf:
+            for outcome, board, output in details:
+                print()
+                print(colorize_str('%s:%s:' % (application, board), color))
+                print('%s'  % output.getvalue())
+
+def print_outcome(outputListDescription):
+    print()
+    print('Outcome:')
+    for color, group, name in outputListDescription:
+        applications = group
+        if applications:
+            print('\t{}{}{}: {}'.format(color, name, Termcolor.end, ', '.join(applications)))
+
+def print_num_of_errors_and_warnings():
+    stdout.write('Errors: ')
+    if errors:
+        num_of_errors = sum(map(lambda x: len(x[1]), errors))
+        stdout.write('%s' % colorize_str(str(num_of_errors), Termcolor.red))
+    else:
+        stdout.write('0')
+    stdout.write(' Warnings: ')
+    if warnings:
+        num_of_warnings = sum(map(lambda x: len(x[1]), warnings))
+        stdout.write('%s' % colorize_str(str(num_of_warnings), Termcolor.yellow))
+    else:
+        stdout.write('0')
+    stdout.write('\n')
+
+
+if __name__ == '__main__':
+    success = []
+    failed = []
+    skipped = []
+    exceptions = []
+    warnings = []
+    errors = []
+    null = open(devnull, 'w', 0)
+
+    if len(argv) > 1:
+        base_branch = argv[1]
+        diff_files = check_output(('git', 'diff', '--name-only', base_branch, 'HEAD'))
+        diff_files = set(diff_files.split())
+    else:
+        base_branch = ''
 
-            lines = get_lines(subprocess.stdout.readline, 'Building for ')
-            lines = groupby(sorted(lines), lambda (outcome, board): outcome)
+    build_all()
 
-            print()
-            for group, results in lines:
-                print('\t\t{}: {}'.format(group, ', '.join(sorted(board for outcome, board in results))))
+    print_output_for(warnings, 'Warnings', Termcolor.yellow)
+    print_output_for(errors, 'Errors', Termcolor.red)
 
-            returncode = subprocess.wait()
-            if returncode == 0:
-                success.append(application)
-            else:
-                failed.append(application)
-        except Exception, e:
-            print('\n\t\tException: {}'.format(e))
-            exceptions.append(application)
-        finally:
-            try:
-                subprocess.kill()
-            except:
-                pass
-
-print('Outcome:')
-for color, group in (('3', 'skipped'), ('2', 'success'), ('1', 'failed'), ('4', 'exceptions')):
-    applications = locals()[group]
-    if applications:
-        print('\t\033[1;3{}m{}\033[0m: {}'.format(color, group, ', '.join(applications)))
-
-if exceptions:
-    exit(2)
-elif failed:
-    exit(1)
-else:
-    exit(0)
+    outputListDescription = [(Termcolor.yellow, skipped, 'skipped'), (Termcolor.green, success, 'success'),
+                             (Termcolor.red, failed, 'failed'), (Termcolor.blue, exceptions, 'exceptions')]
+    print_outcome(outputListDescription)
+
+    print_num_of_errors_and_warnings()
+
+    if exceptions:
+        exit(2)
+    elif failed:
+        exit(1)
+    else:
+        exit(0)