diff --git a/bare-arm/Makefile b/bare-arm/Makefile
index cfd427c609..90c13de11f 100644
--- a/bare-arm/Makefile
+++ b/bare-arm/Makefile
@@ -4,12 +4,12 @@ include ../py/mkenv.mk
 QSTR_DEFS = qstrdefsport.h
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 CROSS_COMPILE = arm-none-eabi-
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
 
 CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
@@ -45,4 +45,4 @@ $(BUILD)/firmware.elf: $(OBJ)
 	$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
 	$(Q)$(SIZE) $@
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/cc3200/Makefile b/cc3200/Makefile
index 663496435b..4c8b0b8325 100644
--- a/cc3200/Makefile
+++ b/cc3200/Makefile
@@ -34,7 +34,7 @@ ifeq ($(BTARGET), application)
 # qstr definitions (must come before including py.mk)
 QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
 # include MicroPython make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 include application.mk
 else
 ifeq ($(BTARGET), bootloader)
@@ -45,7 +45,7 @@ endif
 endif
 
 # always include MicroPython make rules
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
 
 erase:
 	cc3200tool -p $(PORT) format_flash --size $(FLASH_SIZE_$(BOARD))
diff --git a/cc3200/application.mk b/cc3200/application.mk
index c6b91ed0ed..3ac28823a1 100644
--- a/cc3200/application.mk
+++ b/cc3200/application.mk
@@ -1,5 +1,5 @@
 APP_INC =  -I.
-APP_INC += -I..
+APP_INC += -I$(TOP)
 APP_INC += -Ifatfs/src
 APP_INC += -Ifatfs/src/drivers
 APP_INC += -IFreeRTOS
@@ -10,7 +10,7 @@ APP_INC += -Ihal
 APP_INC += -Ihal/inc
 APP_INC += -Imisc
 APP_INC += -Imods
-APP_INC += -I../drivers/cc3100/inc
+APP_INC += -I$(TOP)/drivers/cc3100/inc
 APP_INC += -Isimplelink
 APP_INC += -Isimplelink/oslib
 APP_INC += -Itelnet
@@ -18,7 +18,7 @@ APP_INC += -Iutil
 APP_INC += -Ibootmgr
 APP_INC += -I$(BUILD)
 APP_INC += -I$(BUILD)/genhdr
-APP_INC += -I../stmhal
+APP_INC += -I$(TOP)/stmhal
 
 APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
 
diff --git a/cc3200/bootmgr/bootloader.mk b/cc3200/bootmgr/bootloader.mk
index ee52369135..b8aa9082c9 100644
--- a/cc3200/bootmgr/bootloader.mk
+++ b/cc3200/bootmgr/bootloader.mk
@@ -4,13 +4,13 @@ BOOT_INC  = -Ibootmgr
 BOOT_INC += -Ibootmgr/sl
 BOOT_INC += -Ihal
 BOOT_INC += -Ihal/inc
-BOOT_INC += -I../drivers/cc3100/inc
+BOOT_INC += -I$(TOP)/drivers/cc3100/inc
 BOOT_INC += -Imisc
 BOOT_INC += -Imods
 BOOT_INC += -Isimplelink
 BOOT_INC += -Isimplelink/oslib
 BOOT_INC += -Iutil
-BOOT_INC += -I..
+BOOT_INC += -I$(TOP)
 BOOT_INC += -I.
 BOOT_INC += -I$(BUILD)
 
diff --git a/esp8266/Makefile b/esp8266/Makefile
index 452efb2cdf..fce11a7d41 100644
--- a/esp8266/Makefile
+++ b/esp8266/Makefile
@@ -12,7 +12,7 @@ FROZEN_DIR ?= scripts
 FROZEN_MPY_DIR ?= modules
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 FWBIN = $(BUILD)/firmware-combined.bin
 PORT ?= /dev/ttyACM0
@@ -23,7 +23,7 @@ CROSS_COMPILE = xtensa-lx106-elf-
 ESP_SDK = $(shell $(CC) -print-sysroot)/usr
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
 INC += -I$(ESP_SDK)/include
 
@@ -220,16 +220,16 @@ ota:
 #$(BUILD)/pins_$(BOARD).o: $(BUILD)/pins_$(BOARD).c
 #	$(call compile_c)
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
 
 axtls: $(BUILD)/libaxtls.a
 
 $(BUILD)/libaxtls.a:
-	cd ../lib/axtls; cp config/upyconfig config/.config
-	cd ../lib/axtls; $(MAKE) oldconfig -B
-	cd ../lib/axtls; $(MAKE) clean
-	cd ../lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=4096"
-	cp ../lib/axtls/_stage/libaxtls.a $@
+	cd $(TOP)/lib/axtls; cp config/upyconfig config/.config
+	cd $(TOP)/lib/axtls; $(MAKE) oldconfig -B
+	cd $(TOP)/lib/axtls; $(MAKE) clean
+	cd $(TOP)/lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=4096"
+	cp $(TOP)/lib/axtls/_stage/libaxtls.a $@
 
 clean-modules:
 	git clean -f -d modules
diff --git a/minimal/Makefile b/minimal/Makefile
index 0fc9194387..c95d639aff 100644
--- a/minimal/Makefile
+++ b/minimal/Makefile
@@ -6,19 +6,19 @@ CROSS = 0
 QSTR_DEFS = qstrdefsport.h
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 ifeq ($(CROSS), 1)
 CROSS_COMPILE = arm-none-eabi-
 endif
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
 
 ifeq ($(CROSS), 1)
-DFU = ../tools/dfu.py
-PYDFU = ../tools/pydfu.py
+DFU = $(TOP)/tools/dfu.py
+PYDFU = $(TOP)/tools/pydfu.py
 CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
 CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
 LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref --gc-sections
@@ -57,7 +57,7 @@ endif
 
 $(BUILD)/_frozen_mpy.c: frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h
 	$(ECHO) "MISC freezing bytecode"
-	$(Q)../tools/mpy-tool.py -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h -mlongint-impl=none $< > $@
+	$(Q)$(TOP)/tools/mpy-tool.py -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h -mlongint-impl=none $< > $@
 
 $(BUILD)/firmware.elf: $(OBJ)
 	$(ECHO) "LINK $@"
@@ -87,4 +87,4 @@ run:
 test: $(BUILD)/firmware.elf
 	$(Q)/bin/echo -e "print('hello world!', list(x+1 for x in range(10)), end='eol\\\\n')\\r\\n\\x04" | $(BUILD)/firmware.elf | tail -n2 | grep "^hello world! \\[1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\]eol"
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile
index cdec130eed..5399b5ae77 100644
--- a/mpy-cross/Makefile
+++ b/mpy-cross/Makefile
@@ -23,10 +23,10 @@ QSTR_DEFS = qstrdefsport.h
 UNAME_S := $(shell uname -s)
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 INC +=  -I.
-INC +=  -I..
+INC +=  -I$(TOP)
 INC += -I$(BUILD)
 
 # compiler settings
@@ -71,4 +71,4 @@ endif
 OBJ = $(PY_O)
 OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/pic16bit/Makefile b/pic16bit/Makefile
index b953612fdb..ebf4fc2e80 100644
--- a/pic16bit/Makefile
+++ b/pic16bit/Makefile
@@ -4,7 +4,7 @@ include ../py/mkenv.mk
 QSTR_DEFS = qstrdefsport.h
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 XC16 = /opt/microchip/xc16/v1.24
 CROSS_COMPILE = $(XC16)/bin/xc16-
@@ -13,7 +13,7 @@ PARTFAMILY = dsPIC33F
 PART = 33FJ256GP506
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
 INC += -I$(XC16)/include
 INC += -I$(XC16)/support/$(PARTFAMILY)/h
@@ -67,4 +67,4 @@ $(BUILD)/firmware.elf: $(OBJ)
 $(PY_BUILD)/gc.o: CFLAGS += -O1
 $(PY_BUILD)/vm.o: CFLAGS += -O1
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/py/py.mk b/py/py.mk
index 02f2df8e12..6632376032 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -22,13 +22,13 @@ CFLAGS_MOD += -DFFCONF_H=\"lib/oofatfs/ffconf.h\"
 ifeq ($(MICROPY_PY_USSL),1)
 CFLAGS_MOD += -DMICROPY_PY_USSL=1
 ifeq ($(MICROPY_SSL_AXTLS),1)
-CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I../lib/axtls/ssl -I../lib/axtls/crypto -I../lib/axtls/config
+CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/lib/axtls/config
 LDFLAGS_MOD += -Lbuild -laxtls
 else ifeq ($(MICROPY_SSL_MBEDTLS),1)
 # Can be overridden by ports which have "builtin" mbedTLS
-MICROPY_SSL_MBEDTLS_INCLUDE ?= ../lib/mbedtls/include
+MICROPY_SSL_MBEDTLS_INCLUDE ?= $(TOP)/lib/mbedtls/include
 CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(MICROPY_SSL_MBEDTLS_INCLUDE)
-LDFLAGS_MOD += -L../lib/mbedtls/library -lmbedx509 -lmbedtls -lmbedcrypto
+LDFLAGS_MOD += -L$(TOP)/lib/mbedtls/library -lmbedx509 -lmbedtls -lmbedcrypto
 endif
 endif
 
@@ -38,7 +38,7 @@ endif
 
 ifeq ($(MICROPY_PY_LWIP),1)
 LWIP_DIR = lib/lwip/src
-INC += -I../lib/lwip/src/include -I../lib/lwip/src/include/ipv4 -I../extmod/lwip-include
+INC += -I$(TOP)/lib/lwip/src/include -I$(TOP)/lib/lwip/src/include/ipv4 -I$(TOP)/extmod/lwip-include
 CFLAGS_MOD += -DMICROPY_PY_LWIP=1
 SRC_MOD += extmod/modlwip.c lib/netutils/netutils.c
 SRC_MOD += $(addprefix $(LWIP_DIR)/,\
@@ -75,7 +75,7 @@ endif
 ifeq ($(MICROPY_PY_BTREE),1)
 BTREE_DIR = lib/berkeley-db-1.xx
 BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error=printf -Dabort=abort_ -Dvirt_fd_t=mp_obj_t "-DVIRT_FD_T_HEADER=<py/obj.h>"
-INC += -I../$(BTREE_DIR)/PORT/include
+INC += -I$(TOP)/$(BTREE_DIR)/PORT/include
 SRC_MOD += extmod/modbtree.c
 SRC_MOD += $(addprefix $(BTREE_DIR)/,\
 btree/bt_close.c \
diff --git a/qemu-arm/Makefile b/qemu-arm/Makefile
index 743b6683a8..71403cb5e7 100644
--- a/qemu-arm/Makefile
+++ b/qemu-arm/Makefile
@@ -5,14 +5,14 @@ include ../py/mkenv.mk
 QSTR_DEFS = qstrdefsport.h
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 CROSS_COMPILE = arm-none-eabi-
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
-INC += -I../tools/tinytest/
+INC += -I$(TOP)/tools/tinytest/
 
 CFLAGS_CORTEX_M3 = -mthumb -mcpu=cortex-m3 -mfloat-abi=soft
 CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 $(CFLAGS_CORTEX_M3) $(COPT) \
@@ -98,10 +98,10 @@ test: $(BUILD)/firmware-test.elf
 
 $(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h
 $(BUILD)/genhdr/tests.h:
-	$(Q)echo "Generating $@";(cd ../tests; ../tools/tinytest-codegen.py) > $@
+	$(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@
 
 $(BUILD)/tinytest.o:
-	$(Q)$(CC) $(CFLAGS) -DNO_FORKING -o $@ -c ../tools/tinytest/tinytest.c
+	$(Q)$(CC) $(CFLAGS) -DNO_FORKING -o $@ -c $(TOP)/tools/tinytest/tinytest.c
 
 ## `$(LD)` doesn't seem to like `--specs` for some reason, but we can just use `$(CC)` here.
 $(BUILD)/firmware.elf: $(OBJ_COMMON) $(OBJ_RUN)
@@ -112,4 +112,4 @@ $(BUILD)/firmware-test.elf: $(OBJ_COMMON) $(OBJ_TEST)
 	$(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
 	$(Q)$(SIZE) $@
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/stmhal/Makefile b/stmhal/Makefile
index ae1db2ae95..8735d84c31 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -19,7 +19,7 @@ QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h $(BUILD)/modstm_qstr.h
 FROZEN_MPY_DIR ?= modules
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 LD_DIR=boards
 CMSIS_DIR=cmsis
@@ -27,10 +27,10 @@ HAL_DIR=hal/$(MCU_SERIES)
 USBDEV_DIR=usbdev
 #USBHOST_DIR=usbhost
 FATFS_DIR=lib/oofatfs
-DFU=../tools/dfu.py
+DFU=$(TOP)/tools/dfu.py
 # may need to prefix dfu-util with sudo
 USE_PYDFU ?= 1
-PYDFU ?= ../tools/pydfu.py
+PYDFU ?= $(TOP)/tools/pydfu.py
 DFU_UTIL ?= dfu-util
 DEVICE=0483:df11
 STFLASH ?= st-flash
@@ -40,9 +40,9 @@ OPENOCD_CONFIG ?= boards/openocd_stm32f4.cfg
 CROSS_COMPILE = arm-none-eabi-
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
-INC += -I../lib/cmsis/inc
+INC += -I$(TOP)/lib/cmsis/inc
 INC += -I$(CMSIS_DIR)/
 INC += -I$(HAL_DIR)/inc
 INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc
@@ -406,8 +406,8 @@ GEN_PINS_QSTR = $(BUILD)/pins_qstr.h
 GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h
 GEN_PINS_AF_PY = $(BUILD)/pins_af.py
 
-INSERT_USB_IDS = ../tools/insert-usb-ids.py
-FILE2H = ../tools/file2h.py
+INSERT_USB_IDS = $(TOP)/tools/insert-usb-ids.py
+FILE2H = $(TOP)/tools/file2h.py
 
 USB_IDS_FILE = usb.h
 CDCINF_TEMPLATE = pybcdc.inf_template
@@ -464,4 +464,4 @@ $(GEN_CDCINF_FILE): $(CDCINF_TEMPLATE) $(INSERT_USB_IDS) $(USB_IDS_FILE) | $(HEA
 	$(ECHO) "Create $@"
 	$(Q)$(PYTHON) $(INSERT_USB_IDS) $(USB_IDS_FILE) $< > $@
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/teensy/Makefile b/teensy/Makefile
index 575e15e542..944e281a43 100644
--- a/teensy/Makefile
+++ b/teensy/Makefile
@@ -4,7 +4,7 @@ include ../py/mkenv.mk
 QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 # If you set USE_ARDUINO_TOOLCHAIN=1 then this makefile will attempt to use
 # the toolchain that comes with Teensyduino
@@ -30,8 +30,8 @@ CFLAGS_TEENSY = -DF_CPU=96000000 -DUSB_SERIAL -D__MK20DX256__
 CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mcpu=cortex-m4 -msoft-float -mfloat-abi=soft -fsingle-precision-constant -Wdouble-promotion $(CFLAGS_TEENSY)
 
 INC += -I.
-INC += -I..
-INC += -I../stmhal
+INC += -I$(TOP)
+INC += -I$(TOP)/stmhal
 INC += -I$(BUILD)
 INC += -Icore
 
@@ -135,7 +135,7 @@ SRC_C += \
 
 OBJ += $(BUILD)/memzip-files.o
 
-MAKE_MEMZIP = ../lib/memzip/make-memzip.py
+MAKE_MEMZIP = $(TOP)/lib/memzip/make-memzip.py
 ifeq ($(MEMZIP_DIR),)
 MEMZIP_DIR = memzip_files
 endif
@@ -232,4 +232,4 @@ $(BUILD)/%.pp: $(BUILD)/%.c
 	$(ECHO) "PreProcess $<"
 	$(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/unix/Makefile b/unix/Makefile
index 8672b4f188..08bd4db306 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -14,10 +14,10 @@ QSTR_DEFS = qstrdefsport.h
 UNAME_S := $(shell uname -s)
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 INC +=  -I.
-INC +=  -I..
+INC +=  -I$(TOP)
 INC += -I$(BUILD)
 
 # compiler settings
@@ -87,7 +87,7 @@ endif
 endif
 
 ifeq ($(MICROPY_USE_READLINE),1)
-INC +=  -I../lib/mp-readline
+INC +=  -I$(TOP)/lib/mp-readline
 CFLAGS_MOD += -DMICROPY_USE_READLINE=1
 LIB_SRC_C_EXTRA += mp-readline/readline.c
 endif
@@ -107,11 +107,11 @@ endif
 ifeq ($(MICROPY_PY_FFI),1)
 
 ifeq ($(MICROPY_STANDALONE),1)
-LIBFFI_CFLAGS_MOD := -I$(shell ls -1d ../lib/libffi/build_dir/out/lib/libffi-*/include)
+LIBFFI_CFLAGS_MOD := -I$(shell ls -1d $(TOP)/lib/libffi/build_dir/out/lib/libffi-*/include)
  ifeq ($(MICROPY_FORCE_32BIT),1)
-  LIBFFI_LDFLAGS_MOD = ../lib/libffi/build_dir/out/lib32/libffi.a
+  LIBFFI_LDFLAGS_MOD = $(TOP)/lib/libffi/build_dir/out/lib32/libffi.a
  else
-  LIBFFI_LDFLAGS_MOD = ../lib/libffi/build_dir/out/lib/libffi.a
+  LIBFFI_LDFLAGS_MOD = $(TOP)/lib/libffi/build_dir/out/lib/libffi.a
  endif
 else
 LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi)
@@ -183,13 +183,13 @@ MPY_CROSS_FLAGS += -mcache-lookup-bc
 endif
 
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
 
 .PHONY: test
 
-test: $(PROG) ../tests/run-tests
+test: $(PROG) $(TOP)/tests/run-tests
 	$(eval DIRNAME=$(notdir $(CURDIR)))
-	cd ../tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests
+	cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests
 
 # install micropython in /usr/local/bin
 TARGET = micropython
@@ -254,12 +254,12 @@ coverage:
 
 coverage_test: coverage
 	$(eval DIRNAME=$(notdir $(CURDIR)))
-	cd ../tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests
-	cd ../tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -d thread
-	cd ../tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --emit native
-	cd ../tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy -d basics float
-	gcov -o build-coverage/py ../py/*.c
-	gcov -o build-coverage/extmod ../extmod/*.c
+	cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests
+	cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -d thread
+	cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --emit native
+	cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy -d basics float
+	gcov -o build-coverage/py $(TOP)/py/*.c
+	gcov -o build-coverage/extmod $(TOP)/extmod/*.c
 
 # Value of configure's --host= option (required for cross-compilation).
 # Deduce it from CROSS_COMPILE by default, but can be overridden.
@@ -274,21 +274,21 @@ deplibs: libffi axtls
 # install-exec-recursive & install-data-am targets are used to avoid building
 # docs and depending on makeinfo
 libffi:
-	cd ../lib/libffi; git clean -d -x -f
-	cd ../lib/libffi; ./autogen.sh
-	mkdir -p ../lib/libffi/build_dir; cd ../lib/libffi/build_dir; \
+	cd $(TOP)/lib/libffi; git clean -d -x -f
+	cd $(TOP)/lib/libffi; ./autogen.sh
+	mkdir -p $(TOP)/lib/libffi/build_dir; cd $(TOP)/lib/libffi/build_dir; \
 	../configure $(CROSS_COMPILE_HOST) --prefix=$$PWD/out --disable-structs CC="$(CC)" CXX="$(CXX)" LD="$(LD)" CFLAGS="-Os -fomit-frame-pointer -fstrict-aliasing -ffast-math -fno-exceptions"; \
 	$(MAKE) install-exec-recursive; $(MAKE) -C include install-data-am
 
 axtls: $(BUILD)/libaxtls.a
 
-$(BUILD)/libaxtls.a: ../lib/axtls/README | $(OBJ_DIRS)
-	cd ../lib/axtls; cp config/upyconfig config/.config
-	cd ../lib/axtls; $(MAKE) oldconfig -B
-	cd ../lib/axtls; $(MAKE) clean
-	cd ../lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)"
-	cp ../lib/axtls/_stage/libaxtls.a $@
+$(BUILD)/libaxtls.a: $(TOP)/lib/axtls/README | $(OBJ_DIRS)
+	cd $(TOP)/lib/axtls; cp config/upyconfig config/.config
+	cd $(TOP)/lib/axtls; $(MAKE) oldconfig -B
+	cd $(TOP)/lib/axtls; $(MAKE) clean
+	cd $(TOP)/lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)"
+	cp $(TOP)/lib/axtls/_stage/libaxtls.a $@
 
-../lib/axtls/README:
+$(TOP)/lib/axtls/README:
 	@echo "You cloned without --recursive, fetching submodules for you."
-	(cd ..; git submodule update --init --recursive)
+	(cd $(TOP); git submodule update --init --recursive)
diff --git a/windows/Makefile b/windows/Makefile
index 72c97381bd..a39d348266 100644
--- a/windows/Makefile
+++ b/windows/Makefile
@@ -8,10 +8,10 @@ PROG = micropython.exe
 QSTR_DEFS = ../unix/qstrdefsport.h
 
 # include py core make definitions
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
 
 # compiler settings
@@ -62,4 +62,4 @@ SRC_QSTR += $(SRC_C)
 # SRC_QSTR
 SRC_QSTR_AUTO_DEPS +=
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
diff --git a/zephyr/Makefile b/zephyr/Makefile
index 988b32fe89..5840cc47ec 100644
--- a/zephyr/Makefile
+++ b/zephyr/Makefile
@@ -27,10 +27,10 @@ include $(Z_EXPORTS)
 endif
 
 include ../py/mkenv.mk
-include ../py/py.mk
+include $(TOP)/py/py.mk
 
 INC += -I.
-INC += -I..
+INC += -I$(TOP)
 INC += -I$(BUILD)
 INC += -I$(ZEPHYR_BASE)/net/ip
 INC += -I$(ZEPHYR_BASE)/net/ip/contiki
@@ -59,7 +59,7 @@ OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
 CFLAGS = $(KBUILD_CFLAGS) $(NOSTDINC_FLAGS) $(ZEPHYRINCLUDE) \
 	 -std=gnu99 -fomit-frame-pointer -DNDEBUG -DMICROPY_HEAP_SIZE=$(MICROPY_HEAP_SIZE) $(CFLAGS_EXTRA) $(INC)
 
-include ../py/mkrules.mk
+include $(TOP)/py/mkrules.mk
 
 # We use single target here ($(Z_EXPORTS)) for simplicity, but actually
 # number of things get generated here: 'initconfig' generates C header for
@@ -102,4 +102,4 @@ prj_$(BOARD)_merged.conf: prj_base.conf prj_$(BOARD).conf
 	$(PYTHON) makeprj.py prj_base.conf prj_$(BOARD).conf $@
 
 test:
-	cd ../tests && ./run-tests --target minimal --device "execpty:make -C ../zephyr run BOARD=$(BOARD) QEMU_PTY=1"
+	cd $(TOP)/tests && ./run-tests --target minimal --device "execpty:make -C ../zephyr run BOARD=$(BOARD) QEMU_PTY=1"