diff --git a/mk/stage3.mk b/mk/stage3.mk
index 70d3f26d309..d8604ed999e 100644
--- a/mk/stage3.mk
+++ b/mk/stage3.mk
@@ -1,13 +1,8 @@
-stage3/std.o: $(STDLIB_CRATE) $(STDLIB_INPUTS) \
+stage3/$(CFG_STDLIB): $(STDLIB_CRATE) $(STDLIB_INPUTS) \
               stage2/rustc$(X) stage2/$(CFG_STDLIB) stage2/intrinsics.bc \
               $(LREQ) $(MKFILES)
-	@$(call E, compile: $@)
-	$(STAGE2) -c --shared -o $@ $<
-
-stage3/$(CFG_STDLIB): stage2/std.o stage2/glue.o
-	@$(call E, link: $@)
-	$(Q)gcc $(CFG_GCCISH_CFLAGS) stage2/glue.o $(CFG_GCCISH_LINK_FLAGS) -o \
-        $@ $< -Lstage2 -Lrt -lrustrt
+	@$(call E, compile_and_link: $@)
+	$(STAGE2)  --shared -o $@ $<
 
 stage3/librustc.o: $(COMPILER_CRATE) $(COMPILER_INPUTS) $(SREQ2)
 	@$(call E, compile: $@)
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs
index 9aef46058ee..e2f1164ed0c 100644
--- a/src/comp/driver/rustc.rs
+++ b/src/comp/driver/rustc.rs
@@ -399,37 +399,34 @@ fn main(vec[str] args) {
         let str prog = "gcc";
         // The invocations of gcc share some flags across platforms
 
-        let vec[str] common_cflags =
-            ["-fno-strict-aliasing", "-fPIC", "-Wall", "-fno-rtti",
-             "-fno-exceptions", "-g"];
-        let vec[str] common_libs =
-            [stage, "-Lrustllvm", "-Lrt", "-lrustrt", "-lrustllvm", "-lstd",
-             "-lm"];
+        let vec[str] common_args = [stage, "-Lrt", "-lrustrt",
+         "-fno-strict-aliasing", "-fPIC", "-Wall",
+         "-fno-rtti", "-fno-exceptions", "-g", glu, "-o",
+         saved_out_filename, saved_out_filename + ".o"];
+
+       auto shared_cmd;
+
         alt (sess.get_targ_cfg().os) {
             case (session::os_win32) {
-                gcc_args =
-                    common_cflags +
-                        ["-march=i686", "-O2", glu, main, "-o",
-                         saved_out_filename, saved_out_filename + ".o"] +
-                        common_libs;
+                shared_cmd = "-shared";
+                gcc_args = common_args + ["-march=i686", "-O2"];
             }
             case (session::os_macos) {
-                gcc_args =
-                    common_cflags +
-                        ["-arch i386", "-O0", "-m32", glu, main, "-o",
-                         saved_out_filename, saved_out_filename + ".o"] +
-                        common_libs;
+                shared_cmd = "-dynamiclib";
+                gcc_args = common_args + ["-arch i386", "-O0", "-m32"];
             }
             case (session::os_linux) {
-                gcc_args =
-                    common_cflags +
-                        ["-march=i686", "-O2", "-m32", glu, main, "-o",
-                         saved_out_filename, saved_out_filename + ".o"] +
-                        common_libs;
+                shared_cmd = "-shared";
+                gcc_args = common_args + ["-march=i686", "-O2", "-m32"];
             }
         }
-        // We run 'gcc' here
+        if (sopts.shared) {
+           gcc_args += [shared_cmd];
+        } else {
+           gcc_args += ["-Lrustllvm", "-lrustllvm", "-lstd", "-lm", main];
+        }
 
+        // We run 'gcc' here
         run::run_program(prog, gcc_args);
         // Clean up on Darwin