diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d145e2019daf3a54de10d5d4cefec32c41fc789c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,24 @@
+.PHONY: all clean fmt test
+
+all: openlibm/libopenlibm.a target/debug/libc.a target/debug/libcrt0.a
+	cargo build
+
+clean:
+	cargo clean
+	make -C openlibm clean
+	make -C tests clean
+
+fmt:
+	./fmt.sh
+
+test: openlibm/libopenlibm.a
+	make -C tests run
+
+target/debug/libc.a:
+	cargo build
+
+target/debug/libcrt0.a:
+	cargo build --manifest-path src/crt0/Cargo.toml
+
+openlibm/libopenlibm.a:
+	CFLAGS=-fno-stack-protector make -C openlibm libopenlibm.a
diff --git a/test.sh b/test.sh
index 1e6d7b819ac637d79c68985d9001e169474109b7..6b3063413f9a556053d62161dfc498902c050eda 100755
--- a/test.sh
+++ b/test.sh
@@ -1,10 +1,7 @@
 #!/bin/bash
 set -ex
 
-cargo build
-cargo build --manifest-path src/crt0/Cargo.toml
-
-CFLAGS=-fno-stack-protector make -C openlibm
+make
 
 make -C tests clean
 make -C tests run