Rework the vboot_reference make system.

After this change the generated files are placed in a
separate tree (such thet they don't show in the
`git status' output anymore) and the dependencies are
followed properly (if a .h file changes the
appropriate .o files and apps get rebuilt).

Tested as follows:

> $ make clean
> $ make # build succeeds
> $ git status # shows clean directory
> $ RUNTESTS=1 make # (captured test output matches that of the test run before any changes)
> $ touch ./vboot_firmware/include/tlcl.h
> $ make  # make succeeds
> $ find build -type f -newer ./vboot_firmware/include/tlcl.h
build/vboot_firmware/lib/rollback_index.o
build/vboot_firmware/lib/rollback_index.o.d
build/vboot_firmware/a.out
build/vboot_fw.a
build/utility/vbutil_key
build/utility/kernel_utility.d
build/utility/vbutil_key.d
build/utility/verify_data
build/utility/load_kernel_test.d
build/utility/vbutil_keyblock.d
build/utility/vbutil_kernel
build/utility/vbutil_kernel.d
build/utility/firmware_utility
build/utility/signature_digest_utility.d
build/utility/kernel_utility
build/utility/verify_data.d
build/utility/vbutil_keyblock
build/utility/signature_digest_utility
build/utility/load_kernel_test
build/utility/firmware_utility.d
build/tests/vboot_common3_tests
build/tests/vboot_common2_tests
build/host/a.out
$ >

Review URL: http://codereview.chromium.org/2845001
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..db3c8b0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/build
+ID
diff --git a/Makefile b/Makefile
index 853bfbf..4022daf 100644
--- a/Makefile
+++ b/Makefile
@@ -12,22 +12,27 @@
 	-I$(FWDIR)/include \
 	-I$(TOP)/misclibs/include
 
-export FWLIB=$(FWDIR)/vboot_fw.a
-export HOSTLIB=$(HOSTDIR)/vboot_host.a
+export BUILD = ${TOP}/build
+export FWLIB = ${BUILD}/vboot_fw.a
+export HOSTLIB= ${BUILD}/vboot_host.a
 
-SUBDIRS=vboot_firmware misclibs host vfirmware vkernel utility cgpt tests
+SUBDIRS = vboot_firmware misclibs host vfirmware vkernel utility cgpt tests
 
 all:
 	set -e; \
+	for d in $(shell find ${SUBDIRS} -name '*.c' -exec  dirname {} \; |\
+		 sort -u); do \
+		newdir=${BUILD}/$$d; \
+		if [ ! -d $$newdir ]; then \
+			mkdir -p $$newdir; \
+		fi; \
+	done && \
 	for i in $(SUBDIRS); do \
 		make -C $$i; \
 	done
 
 clean:
-	set -e; \
-	for i in $(SUBDIRS); do \
-		make -C $$i clean; \
-	done
+	/bin/rm -rf ${BUILD}
 
 install:
 	$(MAKE) -C utility install
diff --git a/README b/README
index e350be6..ad88b22 100644
--- a/README
+++ b/README
@@ -27,6 +27,35 @@
 implementation. Please have a look at these if you'd like to
 understand how to use the reference implementation.
 
+build/ - a directory where the generated files go to.
+
+--------------------
+Building and testing
+--------------------
+
+The suite can be built on the host or in the chroot environment.
+
+Building on the host could fail if certain packages are not installed. If
+there are host environment build problems due to missing .h files, try
+researching what packages the files belong to and install the missing packages
+before reporting a problem.
+
+To build the software run
+
+make
+
+in the top level directory. The build output is placed in the ./build
+directory.
+
+To run the tests either invoke
+
+RUNTESTS=1 make
+
+in the top level directory or
+
+cd tests
+BUILD=../build make runtests
+
 
 ---------- 
 Some useful utilities: 
diff --git a/cgpt/Makefile b/cgpt/Makefile
index 1f8dede..47856d5 100644
--- a/cgpt/Makefile
+++ b/cgpt/Makefile
@@ -2,44 +2,36 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-CC ?= gcc
-TOP ?= ..
-CFLAGS ?= -Wall -DNDEBUG -O3 -Werror
 CFLAGS += -static
 LDFLAGS += -luuid
-FWDIR=$(TOP)/vboot_firmware
+BUILD_ROOT := ${BUILD}/cgpt
 
 INCLUDES = -I$(FWDIR)/lib/cgptlib/include
-LIBS = $(FWDIR)/vboot_fw.a
+LIBS = ${FWLIB}
 
 DESTDIR ?= /usr/bin
 
-PROGNAME = cgpt
+PROGNAME = ${BUILD_ROOT}/cgpt
 
-OBJS= \
-	cgpt.o \
-	cmd_show.o \
-	cmd_repair.o \
-	cmd_create.o \
-	cmd_add.o \
-	cmd_boot.o \
-	cgpt_common.o
+ALL_SRCS = \
+	cgpt.c \
+	cmd_show.c \
+	cmd_repair.c \
+	cmd_create.c \
+	cmd_add.c \
+	cmd_boot.c \
+	cgpt_common.c
 
+include ../common.mk
 
 all: $(PROGNAME)
 
-$(PROGNAME): $(OBJS) $(LIBS)
+$(PROGNAME): $(ALL_OBJS) $(LIBS)
 	$(CC) -o $(PROGNAME) $(CFLAGS) $^ $(LDFLAGS)
 
-.c.o:
-	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
-
-clean:
-	rm -f $(PROGNAME) *.o *~
-
 install: $(PROGNAME)
 	mkdir -p $(DESTDIR)
 	cp -f $^ $(DESTDIR)
-	chmod a+rx $(patsubst %,$(DESTDIR)/%,$^)
+	chmod a+rx $(patsubst ${BUILD_ROOT}/%,$(DESTDIR)/%,$^)
 
-.PHONY: all clean install
+.PHONY: all install
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..a4a21dd
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,11 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+ALL_OBJS = $(ALL_SRCS:%.c=${BUILD_ROOT}/%.o)
+ALL_DEPS = $(ALL_OBJS:%.o=%.o.d)
+
+${BUILD_ROOT}/%.o : %.c
+	$(CC) $(CFLAGS) $(INCLUDES) -MMD -MF $@.d -c -o $@ $<
+
+-include ${ALL_DEPS}
diff --git a/host/Makefile b/host/Makefile
index f0bdf85..7f1c9f1 100644
--- a/host/Makefile
+++ b/host/Makefile
@@ -2,46 +2,31 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-LIBNAME = vboot_host.a
-
-CC ?= gcc
-CFLAGS = -Wall -DNDEBUG -O3 -Werror
-
 HOSTTOP := $(shell pwd)
-LIBDIR = $(HOSTTOP)/lib
 TESTDIR = $(HOSTTOP)/linktest
+BUILD_ROOT := ${BUILD}/$(shell basename ${HOSTTOP})
 
 INCLUDES += \
 	-I$(HOSTTOP)/include \
 	-I$(FWDIR)/lib/include \
 	-I$(FWDIR)/lib/cgptlib/include \
-	-I$(FWDIR)/lib/cryptolib/include 
+	-I$(FWDIR)/lib/cryptolib/include
 
 # find ./lib -iname '*.c' | sort
-LIB_SRCS = \
+ALL_SRCS = \
 	./lib/host_common.c \
 	./lib/host_key.c \
 	./lib/host_keyblock.c \
 	./lib/host_misc.c \
-	./lib/host_signature.c 
+	./lib/host_signature.c
 
-LIB_OBJS = $(LIB_SRCS:%.c=%.o)
 
-test : $(LIBNAME)
-	$(CC) $(CFLAGS) $(INCLUDES) -o $(TESTDIR)/a.out $(TESTDIR)/main.c \
-	$(LIBNAME) $(FWLIB) -lcrypto
+test : $(HOSTLIB)
+	$(CC) $(CFLAGS) $(INCLUDES) -o $(BUILD_ROOT)/a.out $(TESTDIR)/main.c \
+	$(HOSTLIB) $(FWLIB) -lcrypto
 
-$(LIBNAME) : $(LIB_OBJS) $(STUB_OBJS)
+include ../common.mk
+
+$(HOSTLIB) : $(ALL_OBJS)
 	rm -f $@
 	ar qc $@ $^
-
-%o : %c
-	$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
-
-clean: FORCE
-	rm -f $(LIBNAME) $(LIB_OBJS) $(STUB_OBJS) $(TESTDIR)/a.out
-
-FORCE:
-
-
-.PHONY: FORCE
diff --git a/misclibs/Makefile b/misclibs/Makefile
index 261158b..732f7ee 100644
--- a/misclibs/Makefile
+++ b/misclibs/Makefile
@@ -2,23 +2,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-TOP ?= ../
-CC ?= gcc
 INCLUDES += -I./include \
 		-I$(TOP)/common/include \
 		-I$(TOP)/vboot_firmware/lib/cryptolib/include \
 		-I$(TOP)/vfirmware/include \
 		-I$(TOP)/vkernel/include
 
-CFLAGS ?= -Wall -DNDEBUG -O3 -Werror $(INCLUDES)
-TOP ?= ../
+BUILD_ROOT := ${BUILD}/misclibs
 
-MISCLIB_OUT = file_keys.o signature_digest.o
+ALL_SRCS = file_keys.c signature_digest.c
 
-all: $(MISCLIB_OUT)
+include ../common.mk
 
-.c.o:
-	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
-
-clean: 
-	rm -f $(MISCLIB_OUT)
+all: $(ALL_OBJS)
diff --git a/tests/Makefile b/tests/Makefile
index 5ad4b74..181d1d1 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -2,9 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-TOP ?= ../
-CC ?= gcc
-CFLAGS ?= -Wall -DNDEBUG -O3 -Werror
 INCLUDES += -I./include \
 		-I$(FWDIR)/lib/include \
 		-I$(FWDIR)/lib/cgptlib/include \
@@ -14,12 +11,13 @@
 		-I../vboot_firmware/lib/include\
 		-I../vfirmware/include\
 		-I../vkernel/include
-IMAGE_LIBS = $(TOP)/vfirmware/firmware_image.o \
-		$(TOP)/vkernel/kernel_image.o
-UTIL_LIBS = $(TOP)/misclibs/file_keys.o $(TOP)/misclibs/signature_digest.o
+IMAGE_LIBS = $(BUILD)/vfirmware/firmware_image.o \
+		$(BUILD)/vkernel/kernel_image.o
+UTIL_LIBS = $(BUILD)/misclibs/file_keys.o $(BUILD)/misclibs/signature_digest.o
 LIBS = $(IMAGE_LIBS) $(UTIL_LIBS) $(HOSTLIB) $(FWLIB) -lcrypto
+BUILD_ROOT = ${BUILD}/tests
 
-TEST_BINS = big_firmware_tests \
+TEST_NAMES = big_firmware_tests \
 		big_kernel_tests \
 		cgptlib_test \
 		firmware_image_tests \
@@ -39,97 +37,107 @@
 		vboot_common3_tests \
 		verify_firmware_fuzz_driver \
 		verify_kernel_fuzz_driver
+TEST_BINS = $(addprefix ${BUILD_ROOT}/,$(TEST_NAMES))
+ALL_DEPS = $(addsuffix .d,${TEST_BINS})
 
-all: $(TEST_BINS)
+ifneq (${RUNTESTS},)
+EXTRA_TARGET = runtests
+endif
 
-big_firmware_tests: big_firmware_tests.c rollback_index_mock.c test_common.c
+all: $(TEST_BINS) ${EXTRA_TARGET}
+
+${BUILD_ROOT}/big_firmware_tests: big_firmware_tests.c \
+	rollback_index_mock.c test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-big_kernel_tests: big_kernel_tests.c rollback_index_mock.c test_common.c
+${BUILD_ROOT}/big_kernel_tests: big_kernel_tests.c rollback_index_mock.c \
+	test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-cgptlib_test: cgptlib_test.c crc32_test.c
+${BUILD_ROOT}/cgptlib_test: cgptlib_test.c crc32_test.c
 	$(CC) $(CFLAGS) -ansi $(INCLUDES) $^ -o $@ $(LIBS)
 
-firmware_image_tests: firmware_image_tests.c rollback_index_mock.c test_common.c
+${BUILD_ROOT}/firmware_image_tests: firmware_image_tests.c \
+	rollback_index_mock.c test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-firmware_rollback_tests: firmware_rollback_tests.c rollback_index_mock.c \
+${BUILD_ROOT}/firmware_rollback_tests: firmware_rollback_tests.c \
+	rollback_index_mock.c test_common.c
+	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
+${BUILD_ROOT}/firmware_splicing_tests: firmware_splicing_tests.c \
+	rollback_index_mock.c test_common.c
+	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
+${BUILD_ROOT}/firmware_verify_benchmark: firmware_verify_benchmark.c \
+	timer_utils.c rollback_index_mock.c test_common.c
+	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ -lrt $(LIBS)
+
+${BUILD_ROOT}/kernel_image_tests: kernel_image_tests.c rollback_index_mock.c \
 	test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-firmware_splicing_tests: firmware_splicing_tests.c rollback_index_mock.c \
-	test_common.c
+${BUILD_ROOT}/kernel_rollback_tests: kernel_rollback_tests.c \
+	rollback_index_mock.c test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-firmware_verify_benchmark: firmware_verify_benchmark.c timer_utils.c \
+${BUILD_ROOT}/kernel_splicing_tests: kernel_splicing_tests.c \
+	rollback_index_mock.c test_common.c
+	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
+${BUILD_ROOT}/kernel_verify_benchmark: kernel_verify_benchmark.c timer_utils.c \
 	rollback_index_mock.c test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ -lrt $(LIBS)
 
-kernel_image_tests: kernel_image_tests.c rollback_index_mock.c test_common.c
-	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
-
-kernel_rollback_tests: kernel_rollback_tests.c rollback_index_mock.c \
-	test_common.c
-	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
-
-kernel_splicing_tests: kernel_splicing_tests.c rollback_index_mock.c \
-	test_common.c
-	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
-
-kernel_verify_benchmark: kernel_verify_benchmark.c timer_utils.c \
-	rollback_index_mock.c test_common.c
-	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ -lrt $(LIBS)
-
-rsa_padding_test: rsa_padding_test.c
+${BUILD_ROOT}/rsa_padding_test: rsa_padding_test.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(UTIL_LIBS) $(FWLIB) \
 	-lcrypto
 
-rsa_verify_benchmark: rsa_verify_benchmark.c timer_utils.c
+${BUILD_ROOT}/rsa_verify_benchmark: rsa_verify_benchmark.c timer_utils.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ -lrt $(UTIL_LIBS) $(FWLIB) \
 	-lcrypto
 
-sha_benchmark:	sha_benchmark.c timer_utils.c
+${BUILD_ROOT}/sha_benchmark:	sha_benchmark.c timer_utils.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ -lrt $(FWLIB)
 
-sha_tests: sha_tests.c
+${BUILD_ROOT}/sha_tests: sha_tests.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(FWLIB)
 
-vboot_common_tests: vboot_common_tests.c rollback_index_mock.c test_common.c
+${BUILD_ROOT}/vboot_common_tests: vboot_common_tests.c \
+	rollback_index_mock.c test_common.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-vboot_common2_tests: vboot_common2_tests.c test_common.c $(HOSTLIB) $(FWLIB)
+${BUILD_ROOT}/vboot_common2_tests: vboot_common2_tests.c \
+	test_common.c $(HOSTLIB) $(FWLIB)
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-vboot_common3_tests: vboot_common3_tests.c test_common.c $(HOSTLIB) $(FWLIB)
+${BUILD_ROOT}/vboot_common3_tests: vboot_common3_tests.c \
+	test_common.c $(HOSTLIB) $(FWLIB)
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-verify_firmware_fuzz_driver: verify_firmware_fuzz_driver.c \
+${BUILD_ROOT}/verify_firmware_fuzz_driver: verify_firmware_fuzz_driver.c \
 	rollback_index_mock.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
-verify_kernel_fuzz_driver: verify_kernel_fuzz_driver.c rollback_index_mock.c
+${BUILD_ROOT}/verify_kernel_fuzz_driver: verify_kernel_fuzz_driver.c \
+	rollback_index_mock.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
 runtests:
+	./gen_test_keys.sh
 	# Crypto tests
 	./run_rsa_tests.sh
-	./sha_tests
+	${BUILD_ROOT}/sha_tests
 	./run_vbutil_tests.sh
 	./run_vboot_common_tests.sh
 	./run_image_verification_tests.sh
 	# Splicing tests
-	./firmware_splicing_tests
-	./kernel_splicing_tests	
+	${BUILD_ROOT}/firmware_splicing_tests
+	${BUILD_ROOT}/kernel_splicing_tests
 	# Rollback Tests
-	./firmware_rollback_tests
-	./kernel_rollback_tests
+	${BUILD_ROOT}/firmware_rollback_tests
+	${BUILD_ROOT}/kernel_rollback_tests
 	# Helper Library Tests
-	./cgptlib_test
+	${BUILD_ROOT}/cgptlib_test
 	# Tool tests
-	./run_cgpt_tests.sh
-
-clean:
-	rm -f $(TEST_BINS)
-	rm -f testkeys/*.vbpubk
-	rm -f testkeys/*.keyblock
+	./run_cgpt_tests.sh  ${BUILD}/cgpt/cgpt
diff --git a/tests/common.sh b/tests/common.sh
index 6afcd77..1e2ca03 100755
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -5,7 +5,7 @@
 # found in the LICENSE file.
 
 # Determine script directory.
-if [[ $0 == '/'* ]]; 
+if [[ $0 == '/'* ]];
 then
   SCRIPT_DIR="`dirname $0`"
 elif [[ $0 == './'* ]];
@@ -15,10 +15,17 @@
   SCRIPT_DIR="`pwd`"/"`dirname $0`"
 fi
 
-UTIL_DIR=`dirname ${SCRIPT_DIR}`/utility
-TEST_DIR=${SCRIPT_DIR}
+ROOT_DIR="$(dirname ${SCRIPT_DIR})"
+BUILD_DIR="${ROOT_DIR}/build"
+UTIL_DIR="${BUILD_DIR}/utility"
+TEST_DIR="${BUILD_DIR}/tests"
 TESTKEY_DIR=${SCRIPT_DIR}/testkeys
 TESTCASE_DIR=${SCRIPT_DIR}/testcases
+TESTKEY_SCRATCH_DIR=${TEST_DIR}/testkeys
+
+if [ ! -d ${TESTKEY_SCRATCH_DIR} ]; then
+    mkdir ${TESTKEY_SCRATCH_DIR}
+fi
 
 # Color output encodings.
 COL_RED='\E[31;1m'
diff --git a/tests/gen_test_keys.sh b/tests/gen_test_keys.sh
index bb39fb2..edc3d20 100755
--- a/tests/gen_test_keys.sh
+++ b/tests/gen_test_keys.sh
@@ -13,6 +13,9 @@
 function generate_keys {
   for i in ${key_lengths[@]}
   do
+    if [ -f ${TESTKEY_DIR}/key_rsa$i.keyb ]; then
+      continue
+    fi
     openssl genrsa -F4 -out ${TESTKEY_DIR}/key_rsa$i.pem $i
     # Generate self-signed certificate from key.
     openssl req -batch -new -x509 -key ${TESTKEY_DIR}/key_rsa$i.pem \
diff --git a/tests/run_cgpt_tests.sh b/tests/run_cgpt_tests.sh
index 2dcca99..b70af2f 100755
--- a/tests/run_cgpt_tests.sh
+++ b/tests/run_cgpt_tests.sh
@@ -9,7 +9,7 @@
 # Load common constants and variables.
 . "$(dirname "$0")/common.sh"
 
-GPT=${1:-../cgpt/cgpt}
+GPT=$1
 [ -x "$GPT" ] || error "Can't execute $GPT"
 warning "testing $GPT"
 
diff --git a/tests/run_vbutil_tests.sh b/tests/run_vbutil_tests.sh
index f3e7594..ce86e17 100755
--- a/tests/run_vbutil_tests.sh
+++ b/tests/run_vbutil_tests.sh
@@ -21,7 +21,7 @@
       # Pack the key
       ${UTIL_DIR}/vbutil_key --pack \
         --in ${TESTKEY_DIR}/key_rsa${keylen}.keyb \
-        --out ${TESTKEY_DIR}/key_alg${algorithmcounter}.vbpubk \
+        --out ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk \
         --version 1 \
         --algorithm $algorithmcounter
       if [ $? -ne 0 ]
@@ -32,7 +32,7 @@
       # Unpack the key
       # TODO: should verify we get the same key back out?
       ${UTIL_DIR}/vbutil_key --unpack \
-        --in ${TESTKEY_DIR}/key_alg${algorithmcounter}.vbpubk 
+        --in ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk
       if [ $? -ne 0 ]
       then
         return_code=255
@@ -63,13 +63,15 @@
 and ${COL_YELLOW}data key algorithm RSA-${datakeylen}/\
 ${datahashalgo}${COL_STOP}"
           # Remove old file
-          keyblockfile=${TESTKEY_DIR}/sign${signing_algorithmcounter}_data${data_algorithmcounter}.keyblock
+          keyblockfile="${TESTKEY_SCRATCH_DIR}/"
+          keyblockfile+="sign${signing_algorithmcounter}_data"
+          keyblockfile+="${data_algorithmcounter}.keyblock"
           rm -f ${keyblockfile}
 
           # Pack
           ${UTIL_DIR}/vbutil_keyblock --pack ${keyblockfile} \
             --datapubkey \
-            ${TESTKEY_DIR}/key_alg${data_algorithmcounter}.vbpubk \
+            ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \
             --signprivate ${TESTKEY_DIR}/key_rsa${signing_keylen}.pem \
             --algorithm $signing_algorithmcounter
           if [ $? -ne 0 ]
@@ -80,7 +82,7 @@
           # Unpack
           ${UTIL_DIR}/vbutil_keyblock --unpack ${keyblockfile} \
             --signpubkey \
-            ${TESTKEY_DIR}/key_alg${signing_algorithmcounter}.vbpubk
+            ${TESTKEY_SCRATCH_DIR}/key_alg${signing_algorithmcounter}.vbpubk
           # TODO: check data key against the packed one?
           if [ $? -ne 0 ]
           then
diff --git a/utility/Makefile b/utility/Makefile
index 23c0b65..6a65e0b 100644
--- a/utility/Makefile
+++ b/utility/Makefile
@@ -2,10 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-FWDIR ?= ../vboot_firmware/
-TOP ?= ../
-CC ?= gcc
-CXX ?= g++
 INCLUDES += -I./include \
 		-I$(FWDIR)/lib/include \
 		-I$(FWDIR)/lib/cgptlib/include \
@@ -15,17 +11,20 @@
 		-I../vfirmware/include\
 		-I../vboot_firmware/include\
 		-I../vkernel/include
-CFLAGS ?= -Wall -DNDEBUG -O3 -Werror $(INCLUDES)
-LIBS = $(TOP)/misclibs/file_keys.o \
-	$(TOP)/misclibs/signature_digest.o \
-	$(TOP)/vfirmware/firmware_image.o \
-	$(TOP)/vkernel/kernel_image.o \
+CFLAGS += $(INCLUDES)
+CFLAGS += -MMD -MF $@.d
+LIBS = $(BUILD)/misclibs/file_keys.o \
+	$(BUILD)/misclibs/signature_digest.o \
+	$(BUILD)/vfirmware/firmware_image.o \
+	$(BUILD)/vkernel/kernel_image.o \
 	$(HOSTLIB) \
 	$(FWLIB)
 
+BUILD_ROOT = ${BUILD}/utility
+
 DESTDIR ?= /usr/bin
 
-TARGET_BINS = dumpRSAPublicKey \
+TARGET_NAMES = dumpRSAPublicKey \
 		firmware_utility \
 		gbb_utility \
 		kernel_utility \
@@ -36,47 +35,47 @@
 		vbutil_keyblock \
 		verify_data
 
+TARGET_BINS = $(addprefix ${BUILD_ROOT}/,$(TARGET_NAMES))
+ALL_DEPS = $(addsuffix .d,${TARGET_BINS})
+
 all: $(TARGET_BINS)
 
-dumpRSAPublicKey: dumpRSAPublicKey.c
+${BUILD_ROOT}/dumpRSAPublicKey: dumpRSAPublicKey.c
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ -lcrypto
 
-firmware_utility: firmware_utility.cc $(LIBS)
+${BUILD_ROOT}/firmware_utility: firmware_utility.cc $(LIBS)
 	$(CXX) $(CFLAGS) $(INCLUDES) -ggdb -D__STDC_LIMIT_MACROS $< \
 	-o $@ $(LIBS) -lcrypto
 
-gbb_utility: gbb_utility.cc 
-	$(CXX) -DWITH_UTIL_MAIN $(CFLAGS) $(INCLUDES) $< -o $@
+${BUILD_ROOT}/gbb_utility: gbb_utility.cc
+	$(CXX) -DWITH_UTIL_MAIN $(CFLAGS) $< -o $@
 
-load_kernel_test: load_kernel_test.c $(LIBS)
+${BUILD_ROOT}/load_kernel_test: load_kernel_test.c $(LIBS)
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
 
-kernel_utility: kernel_utility.cc $(LIBS)
+${BUILD_ROOT}/kernel_utility: kernel_utility.cc $(LIBS)
 	$(CXX) $(CFLAGS) $(INCLUDES) -ggdb -D__STDC_LIMIT_MACROS $< \
 	-o $@ $(LIBS) -lcrypto
 
-signature_digest_utility: signature_digest_utility.c $(LIBS)
+${BUILD_ROOT}/signature_digest_utility: signature_digest_utility.c $(LIBS)
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
 
-vbutil_kernel: vbutil_kernel.c $(LIBS)
+${BUILD_ROOT}/vbutil_kernel: vbutil_kernel.c $(LIBS)
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
 
-vbutil_key: vbutil_key.c $(LIBS)
+${BUILD_ROOT}/vbutil_key: vbutil_key.c $(LIBS)
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
 
-vbutil_keyblock: vbutil_keyblock.c $(LIBS)
+${BUILD_ROOT}/vbutil_keyblock: vbutil_keyblock.c $(LIBS)
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
 
-verify_data: verify_data.c $(LIBS)
+${BUILD_ROOT}/verify_data: verify_data.c $(LIBS)
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
 
-clean:
-	rm -f $(TARGET_BINS)
 
 install: $(TARGET_BINS)
 	mkdir -p $(DESTDIR)
 	cp -f $(TARGET_BINS) $(DESTDIR)
-	chmod a+rx $(patsubst %,$(DESTDIR)/%,$(TARGET_BINS))
+	chmod a+rx $(patsubst %,$(DESTDIR)/%,$(TARGET_NAMES))
 
-%o : %c
-	$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
+-include ALL_DEPS
diff --git a/vboot_firmware/Makefile b/vboot_firmware/Makefile
index efdb4db..2440487 100644
--- a/vboot_firmware/Makefile
+++ b/vboot_firmware/Makefile
@@ -2,17 +2,13 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-LIBNAME = vboot_fw.a
-
-CC ?= gcc
-CFLAGS = -Wall -DNDEBUG -O3 -Werror
-
 FWTOP := $(shell pwd)
 LIBDIR = $(FWTOP)/lib
 STUBDIR = $(FWTOP)/stub
 TESTDIR = $(FWTOP)/linktest
+BUILD_ROOT := ${BUILD}/$(shell basename ${FWTOP})
 
-INC = \
+INCLUDES = \
 	-I$(FWTOP)/include \
 	-I$(LIBDIR)/include \
 	-I$(LIBDIR)/cgptlib/include \
@@ -40,32 +36,20 @@
 	./lib/vboot_firmware.c \
 	./lib/vboot_kernel.c
 
-LIB_OBJS = $(LIB_SRCS:%.c=%.o)
-
-# find ./stub -iname '*.c' | sort
 STUB_SRCS = \
 	./stub/boot_device_stub.c \
 	./stub/load_firmware_stub.c \
 	./stub/tlcl.c \
 	./stub/utility_stub.c
 
-STUB_OBJS = $(STUB_SRCS:%.c=%.o)
+ALL_SRCS = ${LIB_SRCS} ${STUB_SRCS}
 
+test : $(FWLIB)
+	$(CC) $(CFLAGS) $(INCLUDES) -o $(BUILD_ROOT)/a.out \
+		$(TESTDIR)/main.c $(FWLIB)
 
-test : $(LIBNAME)
-	$(CC) $(CFLAGS) $(INC) -o $(TESTDIR)/a.out $(TESTDIR)/main.c $(LIBNAME)
+include ../common.mk
 
-$(LIBNAME) : $(LIB_OBJS) $(STUB_OBJS)
+$(FWLIB) : $(ALL_OBJS)
 	rm -f $@
 	ar qc $@ $^
-
-%o : %c
-	$(CC) $(CFLAGS) $(INC) -c -o $@ $<
-
-clean: FORCE
-	rm -f $(LIBNAME) $(LIB_OBJS) $(STUB_OBJS) $(TESTDIR)/a.out
-
-FORCE:
-
-
-.PHONY: FORCE
diff --git a/vfirmware/Makefile b/vfirmware/Makefile
index f4ce6ba..d18d19f 100644
--- a/vfirmware/Makefile
+++ b/vfirmware/Makefile
@@ -2,19 +2,17 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-CC ?= gcc
 INCLUDES += -I./include \
 		-I$(FWDIR)/lib/include \
 		-I$(FWDIR)/lib/cryptolib/include \
 		-I../common/include \
 		-I../misclibs/include
-CFLAGS ?= -Wall -DNDEBUG -O3 -Werror
-FIRMWARE_OUT = firmware_image.o
 
-all: $(FIRMWARE_OUT)
+BUILD_ROOT := ${BUILD}/vfirmware
 
-.c.o:
-	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
+ALL_SRCS = firmware_image.c
 
-clean:
-	rm -f $(FIRMWARE_OUT)
+include ../common.mk
+
+all: $(ALL_OBJS)
+
diff --git a/vkernel/Makefile b/vkernel/Makefile
index 1a9fa07..b71466d 100644
--- a/vkernel/Makefile
+++ b/vkernel/Makefile
@@ -2,20 +2,17 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-CC ?= gcc
 INCLUDES += -I./include \
 		-I$(FWDIR)/lib/include \
 		-I$(FWDIR)/lib/cryptolib/include \
 		-I../common/include \
 		-I../utility/include \
 		-I../misclibs/include
-CFLAGS ?= -Wall -DNDEBUG -O3 -Werror
-KERNEL_OUT = kernel_image.o
 
-all: $(KERNEL_OUT)
+BUILD_ROOT := ${BUILD}/vkernel
 
-.c.o:
-	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
+ALL_SRCS = kernel_image.c
 
-clean:
-	rm -f $(KERNEL_OUT)
+include ../common.mk
+
+all: $(ALL_OBJS)