diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index 44d596e..6e8062d 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -51,6 +51,7 @@ extern "C" {
 #define SLBT_DRIVER_HEURISTICS		0x010000
 #define SLBT_DRIVER_STRICT		0x020000
 #define SLBT_DRIVER_NO_UNDEFINED	0x040000
+#define SLBT_DRIVER_MODULE		0x080000
 
 /* execution modes */
 enum slbt_mode {
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 3f7d2c5..5640453 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -480,10 +480,12 @@ static int slbt_init_link_params(struct slbt_driver_ctx_impl * ctx)
 	const char * prefix;
 	const char * base;
 	char *       dot;
+	bool         fmodule;
 
 	program = argv_program_name(ctx->cctx.targv[0]);
 	libname = 0;
 	prefix  = 0;
+	fmodule = false;
 
 	/* output */
 	if (!(ctx->cctx.output)) {
@@ -545,7 +547,10 @@ static int slbt_init_link_params(struct slbt_driver_ctx_impl * ctx)
 
 		if (!strncmp(prefix,base,strlen(prefix)))
 			libname = base;
-		else {
+		else if (ctx->cctx.drvflags & SLBT_DRIVER_MODULE) {
+			libname = base;
+			fmodule = true;
+		} else {
 			if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
 				fprintf(stderr,
 					"%s: error: output file prefix does "
@@ -558,7 +563,10 @@ static int slbt_init_link_params(struct slbt_driver_ctx_impl * ctx)
 		return 0;
 
 	/* libname alloc */
-	if (!(ctx->libname = strdup(libname + strlen(prefix))))
+	if (!fmodule)
+		libname += strlen(prefix);
+
+	if (!(ctx->libname = strdup(libname)))
 		return -1;
 
 	dot  = strrchr(ctx->libname,'.');
@@ -746,6 +754,10 @@ int slbt_get_driver_ctx(
 					cctx.drvflags |= SLBT_DRIVER_NO_UNDEFINED;
 					break;
 
+				case TAG_MODULE:
+					cctx.drvflags |= SLBT_DRIVER_MODULE;
+					break;
+
 				case TAG_SHARED:
 					cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_STATIC;
 					break;
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 80cf5f7..685c511 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -44,6 +44,7 @@ enum app_tags {
 	TAG_SHARED,
 	TAG_STATIC,
 	TAG_NO_UNDEFINED,
+	TAG_MODULE,
 	TAG_COMPILER_FLAG,
 	TAG_VERBATIM_FLAG,
 };
diff --git a/src/logic/slbt_exec_ctx.c b/src/logic/slbt_exec_ctx.c
index 5f08526..39fa26c 100644
--- a/src/logic/slbt_exec_ctx.c
+++ b/src/logic/slbt_exec_ctx.c
@@ -281,7 +281,9 @@ int  slbt_get_exec_ctx(
 		ictx->ctx.lafilename = ch;
 		ch += sprintf(ch,"%s%s%s.la",
 				ictx->ctx.ldirname,
-				dctx->cctx->settings.dsoprefix,
+				(dctx->cctx->drvflags & SLBT_DRIVER_MODULE)
+					? ""
+					: dctx->cctx->settings.dsoprefix,
 				dctx->cctx->libname)
 			+ sizeof('\0');
 
@@ -290,7 +292,9 @@ int  slbt_get_exec_ctx(
 		ictx->ctx.dsofilename = ch;
 		ch += sprintf(ch,"%s%s%s%s",
 				ictx->ctx.ldirname,
-				dctx->cctx->settings.dsoprefix,
+				(dctx->cctx->drvflags & SLBT_DRIVER_MODULE)
+					? ""
+					: dctx->cctx->settings.dsoprefix,
 				dctx->cctx->libname,
 				dctx->cctx->settings.dsosuffix)
 			+ sizeof('\0');
diff --git a/src/skin/slbt_skin_default.c b/src/skin/slbt_skin_default.c
index 7931ff7..f9f2109 100644
--- a/src/skin/slbt_skin_default.c
+++ b/src/skin/slbt_skin_default.c
@@ -102,6 +102,13 @@ const struct argv_option slbt_default_options[] = {
 				"only export symbols mathing the regex expression %s "
 				"[currently a no-op]"},
 
+	{"module",		0,TAG_MODULE,ARGV_OPTARG_NONE,
+				ARGV_OPTION_HYBRID_ONLY,0,0,
+				"create a shared object that will only be "
+				"loaded at runtime via dlopen(3). the shared "
+				"object name need not follow the platform's "
+				"library naming conventions"},
+
 	{"version-info",	0,TAG_VERSION_INFO,ARGV_OPTARG_REQUIRED,
 				ARGV_OPTION_HYBRID_ONLY|ARGV_OPTION_HYBRID_SPACE,0,
 				"<current>[:<revision>[:<age>]]",