name: default
 
 steps:
-- name: Build
+- name: Projects
   image: abcminiuser/docker-avr8-toolchain
   commands:
-  - make --quiet all
+  - make -j --quiet all
 
 - name: Bootloaders
   image: abcminiuser/docker-avr8-toolchain
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null
 
 # identical OBJDIR directory, we need to enforce the use of this project's object file
 # directory as the one where the build object files are to be stored, by giving it a
 # path relative to the current folder.
-OBJDIR      := ./obj
+OBJDIR      := ./xpb-obj
 
 # Include LUFA-specific DMBS extension modules
 DMBS_LUFA_PATH ?= $(LUFA_PATH)/Build/LUFA
 
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-# Need to special-case building without a per-project object directory
-ifeq ($(OBJDIR),)
-   # If no target specified, force "clean all" and disallow parallel build
-   ifeq ($(MAKECMDGOALS),)
-      MAKECMDGOALS := clean all
-      .NOTPARALLEL:
-   endif
-
-   # If one of the targets is to build, force "clean" beforehand and disallow parallel build
-   ifneq ($(findstring all, $(MAKECMDGOALS)),)
-      MAKECMDGOALS := clean $(MAKECMDGOALS)
-      .NOTPARALLEL:
-   endif
-endif
+# Build each directory sequentially, even if we are building using multiple
+# cores within each project
+.NOTPARALLEL:
 
 %: $(PROJECT_DIRECTORIES)
        @echo . > /dev/null