From 3068e74d26ef6548f1fcdd694fbab6ceaa6ff10e Mon Sep 17 00:00:00 2001
From: Brendan Bartels <bbartels@iastate.edu>
Date: Thu, 9 Mar 2017 22:29:15 -0600
Subject: [PATCH] wip: better makefile setup

---
 quad/.gitignore                               |   2 +
 quad/Makefile                                 |  68 ++----
 quad/library.mk                               |  78 ++++++
 quad/src/computation_graph/.gitignore         |   7 +-
 quad/src/computation_graph/Makefile           | 222 +-----------------
 quad/src/computation_graph/Makefile_old       | 220 +++++++++++++++++
 quad/src/computation_graph/node_accumulator.h |   2 +-
 quad/src/computation_graph/node_add.h         |   2 +-
 quad/src/computation_graph/node_constant.h    |   2 +-
 quad/src/computation_graph/node_gain.h        |   2 +-
 quad/src/computation_graph/node_mult.h        |   2 +-
 quad/src/computation_graph/node_pow.h         |   2 +-
 .../{ => test}/test_computation_graph.c       |  12 +-
 quad/src/computation_graph/tests.c            | 151 ------------
 quad/src/computation_graph/tests.h            |  32 ---
 quad/src/gen_diagram/generate.c               |   8 +-
 quad/src/quad_app/.gitignore                  |   2 +
 quad/src/quad_app/Makefile                    |   6 +
 quad/src/quad_app/commands.c                  |   2 +-
 quad/src/quad_app/commands.h                  |   2 +-
 quad/src/quad_app/communication.h             |   1 -
 quad/src/quad_app/computation_graph.c         |   1 -
 quad/src/quad_app/computation_graph.h         |   1 -
 quad/src/quad_app/control_algorithm.c         |  10 +-
 quad/src/quad_app/controllers.c               |   1 -
 quad/src/quad_app/graph_blocks/node_add.c     |   1 -
 quad/src/quad_app/graph_blocks/node_add.h     |   1 -
 .../src/quad_app/graph_blocks/node_constant.c |   1 -
 .../src/quad_app/graph_blocks/node_constant.h |   1 -
 quad/src/quad_app/hw_iface.h                  |   6 +
 quad/src/quad_app/iic_utils.c                 |  28 +--
 quad/src/quad_app/iic_utils.h                 |   3 -
 quad/src/quad_app/initialize_components.h     |   1 -
 quad/src/quad_app/log_data.c                  |   7 +-
 quad/src/quad_app/main.c                      |   2 +-
 quad/src/quad_app/mio7_led.c                  |  10 +-
 quad/src/quad_app/mio7_led.h                  |   1 -
 quad/src/quad_app/node_bounds.h               |   2 +-
 quad/src/quad_app/node_mixer.h                |   2 +-
 quad/src/quad_app/node_pid.h                  |   2 +-
 quad/src/quad_app/packet_processing.c         |   1 -
 quad/src/quad_app/timer.c                     |  11 -
 quad/src/quad_app/timer.h                     |   2 +-
 quad/src/quad_app/util.c                      |  14 --
 quad/src/quad_app/util.h                      |   3 -
 quad/src/queue/.gitignore                     |   4 +-
 quad/src/queue/Makefile                       |  15 +-
 quad/src/queue/{ => test}/test_queue.c        |   0
 quad/src/test/.gitignore                      |   5 +-
 quad/src/test/Makefile                        |  17 +-
 quad/src/test/{ => example}/example.c         |   0
 .../modular_quad_pid/src/main.c               |  19 ++
 52 files changed, 423 insertions(+), 574 deletions(-)
 create mode 100644 quad/library.mk
 create mode 100644 quad/src/computation_graph/Makefile_old
 rename quad/src/computation_graph/{ => test}/test_computation_graph.c (97%)
 delete mode 100644 quad/src/computation_graph/tests.c
 delete mode 100644 quad/src/computation_graph/tests.h
 create mode 100644 quad/src/quad_app/.gitignore
 create mode 100644 quad/src/quad_app/Makefile
 delete mode 120000 quad/src/quad_app/computation_graph.c
 delete mode 120000 quad/src/quad_app/computation_graph.h
 delete mode 120000 quad/src/quad_app/graph_blocks/node_add.c
 delete mode 120000 quad/src/quad_app/graph_blocks/node_add.h
 delete mode 120000 quad/src/quad_app/graph_blocks/node_constant.c
 delete mode 120000 quad/src/quad_app/graph_blocks/node_constant.h
 rename quad/src/queue/{ => test}/test_queue.c (100%)
 rename quad/src/test/{ => example}/example.c (100%)
 create mode 100644 quad/xsdk_workspace/modular_quad_pid/src/main.c

diff --git a/quad/.gitignore b/quad/.gitignore
index 47696c7b6..d22e061fd 100644
--- a/quad/.gitignore
+++ b/quad/.gitignore
@@ -3,4 +3,6 @@ zybo_fsbl/
 test.log
 inc/
 obj/
+lib/
+lib-zybo/
 TAGS
\ No newline at end of file
diff --git a/quad/Makefile b/quad/Makefile
index 26713a948..42c990ec1 100644
--- a/quad/Makefile
+++ b/quad/Makefile
@@ -1,56 +1,26 @@
-# Declaration of variables
+INCDIR = inc
+LIBDIR = lib
+ZYBOLIBDIR = lib-zybo
 
-# Generic Variables
-GCC=gcc
-CFLAGS= -Wall
+.PHONY: default zybo all test clean
 
-HEADERS = $(shell find src -name "*.h")
-INCLUDES = $(foreach dir, $(INCDIR), -I$(dir))
-INCDIR=inc
-LIBS=
-OBJDIR=obj
+default:
+	$(MAKE) -C src/test
+	$(MAKE) -C src/queue
+	$(MAKE) -C src/computation_graph
+	$(MAKE) -C src/quad_app
 
-# Test library specific variables
-TESTSRCDIR=src/test
-TESTSOURCES := $(wildcard $(TESTSRCDIR)/*.c )
-TESTOBJECTS = $(TESTCSOURCES:$(TESTSRCDIR)/%.c=$(OBJDIR)/%.o)
+zybo:
+	$(MAKE) -C src/test zybo
+	$(MAKE) -C src/queue zybo
+	$(MAKE) -C src/computation_graph zybo
+	$(MAKE) -C src/quad_app zybo
 
-# Queue library specific variables
-QUEUESRCDIR=src/queue
-QUEUESOURCES := $(wildcard $(QUEUESRCDIR)/*.c)
-QUEUEOBJECTS = $(QUEUESOURCES:$(QUEUESRCDIR)/%.c=$(OBJDIR)/%.o)
+all: default zybo
 
-# Computation graph library specific variables
-COMPGRAPHSRCDIR=src/computation_graph
-COMPGRAPHSOURCES := $(wildcard $(COMPGRAPHSRCDIR)/*.c)
-COMPGRAPHOBJECTS = $(COMPGRAPHSOURCES:$(COMPGRAPHSRCDIR)/%.c=$(OBJDIR)/%.o)
-
-# Quad app library specific variables
-QUADAPPSRCDIR=src/quad_app
-QUADAPPSOURCES := $(wildcard $(QUADAPPSRCDIR)/*.c)
-QUADAPPOBJECTS = $(QUADAPPSOURCES:$(QUADAPPSRCDIR)/%.c=$(OBJDIR)/%.o)
-
-# Default target
-all: $(INCDIR) $(OBJDIR) $(TESTOBJECTS) $(QUEUEOBJECTS) $(COMPGRAPHOBJECTS) $(QUADAPPOBJECTS)
-
-$(TESTOBJECTS) : $(OBJDIR)/%.o : $(TESTSRCDIR)/%.c
-	$(GCC)  $(CFLAGS) -c $^ -o $@ $(INCLUDES)
-
-$(QUEUEOBJECTS) : $(OBJDIR)/%.o : $(QUEUESRCDIR)/%.c
-	$(GCC)  $(CFLAGS) -c $^ -o $@ $(INCLUDES)
-
-$(COMPGRAPHOBJECTS) : $(OBJDIR)/%.o : $(COMPGRAPHSRCDIR)/%.c
-	$(GCC)  $(CFLAGS) -c $^ -o $@ $(INCLUDES)
-
-$(QUADAPPOBJECTS) : $(OBJDIR)/%.o : $(QUADAPPSRCDIR)/%.c
-	$(GCC)  $(CFLAGS) -c $^ -o $@ $(INCLUDES)
-
-$(INCDIR): $(HEADERS)
-	[ -d $(INCDIR) ] || mkdir $(INCDIR)
-	cp $^ $(INCDIR)
-
-$(OBJDIR):
-	[ -d $(OBJDIR) ] || mkdir $(OBJDIR)
+test:
+	$(MAKE) -C src/queue test
+	$(MAKE) -C src/computation_graph test
 
 clean:
-	rm -rf $(OBJDIR)/
+	rm -rf $(INCDIR) $(LIBDIR) $(ZYBOLIBDIR)
diff --git a/quad/library.mk b/quad/library.mk
new file mode 100644
index 000000000..e5f70e9d7
--- /dev/null
+++ b/quad/library.mk
@@ -0,0 +1,78 @@
+GCC = gcc
+AR = ar
+ZYBOGCC = /remote/Xilinx/2015.4/SDK/2015.4/gnu/arm/lin/bin/arm-xilinx-eabi-gcc
+ZYBOAR = /remote/Xilinx/2015.4/SDK/2015.4/gnu/arm/lin/bin/arm-xilinx-eabi-ar
+
+INCDIR = $(TOP)/inc
+OBJDIR = obj
+ZYBOOBJDIR = obj-zybo
+LIBDIR = $(TOP)/lib
+ZYBOLIBDIR = $(TOP)/lib-zybo
+
+SOURCES = $(wildcard *.c)
+TESTSOURCES = $(wildcard test/*.c)
+HEADERS = $(wildcard *.h)
+INCLUDES = $(addprefix $(INCDIR)/, $(HEADERS))
+OBJECTS = $(patsubst %.c, $(OBJDIR)/%.o, $(SOURCES))
+ZYBOOBJECTS = $(patsubst %.c, $(ZYBOOBJDIR)/%.o, $(SOURCES))
+TESTOBJECTS = $(patsubst $.c, %.o, $(TESTSOURCES))
+
+TARGET = $(LIBDIR)/lib$(NAME).a
+ZYBOTARGET = $(ZYBOLIBDIR)/lib$(NAME).a
+TESTBIN = run_tests
+
+.PHONY: default zybo all test clean
+
+################
+## User Targets
+################
+
+default: $(TARGET) $(INCLUDES)
+
+zybo: $(ZYBOTARGET) $(INCLUDES)
+
+all: default zybo
+
+test: $(TESTBIN)
+	./$(TESTBIN)
+
+clean:
+	rm -rf $(TARGET) $(ZYBOTARGET) $(INCLUDES) $(OBJDIR) $(ZYBOOBJDIR)
+
+####################
+## Internal Targets
+####################
+
+$(TARGET): $(OBJECTS) | $(LIBDIR)
+	$(AR) rcs $@ $^
+
+$(ZYBOTARGET): $(ZYBOOBJECTS) | $(ZYBOLIBDIR)
+	$(ZYBOAR) rcs $@ $^
+
+$(OBJDIR)/%.o : %.c | $(OBJDIR) $(INCDIR)
+	$(GCC) -c -g -o $@ $< -I$(INCDIR)
+
+$(ZYBOOBJDIR)/%.o : %.c | $(ZYBOOBJDIR) $(INCDIR)
+	$(ZYBOGCC) -c -g -o $@ $< -I$(INCDIR)
+
+$(INCDIR)/%.h : %.h | $(INCDIR)
+	cp $^ $(INCDIR)
+
+$(INCDIR):
+	mkdir $(INCDIR)
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+$(LIBDIR):
+	mkdir $(LIBDIR)
+
+$(ZYBOOBJDIR):
+	mkdir $(ZYBOOBJDIR)
+
+$(ZYBOLIBDIR):
+	mkdir $(ZYBOLIBDIR)
+
+
+$(TESTBIN): $(TESTOBJECTS) $(OBJECTS)
+	$(GCC) -o $(TESTBIN) $^ -I$(INCDIR) -L$(LIBDIR) $(REQLIBS)
diff --git a/quad/src/computation_graph/.gitignore b/quad/src/computation_graph/.gitignore
index 429b549db..da2dc67a4 100644
--- a/quad/src/computation_graph/.gitignore
+++ b/quad/src/computation_graph/.gitignore
@@ -1,4 +1,3 @@
-bin/
-build/
-computation_graph
-test/test_computation_graph
+run_tests
+obj/
+obj-zybo/
diff --git a/quad/src/computation_graph/Makefile b/quad/src/computation_graph/Makefile
index 44c7e5926..5142ac39b 100644
--- a/quad/src/computation_graph/Makefile
+++ b/quad/src/computation_graph/Makefile
@@ -1,220 +1,6 @@
-#### PROJECT SETTINGS ####
-# The name of the executable to be created
-BIN_NAME := computation_graph
-# Compiler used
-CC ?= gcc
-# Extension of source files used in the project
-SRC_EXT = c
-# Path to the source directory, relative to the makefile
-SRC_PATH = ./src
-# Space-separated pkg-config libraries used by this project
-LIBS =
-# General compiler flags
-COMPILE_FLAGS = -std=c99 -Wall -Wextra -g
-# Additional release-specific flags
-RCOMPILE_FLAGS = -D NDEBUG
-# Additional debug-specific flags
-DCOMPILE_FLAGS = -D DEBUG
-# Add additional include paths
-INCLUDES = -I $(SRC_PATH)
-# General linker settings
-LINK_FLAGS = -lm
-# Additional release-specific linker settings
-RLINK_FLAGS =
-# Additional debug-specific linker settings
-DLINK_FLAGS =
-# Destination directory, like a jail or mounted system
-DESTDIR = /
-# Install path (bin/ is appended automatically)
-INSTALL_PREFIX = usr/local
-#### END PROJECT SETTINGS ####
+TOP=../..
 
-# Generally should not need to edit below this line
+NAME = computation_graph
+REQLIBS = -ltest -lm
 
-# Obtains the OS type, either 'Darwin' (OS X) or 'Linux'
-UNAME_S:=$(shell uname -s)
-
-# Function used to check variables. Use on the command line:
-# make print-VARNAME
-# Useful for debugging and adding features
-print-%: ; @echo $*=$($*)
-
-# Shell used in this makefile
-# bash is used for 'echo -en'
-SHELL = /bin/bash
-# Clear built-in rules
-.SUFFIXES:
-# Programs for installation
-INSTALL = install
-INSTALL_PROGRAM = $(INSTALL)
-INSTALL_DATA = $(INSTALL) -m 644
-
-# Append pkg-config specific libraries if need be
-ifneq ($(LIBS),)
-	COMPILE_FLAGS += $(shell pkg-config --cflags $(LIBS))
-	LINK_FLAGS += $(shell pkg-config --libs $(LIBS))
-endif
-
-# Verbose option, to output compile and link commands
-export V := false
-export CMD_PREFIX := @
-ifeq ($(V),true)
-	CMD_PREFIX :=
-endif
-
-# Combine compiler and linker flags
-release: export CFLAGS := $(CFLAGS) $(COMPILE_FLAGS) $(RCOMPILE_FLAGS)
-release: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(RLINK_FLAGS)
-debug: export CFLAGS := $(CFLAGS) $(COMPILE_FLAGS) $(DCOMPILE_FLAGS)
-debug: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(DLINK_FLAGS)
-
-# Build and output paths
-release: export BUILD_PATH := build/release
-release: export BIN_PATH := bin/release
-debug: export BUILD_PATH := build/debug
-debug: export BIN_PATH := bin/debug
-install: export BIN_PATH := bin/release
-
-# Find all source files in the source directory, sorted by most
-# recently modified
-ifeq ($(UNAME_S),Darwin)
-	SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' | sort -k 1nr | cut -f2-)
-else
-	SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' -printf '%T@\t%p\n' \
-						| sort -k 1nr | cut -f2-)
-endif
-
-# fallback in case the above fails
-rwildcard = $(foreach d, $(wildcard $1*), $(call rwildcard,$d/,$2) \
-						$(filter $(subst *,%,$2), $d))
-ifeq ($(SOURCES),)
-	SOURCES := $(call rwildcard, $(SRC_PATH), *.$(SRC_EXT))
-endif
-
-# Set the object file names, with the source directory stripped
-# from the path, and the build path prepended in its place
-OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o)
-# Set the dependency files that will be used to add header dependencies
-DEPS = $(OBJECTS:.o=.d)
-
-# Macros for timing compilation
-ifeq ($(UNAME_S),Darwin)
-	CUR_TIME = awk 'BEGIN{srand(); print srand()}'
-	TIME_FILE = $(dir $@).$(notdir $@)_time
-	START_TIME = $(CUR_TIME) > $(TIME_FILE)
-	END_TIME = read st < $(TIME_FILE) ; \
-		$(RM) $(TIME_FILE) ; \
-		st=$$((`$(CUR_TIME)` - $$st)) ; \
-		echo $$st
-else
-	TIME_FILE = $(dir $@).$(notdir $@)_time
-	START_TIME = date '+%s' > $(TIME_FILE)
-	END_TIME = read st < $(TIME_FILE) ; \
-		$(RM) $(TIME_FILE) ; \
-		st=$$((`date '+%s'` - $$st - 86400)) ; \
-		echo `date -u -d @$$st '+%H:%M:%S'`
-endif
-
-# Version macros
-# Comment/remove this section to remove versioning
-USE_VERSION := false
-# If this isn't a git repo or the repo has no tags, git describe will return non-zero
-ifeq ($(shell git describe > /dev/null 2>&1 ; echo $$?), 0)
-	USE_VERSION := true
-	VERSION := $(shell git describe --tags --long --dirty --always | \
-		sed 's/v\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)-\?.*-\([0-9]*\)-\(.*\)/\1 \2 \3 \4 \5/g')
-	VERSION_MAJOR := $(word 1, $(VERSION))
-	VERSION_MINOR := $(word 2, $(VERSION))
-	VERSION_PATCH := $(word 3, $(VERSION))
-	VERSION_REVISION := $(word 4, $(VERSION))
-	VERSION_HASH := $(word 5, $(VERSION))
-	VERSION_STRING := \
-		"$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH).$(VERSION_REVISION)-$(VERSION_HASH)"
-	override CFLAGS := $(CFLAGS) \
-		-D VERSION_MAJOR=$(VERSION_MAJOR) \
-		-D VERSION_MINOR=$(VERSION_MINOR) \
-		-D VERSION_PATCH=$(VERSION_PATCH) \
-		-D VERSION_REVISION=$(VERSION_REVISION) \
-		-D VERSION_HASH=\"$(VERSION_HASH)\"
-endif
-
-# Standard, non-optimized release build
-.PHONY: release
-release: dirs
-ifeq ($(USE_VERSION), true)
-	@echo "Beginning release build v$(VERSION_STRING)"
-else
-	@echo "Beginning release build"
-endif
-	@$(START_TIME)
-	@$(MAKE) all --no-print-directory
-	@echo -n "Total build time: "
-	@$(END_TIME)
-
-# Debug build for gdb debugging
-.PHONY: debug
-debug: dirs
-ifeq ($(USE_VERSION), true)
-	@echo "Beginning debug build v$(VERSION_STRING)"
-else
-	@echo "Beginning debug build"
-endif
-	@$(START_TIME)
-	@$(MAKE) all --no-print-directory
-	@echo -n "Total build time: "
-	@$(END_TIME)
-
-# Create the directories used in the build
-.PHONY: dirs
-dirs:
-	@echo "Creating directories"
-	@mkdir -p $(dir $(OBJECTS))
-	@mkdir -p $(BIN_PATH)
-
-# Installs to the set path
-.PHONY: install
-install:
-	@echo "Installing to $(DESTDIR)$(INSTALL_PREFIX)/bin"
-	@$(INSTALL_PROGRAM) $(BIN_PATH)/$(BIN_NAME) $(DESTDIR)$(INSTALL_PREFIX)/bin
-
-# Uninstalls the program
-.PHONY: uninstall
-uninstall:
-	@echo "Removing $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BIN_NAME)"
-	@$(RM) $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BIN_NAME)
-
-# Removes all build files
-.PHONY: clean
-clean:
-	@echo "Deleting $(BIN_NAME) symlink"
-	@$(RM) $(BIN_NAME)
-	@echo "Deleting directories"
-	@$(RM) -r build
-	@$(RM) -r bin
-
-# Main rule, checks the executable and symlinks to the output
-all: $(BIN_PATH)/$(BIN_NAME)
-	@echo "Making symlink: $(BIN_NAME) -> $<"
-	@$(RM) $(BIN_NAME)
-	@ln -s $(BIN_PATH)/$(BIN_NAME) $(BIN_NAME)
-
-# Link the executable
-$(BIN_PATH)/$(BIN_NAME): $(OBJECTS)
-	@echo "Linking: $@"
-	@$(START_TIME)
-	$(CMD_PREFIX)$(CC) $(OBJECTS) $(LDFLAGS) -o $@
-	@echo -en "\t Link time: "
-	@$(END_TIME)
-
-# Add dependency files, if they exist
--include $(DEPS)
-
-# Source file rules
-# After the first compilation they will be joined with the rules from the
-# dependency files to provide header dependencies
-$(BUILD_PATH)/%.o: $(SRC_PATH)/%.$(SRC_EXT)
-	@echo "Compiling: $< -> $@"
-	@$(START_TIME)
-	$(CMD_PREFIX)$(CC) $(CFLAGS) $(INCLUDES) -MP -MMD -c $< -o $@
-	@echo -en "\t Compile time: "
-	@$(END_TIME)
+include $(TOP)/library.mk
diff --git a/quad/src/computation_graph/Makefile_old b/quad/src/computation_graph/Makefile_old
new file mode 100644
index 000000000..44c7e5926
--- /dev/null
+++ b/quad/src/computation_graph/Makefile_old
@@ -0,0 +1,220 @@
+#### PROJECT SETTINGS ####
+# The name of the executable to be created
+BIN_NAME := computation_graph
+# Compiler used
+CC ?= gcc
+# Extension of source files used in the project
+SRC_EXT = c
+# Path to the source directory, relative to the makefile
+SRC_PATH = ./src
+# Space-separated pkg-config libraries used by this project
+LIBS =
+# General compiler flags
+COMPILE_FLAGS = -std=c99 -Wall -Wextra -g
+# Additional release-specific flags
+RCOMPILE_FLAGS = -D NDEBUG
+# Additional debug-specific flags
+DCOMPILE_FLAGS = -D DEBUG
+# Add additional include paths
+INCLUDES = -I $(SRC_PATH)
+# General linker settings
+LINK_FLAGS = -lm
+# Additional release-specific linker settings
+RLINK_FLAGS =
+# Additional debug-specific linker settings
+DLINK_FLAGS =
+# Destination directory, like a jail or mounted system
+DESTDIR = /
+# Install path (bin/ is appended automatically)
+INSTALL_PREFIX = usr/local
+#### END PROJECT SETTINGS ####
+
+# Generally should not need to edit below this line
+
+# Obtains the OS type, either 'Darwin' (OS X) or 'Linux'
+UNAME_S:=$(shell uname -s)
+
+# Function used to check variables. Use on the command line:
+# make print-VARNAME
+# Useful for debugging and adding features
+print-%: ; @echo $*=$($*)
+
+# Shell used in this makefile
+# bash is used for 'echo -en'
+SHELL = /bin/bash
+# Clear built-in rules
+.SUFFIXES:
+# Programs for installation
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL)
+INSTALL_DATA = $(INSTALL) -m 644
+
+# Append pkg-config specific libraries if need be
+ifneq ($(LIBS),)
+	COMPILE_FLAGS += $(shell pkg-config --cflags $(LIBS))
+	LINK_FLAGS += $(shell pkg-config --libs $(LIBS))
+endif
+
+# Verbose option, to output compile and link commands
+export V := false
+export CMD_PREFIX := @
+ifeq ($(V),true)
+	CMD_PREFIX :=
+endif
+
+# Combine compiler and linker flags
+release: export CFLAGS := $(CFLAGS) $(COMPILE_FLAGS) $(RCOMPILE_FLAGS)
+release: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(RLINK_FLAGS)
+debug: export CFLAGS := $(CFLAGS) $(COMPILE_FLAGS) $(DCOMPILE_FLAGS)
+debug: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(DLINK_FLAGS)
+
+# Build and output paths
+release: export BUILD_PATH := build/release
+release: export BIN_PATH := bin/release
+debug: export BUILD_PATH := build/debug
+debug: export BIN_PATH := bin/debug
+install: export BIN_PATH := bin/release
+
+# Find all source files in the source directory, sorted by most
+# recently modified
+ifeq ($(UNAME_S),Darwin)
+	SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' | sort -k 1nr | cut -f2-)
+else
+	SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' -printf '%T@\t%p\n' \
+						| sort -k 1nr | cut -f2-)
+endif
+
+# fallback in case the above fails
+rwildcard = $(foreach d, $(wildcard $1*), $(call rwildcard,$d/,$2) \
+						$(filter $(subst *,%,$2), $d))
+ifeq ($(SOURCES),)
+	SOURCES := $(call rwildcard, $(SRC_PATH), *.$(SRC_EXT))
+endif
+
+# Set the object file names, with the source directory stripped
+# from the path, and the build path prepended in its place
+OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o)
+# Set the dependency files that will be used to add header dependencies
+DEPS = $(OBJECTS:.o=.d)
+
+# Macros for timing compilation
+ifeq ($(UNAME_S),Darwin)
+	CUR_TIME = awk 'BEGIN{srand(); print srand()}'
+	TIME_FILE = $(dir $@).$(notdir $@)_time
+	START_TIME = $(CUR_TIME) > $(TIME_FILE)
+	END_TIME = read st < $(TIME_FILE) ; \
+		$(RM) $(TIME_FILE) ; \
+		st=$$((`$(CUR_TIME)` - $$st)) ; \
+		echo $$st
+else
+	TIME_FILE = $(dir $@).$(notdir $@)_time
+	START_TIME = date '+%s' > $(TIME_FILE)
+	END_TIME = read st < $(TIME_FILE) ; \
+		$(RM) $(TIME_FILE) ; \
+		st=$$((`date '+%s'` - $$st - 86400)) ; \
+		echo `date -u -d @$$st '+%H:%M:%S'`
+endif
+
+# Version macros
+# Comment/remove this section to remove versioning
+USE_VERSION := false
+# If this isn't a git repo or the repo has no tags, git describe will return non-zero
+ifeq ($(shell git describe > /dev/null 2>&1 ; echo $$?), 0)
+	USE_VERSION := true
+	VERSION := $(shell git describe --tags --long --dirty --always | \
+		sed 's/v\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)-\?.*-\([0-9]*\)-\(.*\)/\1 \2 \3 \4 \5/g')
+	VERSION_MAJOR := $(word 1, $(VERSION))
+	VERSION_MINOR := $(word 2, $(VERSION))
+	VERSION_PATCH := $(word 3, $(VERSION))
+	VERSION_REVISION := $(word 4, $(VERSION))
+	VERSION_HASH := $(word 5, $(VERSION))
+	VERSION_STRING := \
+		"$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH).$(VERSION_REVISION)-$(VERSION_HASH)"
+	override CFLAGS := $(CFLAGS) \
+		-D VERSION_MAJOR=$(VERSION_MAJOR) \
+		-D VERSION_MINOR=$(VERSION_MINOR) \
+		-D VERSION_PATCH=$(VERSION_PATCH) \
+		-D VERSION_REVISION=$(VERSION_REVISION) \
+		-D VERSION_HASH=\"$(VERSION_HASH)\"
+endif
+
+# Standard, non-optimized release build
+.PHONY: release
+release: dirs
+ifeq ($(USE_VERSION), true)
+	@echo "Beginning release build v$(VERSION_STRING)"
+else
+	@echo "Beginning release build"
+endif
+	@$(START_TIME)
+	@$(MAKE) all --no-print-directory
+	@echo -n "Total build time: "
+	@$(END_TIME)
+
+# Debug build for gdb debugging
+.PHONY: debug
+debug: dirs
+ifeq ($(USE_VERSION), true)
+	@echo "Beginning debug build v$(VERSION_STRING)"
+else
+	@echo "Beginning debug build"
+endif
+	@$(START_TIME)
+	@$(MAKE) all --no-print-directory
+	@echo -n "Total build time: "
+	@$(END_TIME)
+
+# Create the directories used in the build
+.PHONY: dirs
+dirs:
+	@echo "Creating directories"
+	@mkdir -p $(dir $(OBJECTS))
+	@mkdir -p $(BIN_PATH)
+
+# Installs to the set path
+.PHONY: install
+install:
+	@echo "Installing to $(DESTDIR)$(INSTALL_PREFIX)/bin"
+	@$(INSTALL_PROGRAM) $(BIN_PATH)/$(BIN_NAME) $(DESTDIR)$(INSTALL_PREFIX)/bin
+
+# Uninstalls the program
+.PHONY: uninstall
+uninstall:
+	@echo "Removing $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BIN_NAME)"
+	@$(RM) $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BIN_NAME)
+
+# Removes all build files
+.PHONY: clean
+clean:
+	@echo "Deleting $(BIN_NAME) symlink"
+	@$(RM) $(BIN_NAME)
+	@echo "Deleting directories"
+	@$(RM) -r build
+	@$(RM) -r bin
+
+# Main rule, checks the executable and symlinks to the output
+all: $(BIN_PATH)/$(BIN_NAME)
+	@echo "Making symlink: $(BIN_NAME) -> $<"
+	@$(RM) $(BIN_NAME)
+	@ln -s $(BIN_PATH)/$(BIN_NAME) $(BIN_NAME)
+
+# Link the executable
+$(BIN_PATH)/$(BIN_NAME): $(OBJECTS)
+	@echo "Linking: $@"
+	@$(START_TIME)
+	$(CMD_PREFIX)$(CC) $(OBJECTS) $(LDFLAGS) -o $@
+	@echo -en "\t Link time: "
+	@$(END_TIME)
+
+# Add dependency files, if they exist
+-include $(DEPS)
+
+# Source file rules
+# After the first compilation they will be joined with the rules from the
+# dependency files to provide header dependencies
+$(BUILD_PATH)/%.o: $(SRC_PATH)/%.$(SRC_EXT)
+	@echo "Compiling: $< -> $@"
+	@$(START_TIME)
+	$(CMD_PREFIX)$(CC) $(CFLAGS) $(INCLUDES) -MP -MMD -c $< -o $@
+	@echo -en "\t Compile time: "
+	@$(END_TIME)
diff --git a/quad/src/computation_graph/node_accumulator.h b/quad/src/computation_graph/node_accumulator.h
index 2df06c9d1..a392a9db2 100644
--- a/quad/src/computation_graph/node_accumulator.h
+++ b/quad/src/computation_graph/node_accumulator.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_ACCUMULATOR_H__
 #define __NODE_ACCUMULATOR_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_accum(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/computation_graph/node_add.h b/quad/src/computation_graph/node_add.h
index cfd2b71e8..390e3d229 100644
--- a/quad/src/computation_graph/node_add.h
+++ b/quad/src/computation_graph/node_add.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_ADD_H__
 #define __NODE_ADD_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_add(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/computation_graph/node_constant.h b/quad/src/computation_graph/node_constant.h
index 91cd6d055..c67ac6e05 100644
--- a/quad/src/computation_graph/node_constant.h
+++ b/quad/src/computation_graph/node_constant.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_CONSTANT_H__
 #define __NODE_CONSTANT_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_const(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/computation_graph/node_gain.h b/quad/src/computation_graph/node_gain.h
index b26d3bfe3..408924498 100644
--- a/quad/src/computation_graph/node_gain.h
+++ b/quad/src/computation_graph/node_gain.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_GAIN_H__
 #define __NODE_GAIN_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_gain(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/computation_graph/node_mult.h b/quad/src/computation_graph/node_mult.h
index 32d2d873d..9ea2bbb9f 100644
--- a/quad/src/computation_graph/node_mult.h
+++ b/quad/src/computation_graph/node_mult.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_MULT_H__
 #define __NODE_MULT_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_mult(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/computation_graph/node_pow.h b/quad/src/computation_graph/node_pow.h
index 11bdd9173..56a73d3d0 100644
--- a/quad/src/computation_graph/node_pow.h
+++ b/quad/src/computation_graph/node_pow.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_POW_H__
 #define __NODE_POW_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_pow(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/computation_graph/test_computation_graph.c b/quad/src/computation_graph/test/test_computation_graph.c
similarity index 97%
rename from quad/src/computation_graph/test_computation_graph.c
rename to quad/src/computation_graph/test/test_computation_graph.c
index 9d7c96bbc..1948421eb 100644
--- a/quad/src/computation_graph/test_computation_graph.c
+++ b/quad/src/computation_graph/test/test_computation_graph.c
@@ -2,11 +2,11 @@
 
 
 #include "computation_graph.h"
-#include "graph_blocks/node_add.h"
-#include "graph_blocks/node_mult.h"
-#include "graph_blocks/node_constant.h"
-#include "graph_blocks/node_gain.h"
-#include "graph_blocks/node_accumulator.h"
+#include "node_add.h"
+#include "node_mult.h"
+#include "node_constant.h"
+#include "node_gain.h"
+#include "node_accumulator.h"
 
 #define GRAPH_TEST_EPS 0.00001
 
@@ -229,5 +229,5 @@ int main() {
     test(graph_test_update_rules, "Tests that nodes only update when their inputs change");
     test(graph_test_update_propagation, "Tests that updates propagate only to their children");
     test(graph_test_update_disconnected, "Tests that nodes get executed when updated, even if disconnected");
-    test_summary();
+    return test_summary();
 }
diff --git a/quad/src/computation_graph/tests.c b/quad/src/computation_graph/tests.c
deleted file mode 100644
index 2f120a269..000000000
--- a/quad/src/computation_graph/tests.c
+++ /dev/null
@@ -1,151 +0,0 @@
-//
-// Created by dawehr on 2/9/2017.
-//
-
-#include "tests.h"
-#define GRAPH_TEST_EPS 0.00001
-
-static int nequal(double val1, double val2) {
-    if (fabs(val1 - val2) < GRAPH_TEST_EPS) {
-        return 0;
-    }
-    return -1;
-}
-
-int graph_run_tests() {
-    int success = 0;
-    success |= graph_test_one_add();
-    success |= graph_test_circular_runs();
-    success |= graph_test_circular_resets();
-    success |= graph_test_accumulator();
-    success |= graph_test_single_run();
-    success |= graph_test_reset_rules();
-    success |= graph_test_self_loop();
-    return success;
-}
-
-int graph_test_one_add() {
-    struct computation_graph *graph = create_graph();
-    int block = graph_add_node_add(graph, "Add");
-    int cblock3 = graph_add_node_const(graph, "3");
-    graph_set_param_val(graph, cblock3, CONST_SET, 3);
-    int cblock4 = graph_add_node_const(graph, "4");
-    graph_set_param_val(graph, cblock4, CONST_SET, 4);
-    graph_set_source(graph, block, ADD_SUMMAND1, cblock3, CONST_VAL);
-    graph_set_source(graph, block, ADD_SUMMAND2, cblock4, CONST_VAL);
-    int to_compute_for[1] = {block};
-    graph_compute_nodes(graph, to_compute_for, 1);
-    double result = graph_get_output(graph, block, ADD_SUM);
-    return nequal(result, 7);
-}
-
-
-int graph_test_circular_runs() {
-    struct computation_graph *graph = create_graph();
-    int gain1 = graph_add_node_gain(graph, "gain1");
-    int gain2 = graph_add_node_gain(graph, "gain2");
-    graph_set_source(graph, gain2, GAIN_INPUT, gain1, GAIN_RESULT);
-    graph_set_source(graph, gain1, GAIN_INPUT, gain2, GAIN_RESULT);
-    int to_compute_for[1] = {gain2};
-    graph_compute_nodes(graph, to_compute_for, 1);
-    // If no infinite loop, then success. Value is undefined for circular graphs
-    return 0;
-}
-
-int graph_test_circular_resets() {
-    struct computation_graph *graph = create_graph();
-    int acum1 = graph_add_node_accum(graph, "accumulator1");
-    int acum2 = graph_add_node_accum(graph, "accumulator2");
-    graph_set_source(graph, acum2, ACCUM_IN, acum1, ACCUMULATED);
-    graph_set_source(graph, acum1, ACCUM_IN, acum2, ACCUMULATED);
-    return 0; // Passes if no infinite loop
-}
-
-// Tests the accumulator block, thereby testing reset and state changes
-int graph_test_accumulator() {
-    struct computation_graph *graph = create_graph();
-    int cblock = graph_add_node_const(graph, "const");
-    int acum_b = graph_add_node_accum(graph, "accumulator");
-    graph_set_source(graph, acum_b, ACCUM_IN, cblock, CONST_VAL);
-
-    int to_compute_for[1] = {acum_b};
-    graph_set_param_val(graph, cblock, CONST_SET, 3);
-    graph_compute_nodes(graph, to_compute_for, 1);
-    graph_set_param_val(graph, cblock, CONST_SET, 8);
-    graph_compute_nodes(graph, to_compute_for, 1);
-    graph_set_param_val(graph, cblock, CONST_SET, -2);
-    graph_compute_nodes(graph, to_compute_for, 1);
-
-    double result = graph_get_output(graph, acum_b, ACCUMULATED);
-    if (nequal(result, 9)) {
-        printf("graph_test_accumulator failed on step 1, equals %f\n", result);
-        return -1;
-    }
-
-    // Test reset on source set
-    int gain_b = graph_add_node_gain(graph, "Gain");
-    graph_set_param_val(graph, gain_b, GAIN_GAIN, 1);
-    graph_set_source(graph, gain_b, GAIN_INPUT, acum_b, ACCUMULATED);
-    to_compute_for[0] = gain_b;
-    graph_compute_nodes(graph, to_compute_for, 1);
-    result = graph_get_output(graph, gain_b, GAIN_RESULT);
-    if (nequal(result, -2)) {
-        printf("graph_test_accumulator failed on step 2\n");
-        return -2;
-    }
-    return 0;
-}
-
-// Tests that a block will only execute once per compute,
-// even if its output is connected to multiple inputs
-int graph_test_single_run() {
-    struct computation_graph *graph = create_graph();
-    int acum_b = graph_add_node_accum(graph, "accumulator");
-    int add_block = graph_add_node_add(graph, "Add");
-    int cblock = graph_add_node_const(graph, "const");
-    graph_set_param_val(graph, cblock, CONST_SET, 2);
-
-
-    graph_set_source(graph, acum_b, ACCUM_IN, cblock, CONST_VAL);
-    graph_set_source(graph, add_block, ADD_SUMMAND1, acum_b, ACCUMULATED);
-    graph_set_source(graph, add_block, ADD_SUMMAND2, acum_b, ACCUMULATED);
-
-    int to_compute_for[1] = {add_block};
-    graph_compute_nodes(graph, to_compute_for, 1);
-    double result = graph_get_output(graph, add_block, ADD_SUM);
-    return nequal(result, 4);
-}
-
-// Tests that upon connection of a second child, a block will not reset
-int graph_test_reset_rules() {
-    struct computation_graph *graph = create_graph();
-    int cblock = graph_add_node_const(graph, "5");
-    graph_set_param_val(graph, cblock, CONST_SET, 5);
-    int acum_b = graph_add_node_accum(graph, "accumulator");
-    int gain1 = graph_add_node_gain(graph, "gain1");
-    graph_set_param_val(graph, gain1, GAIN_GAIN, 1);
-
-    graph_set_source(graph, gain1, GAIN_INPUT, acum_b, ACCUMULATED);
-    graph_set_source(graph, acum_b, ACCUM_IN, cblock, CONST_VAL);
-    int to_compute_for[1] = {gain1};
-    graph_compute_nodes(graph, to_compute_for, 1);
-    // state of acum_b is now 5
-
-    int gain2 = graph_add_node_gain(graph, "gain2");
-    graph_set_param_val(graph, gain2, GAIN_GAIN, 1);
-    // Connect gain 2, and accumulator should not get reset
-    graph_set_source(graph, gain2, GAIN_INPUT, acum_b, ACCUMULATED);
-    to_compute_for[0] = gain2;
-    graph_compute_nodes(graph, to_compute_for, 1);
-    double result = graph_get_output(graph, gain2, GAIN_RESULT);
-    return nequal(result, 10);
-}
-
-int graph_test_self_loop() {
-    struct computation_graph *graph = create_graph();
-    int gain1 = graph_add_node_gain(graph, "gain1");
-    graph_set_source(graph, gain1, GAIN_INPUT, gain1, GAIN_RESULT);
-    int to_compute_for[1] = {gain1};
-    graph_compute_nodes(graph, to_compute_for, 1);
-    return 0;
-}
diff --git a/quad/src/computation_graph/tests.h b/quad/src/computation_graph/tests.h
deleted file mode 100644
index b30b7d806..000000000
--- a/quad/src/computation_graph/tests.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Created by dawehr on 2/9/2017.
-//
-
-#ifndef COMPUTATION_GRAPH_TESTS_H
-#define COMPUTATION_GRAPH_TESTS_H
-
-#include "computation_graph.h"
-#include "graph_blocks/node_add.h"
-#include "graph_blocks/node_mult.h"
-#include "graph_blocks/node_constant.h"
-#include "graph_blocks/node_gain.h"
-#include "graph_blocks/node_accumulator.h"
-#include <math.h>
-
-int graph_run_tests();
-
-int graph_test_one_add();
-
-int graph_test_circular_runs();
-
-int graph_test_circular_resets();
-
-int graph_test_self_loop();
-
-int graph_test_accumulator();
-
-int graph_test_single_run();
-
-int graph_test_reset_rules();
-
-#endif //COMPUTATION_GRAPH_TESTS_H
diff --git a/quad/src/gen_diagram/generate.c b/quad/src/gen_diagram/generate.c
index f04b94717..da5f3c383 100644
--- a/quad/src/gen_diagram/generate.c
+++ b/quad/src/gen_diagram/generate.c
@@ -1,10 +1,10 @@
 #include <stdio.h>
 
 #include "computation_graph.h"
-#include "graph_blocks/node_pid.h"
-#include "graph_blocks/node_bounds.h"
-#include "graph_blocks/node_constant.h"
-#include "graph_blocks/node_mixer.h"
+#include "node_pid.h"
+#include "node_bounds.h"
+#include "node_constant.h"
+#include "node_mixer.h"
 #include "PID.h"
 #include "control_algorithm.h"
 
diff --git a/quad/src/quad_app/.gitignore b/quad/src/quad_app/.gitignore
new file mode 100644
index 000000000..8d9968320
--- /dev/null
+++ b/quad/src/quad_app/.gitignore
@@ -0,0 +1,2 @@
+obj-zybo/
+obj/
\ No newline at end of file
diff --git a/quad/src/quad_app/Makefile b/quad/src/quad_app/Makefile
new file mode 100644
index 000000000..81aebd95c
--- /dev/null
+++ b/quad/src/quad_app/Makefile
@@ -0,0 +1,6 @@
+TOP=../..
+
+NAME = quad_app
+REQLIBS = -ltest -lcomputation_graph
+
+include $(TOP)/library.mk
diff --git a/quad/src/quad_app/commands.c b/quad/src/quad_app/commands.c
index efc117542..d1d22a4de 120000
--- a/quad/src/quad_app/commands.c
+++ b/quad/src/quad_app/commands.c
@@ -1 +1 @@
-../../../../../groundStation/src/backend/commands.c
\ No newline at end of file
+../../../groundStation/src/backend/commands.c
\ No newline at end of file
diff --git a/quad/src/quad_app/commands.h b/quad/src/quad_app/commands.h
index 35567e1f0..6c32c46d7 120000
--- a/quad/src/quad_app/commands.h
+++ b/quad/src/quad_app/commands.h
@@ -1 +1 @@
-../../../../../groundStation/src/backend/commands.h
\ No newline at end of file
+../../../groundStation/src/backend/commands.h
\ No newline at end of file
diff --git a/quad/src/quad_app/communication.h b/quad/src/quad_app/communication.h
index f08470146..4c8b86c80 100644
--- a/quad/src/quad_app/communication.h
+++ b/quad/src/quad_app/communication.h
@@ -2,7 +2,6 @@
 #define _COMMUNICATION_H
 
 #include "type_def.h"
-#include "mio7_led.h"
 #include "timer.h"
 #include "commands.h"
 #include "hw_iface.h"
diff --git a/quad/src/quad_app/computation_graph.c b/quad/src/quad_app/computation_graph.c
deleted file mode 120000
index 0920eab35..000000000
--- a/quad/src/quad_app/computation_graph.c
+++ /dev/null
@@ -1 +0,0 @@
-../../../../computation_graph/src/computation_graph.c
\ No newline at end of file
diff --git a/quad/src/quad_app/computation_graph.h b/quad/src/quad_app/computation_graph.h
deleted file mode 120000
index 26647919e..000000000
--- a/quad/src/quad_app/computation_graph.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../computation_graph/src/computation_graph.h
\ No newline at end of file
diff --git a/quad/src/quad_app/control_algorithm.c b/quad/src/quad_app/control_algorithm.c
index 428323fd4..7edd1837e 100644
--- a/quad/src/quad_app/control_algorithm.c
+++ b/quad/src/quad_app/control_algorithm.c
@@ -8,11 +8,11 @@
 // This implemented modular quadrotor software implements a PID control algorithm
 
 #include "control_algorithm.h"
-#include "graph_blocks/node_pid.h"
-#include "graph_blocks/node_bounds.h"
-#include "graph_blocks/node_constant.h"
-#include "graph_blocks/node_mixer.h"
-#include "graph_blocks/node_add.h"
+#include "node_pid.h"
+#include "node_bounds.h"
+#include "node_constant.h"
+#include "node_mixer.h"
+#include "node_add.h"
 #include "PID.h"
 #include "util.h"
 #include "timer.h"
diff --git a/quad/src/quad_app/controllers.c b/quad/src/quad_app/controllers.c
index 22f8d5d02..1ebf713e3 100644
--- a/quad/src/quad_app/controllers.c
+++ b/quad/src/quad_app/controllers.c
@@ -12,7 +12,6 @@
 #include "iic_utils.h"
 #include "quadposition.h"
 #include "util.h"
-#include "sleep.h"
 #include "stdio.h"
 #include <math.h>
 
diff --git a/quad/src/quad_app/graph_blocks/node_add.c b/quad/src/quad_app/graph_blocks/node_add.c
deleted file mode 120000
index 81c86c24e..000000000
--- a/quad/src/quad_app/graph_blocks/node_add.c
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../computation_graph/src/graph_blocks/node_add.c
\ No newline at end of file
diff --git a/quad/src/quad_app/graph_blocks/node_add.h b/quad/src/quad_app/graph_blocks/node_add.h
deleted file mode 120000
index 06a062061..000000000
--- a/quad/src/quad_app/graph_blocks/node_add.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../computation_graph/src/graph_blocks/node_add.h
\ No newline at end of file
diff --git a/quad/src/quad_app/graph_blocks/node_constant.c b/quad/src/quad_app/graph_blocks/node_constant.c
deleted file mode 120000
index a25748584..000000000
--- a/quad/src/quad_app/graph_blocks/node_constant.c
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../computation_graph/src/graph_blocks/node_constant.c
\ No newline at end of file
diff --git a/quad/src/quad_app/graph_blocks/node_constant.h b/quad/src/quad_app/graph_blocks/node_constant.h
deleted file mode 120000
index 49fe8948a..000000000
--- a/quad/src/quad_app/graph_blocks/node_constant.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../computation_graph/src/graph_blocks/node_constant.h
\ No newline at end of file
diff --git a/quad/src/quad_app/hw_iface.h b/quad/src/quad_app/hw_iface.h
index a5b7d148e..79898e582 100644
--- a/quad/src/quad_app/hw_iface.h
+++ b/quad/src/quad_app/hw_iface.h
@@ -47,4 +47,10 @@ struct LEDDriver {
   int (*turn_off)(struct LEDDriver *self);
 };
 
+struct SystemDriver {
+  void *state;
+  int (*reset)(struct SystemDriver *self);
+  int (*sleep)(struct SystemDriver *self, unsigned long us);
+};
+
 #endif
diff --git a/quad/src/quad_app/iic_utils.c b/quad/src/quad_app/iic_utils.c
index 9bbfd82ed..90cdfb687 100644
--- a/quad/src/quad_app/iic_utils.c
+++ b/quad/src/quad_app/iic_utils.c
@@ -6,28 +6,26 @@
  */
 
 #include <stdio.h>
-#include <sleep.h>
 #include <math.h>
 
-#include "xparameters.h"
 #include "iic_utils.h"
-#include "xbasic_types.h"
-#include "xiicps.h"
 
 
 static struct I2CDriver *i2c;
+static struct SystemDriver *sys;
 
 double magX_correction = -1, magY_correction, magZ_correction;
 
-void iic_set_global(struct I2CDriver *given_i2c) {
+void iic_set_globals(struct I2CDriver *given_i2c, struct SystemDriver *given_system) {
   i2c = given_i2c;
+  sys = given_system;
 }
 
 int iic0_mpu9150_start(){
 
 	// Device Reset & Wake up
 	iic0_mpu9150_write(0x6B, 0x80);
-	usleep(5000);
+	sys->sleep(sys, 5000);
 
 	// Set clock reference to Z Gyro
 	iic0_mpu9150_write(0x6B, 0x03);
@@ -44,7 +42,7 @@ int iic0_mpu9150_start(){
 	// Setup Mag
 	iic0_mpu9150_write(0x37, 0x02);             //INT_PIN_CFG   -- INT_LEVEL=0 ; INT_OPEN=0 ; LATCH_INT_EN=0 ; INT_RD_CLEAR=0 ; FSYNC_INT_LEVEL=0 ; FSYNC_INT_EN=0 ; I2C_BYPASS_EN=0 ; CLKOUT_EN=0
 
-	usleep(100000);
+	sys->sleep(sys, 100000);
 
 	int i;
 	gam_t temp_gam;
@@ -54,7 +52,7 @@ int iic0_mpu9150_start(){
 		if(iic0_mpu9150_read_gam(&temp_gam) == -1){
 			return -1;
 		}
-		usleep(1000);
+		sys->sleep(sys, 1000);
 	}
 
 	return 0;
@@ -109,7 +107,7 @@ void iic0_mpu9150_calc_mag_sensitivity(){
 
 	// Quickly read from the factory ROM to get correction coefficents
 	iic0_mpu9150_write(0x0A, 0x0F);
-	usleep(10000);
+	sys->sleep(sys, 10000);
 
 	// Read raw adjustment values
 	iic0_mpu9150_read(buf, 0x10,3);
@@ -127,7 +125,7 @@ void iic0_mpu9150_calc_mag_sensitivity(){
 void iic0_mpu9150_read_mag(gam_t* gam){
 
 	u8 mag_data[6];
-	Xint16 raw_magX, raw_magY, raw_magZ;
+	i16 raw_magX, raw_magY, raw_magZ;
 
 	// Grab calibrations if not done already
 	if(magX_correction == -1){
@@ -136,7 +134,7 @@ void iic0_mpu9150_read_mag(gam_t* gam){
 
 	// Set Mag to single read mode
 	iic0_mpu9150_write(0x0A, 0x01);
-	usleep(10000);
+	sys->sleep(sys, 10000);
 	mag_data[0] = 0;
 
 	// Keep checking if data is ready before reading new mag data
@@ -163,10 +161,10 @@ void iic0_mpu9150_read_mag(gam_t* gam){
  */
 int iic0_mpu9150_read_gam(gam_t* gam) {
 
-	Xint16 raw_accel_x, raw_accel_y, raw_accel_z;
-	Xint16 gyro_x, gyro_y, gyro_z;
+	i16 raw_accel_x, raw_accel_y, raw_accel_z;
+	i16 gyro_x, gyro_y, gyro_z;
 
-	Xuint8 sensor_data[ACCEL_GYRO_READ_SIZE] = {};
+	u8 sensor_data[ACCEL_GYRO_READ_SIZE] = {};
 
 	// We should only get mag_data ~10Hz
 	//Xint8 mag_data[6] = {};
@@ -227,7 +225,7 @@ int iic0_lidarlite_init() {
 
 	// Device Reset & Wake up with default settings
 	status = iic0_lidarlite_write(0x00, 0x00);
-	usleep(15000);
+	sys->sleep(sys, 15000);
 
 	// Enable Free Running Mode and distance measurements with correction
 	status |= iic0_lidarlite_write(0x11, 0xff);
diff --git a/quad/src/quad_app/iic_utils.h b/quad/src/quad_app/iic_utils.h
index 8d2b54596..276ac22ca 100644
--- a/quad/src/quad_app/iic_utils.h
+++ b/quad/src/quad_app/iic_utils.h
@@ -14,9 +14,6 @@
 #ifndef IIC_UTILS_H
 #define IIC_UTILS_H
 
-
-#include "xbasic_types.h"
-#include "xiicps.h"
 #include "type_def.h"
 #include "hw_iface.h"
 
diff --git a/quad/src/quad_app/initialize_components.h b/quad/src/quad_app/initialize_components.h
index aa2c0e962..f903d4205 100644
--- a/quad/src/quad_app/initialize_components.h
+++ b/quad/src/quad_app/initialize_components.h
@@ -10,7 +10,6 @@
 
 #include "timer.h"
 #include "control_algorithm.h"
-#include "platform.h"
 #include "iic_utils.h"
 #include "util.h"
 #include "type_def.h"
diff --git a/quad/src/quad_app/log_data.c b/quad/src/quad_app/log_data.c
index ee106bef6..f6a0ab21a 100644
--- a/quad/src/quad_app/log_data.c
+++ b/quad/src/quad_app/log_data.c
@@ -10,13 +10,12 @@
 #include <string.h>
 #include "PID.h"
 #include "type_def.h"
-#include "sleep.h"
 #include "log_data.h"
 #include "communication.h"
 #include "computation_graph.h"
-#include "graph_blocks/node_pid.h"
-#include "graph_blocks/node_constant.h"
-#include "graph_blocks/node_mixer.h"
+#include "node_pid.h"
+#include "node_constant.h"
+#include "node_mixer.h"
  
 // Current index of the log array
 int arrayIndex = 0;
diff --git a/quad/src/quad_app/main.c b/quad/src/quad_app/main.c
index 51c7e465f..b76fd3fe3 100644
--- a/quad/src/quad_app/main.c
+++ b/quad/src/quad_app/main.c
@@ -20,7 +20,7 @@
 //#define BENCH_TEST
 //#define UART_BENCHMARK
 
-int main()
+int quad_main()
 {
 	// Structures to be used throughout
 	modular_structs_t structs = { };
diff --git a/quad/src/quad_app/mio7_led.c b/quad/src/quad_app/mio7_led.c
index 1da5ad79f..cabe67ad7 100644
--- a/quad/src/quad_app/mio7_led.c
+++ b/quad/src/quad_app/mio7_led.c
@@ -7,10 +7,12 @@
  
 #include "mio7_led.h"
 
-static struct LEDDriver *mio7_led;
+struct LEDDriver *mio7_led;
+struct SystemDriver *sys;
 
-void mio7_init_global(struct LEDDriver *given_mio7_led) {
+void mio7_init_globals(struct LEDDriver *given_mio7_led, struct SystemDriver *given_system) {
   mio7_led = given_mio7_led;
+  sys = given_system;
 }
 
 void flash_MIO_7_led(int how_many_times, int ms_between_flashes)
@@ -18,9 +20,9 @@ void flash_MIO_7_led(int how_many_times, int ms_between_flashes)
   int i;
   for (i = 0; i < how_many_times; i += 1) {
     mio7_led->turn_on(mio7_led);
-    usleep(ms_between_flashes * 500);
+    sys->sleep(sys, ms_between_flashes * 500);
     mio7_led->turn_off(mio7_led);
-    usleep(ms_between_flashes * 500);
+    sys->sleep(sys, ms_between_flashes * 500);
   }
 }
 
diff --git a/quad/src/quad_app/mio7_led.h b/quad/src/quad_app/mio7_led.h
index 5dd9dc50f..52e9e8faa 100644
--- a/quad/src/quad_app/mio7_led.h
+++ b/quad/src/quad_app/mio7_led.h
@@ -9,7 +9,6 @@
 #define MIO7_LED_H_
  
 #include <stdio.h>
-#include "sleep.h"
 #include "hw_iface.h"
 
 /**
diff --git a/quad/src/quad_app/node_bounds.h b/quad/src/quad_app/node_bounds.h
index 516ebc28a..4c3b93256 100644
--- a/quad/src/quad_app/node_bounds.h
+++ b/quad/src/quad_app/node_bounds.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_BOUNDS_H__
 #define __NODE_BOUNDS_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_bounds(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/quad_app/node_mixer.h b/quad/src/quad_app/node_mixer.h
index 1d58cf54d..ba1ec1c49 100644
--- a/quad/src/quad_app/node_mixer.h
+++ b/quad/src/quad_app/node_mixer.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_MIXER_H__
 #define __NODE_MIXER_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_mixer(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/quad_app/node_pid.h b/quad/src/quad_app/node_pid.h
index ee841adde..7b384bb1a 100644
--- a/quad/src/quad_app/node_pid.h
+++ b/quad/src/quad_app/node_pid.h
@@ -1,6 +1,6 @@
 #ifndef __NODE_PID_H__
 #define __NODE_PID_H__
-#include "../computation_graph.h"
+#include "computation_graph.h"
 
 int graph_add_node_pid(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/quad_app/packet_processing.c b/quad/src/quad_app/packet_processing.c
index 5dc8df320..8652c9233 100644
--- a/quad/src/quad_app/packet_processing.c
+++ b/quad/src/quad_app/packet_processing.c
@@ -6,7 +6,6 @@
  */
 #include "packet_processing.h"
 #include "type_def.h"
-#include "sleep.h"
 #include "util.h"
 #include "communication.h"
 
diff --git a/quad/src/quad_app/timer.c b/quad/src/quad_app/timer.c
index 29b697b5e..ce6333e40 100644
--- a/quad/src/quad_app/timer.c
+++ b/quad/src/quad_app/timer.c
@@ -1,15 +1,4 @@
-/*
- * timer.c
- *
- *  Created on: Feb 24, 2016
- *      Author: ucart
- */
-
-
-
 #include "timer.h"
-#include "xtime_l.h"
-#include <xtmrctr.h>
 
 u32 before = 0, after = 0;
 float LOOP_TIME;
diff --git a/quad/src/quad_app/timer.h b/quad/src/quad_app/timer.h
index c12a2f6eb..8f3d12fb4 100644
--- a/quad/src/quad_app/timer.h
+++ b/quad/src/quad_app/timer.h
@@ -36,7 +36,7 @@ int timer_end_loop(log_t *log_struct);
 // Returns the number of seconds the last loop took
 float get_last_loop_time();
 
-uint32_t timer_get_count();
+u32 timer_get_count();
 
 void timer_init_globals(struct TimerDriver *global_timer, struct TimerDriver *axi_timer);
 #endif /* TIMER_H_ */
diff --git a/quad/src/quad_app/util.c b/quad/src/quad_app/util.c
index 864e61ce3..25a8dae95 100644
--- a/quad/src/quad_app/util.c
+++ b/quad/src/quad_app/util.c
@@ -1,29 +1,15 @@
 #include "util.h"
-#include "../hardware/hw_impl_zybo.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
-#include <xgpiops.h>
 #include "PID.h"
 #include "log_data.h"
-#include <sleep.h>
 #include "controllers.h"
-#include "xparameters.h"
 
 extern int motor0_bias, motor1_bias, motor2_bias, motor3_bias;
 
-void setup_hardware(hardware_t *hardware) {
-  hardware->i2c = create_zybo_i2c();
-  hardware->pwm_inputs = create_zybo_pwm_inputs();
-  hardware->pwm_outputs = create_zybo_pwm_outputs();
-  hardware->uart = create_zybo_uart();
-  hardware->global_timer = create_zybo_global_timer();
-  hardware->axi_timer = create_zybo_axi_timer();
-  hardware->mio7_led = create_zybo_mio7_led();
-}
-
 /**
  * Reads all 6 receiver channels at once
  */
diff --git a/quad/src/quad_app/util.h b/quad/src/quad_app/util.h
index 5524b56ff..0a6bd21c7 100644
--- a/quad/src/quad_app/util.h
+++ b/quad/src/quad_app/util.h
@@ -8,12 +8,9 @@
 #include <math.h>
 #include "PID.h"
 #include "log_data.h"
-#include <sleep.h>
 #include "controllers.h"
 #include "hw_iface.h"
 
-void setup_hardware(hardware_t *hardware);
-
 void read_rec_all(struct PWMInputDriver *pwm_input, u32 *mixer);
 int read_kill(int gear);
 int read_flap(int flap);
diff --git a/quad/src/queue/.gitignore b/quad/src/queue/.gitignore
index 30d74d258..da2dc67a4 100644
--- a/quad/src/queue/.gitignore
+++ b/quad/src/queue/.gitignore
@@ -1 +1,3 @@
-test
\ No newline at end of file
+run_tests
+obj/
+obj-zybo/
diff --git a/quad/src/queue/Makefile b/quad/src/queue/Makefile
index 25a22026d..b1121285d 100644
--- a/quad/src/queue/Makefile
+++ b/quad/src/queue/Makefile
@@ -1,13 +1,6 @@
-OBJ = ../../obj
-INC = ../../inc
+TOP=../..
 
-queue: queue.h queue.c
-	[ -d $(OBJ) ] ||  mkdir -p $(OBJ)
-	[ -d $(INC) ] || mkdir -p $(INC)
-	gcc -c -o $(OBJ)/libqueue.a queue.c
-	cp queue.h $(INC)/
+NAME = queue
+REQLIBS = -ltest
 
-.PHONY : test
-test: queue test_queue.c
-	gcc -o test test_queue.c -I$(INC) -L$(OBJ) -lqueue -ltest
-	./test
+include $(TOP)/library.mk
diff --git a/quad/src/queue/test_queue.c b/quad/src/queue/test/test_queue.c
similarity index 100%
rename from quad/src/queue/test_queue.c
rename to quad/src/queue/test/test_queue.c
diff --git a/quad/src/test/.gitignore b/quad/src/test/.gitignore
index abf45b33b..da2dc67a4 100644
--- a/quad/src/test/.gitignore
+++ b/quad/src/test/.gitignore
@@ -1,2 +1,3 @@
-example
-test.o
\ No newline at end of file
+run_tests
+obj/
+obj-zybo/
diff --git a/quad/src/test/Makefile b/quad/src/test/Makefile
index dc7703f75..2156f7994 100644
--- a/quad/src/test/Makefile
+++ b/quad/src/test/Makefile
@@ -1,15 +1,6 @@
-OBJ = ../../obj
-INC = ../../inc
+TOP=../..
 
-test: test.c test.h
-	[ -d $(OBJ) ] || mkdir -p $(OBJ)
-	[ -d $(INC) ] || mkdir -p $(INC)
-	gcc -c -o $(OBJ)/libtest.a test.c
-	cp test.h $(INC)
+NAME = test
+REQLIBS = -ltest
 
-example: test_lib example.c
-	gcc -g -o example example.c -I$(INC) -L$(OBJ) -ltest
-
-.PHONY: clean
-clean:
-	rm example test.o
+include $(TOP)/library.mk
diff --git a/quad/src/test/example.c b/quad/src/test/example/example.c
similarity index 100%
rename from quad/src/test/example.c
rename to quad/src/test/example/example.c
diff --git a/quad/xsdk_workspace/modular_quad_pid/src/main.c b/quad/xsdk_workspace/modular_quad_pid/src/main.c
new file mode 100644
index 000000000..66d95246c
--- /dev/null
+++ b/quad/xsdk_workspace/modular_quad_pid/src/main.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include "hw_impl_zybo.h"
+#include "type_def.h"
+
+void setup_hardware(hardware_t *hardware) {
+  hardware->i2c = create_zybo_i2c();
+  hardware->pwm_inputs = create_zybo_pwm_inputs();
+  hardware->pwm_outputs = create_zybo_pwm_outputs();
+  hardware->uart = create_zybo_uart();
+  hardware->global_timer = create_zybo_global_timer();
+  hardware->axi_timer = create_zybo_axi_timer();
+  hardware->mio7_led = create_zybo_mio7_led();
+}
+
+int main()
+{
+
+  return 0;
+}
-- 
GitLab