diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index 7fd99f0..360ec7c 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -244,6 +244,7 @@ struct slbt_common_ctx {
 	char **				cargv;
 	char **				targv;
 	char *				libname;
+	const char *			ccwrap;
 	const char *			target;
 	const char *			output;
 	const char *			shrext;
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index a898205..da8bc76 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -263,12 +263,14 @@ static int slbt_split_argv(
 	bool				flast;
 	bool				fcopy;
 	size_t				size;
+	const char *			base;
 	struct argv_meta *		meta;
 	struct argv_entry *		entry;
 	struct argv_entry *		mode;
 	struct argv_entry *		config;
 	struct argv_entry *		finish;
 	struct argv_entry *		features;
+	struct argv_entry *		ccwrap;
 	const struct argv_option **	popt;
 	const struct argv_option **	optout;
 	const struct argv_option *	optv[SLBT_OPTV_ELEMENTS];
@@ -311,7 +313,7 @@ static int slbt_split_argv(
 	}
 
 	/* missing all of --mode, --config, --features, and --finish? */
-	mode = config = finish = features = 0;
+	mode = config = finish = features = ccwrap = 0;
 
 	for (entry=meta->entries; entry->fopt; entry++)
 		if (entry->tag == TAG_MODE)
@@ -322,6 +324,8 @@ static int slbt_split_argv(
 			finish = entry;
 		else if (entry->tag == TAG_FEATURES)
 			features = entry;
+		else if (entry->tag == TAG_CCWRAP)
+			ccwrap = entry;
 
 	argv_free(meta);
 
@@ -422,8 +426,8 @@ static int slbt_split_argv(
 	argv = sargv->dargv;
 
 	/* allocate split vectors */
-	if ((sargv->targv = calloc(2*(argc+1),sizeof(char *))))
-		sargv->cargv = sargv->targv + argc + 1;
+	if ((sargv->targv = calloc(2*(argc+2),sizeof(char *))))
+		sargv->cargv = sargv->targv + argc + 2;
 	else
 		return -1;
 
@@ -441,13 +445,32 @@ static int slbt_split_argv(
 	for (i=0; i<ctx.unitidx; i++)
 		sargv->targv[i] = argv[i];
 
+	/* split vector marks */
+	targv = sargv->targv + i;
+	cargv = sargv->cargv;
+
+	/* known wrappers */
+	if (ctx.unitidx && !ccwrap) {
+		if ((base = strrchr(argv[i],'/')))
+			base++;
+		else if ((base = strrchr(argv[i],'\\')))
+			base++;
+		else
+			base = argv[i];
+
+		if (!strcmp(base,"ccache")
+				|| !strcmp(base,"distcc")
+				|| !strcmp(base,"compiler")
+				|| !strcmp(base,"purify")) {
+			*targv++ = "--ccwrap";
+			*targv++ = argv[i++];
+		}
+	}
+
 	/* split vectors: legacy mixture */
 	for (optout=optv; optout[0]->tag != TAG_OUTPUT; optout++)
 		(void)0;
 
-	targv = sargv->targv + i;
-	cargv = sargv->cargv;
-
 	for (; i<argc; i++) {
 		if (argv[i][0] != '-') {
 			if (argv[i+1] && (argv[i+1][0] == '+')
@@ -1332,6 +1355,10 @@ int slbt_get_driver_ctx(
 
 					break;
 
+				case TAG_CCWRAP:
+					cctx.ccwrap = entry->arg;
+					break;
+
 				case TAG_IMPLIB:
 					if (!strcmp("idata",entry->arg)) {
 						cctx.drvflags |= SLBT_DRIVER_IMPLIB_IDATA;
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 69b3675..19b4f46 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -35,6 +35,7 @@ enum app_tags {
 	TAG_DEPS,
 	TAG_SILENT,
 	TAG_TAG,
+	TAG_CCWRAP,
 	TAG_VERBOSE,
 	TAG_TARGET,
 	TAG_HOST,
diff --git a/src/logic/slbt_exec_compile.c b/src/logic/slbt_exec_compile.c
index cad5bd8..8efa777 100644
--- a/src/logic/slbt_exec_compile.c
+++ b/src/logic/slbt_exec_compile.c
@@ -43,6 +43,7 @@ static int slbt_exec_compile_finalize_argument_vector(
 	char **		cap;
 	char **		src;
 	char **		dst;
+	char *		ccwrap;
 
 	/* vector size */
 	base = ectx->argv;
@@ -89,12 +90,17 @@ static int slbt_exec_compile_finalize_argument_vector(
 		}
 	}
 
-	/* (program name) */
-	dst = &base[1];
+	/* program name, ccwrap */
+	if ((ccwrap = (char *)dctx->cctx->ccwrap)) {
+		base[1] = base[0];
+		base[0] = ccwrap;
+		base++;
+	}
 
 	/* join all other args */
 	src = aargv;
 	cap = aarg;
+	dst = &base[1];
 
 	for (; src<cap; )
 		*dst++ = *src++;
@@ -126,6 +132,7 @@ int  slbt_exec_compile(
 {
 	int				ret;
 	char *				fpic;
+	char *				ccwrap;
 	struct slbt_exec_ctx *		actx = 0;
 	const struct slbt_common_ctx *	cctx = dctx->cctx;
 
@@ -153,7 +160,8 @@ int  slbt_exec_compile(
 		}
 
 	/* compile mode */
-	ectx->program = ectx->compiler;
+	ccwrap        = (char *)cctx->ccwrap;
+	ectx->program = ccwrap ? ccwrap : ectx->compiler;
 	ectx->argv    = ectx->cargv;
 
 	/* -fpic */
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c
index 0bfe7e0..5f94038 100644
--- a/src/logic/slbt_exec_link.c
+++ b/src/logic/slbt_exec_link.c
@@ -588,6 +588,7 @@ static int slbt_exec_link_finalize_argument_vector(
 	char **		dst;
 	char *		arg;
 	char *		dot;
+	char *		ccwrap;
 	const char *	arsuffix;
 
 	/* vector size */
@@ -717,12 +718,17 @@ static int slbt_exec_link_finalize_argument_vector(
 		}
 	}
 
-	/* (program name) */
-	dst = &base[1];
+	/* program name, ccwrap */
+	if ((ccwrap = (char *)dctx->cctx->ccwrap)) {
+		base[1] = base[0];
+		base[0] = ccwrap;
+		base++;
+	}
 
 	/* join object args */
 	src = oargv;
 	cap = oarg;
+	dst = &base[1];
 
 	for (; src<cap; )
 		*dst++ = *src++;
@@ -1254,6 +1260,7 @@ static int slbt_exec_link_create_library(
 	int	fdcwd;
 	char ** parg;
 	char ** xarg;
+	char *	ccwrap;
 	char	cwd    [PATH_MAX];
 	char	output [PATH_MAX];
 	char	soname [PATH_MAX];
@@ -1399,8 +1406,9 @@ static int slbt_exec_link_create_library(
 		return SLBT_NESTED_ERROR(dctx);
 
 	/* using alternate argument vector */
+	ccwrap        = (char *)dctx->cctx->ccwrap;
 	ectx->argv    = depsmeta.altv;
-	ectx->program = depsmeta.altv[0];
+	ectx->program = ccwrap ? ccwrap : depsmeta.altv[0];
 
 	/* sigh */
 	if (slbt_exec_link_finalize_argument_vector(dctx,ectx))
@@ -1432,6 +1440,7 @@ static int slbt_exec_link_create_executable(
 	char ** parg;
 	char ** xarg;
 	char *	base;
+	char *	ccwrap;
 	char	cwd    [PATH_MAX];
 	char	output [PATH_MAX];
 	char	wrapper[PATH_MAX];
@@ -1531,8 +1540,9 @@ static int slbt_exec_link_create_executable(
 		return SLBT_NESTED_ERROR(dctx);
 
 	/* using alternate argument vector */
+	ccwrap        = (char *)dctx->cctx->ccwrap;
 	ectx->argv    = depsmeta.altv;
-	ectx->program = depsmeta.altv[0];
+	ectx->program = ccwrap ? ccwrap : depsmeta.altv[0];
 
 	/* executable wrapper symlink */
 	if ((size_t)snprintf(wraplnk,sizeof(wraplnk),"%s.exe.wrapper",
diff --git a/src/skin/slbt_skin_default.c b/src/skin/slbt_skin_default.c
index 7678f2a..6300d8f 100644
--- a/src/skin/slbt_skin_default.c
+++ b/src/skin/slbt_skin_default.c
@@ -56,6 +56,15 @@ const struct argv_option slbt_default_options[] = {
 				"and/or static archive. option syntax is "
 				"--legabits[=%s]"},
 
+	{"ccwrap",		0,TAG_CCWRAP,ARGV_OPTARG_REQUIRED,0,0,
+				"<program>",
+				"use %s as a compiler driver wrapper; "
+				"for the purpose of compatibility, "
+				"this switch may be omitted for known "
+				"wrappers (ccache, compiler, distcc, "
+				"and purify) when immediately followed "
+				"by the compiler argument."},
+
 	{"no-warnings",		0,TAG_WARNINGS,ARGV_OPTARG_NONE,0,0,0,""},
 
 	{"preserve-dup-deps",	0,TAG_DEPS,ARGV_OPTARG_NONE,0,0,0,