diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index 8ca528f..40c3557 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -139,6 +139,8 @@ slbt_api int  slbt_get_exec_ctx		(const struct slbt_driver_ctx *, struct slbt_ex
 slbt_api void slbt_free_exec_ctx	(struct slbt_exec_ctx *);
 slbt_api void slbt_reset_placeholders	(struct slbt_exec_ctx *);
 
+slbt_api int  slbt_exec_compile		(const struct slbt_driver_ctx *, struct slbt_exec_ctx *);
+
 slbt_api int  slbt_map_input		(int fd, const char * path, int prot, struct slbt_input *);
 slbt_api int  slbt_unmap_input		(struct slbt_input *);
 
diff --git a/project/common.mk b/project/common.mk
index 0dcdcd6..8bc227a 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -1,6 +1,7 @@
 COMMON_SRCS = \
 	src/driver/slbt_driver_ctx.c \
 	src/driver/slbt_unit_ctx.c \
+	src/logic/slbt_exec_compile.c \
 	src/logic/slbt_exec_ctx.c \
 	src/logic/slbt_map_input.c \
 	src/skin/slbt_skin_default.c \
diff --git a/src/logic/slbt_exec_compile.c b/src/logic/slbt_exec_compile.c
new file mode 100644
index 0000000..34fc10d
--- /dev/null
+++ b/src/logic/slbt_exec_compile.c
@@ -0,0 +1,100 @@
+/*******************************************************************/
+/*  slibtool: a skinny libtool implementation, written in C        */
+/*  Copyright (C) 2016  Z. Gilboa                                  */
+/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <string.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <slibtool/slibtool.h>
+#include "slibtool_spawn_impl.h"
+
+int  slbt_exec_compile(
+	const struct slbt_driver_ctx *	dctx,
+	struct slbt_exec_ctx *		ectx)
+{
+	int			ret;
+	int			fdlibs;
+	FILE *			fout;
+	struct slbt_exec_ctx *	actx = 0;
+
+	/* context */
+	if (ectx)
+		slbt_reset_placeholders(ectx);
+	else if ((ret = slbt_get_exec_ctx(dctx,&ectx)))
+		return ret;
+	else
+		actx = ectx;
+
+	/* .libs directory */
+	if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
+		if ((fdlibs = open(ectx->ldirname,O_DIRECTORY)) >= 0)
+			close(fdlibs);
+		else if ((errno != ENOENT) || mkdir(ectx->ldirname,0777)) {
+			slbt_free_exec_ctx(actx);
+			return -1;
+		}
+	}
+
+	/* shared library object */
+	if (dctx->cctx->drvflags & SLBT_DRIVER_SHARED) {
+		if (!(dctx->cctx->drvflags & SLBT_DRIVER_ANTI_PIC)) {
+			*ectx->dpic = "-DPIC";
+			*ectx->fpic = "-fPIC";
+		}
+
+		*ectx->cass = "-c";
+		*ectx->lout[0] = "-o";
+		*ectx->lout[1] = ectx->lobjname;
+
+		if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) {
+			slbt_free_exec_ctx(actx);
+			return -1;
+		}
+	}
+
+	/* static archive object */
+	if (dctx->cctx->drvflags & SLBT_DRIVER_STATIC) {
+		slbt_reset_placeholders(ectx);
+
+		if (dctx->cctx->drvflags & SLBT_DRIVER_PRO_PIC) {
+			*ectx->dpic = "-DPIC";
+			*ectx->fpic = "-fPIC";
+		}
+
+		*ectx->cass = "-c";
+		*ectx->lout[0] = "-o";
+		*ectx->lout[1] = ectx->aobjname;;
+
+		if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) {
+			slbt_free_exec_ctx(actx);
+			return -1;
+		}
+	}
+
+	/* libtool object */
+	if (!(fout = fopen(ectx->ltobjname,"w"))) {
+		slbt_free_exec_ctx(actx);
+		return -1;
+	}
+
+	ret = fprintf(fout,
+		"# slibtool (pre-alphe) generated file\n\n"
+		"pic_object='%s'\n"
+		"non_pic_object='%s'\n",
+		(dctx->cctx->drvflags & SLBT_DRIVER_SHARED)
+			? ectx->lobjname
+			: "none",
+		(dctx->cctx->drvflags & SLBT_DRIVER_STATIC)
+			? ectx->aobjname
+			: "none");
+
+	fclose(fout);
+	slbt_free_exec_ctx(actx);
+
+	return 0;
+}