diff --git a/Usermode/Makefile b/Usermode/Makefile
index 8da9b005625c89e17628faf23d749486fe301968..a2f0eb6d83654c879d0fe3feb3d0d3683c347ad3 100644
--- a/Usermode/Makefile
+++ b/Usermode/Makefile
@@ -30,7 +30,15 @@ RUST_COMMON_FLAGS := --target=$(TARGET_SPEC) --cfg 'arch="$(ARCH)"' --cfg nightl
 RUST_COMMON_FLAGS += -L $(LIBDIR)
 
 XARGO := RUST_TARGET_PATH=$(dir $(abspath $(TARGET_SPEC))) $(XARGO)
-XARGO_FLAGS := --target target-$(ARCH)
+XARGO_TARGET := target-$(ARCH)
+XARGO_PROFILE := release
+XARGO_FLAGS := --target $(XARGO_TARGET)
+ifeq ($(XARGO_PROFILE),debug)
+else ifeq ($(XARGO_PROFILE),release)
+  XARGO_FLAGS += --release
+else
+  $(error Unknown xargo profile $(XARGO_PROFILE))
+endif
 
 RUSTFLAGS := $(RUST_COMMON_FLAGS)
 RUSTFLAGS += -O
@@ -47,6 +55,7 @@ BIN_RUSTFLAGS :=
 #BIN_RUSTFLAGS += -C lto
 
 RUSTFLAGS_compiler_builtins = --cfg feature=\"compiler-builtins\" --cfg stage0
+RUSTFLAGS_alloc = --edition 2018
 
 # - List non-file targets
 .PHONY: all clean
@@ -75,30 +84,33 @@ docs: $(patsubst lib%/,.docs/%/index.html,$(wildcard lib*/))
 	@echo "[RUSTDOC] -o $@"
 	$V$(RUSTDOC) -o .docs $< --crate-name $* $(RUST_COMMON_FLAGS)
 
-LOADER_DEPS := $(patsubst %,$(LIBDIR)lib%.rlib,$(call fn_getdeps,loader/src/main.rs) std std_io core std_rt compiler_builtins)
+LOADER_DEPS := $(patsubst %,$(LIBDIR)lib%.rlib,$(call fn_getdeps,loader/bin/src/main.rs) std std_io core std_rt compiler_builtins)
 
 # Most binary targets have simple templates, but loader and libcore are special
 # loader: Requires an assembly stub
 # > Linking is done in two steps so that --gc-sections works
-#$(BINDIR)loader: loader/link.ld $(OBJDIR)loader/start.ao $(OBJDIR)loader/src/main.o
-$(BINDIR)loader: loader/link.ld $(OBJDIR)loader/start.ao $(OBJDIR)loader/src/main.o $(LOADER_DEPS)
+#$(BINDIR)loader: loader/bin/link.ld $(OBJDIR)loader/bin/start.ao $(OBJDIR)loader/bin/src/main.o
+$(BINDIR)loader: loader/bin/link.ld $(OBJDIR)loader/bin/start.ao $(OBJDIR)loader/bin/src/main.o $(LOADER_DEPS)
 	@mkdir -p $(dir $@)
 	@echo [LD] $@
-	$V$(LD) -r --gc-sections --undefined image_header --entry start -o $(OBJDIR)loader.o $(OBJDIR)loader/start.ao $(OBJDIR)loader/src/main.o $(LOADER_DEPS)
-	$V$(LD) -o $(OBJDIR)loader.elf -T loader/link.ld $(OBJDIR)loader.o -Map $(OBJDIR)loader_map.txt
+	$V$(LD) -r --gc-sections --undefined image_header --entry start -o $(OBJDIR)loader.o $(OBJDIR)loader/bin/start.ao $(OBJDIR)loader/bin/src/main.o $(LOADER_DEPS)
+	$V$(LD) -o $(OBJDIR)loader.elf -T loader/bin/link.ld $(OBJDIR)loader.o -Map $(OBJDIR)loader_map.txt
 	$V$(OBJCOPY) $(OBJDIR)loader.elf -O binary $@
 	$V$(OBJDUMP) -CS $(OBJDIR)loader.elf > $(OBJDIR)loader.dsm
-$(OBJDIR)loader/src/main.o: $(LOADER_DEPS)
-#$(OBJDIR)loader/src/main.o:
+$(OBJDIR)loader/bin/src/main.o: $(LOADER_DEPS)
+#$(OBJDIR)loader/bin/src/main.o:
 #	$(XARGO) build $(XARGO_FLAGS) --manifest-path loader/Cargo.toml
 
 .PHONY: xargo
-xargo:
+xargo: $(LIBDIR)libloader_dyn.so $(OBJDIR)loader/bin/start.ao	# Referenced by link-$(TARGET).ld
+	$(XARGO) build $(XARGO_FLAGS) --manifest-path libstd/Cargo.toml
+	$(XARGO) build $(XARGO_FLAGS) --manifest-path loader/bin/Cargo.toml
+	cp target/$(XARGO_TARGET)/$(XARGO_PROFILE)/libstd.rlib ../.prefix/xargo/lib/rustlib/$(XARGO_TARGET)/lib/
 	$(XARGO) build $(XARGO_FLAGS)
 
 # Low-level loader dummy dynamic library
 # - Used to tell ld that `loader`'s exported symbols actually exist
-$(LIBDIR)libloader_dyn.so: loader/lib.S	$(makefile_deps)
+$(LIBDIR)libloader_dyn.so: loader/bin/lib.S	$(makefile_deps)
 	@mkdir -p $(dir $@)
 	@echo [CC] $@
 	$V$(CC) -o $@.o -c $< -fPIC -D ARCH_$(ARCH)
@@ -158,7 +170,7 @@ $(OBJDIR)lib%.rlib: $(RUSTUP_SRC_DIR)lib%/src/lib.rs $(OBJDIR)libcore.rlib $(TAR
 	@mv $(OBJDIR)$*.d $(OBJDIR)lib$*.d
 
 # - Loader's interface library, lives in the loader directory
-$(OBJDIR)libloader.rlib: loader/lib.rs $(TARGET_SPEC) $(makefile_deps) $(patsubst %,$(LIBDIR)lib%.rlib,$(call fn_getdeps,loader/lib.rs))
+$(OBJDIR)libloader.rlib: loader/lib/lib.rs $(TARGET_SPEC) $(makefile_deps) $(patsubst %,$(LIBDIR)lib%.rlib,$(call fn_getdeps,loader/lib/lib.rs))
 	@mkdir -p $(dir $@)
 	@echo [RUSTC] $@
 	$V$(RUSTC) $(RUSTFLAGS) --emit=link,dep-info --out-dir $(OBJDIR) $< --crate-type=rlib
@@ -181,7 +193,7 @@ $(OBJDIR)%.o: %.rs $(TARGET_SPEC) $(makefile_deps)
 	@mkdir -p $(dir $@)
 	@echo [RUSTC] $@
 	$V$(RUSTC) $(RUSTFLAGS) $< --out-dir=$(dir $@) --emit=obj,dep-info
--include $(OBJDIR)loader/src/main.d
+-include $(OBJDIR)loader/bin/src/main.d
 
 # - Assembly objects (loader)
 $(OBJDIR)%.ao: %.S $(makefile_deps)
@@ -207,7 +219,7 @@ ALL_PRESENT_BINS := $(patsubst %/src/main.rs,%, $(wildcard */src/main.rs))
 
 DEPFILES := $(patsubst %,$(OBJDIR)lib%.d, $(ALL_USED_LIBS))
 DEPFILES += $(patsubst %,$(OBJDIR)%.d, $(ALL_PRESENT_BINS))
-DEPFILES += $(OBJDIR)loader/start.ao.d $(OBJDIR)rustrt0.o.d
+DEPFILES += $(OBJDIR)loader/bin/start.ao.d $(OBJDIR)rustrt0.o.d
 -include $(DEPFILES)
 
 # Official library dependency tree
diff --git a/Usermode/Xargo.toml b/Usermode/Xargo.toml
index a8ecde9ec4ceed38884e0e1ea638295bd3cd7b82..775329b16e436ab6c63e605e4e48422439536ffe 100644
--- a/Usermode/Xargo.toml
+++ b/Usermode/Xargo.toml
@@ -1,6 +1,2 @@
 [dependencies.alloc]
 stage = 0
-
-#[dependencies.std]
-#path = "libstd"
-#stage = 2
diff --git a/Usermode/filebrowser/Cargo.toml b/Usermode/filebrowser/Cargo.toml
index dfef6ed7d023e3c5bd77e785b61418bcbfe0862f..abc74a0efef6b9c262db2d4ac9d51b8b36ada428 100644
--- a/Usermode/filebrowser/Cargo.toml
+++ b/Usermode/filebrowser/Cargo.toml
@@ -3,7 +3,8 @@ name = "filebrowser"
 version = "0.0.1"
 
 [dependencies]
+#std = { path = "../libstd" }
 wtk = { path = "../libwtk" }
 vec_ring = { path = "../libvec_ring" }
 syscalls = { path = "../libsyscalls" }
-loader = { path = "../loader" }
+loader = { path = "../loader/lib" }
diff --git a/Usermode/libmacros/Cargo.toml b/Usermode/libmacros/Cargo.toml
index 47dc80848d6e42682b6c4f9ae3c8bcff8e8735cd..eea72cc7068f735b2a3410410190511395f9539f 100644
--- a/Usermode/libmacros/Cargo.toml
+++ b/Usermode/libmacros/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-crate-type = "lib"
 name = "macros"
 version = "0.0.1"
 
diff --git a/Usermode/libstd_rt/Cargo.toml b/Usermode/libstd_rt/Cargo.toml
index 8f1df4be5090ccb425f758c03359c3f6cea4623b..d9f2887ca1d1092e486c264e4f647782f27633ef 100644
--- a/Usermode/libstd_rt/Cargo.toml
+++ b/Usermode/libstd_rt/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-crate-type = "lib"
 name = "std_rt"
 version = "0.0.1"
 
diff --git a/Usermode/link-amd64.ld b/Usermode/link-amd64.ld
index acba19ec2f2980a6a66610276a5adff45656055b..d20cecf2bd44152e01c96f39cedae9c0ddb7a374 100644
--- a/Usermode/link-amd64.ld
+++ b/Usermode/link-amd64.ld
@@ -1,5 +1,6 @@
 ENTRY(start)
 
+SEARCH_DIR( .ojs/amd64/libs )
 STARTUP( .objs/amd64/rustrt0.o )
 
 PHDRS {
diff --git a/Usermode/loader/Cargo.toml b/Usermode/loader/Cargo.toml
deleted file mode 100644
index 1abf89e35b92ed90b585a87dd7c3c49a8f36f871..0000000000000000000000000000000000000000
--- a/Usermode/loader/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-name = "loader"
-version = "0.0.1"
-
-[[bin]]
-name = "loader"
-path = "src/main.rs"
-
-[lib]
-path = "lib.rs"
-
-[dependencies]
-std = { path = "../libstd" }
-std_rt = { path = "../libstd_rt" }
-syscalls = { path = "../libsyscalls" }
-byteorder = { path = "../libbyteorder" }
-cmdline_words_parser = { path = "../../externals/crates.io/cmdline_words_parser" }
diff --git a/Usermode/loader/bin/Cargo.toml b/Usermode/loader/bin/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..ed015e4ba3d266a6173df5416170097360b59451
--- /dev/null
+++ b/Usermode/loader/bin/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "loader-binary"
+version = "0.0.0"
+
+[lib]
+path = "src/main.rs"
+
+[dependencies]
+loader = { path = "../lib" }
+syscalls = { path = "../../libsyscalls" }
+byteorder = { path = "../../libbyteorder" }
+macros = { path = "../../libmacros" }
+cmdline_words_parser = { path = "../../../externals/crates.io/cmdline_words_parser" }
diff --git a/Usermode/loader/lib.S b/Usermode/loader/bin/lib.S
similarity index 100%
rename from Usermode/loader/lib.S
rename to Usermode/loader/bin/lib.S
diff --git a/Usermode/loader/link.ld b/Usermode/loader/bin/link.ld
similarity index 100%
rename from Usermode/loader/link.ld
rename to Usermode/loader/bin/link.ld
diff --git a/Usermode/loader/src/elf/mod.rs b/Usermode/loader/bin/src/elf/mod.rs
similarity index 100%
rename from Usermode/loader/src/elf/mod.rs
rename to Usermode/loader/bin/src/elf/mod.rs
diff --git a/Usermode/loader/src/interface.rs b/Usermode/loader/bin/src/interface.rs
similarity index 100%
rename from Usermode/loader/src/interface.rs
rename to Usermode/loader/bin/src/interface.rs
diff --git a/Usermode/loader/src/load/mod.rs b/Usermode/loader/bin/src/load/mod.rs
similarity index 100%
rename from Usermode/loader/src/load/mod.rs
rename to Usermode/loader/bin/src/load/mod.rs
diff --git a/Usermode/loader/src/main.rs b/Usermode/loader/bin/src/main.rs
similarity index 99%
rename from Usermode/loader/src/main.rs
rename to Usermode/loader/bin/src/main.rs
index cb2192d18f47fc9d29ea951c96b16d23ea43a8a3..ac3afc9373bce0f461db7a32131a96167242ff32 100644
--- a/Usermode/loader/src/main.rs
+++ b/Usermode/loader/bin/src/main.rs
@@ -4,11 +4,16 @@
 // This program is both the initial entrypoint for the userland, and the default dynamic linker.
 #![feature(const_fn)]
 #![crate_type="lib"]
+#![no_main]
 
 use cmdline_words_parser::StrExt as CmdlineStrExt;
 
 use load::SegmentIterator;
 
+#[link(name="loader_start")]
+extern "C" {
+}
+
 #[macro_use]
 extern crate syscalls;
 
diff --git a/Usermode/loader/start.S b/Usermode/loader/bin/start.S
similarity index 99%
rename from Usermode/loader/start.S
rename to Usermode/loader/bin/start.S
index 426b531d26f278b347a5de83594dca59fb5b7b1d..8d7325916e0ba32c4d11d65ea7c788a5f7dc3cd9 100644
--- a/Usermode/loader/start.S
+++ b/Usermode/loader/bin/start.S
@@ -13,7 +13,7 @@
 .globl LIMIT
 .globl PAGE_SIZE
 
-#include "../rustrt0/common.S"
+#include "../../rustrt0/common.S"
 
 #ifdef ARCH_amd64
 # define DEFPTR 	.quad
diff --git a/Usermode/loader/lib/Cargo.toml b/Usermode/loader/lib/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..d0f1730b3796cec581e139fcfc6700be4be99318
--- /dev/null
+++ b/Usermode/loader/lib/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "loader"
+version = "0.0.1"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+syscalls = { path = "../../libsyscalls" }
+#byteorder = { path = "../libbyteorder" }
+#macros = { path = "../libmacros" }
+#cmdline_words_parser = { path = "../../externals/crates.io/cmdline_words_parser" }
diff --git a/Usermode/loader/lib.rs b/Usermode/loader/lib/lib.rs
similarity index 98%
rename from Usermode/loader/lib.rs
rename to Usermode/loader/lib/lib.rs
index e87ff708bbb46c9cd6de5d6d3a67002b4d8745b9..7c9843869982ab7d40b10ec9d28dc49fe28470f2 100644
--- a/Usermode/loader/lib.rs
+++ b/Usermode/loader/lib/lib.rs
@@ -6,7 +6,7 @@
 #![crate_type="dylib"]
 #![crate_name="loader"]
 
-extern crate std_rt;
+//extern crate std_rt;
 extern crate syscalls;
 
 use core::result::Result;
diff --git a/common.mk b/common.mk
index b12df46846a1a3c463fa0844d8688bfd3338607f..04cc052c56bbcc22acfffce6b1f6bc971c0c9f2e 100644
--- a/common.mk
+++ b/common.mk
@@ -2,6 +2,10 @@
 .PHONY: default
 default: all
 
+nop :=
+space := $(nop) $(nop)
+comma := ,
+
 ARCH ?= amd64
 
 ifeq ($(ARCH),amd64)
@@ -42,6 +46,7 @@ RUSTDOC := $(call fn_rustcmd,rustdoc)
 CARGO := $(call fn_rustcmd,cargo)
 XARGO := XARGO_HOME=$(abspath $(PREFIX)xargo) $(call fn_rustcmd,xargo)
 
+# NOTE: rustc-src doesn't contain compiler_builtins (which is a crates.io package)
 #RUSTUP_SRC_DIR = $(firstword $(wildcard $(PREFIX)toolchains/nightly-*/lib/rustlib/src/rust/src))/
 RUSTUP_SRC_DIR := $(abspath $(ROOTDIR)/rustc-nightly-src/src)/
 $(warning $(RUSTUP_SRC_DIR))