diff --git a/src/semaphore/Cargo.toml b/src/semaphore/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..5bc1c215846febf3c7c1835a5b60369509c03d46
--- /dev/null
+++ b/src/semaphore/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "semaphore"
+version = "0.1.0"
+authors = ["Jeremy Soller <jackpot51@gmail.com>"]
+build = "build.rs"
+
+[build-dependencies]
+cbindgen = { path = "../../cbindgen" }
+
+[dependencies]
+platform = { path = "../../platform" }
diff --git a/src/semaphore/build.rs b/src/semaphore/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e24ff4d6925bf5e90ddf88318b6cb95e8006eddb
--- /dev/null
+++ b/src/semaphore/build.rs
@@ -0,0 +1,11 @@
+extern crate cbindgen;
+
+use std::{env, fs};
+
+fn main() {
+    let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
+    fs::create_dir_all("../../target/include").expect("failed to create include directory");
+    cbindgen::generate(crate_dir)
+      .expect("failed to generate bindings")
+      .write_to_file("../../target/include/semaphore.h");
+}
diff --git a/src/semaphore/cbindgen.toml b/src/semaphore/cbindgen.toml
new file mode 100644
index 0000000000000000000000000000000000000000..db95e2fec95470a7fade7468b9c0ef3ff310118c
--- /dev/null
+++ b/src/semaphore/cbindgen.toml
@@ -0,0 +1,6 @@
+sys_includes = []
+include_guard = "_SEMAPHORE_H"
+language = "C"
+
+[enum]
+prefix_with_name = true
diff --git a/src/semaphore/src/lib.rs b/src/semaphore/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c413aeb8e03a1fe37b11256e11ffe6ae91c201b5
--- /dev/null
+++ b/src/semaphore/src/lib.rs
@@ -0,0 +1,71 @@
+#![no_std]
+
+extern crate platform;
+
+use platform::types::*;
+
+#[repr(C)]
+#[derive(Copy)]
+pub union sem_t {
+    pub size: [c_char; 32usize],
+    pub align: c_long,
+    _bindgen_union_align: [u64; 4usize],
+}
+impl Clone for sem_t {
+    fn clone(&self) -> Self { *self }
+}
+#[no_mangle]
+pub extern "C" fn sem_init(sem: *mut sem_t, pshared: c_int,
+                    value: c_uint) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_destroy(sem: *mut sem_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_open(name: *const c_char,
+                    oflag: c_int, ...) -> *mut sem_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_close(sem: *mut sem_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_unlink(name: *const c_char)
+     -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_wait(sem: *mut sem_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_timedwait(sem: *mut sem_t, abstime: *const timespec)
+     -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_trywait(sem: *mut sem_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_post(sem: *mut sem_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn sem_getvalue(sem: *mut sem_t, sval: *mut c_int)
+     -> c_int {
+    unimplemented!();
+}
+
diff --git a/src/todo/semaphore/lib.rs b/src/todo/semaphore/lib.rs
deleted file mode 100644
index c047a45fc9d15dd278ec054a22dd34addad3f2dc..0000000000000000000000000000000000000000
--- a/src/todo/semaphore/lib.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-#[repr(C)]
-#[derive(Copy)]
-pub union sem_t {
-    pub size: [libc::c_char; 32usize],
-    pub align: libc::c_long,
-    _bindgen_union_align: [u64; 4usize],
-}
-impl Clone for sem_t {
-    fn clone(&self) -> Self { *self }
-}
-#[no_mangle]
-pub extern "C" fn sem_init(sem: *mut sem_t, pshared: libc::c_int,
-                    value: libc::c_uint) -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_destroy(sem: *mut sem_t) -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_open(name: *const libc::c_char,
-                    oflag: libc::c_int, ...) -> *mut sem_t {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_close(sem: *mut sem_t) -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_unlink(name: *const libc::c_char)
-     -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_wait(sem: *mut sem_t) -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_timedwait(sem: *mut sem_t, abstime: *const timespec)
-     -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_trywait(sem: *mut sem_t) -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_post(sem: *mut sem_t) -> libc::c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn sem_getvalue(sem: *mut sem_t, sval: *mut libc::c_int)
-     -> libc::c_int {
-    unimplemented!();
-}
-