diff --git a/testing/ccl/APKBUILD b/testing/ccl/APKBUILD
new file mode 100644
index 0000000000000000000000000000000000000000..995e3d0244f59083b6e4716f4df42a78d56b5798
--- /dev/null
+++ b/testing/ccl/APKBUILD
@@ -0,0 +1,88 @@
+# Contributor: rubicon <rubicon@mailo.com>
+# Maintainer: rubicon <rubicon@mailo.com>
+pkgname=ccl
+pkgver=1.12.1
+pkgrel=0
+pkgdesc="Clozure Lisp compiler"
+url="https://github.com/Clozure/ccl"
+arch="x86_64"
+license="Apache-2.0"
+makedepends="linux-headers m4"
+subpackages="$pkgname-dev $pkgname-doc"
+_testsgitrev=0478abddb34dbc16487a1975560d8d073a988060
+source="$pkgname-$pkgver.tar.gz::https://github.com/Clozure/ccl/releases/download/v$pkgver/ccl-$pkgver-linuxx86.tar.gz
+	https://github.com/Clozure/ccl-tests/archive/$_testsgitrev/ccl-$pkgver-tests.tar.gz
+	ccl.sh
+	musl-fixes.patch
+	makefile64.patch
+	"
+builddir="$srcdir/$pkgname"
+_testsdir="$srcdir/$pkgname-tests-$_testsgitrev"
+
+build() {
+	msg "Rebuilding lisp kernel"
+	make -j1 -C lisp-kernel/linuxx8664 clean all
+
+	msg "Rebuilding heap image"
+	./lx86cl64 --no-init --quiet --batch \
+		-e '(ccl:rebuild-ccl :clean t)' \
+		-e '(ccl:quit)'
+}
+
+check() {
+	cd "$_testsdir"
+	make clean
+
+	# Skip ANSI tests, as there are 21679 of them and
+	# we just want to know if CCL compiled successfully.
+	# Besides that, 4 tests fail: CL-TEST::ACOS.6, ACOS.8,
+	# CL-TEST::COMPILE-FILE.2, and COMPILE-FILE.2A.
+	"$builddir"/lx86cl64 --no-init --batch \
+		--load "load.lisp" \
+		-e '(run-tests :ansi nil :exit t :verbose t)'
+}
+
+package() {
+	mkdir -vp "$pkgdir"/usr/bin \
+		"$pkgdir"/usr/lib/ccl \
+		"$pkgdir"/usr/share/ccl \
+		"$pkgdir"/usr/share/doc
+
+	install -Dv "$srcdir"/ccl.sh "$pkgdir"/usr/bin/ccl
+	cp -av	compiler level-* lib* lisp-kernel objc-bridge \
+		tools xdump x86-headers64 lx86cl64* \
+		"$pkgdir"/usr/lib/ccl/
+	cp -av	examples scripts "$pkgdir"/usr/share/ccl/
+	cp -av	doc "$pkgdir"/usr/share/doc/ccl
+	cp -av	README.md LICENSE "$pkgdir"/usr/share/doc/ccl/
+}
+
+dev() {
+	default_dev
+
+	# Don't move examples to the -dev subpackage
+	local file; for file in $(find "$subpkgdir"/usr/share -type f); do
+		file=${file#$subpkgdir/}
+		mv -v "$subpkgdir"/"$file" "$pkgdir"/"$file"
+		rmdir	-vp "$subpkgdir"/"${file%/*}" \
+			--ignore-fail-on-non-empty
+	done
+
+	local file; for file in $(find "$pkgdir"/usr/lib/ccl \
+		-type f \( \
+		-name '*.o' -o \
+		-name '*.*fsl' \))
+	do
+		file=${file#$pkgdir/}
+		amove "$file"
+	done
+
+}
+
+sha512sums="
+7a4ab6bbb11e1ed3a13512f03626d21b6e97ea8e1f4e34647272fab24ea37c8e54b5471f9f20ad1fffacadb9825ec3b79e72fa9d27c426e01eac7bd3601e62c8  ccl-1.12.1.tar.gz
+eb6f8c22a811841747de4aab5645dae2a19bc077a19ade39324d1cf29beb2eb16c3a1e5c7ef8cea2da750da95795ccd70bb3f74fd4b35461d435f10f2f58a499  ccl-1.12.1-tests.tar.gz
+4e441a81d4ae6365fc61b3287492d743c7757529d921508990f5251fbe22d876cf478321b1c2ac22eaefedd1954070f9b72e3d530b15d53c4cebc633ab9a411f  ccl.sh
+6ec343066aa4d1699925630795808e1b8eb4fad0fcca499db2bc5da31cb5aff8893fa63ee9f0d0807fe46b5321119485efbff0f4bef515a9149f134ff31a6617  musl-fixes.patch
+ee376f5102ccf07ed579503b701ac9b2940c9872b61abe0a95aa05083cb4a37ed2c85c11d040883ea890ff3b807199bf02a1ad0e6d57a2b6bd7a0f99d8a6f56a  makefile64.patch
+"
diff --git a/testing/ccl/ccl.sh b/testing/ccl/ccl.sh
new file mode 100644
index 0000000000000000000000000000000000000000..508e09b39f191e55e43f2e1fb22285b8cbdd6fd7
--- /dev/null
+++ b/testing/ccl/ccl.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /usr/lib/ccl/lx86cl64 "$@"
diff --git a/testing/ccl/makefile64.patch b/testing/ccl/makefile64.patch
new file mode 100644
index 0000000000000000000000000000000000000000..373cb960740de638e876ddf7dee0b5d6890549ee
--- /dev/null
+++ b/testing/ccl/makefile64.patch
@@ -0,0 +1,28 @@
+fortify-headers adds a UD2 instruction because the compiler cannot
+determine the size of "spjump_start" that is used with memmove
+in the remap_spjump() function of pmcl-kernel.c. Disabling this
+allows CCL to run without encountering an "Illegal instruction".
+
+Use -no-pie to suppress compiler warnings about "relocation in
+read-only section `.text'" and "creating DT_TEXTREL in a PIE".
+
+--- a/lisp-kernel/linuxx8664/Makefile
++++ b/lisp-kernel/linuxx8664/Makefile
+@@ -23,7 +23,7 @@
+ M4FLAGS = -DLINUX -DX86 -DX8664 -DHAVE_TLS
+ CDEFINES = -DLINUX -D_REENTRANT -DX86 -DX8664 -D_GNU_SOURCE -DHAVE_TLS  -DVC_REVISION=$(VC_REVISION) #-DDISABLE_EGC -DUSE_FUTEX
+ CDEBUG = -g
+-COPT = -O2
++COPT = -O2 -U_FORTIFY_SOURCE
+ # Once in a while, -Wformat says something useful.  The odds are against that,
+ # however.
+ WFORMAT = -Wno-format
+@@ -74,7 +74,7 @@
+ USE_LINK_MAP = # -T ./elf_x86_64.x
+ 
+ ../../lx86cl64:	$(KSPOBJ) $(KERNELOBJ) $(DEBUGOBJ) Makefile  $(LINK_MAP)
+-	$(CC)  -m64 $(CDEBUG)  -Wl,--export-dynamic $(HASH_STYLE) -o $@ $(USE_LINK_MAP) $(KSPOBJ) $(KERNELOBJ) $(DEBUGOBJ) -Wl,--no-as-needed $(OSLIBS)
++	$(CC)  -m64 $(CDEBUG)  -Wl,--export-dynamic $(HASH_STYLE) -Wl,--no-pie -o $@ $(USE_LINK_MAP) $(KSPOBJ) $(KERNELOBJ) $(DEBUGOBJ) -Wl,--no-as-needed $(OSLIBS)
+ 
+ 
+ $(SPOBJ): $(SPINC)
diff --git a/testing/ccl/musl-fixes.patch b/testing/ccl/musl-fixes.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5fd9c1ae96a0e8bac5f5ea99addf20cd48e90d9f
--- /dev/null
+++ b/testing/ccl/musl-fixes.patch
@@ -0,0 +1,61 @@
+Patch-Source: https://github.com/void-linux/void-packages/raw/master/srcpkgs/ccl/patches/musl-fixes.patch
+
+--- a/lisp-kernel/lisp-debug.c	2015-11-07 07:10:11.000000000 +1100
++++ b/lisp-kernel/lisp-debug.c	2016-12-18 10:35:29.070710875 +1100
+@@ -36,6 +36,11 @@
+ #include <dlfcn.h>
+ #endif
+ 
++#ifndef __GLIBC__
++struct _libc_xmmreg {
++  unsigned int element[4];
++};
++#endif
+ 
+ FILE *dbgout = NULL, *dbgin=NULL;
+ 
+--- a/lisp-kernel/pmcl-kernel.c	2015-11-07 07:10:11.000000000 +1100
++++ b/lisp-kernel/pmcl-kernel.c	2016-12-18 10:34:36.854708181 +1100
+@@ -36,7 +36,7 @@
+ #endif
+ 
+ #ifdef LINUX
+-#ifndef ANDROID
++#ifdef __GLIBC__
+ #include <mcheck.h>
+ #endif
+ #include <dirent.h>
+@@ -1702,6 +1702,10 @@
+ ensure_gs_available(char *progname)
+ {
+   LispObj fs_addr = 0L, gs_addr = 0L, cur_thread = (LispObj)pthread_self();
++  #ifdef __GLIBC__
+   char *gnu_get_libc_version(void);
++  #else
++  #define gnu_get_libc_version() ""
++  #endif
+   /*
+    * According arch_prctl(2), there's no function prototype for
+--- a/lisp-kernel/thread_manager.c	2015-11-07 07:10:11.000000000 +1100
++++ b/lisp-kernel/thread_manager.c	2016-12-18 10:32:35.095701899 +1100
+@@ -185,7 +185,7 @@
+ void
+ set_thread_affinity(TCR *target, unsigned cpuno)
+ {
+-#ifdef LINUX
++#ifdef __GLIBC__
+ #ifndef ANDROID                 /* too useful to be in Android ... */
+   pthread_t thread = (pthread_t)(target->osid);
+   cpu_set_t mask;
+--- a/lisp-kernel/x86-exceptions.c	2015-11-07 07:10:11.000000000 +1100
++++ b/lisp-kernel/x86-exceptions.c	2016-12-18 10:30:47.952696372 +1100
+@@ -29,7 +29,9 @@
+ #ifdef LINUX
+ #include <strings.h>
+ #include <sys/mman.h>
++#ifdef __GLIBC__
+ #include <fpu_control.h>
++#endif
+ #include <linux/prctl.h>
+ #endif
+ #ifdef DARWIN