diff --git a/Makefile b/Makefile
index 47b4a5f65e9bcc77a8db9f1a6861f21c70f9325f..5ebefa21c7580a0c06c3809d241668cce4bb04dc 100644
--- a/Makefile
+++ b/Makefile
@@ -4,15 +4,6 @@ LC_ALL:=C
 LANG:=C
 export LC_ALL LANG
 
-
-# initialize (possibly already user set) directory variables
-GLUON_SITEDIR ?= site
-GLUON_TMPDIR ?= tmp
-GLUON_OUTPUTDIR ?= output
-
-GLUON_IMAGEDIR ?= $(GLUON_OUTPUTDIR)/images
-GLUON_PACKAGEDIR ?= $(GLUON_OUTPUTDIR)/packages
-
 # check for spaces & resolve possibly relative paths
 define mkabspath
  ifneq (1,$(words [$($(1))]))
@@ -21,14 +12,8 @@ define mkabspath
  override $(1) := $(abspath $($(1)))
 endef
 
+GLUON_SITEDIR ?= site
 $(eval $(call mkabspath,GLUON_SITEDIR))
-$(eval $(call mkabspath,GLUON_TMPDIR))
-$(eval $(call mkabspath,GLUON_OUTPUTDIR))
-$(eval $(call mkabspath,GLUON_IMAGEDIR))
-$(eval $(call mkabspath,GLUON_PACKAGEDIR))
-
-export GLUON_TMPDIR GLUON_IMAGEDIR GLUON_PACKAGEDIR GLUON_DEVICES
-
 
 $(GLUON_SITEDIR)/site.mk:
 	$(error No site configuration was found. Please check out a site configuration to $(GLUON_SITEDIR))
@@ -37,11 +22,27 @@ include $(GLUON_SITEDIR)/site.mk
 
 GLUON_RELEASE ?= $(error GLUON_RELEASE not set. GLUON_RELEASE can be set in site.mk or on the command line)
 
+# initialize (possibly already user set) directory variables
+GLUON_TMPDIR ?= tmp
+GLUON_OUTPUTDIR ?= output
+GLUON_IMAGEDIR ?= $(GLUON_OUTPUTDIR)/images
+GLUON_PACKAGEDIR ?= $(GLUON_OUTPUTDIR)/packages
+GLUON_TARGETSDIR ?= targets
+GLUON_PATCHESDIR ?= patches
+
+$(eval $(call mkabspath,GLUON_TMPDIR))
+$(eval $(call mkabspath,GLUON_OUTPUTDIR))
+$(eval $(call mkabspath,GLUON_IMAGEDIR))
+$(eval $(call mkabspath,GLUON_PACKAGEDIR))
+$(eval $(call mkabspath,GLUON_TARGETSDIR))
+$(eval $(call mkabspath,GLUON_PATCHESDIR))
+
 GLUON_MULTIDOMAIN ?= 0
 GLUON_WLAN_MESH ?= 11s
 GLUON_DEBUG ?= 0
 
-export GLUON_RELEASE GLUON_REGION GLUON_MULTIDOMAIN GLUON_WLAN_MESH GLUON_DEBUG
+export GLUON_RELEASE GLUON_REGION GLUON_MULTIDOMAIN GLUON_WLAN_MESH GLUON_DEBUG GLUON_DEVICES \
+	 GLUON_TARGETSDIR GLUON_PATCHESDIR GLUON_TMPDIR GLUON_IMAGEDIR GLUON_PACKAGEDIR
 
 show-release:
 	@echo '$(GLUON_RELEASE)'
@@ -70,7 +71,7 @@ GLUON_TARGET_$$(gluon_target)_BOARD := $(1)
 GLUON_TARGET_$$(gluon_target)_SUBTARGET := $(2)
 endef
 
-include targets/targets.mk
+include $(GLUON_TARGETSDIR)/targets.mk
 
 
 OPENWRTMAKE = $(MAKE) -C openwrt
diff --git a/scripts/copy_output.sh b/scripts/copy_output.sh
index d84d5fe2c6fd0009bf8e371dae898317ec20bf29..897a3f83c11be426a3d92cc438e10e79a8020e9d 100755
--- a/scripts/copy_output.sh
+++ b/scripts/copy_output.sh
@@ -2,7 +2,7 @@
 
 set -e
 
-[ "$GLUON_IMAGEDIR" -a "$GLUON_PACKAGEDIR" -a "$OPENWRT_TARGET" -a "$GLUON_RELEASE" -a "$GLUON_SITEDIR" ] || exit 1
+[ "$GLUON_IMAGEDIR" -a "$GLUON_PACKAGEDIR" -a "$OPENWRT_TARGET" -a "$GLUON_RELEASE" -a "$GLUON_SITEDIR" -a "$GLUON_TARGETSDIR" ] || exit 1
 
 
 default_factory_ext='.bin'
@@ -191,7 +191,7 @@ no_opkg() {
 }
 
 
-. targets/"$1"; copy
+. "${GLUON_TARGETSDIR}/$1"; copy
 
 # Copy opkg repo
 if [ -z "$no_opkg" -a -z "$GLUON_DEVICES" ]; then
diff --git a/scripts/generate_manifest.sh b/scripts/generate_manifest.sh
index 85e3ef5300eacc47c1cd67d5543d4ff882fb4ffd..04494a37f91c40c8d1704313f7721dc5e4490c53 100755
--- a/scripts/generate_manifest.sh
+++ b/scripts/generate_manifest.sh
@@ -2,7 +2,7 @@
 
 set -e
 
-[ "$GLUON_IMAGEDIR" -a "$GLUON_RELEASE" -a "$GLUON_SITEDIR" ] || exit 1
+[ "$GLUON_IMAGEDIR" -a "$GLUON_RELEASE" -a "$GLUON_SITEDIR" -a "$GLUON_TARGETSDIR" ] || exit 1
 
 
 default_sysupgrade_ext='.bin'
@@ -110,4 +110,4 @@ sysupgrade() {
 	fi
 }
 
-. targets/"$1"; generate
+. "${GLUON_TARGETSDIR}/$1"; generate
diff --git a/scripts/patch.sh b/scripts/patch.sh
index 61d5f45570d6b326c4c4753b42bca12530c44bf3..082ca1fce2a39072aefd680998752858baf27375 100755
--- a/scripts/patch.sh
+++ b/scripts/patch.sh
@@ -3,6 +3,8 @@
 set -e
 shopt -s nullglob
 
+[ "$GLUON_TMPDIR" -a "$GLUON_PATCHESDIR" ] || exit 1
+
 . scripts/modules.sh
 
 
@@ -19,7 +21,7 @@ for module in $GLUON_MODULES; do
 	git clone -s -b base --single-branch "$GLUONDIR/$module" "$PATCHDIR" 2>/dev/null
 
 	cd "$PATCHDIR"
-	for patch in "$GLUONDIR/patches/$module"/*.patch; do
+	for patch in "${GLUON_PATCHESDIR}/$module"/*.patch; do
 		git -c user.name='Gluon Patch Manager' -c user.email='gluon@void.example.com' -c commit.gpgsign=false am --whitespace=nowarn --committer-date-is-author-date "$patch"
 	done
 
diff --git a/scripts/target_config.sh b/scripts/target_config.sh
index 7ffa6403d7df52da5784b1192d69e9f8f71b24cb..559eabea1b0373df53769a998683fc03e4183f70 100755
--- a/scripts/target_config.sh
+++ b/scripts/target_config.sh
@@ -2,7 +2,7 @@
 
 set -e
 
-[ "$OPENWRT_TARGET" ] || exit 1
+[ "$OPENWRT_TARGET" -a "$GLUON_TARGETSDIR" ] || exit 1
 
 target="$1"
 packages=$2
@@ -74,9 +74,9 @@ packages() {
 # The sort will not only remove duplicate entries,
 # but also magically make =y entries override =m ones
 (
-	. targets/generic
+	. "${GLUON_TARGETSDIR}/generic"
 	packages $packages
 
-	. targets/"$target"
+	. "${GLUON_TARGETSDIR}/$target"
 	emit
 ) | sort -u
diff --git a/scripts/target_config_check.sh b/scripts/target_config_check.sh
index bfdc51bb0ed3d865d70a15485f53a1f3512dc0fc..3ae018441c688d65382598077c1f7b634daf8f6d 100755
--- a/scripts/target_config_check.sh
+++ b/scripts/target_config_check.sh
@@ -2,7 +2,7 @@
 
 set -e
 
-[ "$OPENWRT_TARGET" ] || exit 1
+[ "$OPENWRT_TARGET" -a "$GLUON_TARGETSDIR" ] || exit 1
 
 target="$1"
 packages=$2
@@ -92,10 +92,10 @@ packages() {
 }
 
 
-. targets/generic
+. "${GLUON_TARGETSDIR}/generic"
 packages $packages
 
-. targets/"$target"
+. "${GLUON_TARGETSDIR}/$target"
 check_devices
 
 
diff --git a/scripts/update-patches.sh b/scripts/update-patches.sh
index cb38c37d9c35cdb52222ef92c09e0efb40580b16..933d20acddf0e91d4d65ab7d6736ad138f2673cc 100755
--- a/scripts/update-patches.sh
+++ b/scripts/update-patches.sh
@@ -3,6 +3,8 @@
 set -e
 shopt -s nullglob
 
+[ "$GLUON_PATCHESDIR" ] || exit 1
+
 . scripts/modules.sh
 
 
@@ -11,14 +13,14 @@ GLUONDIR="$(pwd)"
 for module in $GLUON_MODULES; do
 	echo "--- Updating patches for module '$module' ---"
 
-	rm -rf "$GLUONDIR"/patches/"$module"
+	rm -rf "${GLUON_PATCHESDIR}/$module"
 
 	cd "$GLUONDIR"/"$module"
 
 	n=0
 	for commit in $(git rev-list --reverse --no-merges base..patched); do
 		let n=n+1
-		mkdir -p "$GLUONDIR"/patches/"$module"
-		git -c core.abbrev=40 show --pretty=format:'From: %an <%ae>%nDate: %aD%nSubject: %B' --no-renames --binary "$commit" > "$GLUONDIR/patches/$module/$(printf '%04u' $n)-$(git show -s --pretty=format:%f "$commit").patch"
+		mkdir -p "${GLUON_PATCHESDIR}/$module"
+		git -c core.abbrev=40 show --pretty=format:'From: %an <%ae>%nDate: %aD%nSubject: %B' --no-renames --binary "$commit" > "${GLUON_PATCHESDIR}/$module/$(printf '%04u' $n)-$(git show -s --pretty=format:%f "$commit").patch"
 	done
 done
diff --git a/targets/brcm2708-bcm2708 b/targets/brcm2708-bcm2708
index 1fe6f3908185b646ec3060ca03d8666225aaf81c..719a04cf59efe8156b78220686f427da79bc904b 100644
--- a/targets/brcm2708-bcm2708
+++ b/targets/brcm2708-bcm2708
@@ -1,4 +1,4 @@
-. targets/brcm2708.inc
+. "${GLUON_TARGETSDIR}/brcm2708.inc"
 
 device raspberry-pi rpi
 manifest_alias raspberry-pi-model-b-rev-2
diff --git a/targets/brcm2708-bcm2709 b/targets/brcm2708-bcm2709
index 78116f93051355da7b806edb321a5f5b096878d6..bc63212623f4da6b7d0e7dc49499b675ae625366 100644
--- a/targets/brcm2708-bcm2709
+++ b/targets/brcm2708-bcm2709
@@ -1,4 +1,4 @@
-. targets/brcm2708.inc
+. "${GLUON_TARGETSDIR}/brcm2708.inc"
 
 device raspberry-pi-2 rpi-2
 manifest_alias raspberry-pi-2-model-b-rev-1.1
diff --git a/targets/brcm2708-bcm2710 b/targets/brcm2708-bcm2710
index e523dce6e4db8d27253a38ad6f8261f1f328c02e..c8f031af6769b58e20e81d816e26e327b27388aa 100644
--- a/targets/brcm2708-bcm2710
+++ b/targets/brcm2708-bcm2710
@@ -1,3 +1,3 @@
-. targets/brcm2708.inc
+. "${GLUON_TARGETSDIR}/brcm2708.inc"
 
 device raspberry-pi-3 rpi-3
diff --git a/targets/x86-64 b/targets/x86-64
index 1a739122c84ae648a0a887f2cf5fb46b3165a0be..48d95cecc6fb61f759f55b56d954e61e284db0d9 100644
--- a/targets/x86-64
+++ b/targets/x86-64
@@ -1,4 +1,4 @@
-. targets/x86.inc
+. "${GLUON_TARGETSDIR}/x86.inc"
 
 factory_image x86-64 combined-squashfs .img.gz
 factory_image x86-64 combined-squashfs .vdi
diff --git a/targets/x86-generic b/targets/x86-generic
index 2dfc852b2b11f51b65d94b17813260ca0d57996c..2699a316c7886a7674636bc2e377f8381b50391b 100644
--- a/targets/x86-generic
+++ b/targets/x86-generic
@@ -1,4 +1,4 @@
-. targets/x86.inc
+. "${GLUON_TARGETSDIR}/x86.inc"
 
 factory_image x86-generic combined-squashfs .img.gz
 factory_image x86-generic combined-squashfs .vdi