diff --git a/Makefile b/Makefile
index 02f881e..a30c212 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,6 @@
 CC=gcc
 AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
 CFLAGS = -g -Werror -Os
-objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
-	  root-tree.o dir-item.o file-item.o inode-item.o \
-	  inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
-	  volumes.o utils.o
-
 #
 CHECKFLAGS=-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
 		-Wuninitialized -Wshadow -Wundef
@@ -16,8 +11,7 @@ prefix ?= /usr/local
 bindir = $(prefix)/bin
 LIBS=-luuid
 
-progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \
-	btrfs-map-logical
+SUBDIRS=lib misc man
 
 # make C=1 to enable sparse
 ifdef C
@@ -31,60 +25,12 @@ endif
 	$(CC) $(DEPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c $<
 
 
-all: version $(progs) manpages
-
-version:
-	bash version.sh
-
-btrfsctl: $(objects) btrfsctl.o
-	gcc $(CFLAGS) -o btrfsctl btrfsctl.o $(objects) $(LDFLAGS) $(LIBS)
-
-btrfs-vol: $(objects) btrfs-vol.o
-	gcc $(CFLAGS) -o btrfs-vol btrfs-vol.o $(objects) $(LDFLAGS) $(LIBS)
-
-btrfs-show: $(objects) btrfs-show.o
-	gcc $(CFLAGS) -o btrfs-show btrfs-show.o $(objects) $(LDFLAGS) $(LIBS)
-
-btrfsck: $(objects) btrfsck.o
-	gcc $(CFLAGS) -o btrfsck btrfsck.o $(objects) $(LDFLAGS) $(LIBS)
-
-mkfs.btrfs: $(objects) mkfs.o
-	gcc $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o $(LDFLAGS) $(LIBS)
-
-btrfs-debug-tree: $(objects) debug-tree.o
-	gcc $(CFLAGS) -o btrfs-debug-tree $(objects) debug-tree.o $(LDFLAGS) $(LIBS)
-
-btrfstune: $(objects) btrfstune.o
-	gcc $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS)
-
-btrfs-map-logical: $(objects) btrfs-map-logical.o
-	gcc $(CFLAGS) -o btrfs-map-logical $(objects) btrfs-map-logical.o $(LDFLAGS) $(LIBS)
-
-btrfs-image: $(objects) btrfs-image.o
-	gcc $(CFLAGS) -o btrfs-image $(objects) btrfs-image.o -lpthread -lz $(LDFLAGS) $(LIBS)
-
-dir-test: $(objects) dir-test.o
-	gcc $(CFLAGS) -o dir-test $(objects) dir-test.o $(LDFLAGS) $(LIBS)
-
-quick-test: $(objects) quick-test.o
-	gcc $(CFLAGS) -o quick-test $(objects) quick-test.o $(LDFLAGS) $(LIBS)
-
-convert: $(objects) convert.o
-	gcc $(CFLAGS) -o btrfs-convert $(objects) convert.o -lext2fs $(LDFLAGS) $(LIBS)
-
-manpages:
-	cd man; make
-
-install-man:
-	cd man; make install
-
-clean :
-	rm -f $(progs) cscope.out *.o .*.d btrfs-convert
-	cd man; make clean
-
-install: $(progs) install-man
-	$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
-	$(INSTALL) $(progs) $(DESTDIR)$(bindir)
-	if [ -e btrfs-convert ]; then $(INSTALL) btrfs-convert $(DESTDIR)$(bindir); fi
+all clean install:
+	@for subdir in $(SUBDIRS); do \
+	  if test -d $$subdir ; then \
+	    target=`echo $@`; \
+	    echo making $$target in $$subdir; \
+	    (cd $$subdir && $(MAKE) $$target) || exit 1; \
+	  fi ; \
+	done
 
--include .*.d
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..7ece415
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,47 @@
+CC=gcc
+AR = ar
+ARGEN = $(AR) rc
+RANLIB = ranlib
+AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
+CFLAGS = -g -Werror -Os
+objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
+	  root-tree.o dir-item.o file-item.o inode-item.o \
+	  inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
+	  volumes.o utils.o
+
+#
+CHECKFLAGS=-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
+		-Wuninitialized -Wshadow -Wundef
+DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
+
+INSTALL= install
+prefix ?= /usr/local
+libdir = $(prefix)/lib/
+
+
+# make C=1 to enable sparse
+ifdef C
+	check=sparse $(CHECKFLAGS)
+else
+	check=ls
+endif
+
+.c.o:
+	$(check) $<
+	$(CC) $(DEPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c $<
+
+all: libbtrfs.a
+
+libbtrfs.a: $(objects)
+	$(ARGEN) $@ $(objects)
+	$(RANLIB) $@
+
+clean :
+	rm -f $(progs) *.o .*.d
+	rm -f libbtrfs.a
+
+install: $(progs)
+	$(INSTALL) -m755 -d $(DESTDIR)$(libdir)
+	$(INSTALL) libbtrfs.a $(DESTDIR)$(libdir)
+
+-include .*.d
diff --git a/bit-radix.c b/lib/bit-radix.c
similarity index 100%
rename from bit-radix.c
rename to lib/bit-radix.c
diff --git a/bit-radix.h b/lib/bit-radix.h
similarity index 100%
rename from bit-radix.h
rename to lib/bit-radix.h
diff --git a/crc32c.c b/lib/crc32c.c
similarity index 100%
rename from crc32c.c
rename to lib/crc32c.c
diff --git a/crc32c.h b/lib/crc32c.h
similarity index 100%
rename from crc32c.h
rename to lib/crc32c.h
diff --git a/ctree.c b/lib/ctree.c
similarity index 100%
rename from ctree.c
rename to lib/ctree.c
diff --git a/ctree.h b/lib/ctree.h
similarity index 100%
rename from ctree.h
rename to lib/ctree.h
diff --git a/dir-item.c b/lib/dir-item.c
similarity index 100%
rename from dir-item.c
rename to lib/dir-item.c
diff --git a/disk-io.c b/lib/disk-io.c
similarity index 100%
rename from disk-io.c
rename to lib/disk-io.c
diff --git a/disk-io.h b/lib/disk-io.h
similarity index 100%
rename from disk-io.h
rename to lib/disk-io.h
diff --git a/extent-cache.c b/lib/extent-cache.c
similarity index 100%
rename from extent-cache.c
rename to lib/extent-cache.c
diff --git a/extent-cache.h b/lib/extent-cache.h
similarity index 100%
rename from extent-cache.h
rename to lib/extent-cache.h
diff --git a/extent-tree.c b/lib/extent-tree.c
similarity index 100%
rename from extent-tree.c
rename to lib/extent-tree.c
diff --git a/extent_io.c b/lib/extent_io.c
similarity index 100%
rename from extent_io.c
rename to lib/extent_io.c
diff --git a/extent_io.h b/lib/extent_io.h
similarity index 100%
rename from extent_io.h
rename to lib/extent_io.h
diff --git a/file-item.c b/lib/file-item.c
similarity index 100%
rename from file-item.c
rename to lib/file-item.c
diff --git a/hash.h b/lib/hash.h
similarity index 100%
rename from hash.h
rename to lib/hash.h
diff --git a/inode-item.c b/lib/inode-item.c
similarity index 100%
rename from inode-item.c
rename to lib/inode-item.c
diff --git a/inode-map.c b/lib/inode-map.c
similarity index 100%
rename from inode-map.c
rename to lib/inode-map.c
diff --git a/ioctl.h b/lib/ioctl.h
similarity index 100%
rename from ioctl.h
rename to lib/ioctl.h
diff --git a/kerncompat.h b/lib/kerncompat.h
similarity index 100%
rename from kerncompat.h
rename to lib/kerncompat.h
diff --git a/list.h b/lib/list.h
similarity index 100%
rename from list.h
rename to lib/list.h
diff --git a/print-tree.c b/lib/print-tree.c
similarity index 100%
rename from print-tree.c
rename to lib/print-tree.c
diff --git a/print-tree.h b/lib/print-tree.h
similarity index 100%
rename from print-tree.h
rename to lib/print-tree.h
diff --git a/radix-tree.c b/lib/radix-tree.c
similarity index 100%
rename from radix-tree.c
rename to lib/radix-tree.c
diff --git a/radix-tree.h b/lib/radix-tree.h
similarity index 100%
rename from radix-tree.h
rename to lib/radix-tree.h
diff --git a/rbtree.c b/lib/rbtree.c
similarity index 100%
rename from rbtree.c
rename to lib/rbtree.c
diff --git a/rbtree.h b/lib/rbtree.h
similarity index 100%
rename from rbtree.h
rename to lib/rbtree.h
diff --git a/root-tree.c b/lib/root-tree.c
similarity index 100%
rename from root-tree.c
rename to lib/root-tree.c
diff --git a/transaction.h b/lib/transaction.h
similarity index 100%
rename from transaction.h
rename to lib/transaction.h
diff --git a/utils.c b/lib/utils.c
similarity index 100%
rename from utils.c
rename to lib/utils.c
diff --git a/utils.h b/lib/utils.h
similarity index 100%
rename from utils.h
rename to lib/utils.h
diff --git a/volumes.c b/lib/volumes.c
similarity index 100%
rename from volumes.c
rename to lib/volumes.c
diff --git a/volumes.h b/lib/volumes.h
similarity index 100%
rename from volumes.h
rename to lib/volumes.h
diff --git a/misc/Makefile b/misc/Makefile
new file mode 100644
index 0000000..4a39c80
--- /dev/null
+++ b/misc/Makefile
@@ -0,0 +1,79 @@
+CC=gcc
+AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
+CFLAGS = -g -Werror -Os -I../lib/
+#
+CHECKFLAGS=-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
+		-Wuninitialized -Wshadow -Wundef
+DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
+
+INSTALL= install
+prefix ?= /usr/local
+bindir = $(prefix)/bin
+LIBS=-luuid
+TOPDIR=../
+
+progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \
+	btrfs-map-logical
+
+# make C=1 to enable sparse
+ifdef C
+	check=sparse $(CHECKFLAGS)
+else
+	check=ls
+endif
+
+.c.o:
+	$(check) $<
+	$(CC) $(DEPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c $<
+
+all: version $(progs)
+
+version:
+	bash version.sh
+
+btrfsctl: $(TOPDIR)/lib/libbtrfs.a btrfsctl.o
+	gcc $(CFLAGS) -static -o btrfsctl btrfsctl.o $(TOPDIR)/lib/libbtrfs.a $(LDFLAGS) $(LIBS)
+
+btrfs-vol: $(TOPDIR)/lib/libbtrfs.a btrfs-vol.o
+	gcc $(CFLAGS) -o btrfs-vol btrfs-vol.o $(TOPDIR)/lib/libbtrfs.a $(LDFLAGS) $(LIBS)
+
+btrfs-show: $(TOPDIR)/lib/libbtrfs.a btrfs-show.o
+	gcc $(CFLAGS) -o btrfs-show btrfs-show.o $(TOPDIR)/lib/libbtrfs.a $(LDFLAGS) $(LIBS)
+
+btrfsck: $(TOPDIR)/lib/libbtrfs.a btrfsck.o
+	gcc $(CFLAGS) -o btrfsck btrfsck.o $(TOPDIR)/lib/libbtrfs.a $(LDFLAGS) $(LIBS)
+
+mkfs.btrfs: $(TOPDIR)/lib/libbtrfs.a mkfs.o
+	gcc $(CFLAGS) -o mkfs.btrfs mkfs.o  $(TOPDIR)/lib/libbtrfs.a  $(LDFLAGS) $(LIBS)
+
+btrfs-debug-tree: $(TOPDIR)/lib/libbtrfs.a debug-tree.o
+	gcc $(CFLAGS) -o btrfs-debug-tree debug-tree.o $(TOPDIR)/lib/libbtrfs.a  $(LDFLAGS) $(LIBS)
+
+btrfstune: $(TOPDIR)/lib/libbtrfs.a btrfstune.o
+	gcc $(CFLAGS) -o btrfstune btrfstune.o $(TOPDIR)/lib/libbtrfs.a  $(LDFLAGS) $(LIBS)
+
+btrfs-map-logical: $(TOPDIR)/lib/libbtrfs.a btrfs-map-logical.o
+	gcc $(CFLAGS) -o btrfs-map-logical btrfs-map-logical.o $(TOPDIR)/lib/libbtrfs.a  $(LDFLAGS) $(LIBS)
+
+btrfs-image: $(TOPDIR)/lib/libbtrfs.a btrfs-image.o
+	gcc $(CFLAGS) -o btrfs-image btrfs-image.o $(TOPDIR)/lib/libbtrfs.a  -lpthread -lz $(LDFLAGS) $(LIBS)
+
+dir-test: $(TOPDIR)/lib/libbtrfs.a dir-test.o
+	gcc $(CFLAGS) -o dir-test dir-test.o $(TOPDIR)/lib/libbtrfs.a  $(LDFLAGS) $(LIBS)
+
+quick-test: $(TOPDIR)/lib/libbtrfs.a quick-test.o
+	gcc $(CFLAGS) -o quick-test quick-test.o $(TOPDIR)/lib/libbtrfs.a  $(LDFLAGS) $(LIBS)
+
+convert: $(TOPDIR)/lib/libbtrfs.a convert.o
+	gcc $(CFLAGS) -o btrfs-convert convert.o $(TOPDIR)/lib/libbtrfs.a  -lext2fs $(LDFLAGS) $(LIBS)
+
+clean :
+	rm -f $(progs) cscope.out *.o .*.d btrfs-convert
+	rm -f version.h
+
+install: $(progs) install-man
+	$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
+	$(INSTALL) $(progs) $(DESTDIR)$(bindir)
+	if [ -e btrfs-convert ]; then $(INSTALL) btrfs-convert $(DESTDIR)$(bindir); fi
+
+-include .*.d
diff --git a/bcp b/misc/bcp
old mode 100755
new mode 100644
similarity index 100%
rename from bcp
rename to misc/bcp
diff --git a/btrfs-image.c b/misc/btrfs-image.c
similarity index 100%
rename from btrfs-image.c
rename to misc/btrfs-image.c
diff --git a/btrfs-map-logical.c b/misc/btrfs-map-logical.c
similarity index 100%
rename from btrfs-map-logical.c
rename to misc/btrfs-map-logical.c
diff --git a/btrfs-show.c b/misc/btrfs-show.c
similarity index 100%
rename from btrfs-show.c
rename to misc/btrfs-show.c
diff --git a/btrfs-vol.c b/misc/btrfs-vol.c
similarity index 100%
rename from btrfs-vol.c
rename to misc/btrfs-vol.c
diff --git a/btrfsck.c b/misc/btrfsck.c
similarity index 100%
rename from btrfsck.c
rename to misc/btrfsck.c
diff --git a/btrfsctl.c b/misc/btrfsctl.c
similarity index 100%
rename from btrfsctl.c
rename to misc/btrfsctl.c
diff --git a/btrfstune.c b/misc/btrfstune.c
similarity index 100%
rename from btrfstune.c
rename to misc/btrfstune.c
diff --git a/convert.c b/misc/convert.c
similarity index 100%
rename from convert.c
rename to misc/convert.c
diff --git a/debug-tree.c b/misc/debug-tree.c
similarity index 100%
rename from debug-tree.c
rename to misc/debug-tree.c
diff --git a/mkfs.c b/misc/mkfs.c
similarity index 100%
rename from mkfs.c
rename to misc/mkfs.c
diff --git a/version.sh b/misc/version.sh
similarity index 100%
rename from version.sh
rename to misc/version.sh
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..e8df52c
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,88 @@
+CC=gcc
+AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
+CFLAGS = -g -Werror -Os
+objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
+	  root-tree.o dir-item.o file-item.o inode-item.o \
+	  inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
+	  volumes.o utils.o
+
+#
+CHECKFLAGS=-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise \
+		-Wuninitialized -Wshadow -Wundef
+DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
+
+INSTALL= install
+prefix ?= /usr/local
+bindir = $(prefix)/bin
+LIBS=-luuid
+
+progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \
+	btrfs-map-logical
+
+# make C=1 to enable sparse
+ifdef C
+	check=sparse $(CHECKFLAGS)
+else
+	check=ls
+endif
+
+.c.o:
+	$(check) $<
+	$(CC) $(DEPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c $<
+
+
+all: version $(progs) manpages
+
+version:
+	bash version.sh
+
+btrfsctl: $(objects) btrfsctl.o
+	gcc $(CFLAGS) -static -o btrfsctl btrfsctl.o $(objects) $(LDFLAGS) $(LIBS)
+
+btrfs-vol: $(objects) btrfs-vol.o
+	gcc $(CFLAGS) -o btrfs-vol btrfs-vol.o $(objects) $(LDFLAGS) $(LIBS)
+	gcc $(CFLAGS) -o btrfs-show btrfs-show.o $(objects) $(LDFLAGS) $(LIBS)
+
+btrfsck: $(objects) btrfsck.o
+	gcc $(CFLAGS) -o btrfsck btrfsck.o $(objects) $(LDFLAGS) $(LIBS)
+
+mkfs.btrfs: $(objects) mkfs.o
+	gcc $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o $(LDFLAGS) $(LIBS)
+
+btrfs-debug-tree: $(objects) debug-tree.o
+	gcc $(CFLAGS) -o btrfs-debug-tree $(objects) debug-tree.o $(LDFLAGS) $(LIBS)
+
+btrfstune: $(objects) btrfstune.o
+	gcc $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS)
+
+btrfs-map-logical: $(objects) btrfs-map-logical.o
+	gcc $(CFLAGS) -o btrfs-map-logical $(objects) btrfs-map-logical.o $(LDFLAGS) $(LIBS)
+
+btrfs-image: $(objects) btrfs-image.o
+	gcc $(CFLAGS) -o btrfs-image $(objects) btrfs-image.o -lpthread -lz $(LDFLAGS) $(LIBS)
+
+dir-test: $(objects) dir-test.o
+	gcc $(CFLAGS) -o dir-test $(objects) dir-test.o $(LDFLAGS) $(LIBS)
+
+quick-test: $(objects) quick-test.o
+	gcc $(CFLAGS) -o quick-test $(objects) quick-test.o $(LDFLAGS) $(LIBS)
+
+convert: $(objects) convert.o
+	gcc $(CFLAGS) -o btrfs-convert $(objects) convert.o -lext2fs $(LDFLAGS) $(LIBS)
+
+manpages:
+	cd man; make
+
+install-man:
+	cd man; make install
+
+clean :
+	rm -f $(progs) cscope.out *.o .*.d btrfs-convert
+	cd man; make clean
+
+install: $(progs) install-man
+	$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
+	$(INSTALL) $(progs) $(DESTDIR)$(bindir)
+	if [ -e btrfs-convert ]; then $(INSTALL) btrfs-convert $(DESTDIR)$(bindir); fi
+
+-include .*.d
