diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8f4b98120703c0e7690801ffa910c53bf509aaf8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,140 @@
+# CMake file for the Corryvreckan framework
+CMAKE_MINIMUM_REQUIRED(VERSION 3.4.3 FATAL_ERROR)
+IF(COMMAND CMAKE_POLICY)
+  CMAKE_POLICY(SET CMP0003 NEW) # change linker path search behaviour
+  CMAKE_POLICY(SET CMP0048 NEW) # set project version
+ENDIF(COMMAND CMAKE_POLICY)
+
+# Set default version
+SET(CORRYVRECKAN_VERSION "v0.1")
+
+# Set default build type
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+# Overwrite with the version from git if found
+INCLUDE("cmake/tools.cmake")
+GET_VERSION(CORRYVRECKAN_VERSION)
+
+# Print version
+MESSAGE(STATUS "Building Corryvreckan version ${CORRYVRECKAN_VERSION}.")
+
+# Define the project with the simple version
+STRING(REGEX MATCH "([0-9.]+)+" SIMPLE_VERSION "${CORRYVRECKAN_VERSION}")
+# Set languages to NONE to allow the documentation to be built without CXX compiler:
+PROJECT(Corryvreckan VERSION ${SIMPLE_VERSION} LANGUAGES NONE)
+# Access the project name (for install locations) in the source
+ADD_DEFINITIONS(-DCORRYVRECKAN_PROJECT_NAME="${CMAKE_PROJECT_NAME}" -DCORRYVRECKAN_PROJECT_VERSION="${CORRYVRECKAN_VERSION}")
+
+# Include a generated configuration file
+# FIXME: this should be combined with the ADD_DEFINITIONS
+CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake.h" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
+
+###############################
+# Setup the build environment #
+###############################
+
+# Enable CXX as project language to perform compiler checks:
+ENABLE_LANGUAGE(CXX)
+
+# Additional packages to be searched for by cmake
+LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
+
+# Configure the installation prefix to allow both local as system-wide installation
+IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+    SET(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}" CACHE PATH "Prefix prepended to install directories" FORCE)
+ENDIF()
+
+# Set up the RPATH so executables find the libraries even when installed in non-default location
+SET(CMAKE_MACOSX_RPATH TRUE)
+SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+
+# Add the automatically determined parts of the RPATH which point to directories outside the build tree to the install RPATH
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+# The RPATH to be used when installing, but only if it's not a system directory
+LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" IsSystemDir)
+IF("${IsSystemDir}" STREQUAL "-1")
+   SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+ENDIF("${IsSystemDir}" STREQUAL "-1")
+
+#########################################
+# Define build flags for Corryvreckan   #
+#########################################
+
+# Set standard build flags
+#SET(COMPILER_FLAGS -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wconversion -Wuseless-cast -Wctor-dtor-privacy -Wzero-as-null-pointer-constant -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wshadow -Wformat-security -Wdeprecated -fdiagnostics-color=auto -Wheader-hygiene)
+
+# Require a C++14 compiler but do allow extensions
+SET(CMAKE_CXX_STANDARD 14)
+SET(CMAKE_CXX_STANDARD_REQUIRED ON)
+SET(CMAKE_CXX_EXTENSIONS OFF)
+
+INCLUDE("cmake/compiler-flag-checks.cmake")
+
+# Set some debug flags
+# FIXME: not using the flag checker now because it wrongly rejects a sanitizer flag..
+IF(CMAKE_BUILD_TYPE MATCHES Debug AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
+    MESSAGE(STATUS "Running debug build - Adding extra sanitizer flags")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined")
+    # FIXME: remove earlier shared linker flags, because they can break the sanitizer debug build
+    SET(CMAKE_SHARED_LINKER_FLAGS "-fsanitize=address -fsanitize=undefined")
+ENDIF()
+
+###################################
+# Prerequisistes for Corryvreckan #
+###################################
+
+# Define the libraries
+SET(CORRYVRECKAN_LIBRARIES "")
+
+# ROOT is required for vector and persistency etc
+FIND_PACKAGE(ROOT REQUIRED COMPONENTS Minuit Minuit2 Gui GenVector)
+IF(NOT ROOT_FOUND)
+    MESSAGE(FATAL_ERROR "Could not find ROOT, make sure to source the ROOT environment\n"
+    "$ source YOUR_ROOT_DIR/bin/thisroot.sh")
+ENDIF()
+
+# Check ROOT version
+IF (NOT ${ROOT_VERSION} VERSION_GREATER "6.0")
+    MESSAGE(FATAL_ERROR "ROOT versions below 6.0 are not supported")
+ENDIF()
+
+# Set the dependencies
+SET(CORRYVRECKAN_DEPS_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS})
+SET(CORRYVRECKAN_DEPS_LIBRARIES ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES})
+
+
+###################################
+# Load cpp format and check tools #
+###################################
+
+# Set the source files to clang-format (FIXME: determine this better)
+FILE(GLOB_RECURSE
+     CHECK_CXX_SOURCE_FILES
+        src/*.[tch]pp src/*.h src/*.C
+     )
+INCLUDE("cmake/clang-cpp-checks.cmake")
+
+#########################################
+# Define build targets for Corryvreckan #
+#########################################
+
+# Always include sources from top directory
+INCLUDE_DIRECTORIES(src)
+
+# Build core Corryvreckan library
+ADD_SUBDIRECTORY(src/core)
+SET(CORRYVRECKAN_LIBRARIES ${CORRYVRECKAN_LIBRARIES} CorryvreckanCore)
+
+# Build objects library
+ADD_SUBDIRECTORY(src/objects)
+SET(CORRYVRECKAN_LIBRARIES ${CORRYVRECKAN_LIBRARIES} CorryvreckanObjects)
+
+# Build required modules
+ADD_SUBDIRECTORY(src/algorithms)
+
+# Build the executable
+ADD_SUBDIRECTORY(src/exec)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..edc8f1b5a31033b936dfc70422bc22646719366b
--- /dev/null
+++ b/src/core/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Include the dependencies
+INCLUDE_DIRECTORIES(SYSTEM ${CORRYVRECKAN_DEPS_INCLUDE_DIRS})
+
+# Create core library
+ADD_LIBRARY(CorryvreckanCore SHARED
+    Analysis.C
+    Parameters.C
+    utils/log.cpp
+    utils/unit.cpp
+    config/ConfigManager.cpp
+    config/ConfigReader.cpp
+    config/Configuration.cpp
+    config/exceptions.cpp
+)
+
+# Link the dependencies
+TARGET_LINK_LIBRARIES(CorryvreckanCore ${CORRYVRECKAN_DEPS_LIBRARIES})
+TARGET_LINK_LIBRARIES(CorryvreckanCore ${CORRYVRECKAN_LIBRARIES})
+
+# Define compile-time library extension
+TARGET_COMPILE_DEFINITIONS(CorryvreckanCore PRIVATE SHARED_LIBRARY_SUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}")
+# Link the DL libraries
+TARGET_LINK_LIBRARIES(CorryvreckanCore ${CMAKE_DL_LIBS})
+
+# Create standard install target
+INSTALL(TARGETS CorryvreckanCore
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib)
diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ccf7e37533c5840218e9ac2d4481aead441d5924
--- /dev/null
+++ b/src/objects/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Include the standard dependencies
+INCLUDE_DIRECTORIES(SYSTEM ${CORRYVRECKAN_DEPS_INCLUDE_DIRS})
+
+# Find the RootNewMacros.cmake file and include it
+GET_FILENAME_COMPONENT(ROOT_CMAKE_DIR ${ROOT_USE_FILE} DIRECTORY)
+FIND_FILE(ROOT_MACROS_FILE
+          NAMES RootNewMacros.cmake
+          HINTS ${ROOT_CMAKE_DIR}/modules/ $ENV{ROOTSYS}/cmake/modules)
+
+IF(NOT ROOT_MACROS_FILE)
+    MESSAGE(WARNING "Cannot find ROOT macros, including generic file as fallback.")
+    INCLUDE(${ROOT_USE_FILE})
+ELSE()
+    INCLUDE(${ROOT_MACROS_FILE})
+ENDIF()
+
+# Generate the ROOT dictionary
+ROOT_GENERATE_DICTIONARY(CorryvreckanObjectsDictionary
+    ${CMAKE_CURRENT_SOURCE_DIR}/Cluster.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/GuiDisplay.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/KDTree.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/KDTreeTimepix3.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/Pixel.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/SpidrSignal.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/TestBeamObject.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/Timepix3Cluster.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/Timepix3Pixel.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/Timepix3Track.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/Track.h
+    MODULE
+    CorryvreckanObjects
+)
+
+# Explicitly add all the dependent include dirs to the manual command
+FOREACH(dir IN ITEMS ${CORRYVRECKAN_DEPS_INCLUDE_DIRS})
+    IF(NOT INCLUDE_DIR_ARGS)
+        SET(INCLUDE_DIR_ARGS "-I${dir}")
+    ELSE()
+        SET(INCLUDE_DIR_ARGS "${INCLUDE_DIR_ARGS} -I${dir}")
+    ENDIF()
+ENDFOREACH()
+
+# Compile the dictionary through a special target
+# WARNING This hack is necessary to prevent standard warnings and those in clang-tidy for use in the CI
+ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDictionary.cxx.o COMMAND ${CMAKE_CXX_COMPILER} -fPIC -std=c++${CMAKE_CXX_STANDARD} -I${CMAKE_SOURCE_DIR}/src ${INCLUDE_DIR_ARGS} -o ${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDictionary.cxx.o -c ${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDictionary.cxx DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDictionary.cxx)
+
+# Define the library adding the object file created above
+ADD_LIBRARY(CorryvreckanObjects SHARED
+    TestBeamObject.C
+    ${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDictionary.cxx.o
+)
+
+# Link the standard dependencies
+TARGET_LINK_LIBRARIES(CorryvreckanObjects ${CORRYVRECKAN_DEPS_LIBRARIES})
+
+# Specify install for the messages
+INSTALL(TARGETS CorryvreckanObjects
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib)
+
+# Also install the dictionary objects
+INSTALL(FILES
+    ${CMAKE_CURRENT_BINARY_DIR}/libCorryvreckanObjects_rdict.pcm
+    ${CMAKE_CURRENT_BINARY_DIR}/libCorryvreckanObjects.rootmap
+    DESTINATION lib)