diff --git a/Makefile b/Makefile
index 021ab97fe94bf37b248b803285abfaa575a80d6a..9e1948eb7706e7b85a1d6b3b68588d2bcb9efead 100644
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,295 @@
-# SPDX-License-Identifier: 0BSD
-################################################################################
-# CTL
-################################################################################
-MAKEFILE_PATH := makefiles
-include $(MAKEFILE_PATH)/config.mk
-PROJECT := futharkmpi
-PROJECT_TYPE := program
-# Add the compilation of *.fut with `futhark c` as a dependency
-PROJECT_DEPS := futharkc
-INC_DIRS    += $(shell mpicc --showme:incdirs)
-MPI_LDFLAGS := $(shell mpicc --showme:libdirs)
-LDFLAGS     += $(MPI_LDFLAGS:%=-L%)
-MPI_LDLIBS  := $(shell mpicc --showme:libs)
-LDLIBS      += $(MPI_LDLIBS:%=-l%)
-LDLIBS      += -lm
-# Remove `-pedantic-errors` to allow code generated by Futhark to compile
-CC_ERROR := $(filter-out -pedantic-errors,$(CC_ERROR))
-################################################################################
-# TARGETS
-################################################################################
-# Default targets
-include $(MAKEFILE_PATH)/targets.mk
+################################################################################
+# CONFIG
+################################################################################
+.DEFAULT_GOAL := all
+export MAKEFLAGS += -R
+VERSION_MAJOR := 0
+VERSION_MINOR := 1
+VERSION_PATCH := 0
+VERSION       := $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
+BUILD_MODE    := debug
+prefix         = $(DESTDIR)/usr/local
+exec_prefix    = $(prefix)
+includedir     = $(prefix)/include
+libdir         = $(exec_prefix)/lib
+VPATH          = src
+SRC_FILES := $(sort $(shell find src -name '*.c' -type f)) src/fmpi_futhark_entry.c
+OBJ_FILES_PASS_1 = $(notdir $(SRC_FILES:.c=.o))
+OBJ_FILES = $(OBJ_FILES_PASS_1:%=build/$(BUILD_MODE)/obj/%)
+DEP_FILES = $(OBJ_FILES:.o=.d)
+MPI_INCDIRS := $(shell mpicc --showme:incdirs)
+MPI_INCDIRS := $(MPI_INCDIRS:%=-I%)
+MPI_LIBDIRS := $(shell mpicc --showme:libdirs)
+LDFLAGS     := $(MPI_LIBDIRS:%=-L%)
+MPI_LIBS    := $(shell mpicc --showme:libs)
+LDLIBS      := $(MPI_LIBS:%=-l%)
+
+export CC = gcc
+CFLAGS = -Wall -Walloc-zero -Warith-conversion -Warray-bounds=2 \
+-Wbad-function-cast -Wc11-c2x-compat -Wcast-align=strict -Wcast-qual \
+-Wconversion -Wdisabled-optimization -Wdouble-promotion -Wduplicated-branches \
+-Wduplicated-cond -Wextra -Wfloat-equal -Wformat=2 -Wformat-overflow=2 \
+-Wformat-signedness -Wformat-truncation=2 -Wimplicit-fallthrough=4 -Winit-self \
+-Winline -Wjump-misses-init -Wlogical-op -Wmissing-declarations \
+-Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wnormalized \
+-Wnull-dereference -Wold-style-definition -Wpedantic -Wredundant-decls \
+-Wshadow -Wshift-overflow=2 -Wstack-protector -Wstrict-overflow=5 \
+-Wstrict-prototypes -Wstringop-overflow=4 -Wsuggest-attribute=noreturn \
+-Wswitch-default -Wswitch-enum -Wtrampolines -Wundef \
+-Wunsafe-loop-optimizations -Wunsuffixed-float-constants \
+-Wunused-const-variable=2 -Wvector-operation-performance -Wvla -Wwrite-strings \
+-funsafe-loop-optimizations -std=c17
+ifeq ($(BUILD_MODE),debug)
+    CFLAGS += -g3 -Og
+else
+    CFLAGS += -O2 -fstack-protector-all -fstack-protector-strong -DNDEBUG
+endif
+CFLAGS += -Iinclude $(MPI_INCDIRS)
+CPPFLAGS = -MMD -MT $@ -MP -MF build/$(BUILD_MODE)/obj/$*.d
+
+ifeq ($(filter $(BUILD_MODE),debug release),)
+    $(error BUILD_MODE must be one of [debug, release])
+endif
+################################################################################
+# BUILD TARGETS - MAIN
+################################################################################
+.PHONY: all
+all: futharkc build/$(BUILD_MODE)/libfmpi.so examples
+
+.PHONY: all-debug
+all_debug:
+	$(MAKE) all BUILD_MODE=debug
+
+.PHONY: all-release
+all_release:
+	$(MAKE) all BUILD_MODE=release
+
+build/$(BUILD_MODE)/obj/%.o: %.c build/$(BUILD_MODE)/obj/%.d | build/$(BUILD_MODE)/obj
+	$(CC) $< -o $@ -c -fPIC $(CFLAGS) $(CPPFLAGS)
+
+build/$(BUILD_MODE)/libfmpi.so: build/$(BUILD_MODE)/libfmpi.so.$(VERSION_MAJOR)
+	ln -sf $(notdir $^) $@
+
+build/$(BUILD_MODE)/libfmpi.so.$(VERSION_MAJOR): build/$(BUILD_MODE)/libfmpi.so.$(VERSION)
+	ln -sf $(notdir $^) $@
+
+build/$(BUILD_MODE)/libfmpi.so.$(VERSION): $(OBJ_FILES) | build/$(BUILD_MODE)
+	$(CC) -o $@ $(CFLAGS) $(LDFLAGS) -shared -Wl,-soname,libfmpi.so.$(VERSION_MAJOR) $^ $(LDLIBS)
 
 .PHONY: futharkc
-futharkc: src/fmpi_fut.c
+futharkc: include/internal/fmpi_futhark_entry.h src/fmpi_futhark_entry.c
+
+include/internal/fmpi_futhark_entry.h: src/futhark/fmpi_entry.h
+	cp $< $@
+
+src/fmpi_futhark_entry.c: src/futhark/fmpi_entry.c
+	cp $< $@
+
+.INTERMEDIATE: src/futhark/fmpi_entry.h src/futhark/fmpi_entry.c
+src/futhark/fmpi_entry.h src/futhark/fmpi_entry.c &: src/futhark/fmpi_entry.fut
+	futhark c --library $<
+	mv src/futhark/fmpi_entry.json .
+################################################################################
+# BUILD TARGETS - EXAMPLES
+################################################################################
+.PHONY: examples
+examples: export BUILD_MODE := $(BUILD_MODE)
+examples: export CFLAGS     := $(filter-out -Iinclude,$(CFLAGS)) -I../../include
+examples: export LDFLAGS    := -L../../build/$(BUILD_MODE)
+examples: export LDLIBS     := -lfmpi
+examples: array-sum
+
+.PHONY: array-sum
+array-sum:
+	$(MAKE) -C examples/array_sum all
+################################################################################
+# INSTALL TARGETS
+################################################################################
+.PHONY: install
+install: build/$(BUILD_MODE)/libfmpi.so install-headers install-pkgconfig
+	cp $< $(libdir)/fmpi
+	cp $<.$(VERSION_MAJOR) $(libdir)/fmpi
+	cp $<.$(VERSION) $(libdir)/fmpi
+
+.PHONY: install-headers
+install-headers: include/internal/fmpi_futhark_entry.h
+	cp -r external/cpl $(includedir)/fmpi
+	cp -r include/* $(includedir)/fmpi
+
+.PHONY: install-pkgconfig
+install-pkgconfig: build/$(BUILD_MODE)/fmpi.pc | $(libdir)/pkgconfig
+	cp $^ $(libdir)/pkgconfig
+
+build/$(BUILD_MODE)/fmpi.pc: fmpi.pc.in
+	sed \
+-e 's|@PREFIX@|$(prefix)|' \
+-e 's|@EXEC_PREFIX@|$(exec_prefix)|' \
+-e 's|@INCLUDEDIR@|$(includedir)|' \
+-e 's|@LIBDIR@|$(libdir)|' \
+-e 's|@VERSION@|$(VERSION)|' \
+-e 's|@LIBS@||' \
+-e 's|@LIBS_PRIVATE@||' \
+-e 's|@CFLAGS@||' \
+$^ > $@
+################################################################################
+# UNINSTALL TARGETS
+################################################################################
+.PHONY: uninstall
+uninstall: uninstall-headers uninstall-pkgconfig
+	rm -f $(libdir)/fmpi/libfmpi.so
+	rm -f $(libdir)/fmpi/libfmpi.so.$(VERSION_MAJOR)
+	rm -f $(libdir)/fmpi/libfmpi.so.$(VERSION)
 
-src/fmpi_fut.c: src/futhark/fmpi_fut.fut
-	futhark c src/futhark/fmpi_fut.fut --library
-	mv src/futhark/fmpi_fut.h $(INC_PATH)/internal
-	mv src/futhark/fmpi_fut.c $(SRC_PATH)
+.PHONY: uninstall-headers
+uninstall-headers:
+	rm -rf $(includedir)/fmpi
+
+.PHONY: uninstall-pkgconfig
+uninstall-pkgconfig:
+	rm -f $(libdir)/pkgconfig/fmpi.pc
+################################################################################
+# CLEAN TARGETS
+################################################################################
+.PHONY: clean
+clean: clean-$(BUILD_MODE)
+
+.PHONY: clean-all
+clean-all: clean-debug clean-release clean-futhark clean-examples-all
+	rm -rf build
+
+.PHONY: clean-debug
+clean-debug:
+	rm -rf build/debug
+
+.PHONY: clean-release
+clean-release:
+	rm -rf build/release
+
+.PHONY: clean-futhark
+clean-futhark:
+	rm -f include/internal/fmpi_futhark_entry.h
+	rm -f src/fmpi_futhark_entry.c
+	rm -f fmpi_entry.json
+
+.PHONY: clean-examples
+clean-examples: clean-examples-$(BUILD_MODE)
+
+.PHONY: clean-examples-all
+clean-examples-all:
+	$(MAKE) -C examples/array_sum clean-all
+
+.PHONY: clean-examples-debug
+clean-examples-debug:
+	$(MAKE) -C examples/array_sum clean-debug
+
+.PHONY: clean-examples-release
+clean-examples-release:
+	$(MAKE) -C examples/array_sum clean-release
+################################################################################
+# REBUILD TARGETS
+################################################################################
+.PHONY: rebuild
+rebuild: clean-all all
+
+.PHONY: rebuild-debug
+rebuild-debug: clean-debug all-debug
+
+.PHONY: rebuild-release
+rebuild-release: clean-release all-release
+################################################################################
+# RUN TARGETS
+################################################################################
+.PHONY: run-as
+run-as:
+	$(MAKE) -C examples/array_sum run-$(BUILD_MODE)
+
+.PHONY: run-as-debug
+run-as-debug:
+	$(MAKE) -C examples/array_sum run-debug
+
+.PHONY: run-as-release
+run-as-release:
+	$(MAKE) -C examples/array_sum run-release
+################################################################################
+# MISC TARGETS
+################################################################################
+.PHONY: doc
+doc: | doc/doxygen
+	doxygen
+
+$(includedir)/fmpi:      ;mkdir -p $@
+$(libdir)/fmpi:          ;mkdir -p $@
+$(libdir)/pkgconfig:     ;mkdir -p $@
+build/$(BUILD_MODE)/obj: ;mkdir -p $@
+build/$(BUILD_MODE):     ;mkdir -p $@
+doc/doxygen:             ;mkdir -p $@
+
+$(DEP_FILES):
+ifeq ($(MAKECMDGOALS),$(findstring $(MAKECMDGOALS),all all-debug all-release))
+    include $(wildcard $(DEP_FILES))
+endif
+################################################################################
+# HELP TARGET
+################################################################################
+.PHONY: help
+help:
+	@printf "Usage: make [TARGETS] [OPTIONS]\n"
+	@printf "\n"
+	@printf " - The default build mode is 'debug'(See BUILD OPTIONS).\n"
+	@printf " - The default installation paths are(See INSTALLATION OPTIONS):\n"
+	@printf "     - '/usr/local/include'\n"
+	@printf "     - '/usr/local/lib'\n"
+	@printf "     - '/usr/local/lib/pkgconfig'\n"
+	@printf "\n"
+	@printf '-----TARGETS-------------------------------------------------------\n'
+	@printf "BUILD:\n"
+	@printf "  all                        : Build fmpi library.\n"
+	@printf "  all-debug                  : Build fmpi in debug mode(Same as 'make all BUILD_MODE=debug').\n"
+	@printf "  all-release                : Build fmpi in release mode(Same as 'make all BUILD_MODE=release').\n"
+	@printf "  doc                        : Build documentation.\n"
+	@printf "  examples                   : Build examples.\n"
+	@printf "  tests                      : Build tests.\n"
+	@printf "\n"
+	@printf "CLEAN:\n"
+	@printf "  clean                      : Remove build files.\n"
+	@printf "  clean-all                  :\n"
+	@printf "  clean-debug                : Remove debug build files(Same as 'make clean BUILD_MODE=debug').\n"
+	@printf "  clean-examples             : Remove examples build files.\n"
+	@printf "  clean-futhark              : Remove files generated by futhark.\n"
+	@printf "  clean-release              : Remove release build files(Same as 'make clean BUILD_MODE=release').\n"
+	@printf "\n"
+	@printf "INSTALL:\n"
+	@printf "  install                    : Build and install fmpi.\n"
+	@printf "  install-all                : Build and install fmpi as both a shared and a static library.\n"
+	@printf "  install-headers            : Build and install fmpi headers.\n"
+	@printf "  install-pkgconfig          : Build and install fmpi pkg-config file.\n"
+	@printf "\n"
+	@printf "REBUILD:\n"
+	@printf "  rebuild                    : Same as 'make clean && make all'.\n"
+	@printf "  rebuild-debug              : Same as 'make clean-debug && make all-debug'.\n"
+	@printf "  rebuild-release            : Same as 'make clean-release && make all-release'.\n"
+	@printf "\n"
+	@printf "RUN:\n"
+	@printf "  run-as                     : Run 'Array sum' example.\n"
+	@printf "  run-gol                    : Run 'Game of Life' example.\n"
+	@printf "\n"
+	@printf "UNINSTALL:\n"
+	@printf "  uninstall                  : Uninstall fmpi static and shared libray, headers and pkg-config file.\n"
+	@printf "  uninstall-headers          : Uninstall fmpi headers(library and pkg-config file are kept).\n"
+	@printf "  uninstall-pkgconfig        : Uninstall fmpi pkg-config file(library and headers are kept).\n"
+	@printf "\n"
+	@printf '-----OPTIONS-------------------------------------------------------\n'
+	@printf "BUILD:\n"
+	@printf "  BUILD_MODE=<mode>          : <mode> must be one of [debug, release](default: debug).\n"
+	@printf "  BUILD_TESTS=<true|false>   : Build tests if true(default: true).\n"
+	@printf "  BUILD_DOC=<true|false>     : Build documentation if true(default: true).\n"
+	@printf "  BUILD_EXAMPLES=<true|false>: Build examples if true(default: false).\n"
+	@printf "\n"
+	@printf "INSTALLATION:\n"
+	@printf "  DESTDIR=<path>             : (default: '').\n"
+	@printf "  prefix=<path>              : (default: '/usr/local').\n"
+	@printf "  exec_prefix=<path>         : (default: '/usr/local').\n"
+	@printf "  includedir=<path>          : (default: '/usr/local/include').\n"
+	@printf "  libdir=<path>              : (default: '/usr/local/lib').\n"
 
-# Call the program with `mpirun`
-RUN_CMD := $(RUN_CMD:%=mpirun %)
+.DELETE_ON_ERROR:
diff --git a/fmpi.pc.in b/fmpi.pc.in
new file mode 100644
index 0000000000000000000000000000000000000000..19a2f4dc230d3ade43746b88b3623d0c1216ed7e
--- /dev/null
+++ b/fmpi.pc.in
@@ -0,0 +1,12 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+includedir=@INCLUDEDIR@
+libdir=@LIBDIR@
+
+Name: fmpi
+Description: Futhark and MPI
+URL: https://githepia.hesge.ch/raphael.bach/futharkmpi
+Version: @VERSION@
+Libs: -L${libdir} -lfmpi
+Libs.private: -L${libdir} @LIBS_PRIVATE@
+Cflags: -I${includedir} @CFLAGS@
diff --git a/makefiles/cc.mk b/makefiles/cc.mk
deleted file mode 100644
index 1ed9a8969173781ba226863b3e600289c3e709f4..0000000000000000000000000000000000000000
--- a/makefiles/cc.mk
+++ /dev/null
@@ -1,255 +0,0 @@
-# SPDX-License-Identifier: 0BSD
-################################################################################
-# CC
-#
-# [R]: Variable can be redefined with a single value.
-# [+]: Variable can be redefined and/or have values added to it.
-# [X]: Variable must not be redefined nor have values added to it.
-################################################################################
-# Compiler name                                                              [R]
-CC_NAME := gcc
-# Compiler version                                                           [R]
-CC_VERSION :=
-# Set CC to `name-version` if CC_VERSION isn't empty or to `name` otherwise
-ifeq ($(strip $(CC_VERSION)),)
-CC_VERSION := $(shell \
-    gcc -v 2>&1 >/dev/null \
-    | sed -Ene 's/gcc version ([0-9]+).*$$/\1/p')
-endif
-CC = $(CC_NAME)-$(CC_VERSION)
-################################################################################
-# WARNING
-#
-# https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-################################################################################
-# Enable the bare minimum number of warnings to write C
-CC_WARNING += -Wall
-# calloc/malloc/realloc(0) (behavior is implementation defined)
-CC_WARNING += -Walloc-zero
-# Implicit conversions from arithmetic operations
-ifneq ($(filter $(CC),gcc-11),)
-CC_WARNING += -Warith-conversion
-endif
-# Warn for out of bounds access to arrays at the end of a struct and when arrays
-# are accessed through pointers
-# May give false positives
-# Need -ftree-vrp(-O2)
-CC_WARNING += -Warray-bounds=2
-# Function call is cast to the wrong type
-CC_WARNING += -Wbad-function-cast
-# C2x features not present in C11
-ifneq ($(filter $(CC),gcc-11),)
-CC_WARNING += -Wc11-c2x-compat
-endif
-# Pointer is cast to a type with stricter alignment
-# Warn even for platform allowing missaligned memory access(x86)
-ifneq ($(filter $(CC),gcc-8 gcc-9 gcc-10 gcc-11),)
-CC_WARNING += -Wcast-align=strict
-endif
-# Pointer is cast to remove a type qualifier
-CC_WARNING += -Wcast-qual
-# Implicit cast that may change the value
-# Enable -Wsign-conversion and -Wfloat-conversion
-CC_WARNING += -Wconversion
-# GCC can't optimize the code
-CC_WARNING += -Wdisabled-optimization
-# Implicit promotion from float to double
-CC_WARNING += -Wdouble-promotion
-# If branch has the same code as the else one
-CC_WARNING += -Wduplicated-branches
-# If condition is the same as the else one
-CC_WARNING += -Wduplicated-cond
-# Extra mandatory warnings to write C
-CC_WARNING += -Wextra
-# Float values are compared with '=='
-CC_WARNING += -Wfloat-equal
-# Enable -Wformat -Wformat-nonliteral -Wformat-security -Wformat-y2k
-CC_WARNING += -Wformat=2
-# Calls to formatted input/output functions might overflow the destination
-# buffer
-# Optimization may give false positives
-CC_WARNING += -Wformat-overflow=2
-# Difference signedness between the format string and the argument
-# Need -Wformat(-Wall)
-CC_WARNING += -Wformat-signedness
-# Calls to formatted input/output functions might result in output truncation
-# Optimization may give false positives
-CC_WARNING += -Wformat-truncation=2
-# Switch case falls through unless commented with those regex:
-#    -fallthrough
-#    @fallthrough@
-#    lint -fallthrough[ \t]*
-#    [ \t]*FALLTHR(OUGH|U)[ \t]*
-CC_WARNING += -Wimplicit-fallthrough=4
-# Variable is initialized with itself
-# Need -Wunitialized(-Wall/-Wextra)
-CC_WARNING += -Winit-self
-# GCC cant' inline a function declared with 'inline'
-CC_WARNING += -Winline
-# Goto or switch statement jumps forward or backward accross a variable
-# initialized when declared
-CC_WARNING += -Wjump-misses-init
-# Suspicious uses of logical operators
-CC_WARNING += -Wlogical-op
-# Global function is defined without a previous declaration
-CC_WARNING += -Wmissing-declarations
-# User-supplied include directory doesn't exist
-CC_WARNING += -Wmissing-include-dirs
-# Global function is defined without a previous prototype declaration
-CC_WARNING += -Wmissing-prototypes
-# Extern declaration within a function
-CC_WARNING += -Wnested-externs
-CC_WARNING += -Wnormalized
-# Dereferencing a null pointer
-# Need -fdelete-null-pointer-checks(-O2)
-CC_WARNING += -Wnull-dereference
-# Old-style function definition: int foo();
-CC_WARNING += -Wold-style-definition
-# Structure padding
-#CC_WARNING += -Wpadded
-# Strict ISO C warnings
-CC_WARNING += -Wpedantic
-# Two or more identical declarations in the same scope
-CC_WARNING += -Wredundant-decls
-# Variable or type declaration shadowing
-CC_WARNING += -Wshadow
-# Left shift overflows(sign bit included)
-CC_WARNING += -Wshift-overflow=2
-# Functions not protected against stack smashing
-# Need -fstack-protector
-CC_WARNING += -Wstack-protector
-# Compiler optimizations assuming signed overflow does not occur
-CC_WARNING += -Wstrict-overflow=5
-# Function declaration/defintion without argument types
-CC_WARNING += -Wstrict-prototypes
-# String manipulation functions determined to overflow the destination buffer
-CC_WARNING += -Wstringop-overflow=4
-CC_WARNING += -Wsuggest-attribute=noreturn
-# Missing default in a switch
-CC_WARNING += -Wswitch-default
-# Missing case when using enum in a switch statement
-CC_WARNING += -Wswitch-enum
-# Trampolines generated for pointers to nested functions
-CC_WARNING += -Wtrampolines
-# Undefined identifier is evaluated in an #if directive
-CC_WARNING += -Wundef
-# Loop cannot be optimized
-CC_WARNING += -Wunsafe-loop-optimizations
-# Floating constants without suffix
-CC_WARNING += -Wunsuffixed-float-constants
-# Unused static const variables
-CC_WARNING += -Wunused-const-variable=2
-# Macro is unused
-#CC_WARNING += -Wunused-macros
-# Vector operation is not implemented via SIMD
-CC_WARNING += -Wvector-operation-performance
-# use of variable-length array
-CC_WARNING += -Wvla
-# Writing into a string constant
-CC_WARNING += -Wwrite-strings
-CC_WARNING += -D_FORTIFY_SOURCE=2
-# Treat -Wpedantic warnings as errors
-CC_ERROR := -pedantic-errors
-# Treat all warnings as errors
-CC_ERROR += #-Werror
-# Set the C version to the latest standard supported by the compiler used.
-ifneq ($(filter $(CC),gcc-8 gcc-9 gcc-10 gcc-11),)
-CC_C_VERSION := -std=c17
-else
-CC_C_VERSION := -std=c11
-endif
-# Default build mode is debug
-CC_DEBUG := -g3
-# Og is a level of optimization specially made for debug.
-CC_OPTIMIZATION := -Og
-CC_PROFILING    := #-pg
-# Valgrind doesn't seem to work properly on executables build with --coverage.
-# Invoke -fprofile-arcs -ftest-coverage(when compiling) and -lcov(when linking).
-# Create *.gcno files.
-COVERAGE ?= false
-ifeq ($(COVERAGE),true)
-CC_COVERAGE := --coverage
-endif
-# Directories to be used with the -I option
-CC_IDIRS  = $(SRC_DIRS:%=-I%)
-CC_IDIRS += $(INC_DIRS:%=-I%)
-
-ifeq ($(BUILD_MODE),release)
-    CC_OPTIMIZATION := -O2
-    CC_OPTIMIZATION += -fstack-protector-all
-    CC_OPTIMIZATION += -fstack-protector-strong
-    CC_DEBUG        := -DNDEBUG
-endif
-CC_OPTIMIZATION += -funsafe-loop-optimizations
-
-# Extra flags for the compiler
-CFLAGS  = $(CC_WARNING)
-CFLAGS += $(CC_ERROR)
-CFLAGS += $(CC_C_VERSION)
-CFLAGS += $(CC_DEBUG)
-CFLAGS += $(CC_OPTIMIZATION)
-CFLAGS += $(CC_ANALYZER)
-CFLAGS += $(CC_PROFILING)
-CFLAGS += $(CC_COVERAGE)
-CFLAGS += $(CC_IDIRS)
-CFLAGS += -o $@
-# Extra flags for the preprocessor
-# MMD  : Create a dependency file which contains a target and its dependencies
-# MT $@: Set the target name to the one in the Makefile
-# MP   : Create a target for each .h
-# MF   : Output path for the .d file
-CPPFLAGS = -MMD -MT $@ -MP -MF $(DEP_PATH)/$*.d
-
-# Command to make a preprocessor pass only.
-PREPROCESSOR  = $(CC)
-PREPROCESSOR += $<
-PREPROCESSOR += $(CC_C_VERSION)
-PREPROCESSOR += $(CC_IDIRS)
-PREPROCESSOR += $(CPPFLAGS)
-PREPROCESSOR += -dU -E
-PREPROCESSOR += -o $@
-# Command to compile *.c files
-COMPILE  = $(CC)
-COMPILE += $<
-COMPILE += -c -fPIC
-COMPILE += $(CFLAGS)
-COMPILE += $(CPPFLAGS)
-# Extra flags (-Lfoo) for the compiler when invoking the linker
-LDFLAGS = $(EXT_LIB_DIRS:%=-L%)
-# Libs name (-lfoo) for the compiler when invoking the linker
-# Must be put at the very end of a link command
-LDLIBS  =
-# Command to link *.o files into a program
-LINK_PROGRAM  = $(CC)
-LINK_PROGRAM += $(CFLAGS)
-LINK_PROGRAM += $^
-LINK_PROGRAM += $(LDFLAGS)
-LINK_PROGRAM += $(LDLIBS)
-# Command to link *.o files into a shared library
-LINK_SHARED  = $(CC)
-LINK_SHARED += $(CFLAGS)
-LINK_SHARED += $(LDFLAGS)
-LINK_SHARED += -shared
-LINK_SHARED += -Wl,-soname,$(LIB_SHARED_X)
-LINK_SHARED += $^
-LINK_SHARED += $(LDLIBS)
-################################################################################
-# AR
-################################################################################
-# Archiver name                                                              [R]
-AR_NAME := gcc-ar
-# Archiver version                                                           [R]
-AR_VERSION ?= $(CC_VERSION)
-# Set AR to `name-version` if AR_VERSION isn't empty or to `name` otherwise
-ifeq ($(strip $(CC_VERSION)),)
-AR = $(AR_NAME)
-else
-AR = $(AR_NAME)-$(AR_VERSION)
-endif
-# Extra flags to give to ar
-ARFLAGS  = -rcs
-# Command to archive *.o files
-ARCHIVE  = $(AR)
-ARCHIVE += $(ARFLAGS)
-ARCHIVE += $@
-ARCHIVE += $^
diff --git a/makefiles/config.mk b/makefiles/config.mk
deleted file mode 100644
index da7613d09341430790d358806a65785b7299be88..0000000000000000000000000000000000000000
--- a/makefiles/config.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# SPDX-License-Identifier: 0BSD
-################################################################################
-# [R]: Variable can be redefined with a single value.
-# [+]: Variable can be redefined and/or have values added to it.
-# [X]: Variable must not be redefined nor have values added to it.
-################################################################################
-# Set `all` as the default target.
-.DEFAULT_GOAL := all
-
-# Set the shell to `/usr/bin/env bash` since it's apparently more portable than
-# the default `/bin/sh`.
-SHELL := /usr/bin/env bash
-
-# Eliminate use of the built-in rule-specific variables(--no-builtin-variables).
-# Eliminate use of the built-in implicit rules(--no-builtin-rules/-r).
-MAKEFLAGS += -R
-
-#
-include $(MAKEFILE_PATH)/project.mk
-include $(MAKEFILE_PATH)/cc.mk
-include $(MAKEFILE_PATH)/tools.mk
-
-#
-ifeq ($(filter $(PROJECT_TYPE),header program shared static),)
-    $(error PROJECT_TYPE must be one of [header, program, shared, static])
-endif
-
-ifeq ($(filter $(BUILD_MODE),debug release),)
-    $(error BUILD_MODE must be one of [debug, release])
-endif
-
-ifeq ($(filter $(COVERAGE),true false),)
-    $(error COVERAGE must be one of [true, false])
-endif
-
-ifneq ($(filter $(MAKECMDGOALS),analyze),)
-  ifeq ($(ANALYSIS_CMD),)
-    $(info No tools found to analyze code!)
-  endif
-endif
-
-ifneq ($(filter $(MAKECMDGOALS),cov),)
-  ifeq ($(COV_CMD),)
-    $(info No tools found to make code coverage!)
-  endif
-endif
-
-ifneq ($(filter $(MAKECMDGOALS),doc),)
-  ifeq ($(DOC_CMD),)
-    $(info No tools found to build documentation!)
-  endif
-endif
diff --git a/makefiles/header.pc.in b/makefiles/header.pc.in
deleted file mode 100644
index b79ea2ac980a3ae51bb40686e7b392ffa54b3d90..0000000000000000000000000000000000000000
--- a/makefiles/header.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-includedir=@includedir@
-libdir=@libdir@
-
-Name: @PROJECT@
-Description: @DESCRIPTION@
-Version: @VERSION@
-URL:
-Cflags: -I${includedir}
diff --git a/makefiles/project.mk b/makefiles/project.mk
deleted file mode 100644
index c3cd581e0728051735e934207154084dcef4ecf3..0000000000000000000000000000000000000000
--- a/makefiles/project.mk
+++ /dev/null
@@ -1,164 +0,0 @@
-# SPDX-License-Identifier: 0BSD
-################################################################################
-# PROJECT
-#
-# [R]: Variable can be redefined with a single value.
-# [+]: Variable can be redefined and/or have values added to it.
-# [X]: Variable must not be redefined nor have values added to it.
-################################################################################
-# Project name: must not contain spaces                                      [R]
-PROJECT := untitled
-# Project type: one of [header, program, shared, static]                     [R]
-PROJECT_TYPE := program
-# Incompatible API changes                                                   [R]
-VERSION_MAJOR := 0
-# Functionality in a backwards compatible manner added                       [R]
-VERSION_MINOR := 1
-# Backwards compatible bug fixes                                             [R]
-VERSION_PATCH := 0
-# Full version(default to 0.1.0)                                             [X]
-VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
-# Project description                                                        [R]
-DESCRIPTION :=
-# Build mode. Change it at runtime with 'make <target> BUILD_MODE=release'   [R]
-BUILD_MODE ?= debug
-################################################################################
-# BASIC FOLDER AND PATH
-################################################################################
-# Output folder for analysis tools like valgrind or scan-build               [X]
-ANALYSIS_FOLDER := analysis
-# Installation folder for programs                                           [X]
-BIN_FOLDER := bin
-# Output folder for executables, *.a, *.so, etc                              [X]
-BUILD_FOLDER := build
-# Input/output folder for generated dependency files(*.d)                    [X]
-DEP_FOLDER := dep
-# Output folder for documentation generated by tools like doxygen            [X]
-DOC_FOLDER := doc
-# Input/output folder for third-parties sources, libraries, tools, etc       [X]
-EXT_FOLDER := external
-# Input/installation folder for header files(*.h)                            [X]
-INC_FOLDER := include
-# Input/installation folder for shared objects/archives(*.so/*.a)            [X]
-LIB_FOLDER := lib
-# Input/output folder for object files(*.o)                                  [X]
-OBJ_FOLDER := obj
-# Output folder for the preprocessor pass(*.pre)                             [x]
-PRE_FOLDER := pre
-# Input folder for source files(*.c)                                         [X]
-SRC_FOLDER := src
-# Input/output folder for tests                                              [X]
-TEST_FOLDER := test
-# Paths to above folders                                                     [R]
-ANALYSIS_PATH   = $(ANALYSIS_FOLDER)
-BUILD_PATH      = $(BUILD_ROOT_PATH)/$(BUILD_MODE)
-BUILD_ROOT_PATH = $(BUILD_FOLDER)
-DEP_PATH        = $(BUILD_PATH)/$(DEP_FOLDER)
-DOC_PATH        = $(DOC_FOLDER)
-EXT_PATH        = $(EXT_FOLDER)
-INC_PATH        = $(INC_FOLDER)
-LIB_PATH        = $(LIB_FOLDER)
-OBJ_PATH        = $(BUILD_PATH)/$(OBJ_FOLDER)
-PRE_PATH        = $(BUILD_PATH)/$(PRE_FOLDER)
-SRC_PATH        = $(SRC_FOLDER)
-TEST_PATH       = $(TEST_FOLDER)
-# Prefix for installation path                                               [X]
-INSTALL_PREFIX := /usr/local
-# Expected existing variables                                                [R]
-DESTDIR    ?=
-prefix      = $(DESTDIR)$(INSTALL_PREFIX)
-exec_prefix = $(prefix)
-bindir      = $(exec_prefix)/$(BIN_FOLDER)
-includedir  = $(prefix)/$(INC_FOLDER)
-libdir      = $(exec_prefix)/$(LIB_FOLDER)
-################################################################################
-# EXTERNAL
-################################################################################
-# Target to build tests                                                      [X]
-TEST_TARGET = $(wildcard $(TEST_PATH))
-# List of directories containing header files(*.h)                           [+]
-INC_DIRS = $(INC_PATH)
-# List of directories containing source files(*.c)                           [+]
-SRC_DIRS = $(shell find $(SRC_PATH)/ -type d)
-# Paths in which to look for source files in rules like %.o: %.c             [X]
-# Modify SRC_DIRS if other directories must be added to VPATH
-VPATH = $(SRC_DIRS)
-# List of source files(*.c)                                                  [+]
-SRC_FILES = $(sort $(shell find $(SRC_DIRS) -name '*.c' -type f))
-# Change .c extension to .o and remove directory-part(path/to/foo.c => foo.o)[X]
-OBJ_FILES_PASS1 = $(notdir $(SRC_FILES:.c=.o))
-# Prefix all files with $(OBJ_PATH)(foo.o => ./obj/debug/foo.o)              [+]
-OBJ_FILES = $(OBJ_FILES_PASS1:%=$(OBJ_PATH)/%)
-# Change .o extension to .d(foo.o => foo.d)                                  [X]
-DEP_FILES_PASS1 = $(OBJ_FILES_PASS1:.o=.d)
-# Prefix all files all with $(DEP_PATH)(foo.d => ./dep/foo.d)                [X]
-DEP_FILES = $(DEP_FILES_PASS1:%=$(DEP_PATH)/%)
-# Dependencies for %.o: %.c rule                                             [X]
-OBJ_DEPS = $(DEP_PATH)/%.d | $(OBJ_PATH) $(DEP_PATH)
-# Change .c extension to .pre and remove directory-part(path/to/foo.c =>     [X]
-# foo.pre)
-PRE_FILES_PASS1 = $(notdir $(SRC_FILES:.c=.pre))
-# Prefix all files with $(PRE_PATH)(foo.pre => ./build/debug/pre/foo.pre)    [X]
-PRE_FILES = $(PRE_FILES_PASS1:%=$(PRE_PATH)/%)
-# Dependencies for %.pre: %.c rule                                           [X]
-PRE_DEPS = $(DEP_PATH)/%.d | $(PRE_PATH) $(DEP_PATH)
-################################################################################
-# EXTERNAL
-################################################################################
-# Input path for third-parties headers                                       [R]
-EXT_INC_PATH = $(EXT_PATH)/$(INC_FOLDER)
-# Input path for third-parties libraries                                     [R]
-EXT_LIB_PATH = $(EXT_PATH)/$(LIB_FOLDER)
-# List of directories containing third-parties libraries                     [+]
-EXT_LIB_DIRS = $(shell find $(EXT_LIB_PATH)/ -type d)
-# Output folder for third-parties                                            [X]
-EXT_INSTALL_PREFIX := $(CURDIR)/$(EXT_PATH)
-# Command to invoke submakes in external folder                              [X]
-EXT_SUBMAKE = $(MAKE) -C $(EXT_PATH)
-# List of directories containing *.h files                                   [+]
-INC_DIRS += $(wildcard $(EXT_PATH))
-INC_DIRS += $(wildcard $(EXT_INC_PATH))
-################################################################################
-# PROGRAM
-################################################################################
-# Name of the program to build                                               [R]
-PROGRAM_NAME = $(PROJECT)
-# Output path for the project program                                        [X]
-PROGRAM_PATH = $(BUILD_PATH)/$(PROGRAM_NAME)
-# Target to build main program                                               [X]
-PROGRAM_TARGET = $(PROGRAM_PATH)
-################################################################################
-# LIBRARY COMMON
-################################################################################
-# 'foo' part in 'libfoo'                                                     [R]
-LIB_NAME = $(PROJECT)
-# Path where to install headers                                              [X]
-HEADER_INSTALL_PATH = $(includedir)/$(LIB_NAME)
-# Path where to install library                                              [X]
-LIB_INSTALL_PATH = $(libdir)/$(LIB_NAME)
-################################################################################
-# SHARED LIBRARY
-################################################################################
-# libfoo.so                                                                  [X]
-LIB_SHARED = lib$(LIB_NAME).so
-# libfoo.so.1                                                                [X]
-LIB_SHARED_X = $(LIB_SHARED).$(VERSION_MAJOR)
-# libfoo.so.1.2.3                                                            [X]
-LIB_SHARED_XYZ = $(LIB_SHARED).$(VERSION)
-# Output path for libfoo.so                                                  [X]
-LIB_SHARED_PATH = $(BUILD_PATH)/$(LIB_SHARED)
-# Output path for libfoo.so.1                                                [X]
-LIB_SHARED_X_PATH = $(BUILD_PATH)/$(LIB_SHARED_X)
-# Output path for libfoo.so.1.2.3                                            [X]
-LIB_SHARED_XYZ_PATH = $(BUILD_PATH)/$(LIB_SHARED_XYZ)
-# Target to build the shared lib                                             [X]
-LIB_SHARED_TARGET = $(LIB_SHARED_XYZ_PATH)
-################################################################################
-# STATIC LIBRARY
-################################################################################
-# libfoo.a                                                                   [X]
-LIB_STATIC = lib$(LIB_NAME).a
-# Output path for libfoo.a                                                   [X]
-LIB_STATIC_PATH = $(BUILD_PATH)/$(LIB_STATIC)
-# Target to build the static lib                                             [X]
-LIB_STATIC_TARGET = $(LIB_STATIC_PATH)
diff --git a/makefiles/targets.mk b/makefiles/targets.mk
deleted file mode 100644
index fcb1423055a9f4fe489a5b8d576643d5d3818367..0000000000000000000000000000000000000000
--- a/makefiles/targets.mk
+++ /dev/null
@@ -1,267 +0,0 @@
-# SPDX-License-Identifier: 0BSD
-################################################################################
-# TARGETS
-#
-# [R]: Variable can be redefined with a single value.
-# [+]: Variable can be redefined and/or have values added to it.
-# [X]: Variable must not be redefined nor have values added to it.
-################################################################################
-# Build project and tests(if there is a test folder) with the default build mode
-# (debug).
-.PHONY: all
-ALL_CMD :=
-all:: $(PROJECT_DEPS) $(PROJECT_TYPE) $(TEST_TARGET)
-	$(ALL_CMD)
-
-# Same as `all` target but also build in release mode.
-.PHONY: all_dr
-all_dr::
-	$(MAKE) all BUILD_MODE=debug
-	$(MAKE) all BUILD_MODE=release
-
-# Compile *.c files
-$(OBJ_PATH)/%.o: %.c $(OBJ_DEPS)
-	$(COMPILE)
-################################################################################
-# HEADER PROJECT
-#
-# Project which only provide headers (*.h) and thus does not need to compile
-# code(apart from tests).
-################################################################################
-ifeq ($(PROJECT_TYPE),header)
-# Nothing to build for header only project(tests are built with the `test`
-# target).
-SRC_DIRS :=
-COV_CMD :=
-.PHONY: header
-header::;
-endif
-################################################################################
-# HEADER/LIBRARY PROJECT COMMON
-################################################################################
-ifeq ($(PROJECT_TYPE),$(findstring $(PROJECT_TYPE),header shared static))
-# Install header files(*.h)
-INSTALL_DEPS := install_header
-.PHONY: install_header
-install_header:: $(PKG_HEADER_TARGET) | $(HEADER_INSTALL_PATH) $(PKG_PC_INSTALL_PATH)
-	cp -r $(INC_PATH)/. $(HEADER_INSTALL_PATH)
-	mv $(PKG_PC_NAME) $(PKG_PC_INSTALL_PATH)
-
-# *.pc.in => *.pc
-$(PKG_HEADER_TARGET)::
-	$(PKG_PC_IN)
-
-# Uninstall header files(*.h/*.pc)
-UNINSTALL_DEPS := uninstall_header
-.PHONY: uninstall_header
-uninstall_header::
-	rm -r $(HEADER_INSTALL_PATH)
-	rm $(PKG_PC_INSTALL_PATH)/$(PKG_PC_NAME)
-endif
-################################################################################
-# LIBRARY PROJECT
-################################################################################
-ifeq ($(PROJECT_TYPE),$(findstring $(PROJECT_TYPE),shared static))
-# Install library files(*.a/*.so)
-INSTALL_DEPS := install_lib
-.PHONY: install_lib
-install_lib:: install_header | $(LIB_INSTALL_PATH)
-	cp -ar $(BUILD_PATH)/* $(LIB_INSTALL_PATH)
-	find $(EXT_LIB_PATH) -type f,l -exec cp -at $(LIB_INSTALL_PATH) {} +
-
-# Build shared library(*.so)
-.PHONY: shared
-shared:: $(LIB_SHARED_TARGET)
-
-# *.o => *.so.*
-$(LIB_SHARED_TARGET): $(OBJ_FILES) | $(BUILD_PATH)
-	$(LINK_SHARED)
-	ln -sf $(LIB_SHARED_XYZ) $(LIB_SHARED_X_PATH)
-	ln -sf $(LIB_SHARED_X) $(LIB_SHARED_PATH)
-
-# Build static library(*.a)
-.PHONY: static
-static:: $(LIB_STATIC_TARGET)
-
-# *.o => *.a
-$(LIB_STATIC_TARGET): $(OBJ_FILES) | $(BUILD_PATH)
-	$(ARCHIVE)
-
-# Uninstall library files(*.a/*.so.*/*.h/*.pc)
-UNINSTALL_DEPS := uninstall_lib
-.PHONY: uninstall_lib
-uninstall_lib:: uninstall_header
-	rm -r $(LIB_INSTALL_PATH)
-endif
-################################################################################
-# PROGRAM PROJECT
-################################################################################
-# Build program
-ifeq ($(PROJECT_TYPE),program)
-.PHONY: program
-program:: $(PROGRAM_TARGET)
-
-# *.o => executable
-$(PROGRAM_TARGET): $(OBJ_FILES) | $(BUILD_PATH)
-	$(LINK_PROGRAM)
-
-# Run program
-RUN_CMD = $(PROGRAM_PATH)
-.PHONY: run
-run:: $(RUN_DEPS)
-	$(RUN_CMD)
-endif
-################################################################################
-# TEST
-################################################################################
-# Build tests if there is a test folder
-ifneq ($(TEST_TARGET),)
-.PHONY: test
-test::
-	$(MAKE) -C $(TEST_PATH) all CC=$(CC) MAKEFILE_PATH=../$(MAKEFILE_PATH)
-
-PRE_PASS_DEPS = pre_pass_test
-.PHONY: pre_pass_test
-pre_pass_test::
-	$(MAKE) -C $(TEST_PATH) pre_pass MAKEFILE_PATH=../$(MAKEFILE_PATH)
-
-# Run tests
-.PHONY: check
-check:: test
-	$(MAKE) -C $(TEST_PATH) run MAKEFILE_PATH=../$(MAKEFILE_PATH)
-
-# Remove test build files
-CLEAN_DEPS := clean_test
-.PHONY: clean_test
-clean_test::
-	$(MAKE) -C $(TEST_PATH) clean MAKEFILE_PATH=../$(MAKEFILE_PATH)
-
-# Tests analyze
-ANALYZE_DEPS += analyze_test
-.PHONY: analyze_test
-analyze_test::
-	$(MAKE) -C $(TEST_PATH) analyze MAKEFILE_PATH=../$(MAKEFILE_PATH)
-
-# Tests coverage
-COV_DEPS += cov_test
-.PHONY: cov_test
-cov_test::
-	$(MAKE) -C $(TEST_PATH) cov MAKEFILE_PATH=../$(MAKEFILE_PATH)
-endif
-################################################################################
-# CODE ANALYSIS/COVERAGE - DOC
-################################################################################
-# Analyze code with various tools
-.PHONY: analyze
-analyze:: $(ANALYZE_DEPS) | $(ANALYSIS_DIR_DEPS)
-	$(ANALYSIS_CMD)
-
-# Code coverage tools
-.PHONY: cov
-cov:: $(COV_DEPS) | $(COV_DIR_DEPS)
-	$(COV_CMD)
-
-# Generate documentation
-.PHONY: doc
-doc:: $(DOC_DEPS) | $(DOC_DIR_DEPS)
-	$(DOC_CMD)
-################################################################################
-# CLEAN/REBUILD/INSTALL/UNINSTALL/PREPROCESSOR
-################################################################################
-# Remove build files
-CLEAN_CMD = rm -rf $(BUILD_ROOT_PATH)
-.PHONY: clean
-clean:: $(CLEAN_DEPS)
-	$(CLEAN_CMD)
-
-# Remove existing build files and build again
-.PHONY: rebuild
-rebuild:: clean all
-
-# Install everything
-.PHONY: install
-install:: $(INSTALL_DEPS)
-
-# Uninstall everything
-.PHONY: uninstall
-uninstall:: $(UNINSTALL_DEPS)
-
-# Only output the result of the preprocessor pass.
-.PHONY: pre_pass
-pre_pass:: $(PRE_FILES) $(PRE_PASS_DEPS)
-
-# Implicit rule to output the result of the preprocessor pass.
-$(PRE_PATH)/%.pre: %.c $(PRE_DEPS)
-	$(PREPROCESSOR)
-################################################################################
-# HELP
-################################################################################
-.PHONY: help
-help::
-	@printf "Usage: make [TARGETS] [OPTIONS]\n"
-	@printf "\n"
-	@printf " - Unless stated otherwise, all targets build in '%s' mode.\n" "$(BUILD_MODE)"
-	@printf "\n"
-	@printf "TARGETS:\n"
-	@printf "  all                  : Default target. Build program(s), static/dynamic lib(s) and tests.\n"
-	@printf "  all_dr               : Same as 'all' but also build in release mode.\n"
-	@printf "  analyze              : \n"
-	@printf "  check                : Run tests(and build them first if needed).\n"
-	@printf "  clean                : \n"
-	@printf "  cov                  : Run code coverage tool(s).\n"
-	@printf "  doc                  : Build documentation.\n"
-	@printf "  install              : Equivalent to calling targets 'install_header' and 'install_lib'.\n"
-	@printf "  install_header       : Install headers. Default path is '%s'.\n" "$(HEADER_INSTALL_PATH)"
-	@printf "  install_lib          : Instal lib. Default path is '%s'.\n" "$(LIB_INSTALL_PATH)"
-	@printf "  pre_pass             : \n"
-	@printf "  program              : Build program.\n"
-	@printf "  rebuild              : Clean project and rebuild it. Equivalent to calling targets 'clean' and 'all' successively.\n"
-	@printf "  run                  : Run program.\n"
-	@printf "  shared               : Build shared lib.\n"
-	@printf "  static               : Build static lib.\n"
-	@printf "  test                 : Build tests.\n"
-	@printf "  uninstall            : \n"
-	@printf "  uninstall_header     : Uninstall headers.\n"
-	@printf "  uninstall_lib        : Uninstall lib.\n"
-	@printf "\n"
-	@printf "OPTIONS:\n"
-	@printf "  BUILD_MODE=<MODE>    : <MODE> must be one of [debug, release]. Default value is '%s'.\n" "$(BUILD_MODE)"
-	@printf "  CC=<COMPILER>        : <COMPILER> must be one of [gcc]. Default value is '%s'.\n" "$(CC)"
-	@printf "  COVERAGE=<true|false>: Default value is '%s'.\n" "$(COVERAGE)"
-	@printf "  DESTDIR=<PATH>       : Default path is '%s'.\n" "$(DESTDIR)"
-	@printf "  bindir=<PATH>        : Default path is '%s'.\n" "$(bindir)"
-	@printf "  exec_prefix=<PATH>   : Default path is '%s'.\n" "$(exec_prefix)"
-	@printf "  includedir=<PATH>    : Default path is '%s'.\n" "$(includedir)"
-	@printf "  libdir=<PATH>        : Default path is '%s'.\n" "$(libdir)"
-	@printf "  prefix=<PATH>        : Default path is '%s'.\n" "$(prefix)"
-################################################################################
-# MISC
-################################################################################
-# Targets depending on the existence of an optional file/directory are
-# redirected here to avoid make failing with `No rule to make target`.
-#.PHONY: _empty_target
-#_empty_target::;
-#%::;
-
-#%::
-#	@echo "$(MAKECMDGOALS)"
-# Targets to create output directories when they are needed but don't exist yet.
-# mkdir -p: No error if directory exists and make parent directories as needed
-$(ANALYSIS_DIR_DEPS):   ;mkdir -p $(ANALYSIS_DIR_DEPS)
-$(BUILD_PATH):          ;mkdir -p $(BUILD_PATH)
-$(COV_DIR_DEPS):        ;mkdir -p $(COV_DIR_DEPS)
-$(DEP_PATH):            ;mkdir -p $(DEP_PATH)
-$(DOC_DIR_DEPS):        ;mkdir -p $(DOC_DIR_DEPS)
-$(HEADER_INSTALL_PATH): ;mkdir -p $(HEADER_INSTALL_PATH)
-$(LIB_INSTALL_PATH):    ;mkdir -p $(LIB_INSTALL_PATH)
-$(OBJ_PATH):            ;mkdir -p $(OBJ_PATH)
-$(PKG_PC_INSTALL_PATH): ;mkdir -p $(PKG_PC_INSTALL_PATH)
-$(PRE_PATH):            ;mkdir -p $(PRE_PATH)
-# Make each *.d file a target so make won't fail if the file doesn't exist
-$(DEP_FILES):
-# Only include *.d files if needed
-ifeq ($(MAKECMDGOALS),$(findstring $(PROJECT_TYPE),program shared static))
-    include $(wildcard $(DEP_FILES))
-endif
-# Delete files generated by a target which failed(prevent corrupted files)
-.DELETE_ON_ERROR:
diff --git a/makefiles/tools.mk b/makefiles/tools.mk
deleted file mode 100644
index 8c7882a05e642ab3b3fbca9946bc039ff3c08e33..0000000000000000000000000000000000000000
--- a/makefiles/tools.mk
+++ /dev/null
@@ -1,173 +0,0 @@
-# SPDX-License-Identifier: 0BSD
-################################################################################
-# TOOLS
-#
-# [R]: Variable can be redefined with a single value.
-# [+]: Variable can be redefined and/or have values added to it.
-# [X]: Variable must not be redefined nor have values added to it.
-################################################################################
-# The following variables are defined here for documentation. They are set as
-# needed for each individual tools used below.
-# Existence of a tool should be tested before adding it to a `<>_CMD` variable
-# to prevent errors when running make.
-
-# List of commands to be run by the `analysis` target.                       [+]
-ANALYSIS_CMD      :=
-# List of directories to be created by the `analysis` target.                [+]
-ANALYSIS_DIR_DEPS :=
-# List of commands to be run by the `cov` target.                            [+]
-COV_CMD           :=
-# List of directories to be created by the `cov` target.                     [+]
-COV_DIR_DEPS      :=
-# List of commands to be run by the `doc` target.                            [+]
-DOC_CMD           :=
-# List of directories to be created by the `doc` target.                     [+]
-DOC_DIR_DEPS      :=
-################################################################################
-# CPPCHECK
-################################################################################
-# Output path for data generated by cppcheck                                 [R]
-CPPCHECK_PATH_OUT = $(ANALYSIS_PATH)/cppcheck
-# Executable name                                                            [R]
-CPPCHECK_EXEC := cppcheck
-# Cppcheck command ran by the `analysis` target                              [+]
-CPPCHECK_CMD = $(CPPCHECK_EXEC)
-# Enable all checks
-CPPCHECK_CMD += --enable=all
-CPPCHECK_CMD += --force
-# Allow reports even if the analysis is inconclusive
-CPPCHECK_CMD += --inconclusive
-CPPCHECK_CMD += --language=c
-CPPCHECK_CMD += --platform=native
-# Only print if there is an error
-CPPCHECK_CMD += --quiet
-CPPCHECK_CMD += --std=c11
-CPPCHECK_CMD += --check-config
-CPPCHECK_CMD += -I./$(INC_PATH)
-CPPCHECK_CMD += -I./$(EXT_PATH) .
-CPPCHECK_CMD += . 2> $(CPPCHECK_PATH_OUT)/cppcheck
-ifneq ($(shell which $(CPPCHECK_EXEC)),)
-ANALYSIS_CMD += $(CPPCHECK_CMD)
-ANALYSIS_DIR_DEPS += $(CPPCHECK_PATH_OUT)
-endif
-################################################################################
-# DOXYGEN
-################################################################################
-# Output path for data generated by doxygen                                  [R]
-DOXYGEN_PATH_OUT = $(DOC_PATH)/doxygen
-DOC_DIR_DEPS += $(DOXYGEN_PATH_OUT)
-DOC_CMD += doxygen
-################################################################################
-# GCOV
-################################################################################
-# Set gcov version to the same as the gcc one.                               [X]
-GCOV_EXEC = gcov$(lastword $(subst -, -,$(CC)))
-################################################################################
-# LCOV
-################################################################################
-# Output path for data generated by lcov                                     [R]
-LCOV_PATH_OUT = $(ANALYSIS_PATH)/lcov
-# Executable name                                                            [R]
-LCOV_EXEC := lcov
-# Lcov command                                                               [+]
-LCOV_CMD = $(LCOV_EXEC)
-# Capture coverage data
-LCOV_CMD += --capture
-# Use current directory as base for relative paths
-LCOV_CMD += --directory .
-# Path to the appropriate gcov executable
-LCOV_CMD += --gcov-tool $(GCOV_EXEC)
-# Don't include external source files
-LCOV_CMD += --no-external
-# Don't print progress messages
-LCOV_CMD += --quiet
-# Capture branch coverage
-LCOV_CMD += --rc lcov_branch_coverage=1
-# Make a first pass to establish a baseline with 0 coverage.
-LCOV_INITIAL  = $(LCOV_CMD)
-LCOV_INITIAL += --initial
-LCOV_INITIAL += -o $(LCOV_PATH_OUT)/test_main_initial.info
-# Make the actual capture run
-LCOV_RUN  = $(LCOV_CMD)
-LCOV_RUN += -o $(LCOV_PATH)/test_main_run.info
-# Combine baseline and run
-LCOV_FINAL  = $(LCOV_EXEC)
-LCOV_FINAL += -a $(LCOV_PATH_OUT)/test_main_initial.info
-LCOV_FINAL += -a $(LCOV_PATH_OUT)/test_main_run.info
-LCOV_FINAL += -o $(LCOV_PATH_OUT)/test_main_final.info
-# Executable name                                                            [R]
-GENHTML_EXEC := genhtml
-# Generate html report                                                       [+]
-GENHTML_CMD = $(GENHTML_EXEC)
-GENHTML_CMD += --legend
-GENHTML_CMD += --quiet
-GENHTML_CMD += --show-details
-GENHTML_CMD += -o $(LCOV_PATH_OUT) $(LCOV_PATH_OUT)/test_main_final.info
-ifneq ($(and \
-    $(shell which $(GCOV_EXEC)), \
-    $(shell which $(LCOV_EXEC)), \
-    $(shell which $(GENHTML_EXEC)) \
-),)
-# Command ran by the `cov` target                                            [+]
-COV_CMD += $(LCOV_INITIAL)
-COV_CMD += $(RUN_CMD)
-COV_CMD += $(LCOV_RUN)
-COV_CMD += $(LCOV_FINAL)
-COV_CMD += $(GENHTML_CMD)
-COV_DIR_DEPS += $(LCOV_PATH_OUT)
-endif
-################################################################################
-# SCANBUILD
-################################################################################
-# Output path for data generated by scanbuild                                [R]
-SCANBUILD_PATH_OUT = $(ANALYSIS_PATH)/scanbuild
-# Executable name                                                            [R]
-SCANBUILD_EXEC := scan-build
-# Scanbuild command ran by the `analysis` target                             [+]
-SCANBUILD_CMD  = $(SCANBUILD_EXEC)
-SCANBUILD_CMD += -analyze-headers
-SCANBUILD_CMD += -o $(SCANBUILD_PATH)
-SCANBUILD_CMD += make --silent all
-ifneq ($(shell which $(SCANBUILD_EXEC)),)
-#ANALYSIS_CMD += $(SCANBUILD_CMD)
-#ANALYSIS_DIR_DEPS += $(SCANBUILD_PATH_OUT)
-endif
-################################################################################
-# VALGRIND
-################################################################################
-# Output path for data generated by valgrind                                 [R]
-VALGRIND_PATH_OUT = $(ANALYSIS_PATH)/valgrind
-# Executable name                                                            [R]
-VALGRIND_EXEC := valgrind
-# Valgrind command ran by the `analysis` target                              [+]
-VALGRIND_CMD  = $(VALGRIND_EXEC)
-VALGRIND_CMD := --leak-check=full
-VALGRIND_CMD += --show-leak-kinds=all
-VALGRIND_CMD += --track-origins=yes
-VALGRIND_CMD += $(TEST_EXE) 2> $(VALGRIND_PATH_OUT)/valgrind
-ifneq ($(shell which $(VALGRIND_EXEC)),)
-#ANALYSIS_CMD += $(VALGRIND_CMD)
-#ANALYSIS_DIR_DEPS += $(VALGRIND_PATH_OUT)
-endif
-################################################################################
-# PKGCONFIG
-################################################################################
-# Name of the pkg-config file(*.pc)                                          [X]
-PKG_PC_NAME = $(PROJECT).pc
-# Installation path for the pkg-config file(*.pc)                            [X]
-PKG_PC_INSTALL_PATH = $(libdir)/pkgconfig
-# Target for the pkg-config file header template                             [X]
-PKG_HEADER_TARGET = $(MAKEFILE_PATH)/header.pc.in
-# Create a pkg-config file(*.pc) by taking a template file (*pc.in) and replace
-# all the `@variable@` with an actual value.
-# `|` is used instead of `/` otherwise sed will fail when variables contain a
-# `/` which is almost always the case with paths(=> 's/@prefix@//usr/local/').
-PKG_PC_IN = sed \
--e 's|@prefix@|$(prefix)|' \
--e 's|@exec_prefix@|$(exec_prefix)|' \
--e 's|@includedir@|$(includedir)|' \
--e 's|@libdir@|$(libdir)|' \
--e 's|@PROJECT@|$(PROJECT)|' \
--e 's|@DESCRIPTION@|$(DESCRIPTION)|' \
--e 's|@VERSION@|$(VERSION)|' \
-$@ > $(PKG_PC_NAME)
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 37221b37f8ba8398ad02d1937e29faf3b9858049..0000000000000000000000000000000000000000
--- a/src/main.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "fmpi.h"
-#include <assert.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define ARRAY_SIZE 16
-#define T double
-int main(int argc, char * argv[])
-{
-    struct fmpi_ctx * ctx = fmpi_init(&argc, &argv);
-    if(ctx == NULL) {
-        fprintf(stderr, "fmpi_init() failed!\n");
-        fmpi_abort(NULL);
-    }
-    if(fmpi_mpi_is_root(ctx->mpi)) {
-        fmpi_ctx_print(ctx);
-    }
-    const size_t start = (size_t)(ctx->mpi->rank * ctx->mpi->size);
-    T array[ARRAY_SIZE] = {
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
-    };
-    T fact_local = fmpi_local_reduce_prod(ctx, (array+start), ARRAY_SIZE/ctx->mpi->size);
-    printf("rank=%d fact_local=%"FMPI_PFMT(T)"\n", ctx->mpi->rank, fact_local);
-    T fact_global = fmpi_reduce_prod(ctx, &fact_local);
-    if(fmpi_mpi_is_root(ctx->mpi)) {
-        printf("rank=%d fact_global=%"FMPI_PFMT(T)"\n", ctx->mpi->rank, fact_global);
-    }
-    fmpi_exit(ctx);
-    return EXIT_SUCCESS;
-}