diff --git a/.gitignore b/.gitignore
index 0996b1f5918be5e046df162643ef489445eb9091..b904f30e859febdb299a0da885e6137fb9fce79a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
 .crystal
 coverage/
 deps/
+.build
diff --git a/Makefile b/Makefile
index 8d5b1d6f2bc1abcc62cf3010d1eb0a66bfb7053a..37e9189685ff1221bce1c1a3f75598a40543686a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,6 @@
+.PHONY: all spec crystal clean
+
+O := .build
 SOURCES := $(shell find src -name '*.cr')
 SPEC_SOURCES := $(shell find spec -name '*.cr')
 
@@ -5,22 +8,14 @@ all: crystal
 spec: all_spec
 	./all_spec
 
-crystal: $(SOURCES)
-	@if [ -x crystal ]; then \
-		echo mv crystal crystal-old; \
-		mv crystal crystal-old; \
-		echo ./crystal-old src/compiler/crystal.cr; \
-		./crystal-old src/compiler/crystal.cr; \
-	else \
-		echo bin/crystal src/compiler/crystal.cr; \
-	  bin/crystal src/compiler/crystal.cr; \
-	fi
+crystal: $(O)/crystal
 
 all_spec: $(SOURCES) $(SPEC_SOURCES)
-	@if [ -x crystal ]; then \
-		echo ./crystal spec/all_spec.cr; \
-		./crystal spec/all_spec.cr; \
-	else \
-		echo bin/crystal spec/all_spec.cr; \
-	  bin/crystal spec/all_spec.cr; \
-	fi
+	./bin/crystal spec/all_spec.cr
+
+$(O)/crystal: $(SOURCES)
+	@mkdir -p $(O)
+	./bin/crystal -o $@ src/compiler/crystal.cr
+
+clean:
+	@rm -rf $(O)
diff --git a/bin/crystal b/bin/crystal
index 4d83a0cc8fc9557b5c3ecf41c60d36d1149a95c7..e5e33185ca9c7aac85c7b1a8d68a812c61fb09b8 100755
--- a/bin/crystal
+++ b/bin/crystal
@@ -2,6 +2,11 @@
 SCRIPT_PATH=`dirname $(readlink $0 || echo $0)`
 DEPS_DIR="$SCRIPT_PATH/../deps"
 
+CRYSTAL_DIR="$SCRIPT_PATH/../.build"
+if [ ! -x $CRYSTAL_DIR/crystal ] ; then
+  CRYSTAL_DIR=$DEPS_DIR
+fi
+
 OS_NAME=`uname -s`
 HW_NAME=`uname -m`
 EXTRACT_FLAG="z"
@@ -72,4 +77,4 @@ fi
 
 export PATH="$DEPS_DIR/llvm/bin":$PATH
 export CRYSTAL_PATH="$SCRIPT_PATH/../src:libs"
-"$DEPS_DIR/crystal" "$@"
+"$CRYSTAL_DIR/crystal" "$@"