diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 48af4ac65124c0a4fae4e3b35efa2a68f863c253..0000000000000000000000000000000000000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,134 +0,0 @@
-cmake_minimum_required(VERSION 3.3)
-
-project(EMPER)
-
-set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
-message("CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
-include(doxygen)
-
-execute_process(COMMAND ${PROJECT_SOURCE_DIR}/scripts/dependencyManager.sh -v install)
-set(EIGEN3_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/external-libs/eigen)
-find_package(Eigen3 REQUIRED)
-
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED on)
-set(CMAKE_EXPORT_COMPILE_COMMANDS on)
-
-set(COMMON_FLAGS "-Wall -pedantic -Wextra -Werror")
-set(COMMON_FLAGS "${COMMON_FLAGS} -fno-exceptions")
-
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}")
-
-message("CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
-message("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
-
-set(COMMON_DEBUG_FLAGS "-ggdb3")
-set(COMMON_BUILD_DEBUG_FLAGS "${COMMON_DEBUG_FLAGS} -O0")
-
-set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMMON_BUILD_DEBUG_FLAGS}")
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_BUILD_DEBUG_FLAGS}")
-
-set(COMMON_BUILD_RELWITHDEBUG_FLAGS "${COMMON_DEBUG_FLAGS} -O3")
-set(CMAKE_C_FLAGS_RELWITHDEBUG "${CMAKE_C_FLAGS_RELWITHDEBUG} ${COMMON_BUILD_RELWITHDEBUG_FLAGS}")
-set(CMAKE_CXX_FLAGS_RELWITHDEBUG "${CMAKE_CXX_FLAGS_RELWITHDEBUG} ${COMMON_BUILD_RELWITHDEBUG_FLAGS}")
-
-# For "-rdynamic" see https://stackoverflow.com/a/77336/194894 and "man gcc"
-# We probably don't need it since EMPER is mostly statically linked,
-# but it can't hurt to have it (hopefully).
-set(CMAKE_EXEC_LINKER_FLAGS_DEBUG "${CMAKE_EXEC_LINKER_FLAGS_DEBUG} -rdynamic")
-
-add_definitions(-D_GNU_SOURCE)
-
-set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
-
-enable_testing()
-
-# Custom options, enable with "cmake -DEMPER_WORKER_SLEEP=ON"
-# Source: https://stackoverflow.com/a/10364240/194894
-macro(emper_option option_name option_description)
-    option(EMPER_${option_name} ${option_description})
-    if(EMPER_${option_name})
-        add_definitions(-DEMPER_${option_name})
-    endif(EMPER_${option_name})
-endmacro()
-
-emper_option(WORKER_SLEEP "Enable sleeping worker support")
-emper_option(LOCKED_WS_QUEUE "Use a fully locked queue for work-stealing")
-emper_option(OVERFLOW_QUEUE "Use a overflow queue in case the primary queue is full")
-emper_option(LOCKED_MPSC_QUEUE "Use the locked variant for the MPSC queue")
-emper_option(STATS "Collect stats and print them at the end of the execution")
-
-# Macro to add files to a var. Can even be used in subdirectories.
-# Source: http://stackoverflow.com/a/7049380/194894
-macro (add_files var)
-    file (RELATIVE_PATH _relPath "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
-    foreach (_src ${ARGN})
-        if (_relPath)
-            list (APPEND ${var} "${_relPath}/${_src}")
-        else()
-            list (APPEND ${var} "${_src}")
-        endif()
-    endforeach()
-    if (_relPath)
-        # propagate ${var} to parent directory
-        set (${var} ${${var}} PARENT_SCOPE)
-    endif()
-endmacro()
-
-enable_language(ASM_NASM)
-
-add_subdirectory("emper")
-
-message("EMPER_SOURCE: ${EMPER_SOURCE}")
-message("EMPER_INCLUDE: ${EMPER_INCLUDE}")
-message("CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
-message("CMAKE_CXX_FLAGS_RELWITHDEBUG: ${CMAKE_CXX_FLAGS_RELWITHDEBUG}")
-message("CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}")
-
-add_library(emper_asm_source STATIC ${EMPER_ASM_SOURCE})
-
-add_library(emper STATIC ${EMPER_SOURCE})
-foreach(include_dir ${EMPER_INCLUDE})
-  message("Adding include directory: ${include_dir}")
-  target_include_directories(emper PUBLIC
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${include_dir}>
-	$<INSTALL_INTERFACE:${include_dir}>
-  )
-endforeach()
-# The following property is supposed to enable something like LTO. But
-# CMake appearantly only supports it for the icc. See
-# http://stackoverflow.com/a/31522585/194894
-# set_property(TARGET emper PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
-target_link_libraries(emper Threads::Threads emper_asm_source)
-
-add_library(c_emper STATIC ${C_EMPER_SOURCE})
-# See comment above regarding INTERPROCEDURAL_OPTIMIZATION
-# set_property(TARGET c_emper PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
-target_link_libraries(c_emper emper)
-
-add_subdirectory("lib")
-
-add_subdirectory("apps")
-
-add_subdirectory("tests")
-
-add_subdirectory("eval")
-
-file(GLOB ALL_SOURCE_FILES *.cpp)
-file(GLOB ALL_HEADER_FILES *.hpp)
-
-add_custom_target(clang-tidy
-  COMMAND clang-tidy
-  -config=''
-  -p ${CMAKE_BINARY_DIR}
-  ${ALL_SOURCE_FILES}
-  )
-add_dependencies(clang-tidy Main)
-
-add_custom_target(CheckEmperVersionHeader
-  COMMAND ${PROJECT_SOURCE_DIR}/scripts/versionManager.sh -v check
-  COMMENT "Checking if EMPER version header is up-to-date"
-  )
-add_dependencies(emper CheckEmperVersionHeader)
diff --git a/Makefile b/Makefile
index 0af760e4ba678290742310b6fda258bbd2ea5312..00ade082bcf1a6755f44a90a85446618a57d36fd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,41 @@
-.PHONY: all clean distclean doc full release relwithdebug reldebug debug stresstest test
+.PHONY: all build check clean distclean doc release debug stresstest test
+
 SHELL = bash
 
-NPROC := $(shell nproc)
-COMMON_MAKE_ARGS := -j $(NPROC) -l $(NPROC) $(MAKEFLAGS)
+all: build
+
+export BUILDTYPE ?= debugoptimized
+export BUILDDIR = build-$(BUILDTYPE)
+
+NINJA_BIN ?= ninja
+NINJA := $(NINJA_BIN) $(EXTRA_NINJA_ARGS)
+
+build:
+	[[ -L build ]] || ./tools/prepare-build-dir
+	$(NINJA) -C $@
+
+release:
+	rm -f build
+	$(MAKE) build BUILDTYPE=$@
+
+debug:
+	rm -f build
+	$(MAKE) build BUILDTYPE=$@
 
 
-all: release
+smoke-test: all
+	cd build && meson test --suite smoke
 
-full: release test doc
+
+TEST_NINJA_TARGETS += test
+
+doc: all
+	$(NINJA) -C build doc/html
+
+check: test
+
+test: all
+	$(NINJA) -C build $(TEST_NINJA_TARGETS)
 
 clean:
 	rm -f build
@@ -18,19 +46,6 @@ distclean: clean
 	./scripts/versionManager.sh -v clean
 	git clean -x -d -f
 
-debug release relwithdebug:
-	[[ -d build-$@ ]] || mkdir build-$@
-	rm -f build
-	ln -rs build-$@ build
-	cd build-$@; \
-		[[ -f CMakeCache.txt ]] || cmake -DCMAKE_BUILD_TYPE=$@ .. \
-		&& make $(COMMON_MAKE_ARGS)
-
-reldebug: relwithdebug
-
-test doc: release
-	cd build \
-		&& make $(COMMON_MAKE_ARGS) $@
 
 stresstest: test
 	./stresstest/stresstest.sh build/tests/simplest_fib_test
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
deleted file mode 100644
index 0c432b9b42e37de3a2970b165cffdea88ec7f33b..0000000000000000000000000000000000000000
--- a/apps/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-function(emper_app_single_file emper_app_name)
-  set(emper_app_filename "${emper_app_name}.cpp")
-  message("EMPER single file app: ${emper_app_name} (${emper_app_filename})")
-  add_executable(${emper_app_name} ${emper_app_filename})
-  target_link_libraries(${emper_app_name} Threads::Threads emper)
-endfunction()
-
-emper_app_single_file(Main)
-emper_app_single_file(WorkerSleepExample)
diff --git a/apps/meson.build b/apps/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..111457173d8872f60d8c6850dcf292f258f2538e
--- /dev/null
+++ b/apps/meson.build
@@ -0,0 +1,13 @@
+fib_exe = executable(
+  'fib',
+  'Main.cpp',
+  include_directories: emper_all_include,
+  link_with: [emper],
+)
+
+worker_sleep_example_exe = executable(
+  'worker_sleep_example',
+  'WorkerSleepExample.cpp',
+  include_directories: emper_all_include,
+  link_with: [emper],
+)
diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake
deleted file mode 120000
index 1249b28f83afdf1abf027dc89c7ee727a10751cb..0000000000000000000000000000000000000000
--- a/cmake/FindEigen3.cmake
+++ /dev/null
@@ -1 +0,0 @@
-../external-libs/eigen/cmake/FindEigen3.cmake
\ No newline at end of file
diff --git a/cmake/doxygen.cmake b/cmake/doxygen.cmake
deleted file mode 100644
index e7e8a0f9a72d0e6720695ca8b58079bb7b07c144..0000000000000000000000000000000000000000
--- a/cmake/doxygen.cmake
+++ /dev/null
@@ -1,31 +0,0 @@
-find_package(Doxygen)
-
-if(NOT DOXYGEN_FOUND)
-  message(FATAL_ERROR 
-    "Doxygen is needed to build the documentation. Please install it correctly")
-endif()
-
-# set output path
-set(DOXY_OUTPUT "doc")
-set(DOXY_GENERATE_LATEX "NO")
-set(DOXY_IGNORE "")
-set(DOXY_INPUT_DIR "${PROJECT_SOURCE_DIR}")
-
-if(DOXYGEN_DOT_FOUND)
-  set(DOXY_USE_GRAPHVIZ "YES" ) 
-  message(STATUS "[DOXYGEN] Using graphviz to draw nice graphs.")
-else(DOXYGEN_DOT_FOUND) 
-  set(DOXY_USE_GRAPHVIY "NO" ) 
-  message(STATUS "[DOXYGEN] GraphViz' Dot tool not found.")
-endif(DOXYGEN_DOT_FOUND) 
-   
-# Configure the Template Doxyfile for our specific project
-configure_file(${PROJECT_SOURCE_DIR}/Doxyfile.in 
-               ${PROJECT_BINARY_DIR}/Doxyfile  @ONLY IMMEDIATE)
-
-# Add a custom target to run Doxygen (make doc)
-add_custom_target (doc
-  COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile
-  SOURCES ${PROJECT_BINARY_DIR}/Doxyfile
-  COMMAND echo "HTML ouput at ${DOXY_OUTPUT}/html/index.html"
-  )
diff --git a/Doxyfile.in b/doc/Doxyfile.in
similarity index 89%
rename from Doxyfile.in
rename to doc/Doxyfile.in
index 7bd719fe314cb5fdd6a54ffbd45678691700709f..e5b333d09494298364bb322101aa79aced4adfea 100644
--- a/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.10
+# Doxyfile 1.8.17
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project.
@@ -17,11 +17,11 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
+# This tag specifies the encoding used for all characters in the configuration
+# file that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
 # The default value is: UTF-8.
 
 DOXYFILE_ENCODING      = UTF-8
@@ -38,7 +38,7 @@ PROJECT_NAME           = @PROJECT_NAME@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = @PROJECT_VERSION@
+PROJECT_NUMBER         = @VERSION@
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -58,7 +58,7 @@ PROJECT_LOGO           =
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = @DOXY_OUTPUT@
+OUTPUT_DIRECTORY       = "@TOP_BUILDDIR@/doc"
 
 # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and
@@ -76,7 +76,7 @@ CREATE_SUBDIRS         = NO
 # U+3044.
 # The default value is: NO.
 
-ALLOW_UNICODE_NAMES    = NO
+ALLOW_UNICODE_NAMES    = YES
 
 # The OUTPUT_LANGUAGE tag is used to specify the language in which all
 # documentation generated by doxygen is written. Doxygen will use this
@@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES    = NO
 
 OUTPUT_LANGUAGE        = English
 
+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all generated output in the proper direction.
+# Possible values are: None, LTR, RTL and Context.
+# The default value is: None.
+
+OUTPUT_TEXT_DIRECTION  = None
+
 # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
 # descriptions after the members that are listed in the file and class
 # documentation (similar to Javadoc). Set to NO to disable this.
@@ -118,7 +126,17 @@ REPEAT_BRIEF           = YES
 # the entity):The $name class, The $name widget, The $name file, is, provides,
 # specifies, contains, represents, a, an and the.
 
-ABBREVIATE_BRIEF       =
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
 
 # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
 # doxygen will generate a detailed section even if there is only a brief
@@ -152,7 +170,7 @@ FULL_PATH_NAMES        = YES
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH        = @CMAKE_SOURCE_DIR@
+STRIP_FROM_PATH        =
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
@@ -179,6 +197,16 @@ SHORT_NAMES            = NO
 
 JAVADOC_AUTOBRIEF      = NO
 
+# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
+# such as
+# /***************
+# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
+# Javadoc-style will behave just like regular comments and it will not be
+# interpreted by doxygen.
+# The default value is: NO.
+
+JAVADOC_BANNER         = NO
+
 # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
 # line (until the first dot) of a Qt-style comment as the brief description. If
 # set to NO, the Qt-style will behave just like regular Qt-style comments (thus
@@ -216,7 +244,7 @@ SEPARATE_MEMBER_PAGES  = NO
 # uses this value to replace tabs by spaces in code fragments.
 # Minimum value: 1, maximum value: 16, default value: 4.
 
-TAB_SIZE               = 8
+TAB_SIZE               = 4
 
 # This tag can be used to specify a number of aliases that act as commands in
 # the documentation. An alias has the form:
@@ -226,7 +254,12 @@ TAB_SIZE               = 8
 # will allow you to put the command \sideeffect (or @sideeffect) in the
 # documentation, which will result in a user-defined paragraph with heading
 # "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
+# newlines (in the resulting output). You can put ^^ in the value part of an
+# alias to insert a newline as if a physical newline was in the original file.
+# When you need a literal { or } or , in the value part of an alias you have to
+# escape them by means of a backslash (\), this can lead to conflicts with the
+# commands \{ and \} for these it is advised to use the version @{ and @} or use
+# a double escape (\\{ and \\})
 
 ALIASES                =
 
@@ -242,7 +275,7 @@ TCL_SUBST              =
 # members will be omitted, etc.
 # The default value is: NO.
 
-OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_FOR_C  = NO
 
 # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
 # Python sources only. Doxygen will then generate output that is more tailored
@@ -264,17 +297,26 @@ OPTIMIZE_FOR_FORTRAN   = NO
 
 OPTIMIZE_OUTPUT_VHDL   = NO
 
+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
+# sources only. Doxygen will then generate output that is more tailored for that
+# language. For instance, namespaces will be presented as modules, types will be
+# separated into more groups, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_SLICE  = NO
+
 # Doxygen selects the parser to use depending on the extension of the files it
 # parses. With this tag you can assign which parser to use for a given
 # extension. Doxygen has a built-in mapping, but you can override or extend it
 # using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
-# Fortran. In the later case the parser tries to guess whether the code is fixed
-# or free formatted code, this is the default for Fortran type files), VHDL. For
-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
+# tries to guess whether the code is fixed or free formatted code, this is the
+# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is
+# Fortran), use: inc=Fortran f=C.
 #
 # Note: For files without extension you can use no_extension as a placeholder.
 #
@@ -285,7 +327,7 @@ EXTENSION_MAPPING      =
 
 # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
 # according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
 # The output of markdown processing is further processed by doxygen, so you can
 # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
 # case of backward compatibilities issues.
@@ -293,6 +335,15 @@ EXTENSION_MAPPING      =
 
 MARKDOWN_SUPPORT       = YES
 
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 5.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS   = 5
+
 # When enabled doxygen tries to link words that correspond to documented
 # classes, or namespaces to their corresponding documentation. Such a link can
 # be prevented in individual cases by putting a % sign in front of the word or
@@ -318,7 +369,7 @@ BUILTIN_STL_SUPPORT    = NO
 CPP_CLI_SUPPORT        = NO
 
 # Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
 # will parse them like normal C++ but will assume all classes use public instead
 # of private inheritance when no explicit protection keyword is present.
 # The default value is: NO.
@@ -416,25 +467,31 @@ LOOKUP_CACHE_SIZE      = 0
 # normally produced when WARNINGS is set to YES.
 # The default value is: NO.
 
-EXTRACT_ALL            = NO
+EXTRACT_ALL            = YES
 
 # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
 # be included in the documentation.
 # The default value is: NO.
 
-EXTRACT_PRIVATE        = NO
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
+# methods of a class will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIV_VIRTUAL   = YES
 
 # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
 # scope will be included in the documentation.
 # The default value is: NO.
 
-EXTRACT_PACKAGE        = NO
+EXTRACT_PACKAGE        = YES
 
 # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
 # included in the documentation.
 # The default value is: NO.
 
-EXTRACT_STATIC         = NO
+EXTRACT_STATIC         = YES
 
 # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
 # locally in source files will be included in the documentation. If set to NO,
@@ -478,8 +535,8 @@ HIDE_UNDOC_MEMBERS     = NO
 HIDE_UNDOC_CLASSES     = NO
 
 # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
+# declarations. If set to NO, these declarations will be included in the
+# documentation.
 # The default value is: NO.
 
 HIDE_FRIEND_COMPOUNDS  = NO
@@ -502,10 +559,10 @@ INTERNAL_DOCS          = NO
 # names in lower-case letters. If set to YES, upper-case letters are also
 # allowed. This is useful if you have classes or files whose names only differ
 # in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
+# (including Cygwin) ands Mac users are advised to set this option to NO.
 # The default value is: system dependent.
 
-CASE_SENSE_NAMES       = NO
+CASE_SENSE_NAMES       = YES
 
 # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
 # their full class and namespace scopes in the documentation. If set to YES, the
@@ -689,7 +746,7 @@ LAYOUT_FILE            =
 # The CITE_BIB_FILES tag can be used to specify one or more bib files containing
 # the reference definitions. This must be a list of .bib files. The .bib
 # extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
 # For LaTeX the style of the bibliography can be controlled using
 # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
 # search path. See also \cite for info how to create references.
@@ -734,10 +791,17 @@ WARN_IF_DOC_ERROR      = YES
 # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
 # are documented, but have no documentation for their parameters or return
 # value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
+# parameter documentation, but not about the absence of documentation. If
+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
 # The default value is: NO.
 
-WARN_NO_PARAMDOC       = NO
+WARN_NO_PARAMDOC       = YES
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = YES
 
 # The WARN_FORMAT tag determines the format of the warning messages that doxygen
 # can produce. The string should contain the $file, $line, and $text tags, which
@@ -765,12 +829,12 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = @DOXY_INPUT_DIR@
+INPUT                  = "@TOP_SRCDIR@/emper"
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
 # libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
 # possible encodings.
 # The default value is: UTF-8.
 
@@ -787,16 +851,64 @@ INPUT_ENCODING         = UTF-8
 # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
 # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
 # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
-# *.vhdl, *.ucf, *.qsf, *.as and *.js.
-
-FILE_PATTERNS          =
+# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
+# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
+# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf and *.ice.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.doc \
+                         *.txt \
+                         *.py \
+                         *.pyw \
+                         *.f90 \
+                         *.f95 \
+                         *.f03 \
+                         *.f08 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.ice
 
 # The RECURSIVE tag can be used to specify whether or not subdirectories should
 # be searched for input files as well.
 # The default value is: NO.
 
-RECURSIVE              = YES
+RECURSIVE              = NO
 
 # The EXCLUDE tag can be used to specify files and/or directories that should be
 # excluded from the INPUT source files. This way you can easily exclude a
@@ -805,7 +917,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = @DOXY_IGNORE@
+EXCLUDE                =
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -845,7 +957,7 @@ EXAMPLE_PATH           =
 # *.h) to filter out the source-files in the directories. If left blank all
 # files are included.
 
-EXAMPLE_PATTERNS       =
+EXAMPLE_PATTERNS       = *
 
 # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
 # searched for input files to be used with the \include or \dontinclude commands
@@ -874,6 +986,10 @@ IMAGE_PATH             =
 # Note that the filter must not add or remove lines; it is applied before the
 # code is scanned, but not when the output code is generated. If lines are added
 # or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
 
 INPUT_FILTER           =
 
@@ -883,6 +999,10 @@ INPUT_FILTER           =
 # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
 # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
 # patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
 
 FILTER_PATTERNS        =
 
@@ -919,13 +1039,13 @@ USE_MDFILE_AS_MAINPAGE =
 # also VERBATIM_HEADERS is set to NO.
 # The default value is: NO.
 
-SOURCE_BROWSER         = YES
+SOURCE_BROWSER         = NO
 
 # Setting the INLINE_SOURCES tag to YES will include the body of functions,
 # classes and enums directly into the documentation.
 # The default value is: NO.
 
-INLINE_SOURCES         = YES
+INLINE_SOURCES         = NO
 
 # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
 # special comment blocks from generated source code fragments. Normal C, C++ and
@@ -935,16 +1055,16 @@ INLINE_SOURCES         = YES
 STRIP_CODE_COMMENTS    = YES
 
 # If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
+# entity all documented functions referencing it will be listed.
 # The default value is: NO.
 
-REFERENCED_BY_RELATION = YES
+REFERENCED_BY_RELATION = NO
 
 # If the REFERENCES_RELATION tag is set to YES then for each documented function
 # all documented entities called/used by that function will be listed.
 # The default value is: NO.
 
-REFERENCES_RELATION    = YES
+REFERENCES_RELATION    = NO
 
 # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
 # to YES then the hyperlinks from functions in REFERENCES_RELATION and
@@ -967,12 +1087,12 @@ SOURCE_TOOLTIPS        = YES
 # If the USE_HTAGS tag is set to YES then the references to source code will
 # point to the HTML generated by the htags(1) tool instead of doxygen built-in
 # source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
+# (see https://www.gnu.org/software/global/global.html). You will need version
 # 4.8.6 or higher.
 #
 # To use it do the following:
 # - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
 # - Make sure the INPUT points to the root of the source tree
 # - Run doxygen as normal
 #
@@ -1112,7 +1232,7 @@ HTML_EXTRA_FILES       =
 # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
 # will adjust the colors in the style sheet and background images according to
 # this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
 # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
 # purple, and 360 is red again.
 # Minimum value: 0, maximum value: 359, default value: 220.
@@ -1146,7 +1266,18 @@ HTML_COLORSTYLE_GAMMA  = 80
 # The default value is: NO.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_TIMESTAMP         = YES
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via JavaScript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have JavaScript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS     = YES
 
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
 # documentation will contain sections that can be hidden and shown after the
@@ -1171,13 +1302,13 @@ HTML_INDEX_NUM_ENTRIES = 100
 
 # If the GENERATE_DOCSET tag is set to YES, additional index files will be
 # generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# environment (see: https://developer.apple.com/xcode/), introduced with OSX
+# 10.5 (Leopard). To create a documentation set, doxygen will generate a
 # Makefile in the HTML output directory. Running make will produce the docset in
 # that directory and running make install will install the docset in
 # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
+# genXcode/_index.html for more information.
 # The default value is: NO.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
@@ -1216,7 +1347,7 @@ DOCSET_PUBLISHER_NAME  = Publisher
 # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
 # additional HTML index files: index.hhp, index.hhc, and index.hhk. The
 # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
 # Windows.
 #
 # The HTML Help Workshop contains a compiler that can convert all HTML output
@@ -1292,7 +1423,7 @@ QCH_FILE               =
 
 # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
 # Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
 # The default value is: org.doxygen.Project.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
@@ -1300,7 +1431,7 @@ QHP_NAMESPACE          = org.doxygen.Project
 
 # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
 # Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
 # folders).
 # The default value is: doc.
 # This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1309,7 +1440,7 @@ QHP_VIRTUAL_FOLDER     = doc
 
 # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
 # filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
@@ -1317,7 +1448,7 @@ QHP_CUST_FILTER_NAME   =
 
 # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
 # custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
@@ -1325,7 +1456,7 @@ QHP_CUST_FILTER_ATTRS  =
 
 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
 # project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHP_SECT_FILTER_ATTRS  =
@@ -1418,7 +1549,7 @@ EXT_LINKS_IN_WINDOW    = NO
 
 FORMULA_FONTSIZE       = 10
 
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
 # generated for formulas are transparent PNGs. Transparent PNGs are not
 # supported properly for IE 6.0, but are supported on all modern browsers.
 #
@@ -1429,8 +1560,14 @@ FORMULA_FONTSIZE       = 10
 
 FORMULA_TRANSPARENT    = YES
 
+# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
+# to create new LaTeX commands to be used in formulas as building blocks. See
+# the section "Including formulas" for details.
+
+FORMULA_MACROFILE      =
+
 # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
+# https://www.mathjax.org) which uses client side JavaScript for the rendering
 # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
 # installed or if you want to formulas look prettier in the HTML output. When
 # enabled you may also need to install MathJax separately and configure the path
@@ -1457,11 +1594,11 @@ MATHJAX_FORMAT         = HTML-CSS
 # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
 # Content Delivery Network so you can quickly see the result without installing
 # MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+MATHJAX_RELPATH        = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/
 
 # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
 # extension names that should be enabled during MathJax rendering. For example
@@ -1500,7 +1637,7 @@ MATHJAX_CODEFILE       =
 SEARCHENGINE           = YES
 
 # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
+# implemented using a web server instead of a web client using JavaScript. There
 # are two flavors of web server based searching depending on the EXTERNAL_SEARCH
 # setting. When disabled, doxygen will generate a PHP script for searching and
 # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@@ -1519,7 +1656,7 @@ SERVER_BASED_SEARCH    = NO
 #
 # Doxygen ships with an example indexer (doxyindexer) and search engine
 # (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
+# Xapian (see: https://xapian.org/).
 #
 # See the section "External Indexing and Searching" for details.
 # The default value is: NO.
@@ -1532,7 +1669,7 @@ EXTERNAL_SEARCH        = NO
 #
 # Doxygen ships with an example indexer (doxyindexer) and search engine
 # (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Xapian (see: https://xapian.org/). See the section "External Indexing and
 # Searching" for details.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
@@ -1571,7 +1708,7 @@ EXTRA_SEARCH_MAPPINGS  =
 # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
 # The default value is: YES.
 
-GENERATE_LATEX         = @DOXY_GENERATE_LATEX@
+GENERATE_LATEX         = YES
 
 # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
 # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1584,21 +1721,35 @@ LATEX_OUTPUT           = latex
 # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
 # invoked.
 #
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
+# Note that when not enabling USE_PDFLATEX the default is latex when enabling
+# USE_PDFLATEX the default is pdflatex and when in the later case latex is
+# chosen this is overwritten by pdflatex. For specific output languages the
+# default can have been set differently, this depends on the implementation of
+# the output language.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_CMD_NAME         = latex
+LATEX_CMD_NAME         =
 
 # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
 # index for LaTeX.
+# Note: This tag is used in the Makefile / make.bat.
+# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
+# (.tex).
 # The default file is: makeindex.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
 MAKEINDEX_CMD_NAME     = makeindex
 
+# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
+# generate index for LaTeX. In case there is no backslash (\) as first character
+# it will be automatically added in the LaTeX code.
+# Note: This tag is used in the generated output file (.tex).
+# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
+# The default value is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_MAKEINDEX_CMD    = makeindex
+
 # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
 # documents. This may be useful for small projects and may help to save some
 # trees in general.
@@ -1719,12 +1870,28 @@ LATEX_SOURCE_CODE      = NO
 
 # The LATEX_BIB_STYLE tag can be used to specify the style to use for the
 # bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
 # The default value is: plain.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_BIB_STYLE        = plain
 
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
+# path from which the emoji images will be read. If a relative path is entered,
+# it will be relative to the LATEX_OUTPUT directory. If left blank the
+# LATEX_OUTPUT directory will be used.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EMOJI_DIRECTORY  =
+
 #---------------------------------------------------------------------------
 # Configuration options related to the RTF output
 #---------------------------------------------------------------------------
@@ -1764,9 +1931,9 @@ COMPACT_RTF            = NO
 
 RTF_HYPERLINKS         = NO
 
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# configuration file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
 #
 # See also section "Doxygen usage" for information on how to generate the
 # default style sheet that doxygen normally uses.
@@ -1775,8 +1942,8 @@ RTF_HYPERLINKS         = NO
 RTF_STYLESHEET_FILE    =
 
 # Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
+# similar to doxygen's configuration file. A template extensions file can be
+# generated using doxygen -e rtf extensionFile.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
 RTF_EXTENSIONS_FILE    =
@@ -1862,6 +2029,13 @@ XML_OUTPUT             = xml
 
 XML_PROGRAMLISTING     = YES
 
+# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
+# namespace members in file scope as well, matching the HTML output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_NS_MEMB_FILE_SCOPE = NO
+
 #---------------------------------------------------------------------------
 # Configuration options related to the DOCBOOK output
 #---------------------------------------------------------------------------
@@ -1894,9 +2068,9 @@ DOCBOOK_PROGRAMLISTING = NO
 #---------------------------------------------------------------------------
 
 # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
+# the structure of the code including all documentation. Note that this feature
+# is still experimental and incomplete at the moment.
 # The default value is: NO.
 
 GENERATE_AUTOGEN_DEF   = NO
@@ -1978,7 +2152,7 @@ SEARCH_INCLUDES        = YES
 # preprocessor.
 # This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
-INCLUDE_PATH           =
+INCLUDE_PATH           = "@TOP_SRCDIR@/emper
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -2063,12 +2237,6 @@ EXTERNAL_GROUPS        = YES
 
 EXTERNAL_PAGES         = YES
 
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH              = /usr/bin/perl
-
 #---------------------------------------------------------------------------
 # Configuration options related to the dot tool
 #---------------------------------------------------------------------------
@@ -2082,15 +2250,6 @@ PERL_PATH              = /usr/bin/perl
 
 CLASS_DIAGRAMS         = YES
 
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH            =
-
 # You can include diagrams made with dia in doxygen documentation. Doxygen will
 # then run dia to produce the diagram and insert it in the documentation. The
 # DIA_PATH tag allows you to specify the directory where the dia binary resides.
@@ -2111,7 +2270,7 @@ HIDE_UNDOC_RELATIONS   = YES
 # set to NO
 # The default value is: NO.
 
-HAVE_DOT               = @DOXY_USE_GRAPHVIZ@
+HAVE_DOT               = @HAVE_DOT@
 
 # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
 # to run in parallel. When set to 0 doxygen will base this on the number of
@@ -2153,7 +2312,7 @@ DOT_FONTPATH           =
 # The default value is: YES.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-CLASS_GRAPH            = NO
+CLASS_GRAPH            = YES
 
 # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
 # graph for each documented class showing the direct and indirect implementation
@@ -2177,7 +2336,7 @@ GROUP_GRAPHS           = YES
 # The default value is: NO.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-UML_LOOK               = YES
+UML_LOOK               = NO
 
 # If the UML_LOOK tag is enabled, the fields and methods are shown inside the
 # class node. If there are many fields or methods and many nodes the graph may
@@ -2198,7 +2357,7 @@ UML_LIMIT_NUM_FIELDS   = 10
 # The default value is: NO.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-TEMPLATE_RELATIONS     = YES
+TEMPLATE_RELATIONS     = NO
 
 # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
 # YES then doxygen will generate a graph for each documented file showing the
@@ -2228,7 +2387,7 @@ INCLUDED_BY_GRAPH      = YES
 # The default value is: NO.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-CALL_GRAPH             = YES
+CALL_GRAPH             = NO
 
 # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
 # dependency graph for every global function or class method.
@@ -2271,7 +2430,7 @@ DIRECTORY_GRAPH        = YES
 # The default value is: png.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_IMAGE_FORMAT       = png
+DOT_IMAGE_FORMAT       = svg
 
 # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
 # enable generation of interactive SVG images that allow zooming and panning.
@@ -2283,7 +2442,7 @@ DOT_IMAGE_FORMAT       = png
 # The default value is: NO.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-INTERACTIVE_SVG        = NO
+INTERACTIVE_SVG        = YES
 
 # The DOT_PATH tag can be used to specify the path where the dot tool can be
 # found. If left blank, it is assumed the dot tool can be found in the path.
@@ -2318,6 +2477,11 @@ DIAFILE_DIRS           =
 
 PLANTUML_JAR_PATH      =
 
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE      =
+
 # When using plantuml, the specified paths are searched for files specified by
 # the !include statement in a plantuml block.
 
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..c7710b829546eccfa3a8be09482206be587f067a
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,33 @@
+doxyfile_conf = configuration_data()
+
+doxyfile_conf.set('PROJECT_NAME', meson.project_name())
+doxyfile_conf.set('VERSION', meson.project_version())
+
+if find_program('dot', required : false).found()
+  have_dot = 'YES'
+else
+  have_dot = 'NO'
+endif
+
+doxyfile_conf.set('HAVE_DOT', have_dot)
+doxyfile_conf.set('TOP_SRCDIR', meson.source_root())
+doxyfile_conf.set('TOP_BUILDDIR', meson.build_root())
+
+doxygen = find_program('doxygen', required : false)
+
+doxyfile = configure_file(input: 'Doxyfile.in',
+                          output: 'Doxyfile',
+                          configuration: doxyfile_conf,
+						 )
+
+if doxygen.found()
+  custom_target('speedymalloc-doc-html',
+				input: doxyfile,
+				output: 'html',
+				command: [doxygen, doxyfile],
+				build_always_stale: true,
+			   )
+else
+  warning('Doxygen not found. The doc/html target will not be available!')
+endif
+
diff --git a/emper/CMakeLists.txt b/emper/CMakeLists.txt
deleted file mode 100644
index e9a18674d28d6c17bfe6d0456eb8ce95308e5e2b..0000000000000000000000000000000000000000
--- a/emper/CMakeLists.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-add_files(EMPER_ASM_SOURCE ContextAsm.nasm)
-
-add_files(EMPER_SOURCE Runtime.cpp)
-add_files(EMPER_SOURCE Fiber.cpp)
-add_files(EMPER_SOURCE FiberManager.cpp)
-add_files(EMPER_SOURCE Context.cpp)
-add_files(EMPER_SOURCE Scheduler.cpp)
-add_files(EMPER_SOURCE Dispatcher.cpp)
-add_files(EMPER_SOURCE Common.cpp)
-add_files(EMPER_SOURCE Debug.cpp)
-add_files(EMPER_SOURCE ContextManager.cpp)
-add_files(EMPER_SOURCE BinaryPrivateSemaphore.cpp)
-add_files(EMPER_SOURCE CountingPrivateSemaphore.cpp)
-add_files(EMPER_SOURCE Semaphore.cpp)
-
-add_files(EMPER_INCLUDE ".")
-add_files(EMPER_INCLUDE "include")
-add_files(EMPER_INCLUDE "lib")
-
-add_subdirectory("lib")
-
-add_subdirectory("strategies")
-
-add_files(C_EMPER_SOURCE c_emper.cpp)
-
-set(EMPER_SOURCE ${EMPER_SOURCE} PARENT_SCOPE)
-set(C_EMPER_SOURCE ${C_EMPER_SOURCE} PARENT_SCOPE)
-set(EMPER_INCLUDE ${EMPER_INCLUDE} PARENT_SCOPE)
-set(EMPER_ASM_SOURCE ${EMPER_ASM_SOURCE} PARENT_SCOPE)
diff --git a/emper/ContextManager.hpp b/emper/ContextManager.hpp
index e39f5b32930c6732c314f1b2059a68ba3603e70c..e62b8afac89ace92b07da08a4f57c1b9133ec706 100644
--- a/emper/ContextManager.hpp
+++ b/emper/ContextManager.hpp
@@ -1,10 +1,10 @@
 #pragma once
 
 #include "Common.hpp"
-#include "WsClQueue.hpp"
-#include "Runtime.hpp"
 #include "Context.hpp"
 #include "MemoryManager.hpp"
+#include "Runtime.hpp"
+#include "lib/adt/WsClQueue.hpp"
 
 class Context;
 
diff --git a/emper/Fiber.hpp b/emper/Fiber.hpp
index 4a88f185c3a7b70c8ab70e1dba8d44e32b9bd994..27104b34e8c24bc6399bb71adca8da80d33d6eb3 100644
--- a/emper/Fiber.hpp
+++ b/emper/Fiber.hpp
@@ -2,7 +2,7 @@
 
 #include "Common.hpp"
 #include "Debug.hpp"
-#include "MpscQueue.hpp"
+#include "lib/adt/MpscQueue.hpp"
 
 #include <functional>
 #include <atomic>
diff --git a/emper/MemoryManager.hpp b/emper/MemoryManager.hpp
index c8494fa3f174a78165bf74c34015cff379fbcd31..0bbbe89d7ee7148996d94f302e12c24464a5e9e5 100644
--- a/emper/MemoryManager.hpp
+++ b/emper/MemoryManager.hpp
@@ -1,9 +1,9 @@
 #pragma once
 
 #include "Common.hpp"
-#include "WsClQueue.hpp"
 #include "Runtime.hpp"
-#include "BoundedBumpArray.hpp"
+#include "lib/adt/BoundedBumpArray.hpp"
+#include "lib/adt/WsClQueue.hpp"
 
 template<typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE>
 class MemoryManager {
diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp
index 69b6ff3b2b90a66607189e5b2c3f6b1d1181d759..cc98834d46702c6efae3fb693a76fb4b3e93122d 100644
--- a/emper/Runtime.hpp
+++ b/emper/Runtime.hpp
@@ -3,13 +3,13 @@
 #include <thread>
 #include <vector>
 
+#include "Common.hpp"
 #include "Debug.hpp"
 #include "Dispatcher.hpp"
-#include "Common.hpp"
-#include "Latch.hpp"
-#include "Scheduler.hpp"
 #include "RuntimeStrategy.hpp"
-#include "WsStrategy.hpp"
+#include "Scheduler.hpp"
+#include "strategies/ws/WsStrategy.hpp"
+#include "lib/sync/Latch.hpp"
 
 class ContextManager;
 
diff --git a/emper/include/meson.build b/emper/include/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..94d02a3a3f9e8c5865a8eba1694e59f8bc99efc2
--- /dev/null
+++ b/emper/include/meson.build
@@ -0,0 +1,8 @@
+emper_include = include_directories('.')
+
+emper_version_h = custom_target(
+  'emper-version.h',
+  output: 'emper-version.h',
+  command: ['@SOURCE_DIR@/scripts/versionManager.sh', 'check', meson.project_version()]
+)
+emper_generated_files += emper_version_h
diff --git a/emper/lib/CMakeLists.txt b/emper/lib/CMakeLists.txt
deleted file mode 100644
index 342e3c2e40b364e7f9646db1a03ca5484b126742..0000000000000000000000000000000000000000
--- a/emper/lib/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# TODO: Remove this and refer to headers there as "adt/File.hpp"
-add_files(EMPER_INCLUDE "adt")
-add_subdirectory("adt")
-
-# TODO: Remove this and refer to headers there as "sync/File.hpp"
-add_files(EMPER_INCLUDE "sync")
-add_subdirectory("sync")
-
-add_files(EMPER_SOURCE DebugUtil.cpp)
diff --git a/emper/lib/adt/CMakeLists.txt b/emper/lib/adt/CMakeLists.txt
deleted file mode 100644
index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000
--- a/emper/lib/adt/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/emper/lib/meson.build b/emper/lib/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..126bdd278cc7cb27c107f35b8c4f230a59f51dc8
--- /dev/null
+++ b/emper/lib/meson.build
@@ -0,0 +1,3 @@
+emper_cpp_sources += files(
+  'DebugUtil.cpp',
+)
diff --git a/emper/lib/sync/CMakeLists.txt b/emper/lib/sync/CMakeLists.txt
deleted file mode 100644
index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000
--- a/emper/lib/sync/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/emper/meson.build b/emper/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..241dc029c57eb75d445def9d180b5b721ed0b288
--- /dev/null
+++ b/emper/meson.build
@@ -0,0 +1,59 @@
+emper_asm_sources = [ 'ContextAsm.nasm' ]
+nasm = find_program('nasm')
+# mesons's nasm support currently means using generator()
+# - https://code.videolan.org/videolan/dav1d/-/blob/6cf58c8e7deb54e287afeee6710b2a3774eded9c/meson.build#L414
+# - https://github.com/mesonbuild/meson/issues/678#issuecomment-239673659
+nasm_gen = generator(nasm,
+					 output: '@BASENAME@.obj',
+					 arguments: ['-f', 'elf64', '@INPUT@', '-o', '@OUTPUT@'],
+					)
+emper_asm_objects = nasm_gen.process(emper_asm_sources)
+
+emper_cpp_sources = [
+  'Runtime.cpp',
+  'Fiber.cpp',
+  'FiberManager.cpp',
+  'Context.cpp',
+  'Scheduler.cpp',
+  'Dispatcher.cpp',
+  'Common.cpp',
+  'Debug.cpp',
+  'ContextManager.cpp',
+  'BinaryPrivateSemaphore.cpp',
+  'CountingPrivateSemaphore.cpp',
+  'Semaphore.cpp',
+]
+
+emper_generated_files = []
+
+subdir('include')
+
+emper_library_include = []
+emper_library_include += include_directories('.')
+
+subdir('lib')
+subdir('strategies')
+
+emper_all_include = emper_library_include + [emper_include]
+
+emper = library(
+  'emper',
+  [emper_cpp_sources, emper_generated_files],
+  emper_asm_objects,
+  include_directories: emper_all_include,
+  dependencies: thread_dep,
+  install: true,
+)
+
+
+emper_c_sources = [
+  'c_emper.cpp',
+]
+
+emper_c = library(
+  'emper-c',
+  emper_c_sources,
+  include_directories: emper_all_include,
+  link_with: emper,
+  install: true,
+)
diff --git a/emper/strategies/CMakeLists.txt b/emper/strategies/CMakeLists.txt
deleted file mode 100644
index 4a412ac1c28d3136fd73fd9602e8589bcd2ef543..0000000000000000000000000000000000000000
--- a/emper/strategies/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-#target_include_directories(emper "ws")
-add_files(EMPER_INCLUDE "ws")
-add_subdirectory("ws")
-
-#target_include_directories(emper "laws")
-add_files(EMPER_INCLUDE "laws")
-add_subdirectory("laws")
-
-set(EMPER_SOURCE ${EMPER_SOURCE} PARENT_SCOPE)
diff --git a/emper/strategies/laws/CMakeLists.txt b/emper/strategies/laws/CMakeLists.txt
deleted file mode 100644
index b91170386fdd6bbe9f52943f6fc694fcbf4ac2aa..0000000000000000000000000000000000000000
--- a/emper/strategies/laws/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_files(EMPER_SOURCE LawsStrategy.cpp)
-add_files(EMPER_SOURCE LawsStrategyStats.cpp)
-add_files(EMPER_SOURCE LawsScheduler.cpp)
-add_files(EMPER_SOURCE LawsDispatcher.cpp)
-
diff --git a/emper/strategies/laws/LawsScheduler.hpp b/emper/strategies/laws/LawsScheduler.hpp
index f3ce4269cd37a74cec706332d4a9f1c172fc6d52..41cdee375b1cc281d78dcb05a8f338e36cfb45ff 100644
--- a/emper/strategies/laws/LawsScheduler.hpp
+++ b/emper/strategies/laws/LawsScheduler.hpp
@@ -1,11 +1,11 @@
 #pragma once
 
-#include "Scheduler.hpp"
-#include "WsClQueue.hpp"
-#include "MpscQueue.hpp"
 #include "Fiber.hpp"
-#include "LockedQueue.hpp"
-#include "LockedUnboundedQueue.hpp"
+#include "Scheduler.hpp"
+#include "lib/adt/LockedQueue.hpp"
+#include "lib/adt/LockedUnboundedQueue.hpp"
+#include "lib/adt/MpscQueue.hpp"
+#include "lib/adt/WsClQueue.hpp"
 
 class LawsStrategy;
 
diff --git a/emper/strategies/laws/meson.build b/emper/strategies/laws/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..3297836ba79d00f5d0f0222b244b4ff60a63088f
--- /dev/null
+++ b/emper/strategies/laws/meson.build
@@ -0,0 +1,6 @@
+emper_cpp_sources += files(
+  'LawsStrategy.cpp',
+  'LawsStrategyStats.cpp',
+  'LawsScheduler.cpp',
+  'LawsDispatcher.cpp',
+)
diff --git a/emper/strategies/meson.build b/emper/strategies/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..24e52026347a40fdaf56a638acd209816d4fe6c6
--- /dev/null
+++ b/emper/strategies/meson.build
@@ -0,0 +1,2 @@
+subdir('ws')
+subdir('laws')
diff --git a/emper/strategies/ws/CMakeLists.txt b/emper/strategies/ws/CMakeLists.txt
deleted file mode 100644
index 7f812e2c0cd484dafa2fd7a671bce1fa9a9f9130..0000000000000000000000000000000000000000
--- a/emper/strategies/ws/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_files(EMPER_SOURCE WsStrategy.cpp)
-add_files(EMPER_SOURCE WsStrategyStats.cpp)
-add_files(EMPER_SOURCE WsScheduler.cpp)
-add_files(EMPER_SOURCE WsDispatcher.cpp)
diff --git a/emper/strategies/ws/WsScheduler.hpp b/emper/strategies/ws/WsScheduler.hpp
index 382caff2e29010d0b79c74a7fb19bf0f00698ac2..02aa0d496600c45bd1d9793065a54ed840a43aa2 100644
--- a/emper/strategies/ws/WsScheduler.hpp
+++ b/emper/strategies/ws/WsScheduler.hpp
@@ -1,9 +1,9 @@
 #pragma once
 
 #include "Scheduler.hpp"
-#include "WsClQueue.hpp"
-#include "LockedQueue.hpp"
 #include "emper-common.h"
+#include "lib/adt/LockedQueue.hpp"
+#include "lib/adt/WsClQueue.hpp"
 
 class WsStrategy;
 
diff --git a/emper/strategies/ws/meson.build b/emper/strategies/ws/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..6554bc5aa9dd7f0dc2df339515d2906a08ff5f74
--- /dev/null
+++ b/emper/strategies/ws/meson.build
@@ -0,0 +1,6 @@
+emper_cpp_sources += files(
+  'WsStrategy.cpp',
+  'WsStrategyStats.cpp',
+  'WsScheduler.cpp',
+  'WsDispatcher.cpp',
+)
diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt
deleted file mode 100644
index d6c2ef0e2a6572785868a2ce57dc7743c9d42bb2..0000000000000000000000000000000000000000
--- a/eval/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_executable(time_to_spawn TimeToSpawn.cpp)
-target_link_libraries(time_to_spawn Threads::Threads emper)
-
-add_executable(spawn_a_lot SpawnALot.cpp)
-target_link_libraries(spawn_a_lot Threads::Threads emper)
-
-add_executable(locality Locality.cpp)
-target_link_libraries(locality Threads::Threads emper)
diff --git a/eval/Locality.cpp b/eval/Locality.cpp
index ccb0b93709a94614178ccf0d13331542f76c0540..2a6e6a166f2c0ca728ee6f9f89dfefd95a0767db 100644
--- a/eval/Locality.cpp
+++ b/eval/Locality.cpp
@@ -3,8 +3,8 @@
 #include "Dispatcher.hpp"
 #include "PrivateSemaphore.hpp"
 #include "CountingPrivateSemaphore.hpp"
-#include "LawsStrategy.hpp"
-#include "DebugUtil.hpp"
+#include "strategies/laws/LawsStrategy.hpp"
+#include "lib/DebugUtil.hpp"
 
 #include <algorithm>
 #include <random>
diff --git a/eval/SpawnALot.cpp b/eval/SpawnALot.cpp
index 643d5d935e161af20078c88d9fcacc0697a112ce..c9b295a82e11ca321f5d50d7d4fc3c02cdc827dc 100644
--- a/eval/SpawnALot.cpp
+++ b/eval/SpawnALot.cpp
@@ -2,7 +2,7 @@
 #include "PrivateSemaphore.hpp"
 #include "BinaryPrivateSemaphore.hpp"
 #include "CountingPrivateSemaphore.hpp"
-#include "DebugUtil.hpp"
+#include "lib/DebugUtil.hpp"
 
 #define CACHE_LINE_SIZE 64
 
diff --git a/eval/meson.build b/eval/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..e33ab63c86c657a416fbc983a14d647d31ecb994
--- /dev/null
+++ b/eval/meson.build
@@ -0,0 +1,22 @@
+executable(
+  'time_to_spawn',
+  'TimeToSpawn.cpp',
+  include_directories: emper_all_include,
+  dependencies: thread_dep,
+  link_with: emper,
+)
+
+executable(
+  'spawn_a_lot',
+  'SpawnALot.cpp',
+  include_directories: emper_all_include,
+  dependencies: thread_dep,
+  link_with: emper,
+)
+
+executable(
+  'locality',
+  'Locality.cpp',
+  include_directories: emper_all_include,
+  link_with: emper,
+)
diff --git a/external-libs/.gitignore b/external-libs/.gitignore
deleted file mode 100644
index a4d350fd071ae7d5111a2cb39ef28802fd727bad..0000000000000000000000000000000000000000
--- a/external-libs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/eigen
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
deleted file mode 100644
index b0f25ea6db320f919219ea091dac5bc60c7d5cf7..0000000000000000000000000000000000000000
--- a/lib/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_library(matrix STATIC Matrix.cpp)
-target_link_libraries(matrix emper)
-target_include_directories(matrix PUBLIC ${EIGEN3_INCLUDE_DIR})
diff --git a/lib/Matrix.cpp b/lib/Matrix.cpp
deleted file mode 100644
index 77b47527f4df78f0b2001cd972b20e7768977009..0000000000000000000000000000000000000000
--- a/lib/Matrix.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "Matrix.hpp"
-
-std::vector<Eigen::MatrixXf*> computeParallel(UNUSED_ARG std::vector<Eigen::MatrixXf*> matrixes, UNUSED_ARG std::vector<Eigen::MatrixXf*> k) {
-	abort();
-}
diff --git a/lib/Matrix.hpp b/lib/Matrix.hpp
deleted file mode 100644
index 0802309201a98df9b5d76847023771e866f67d67..0000000000000000000000000000000000000000
--- a/lib/Matrix.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-#include "Common.hpp"
-
-#include <vector>
-#include <Eigen/Dense>
-
-class Matrix {
-public:
-	static std::vector<Eigen::MatrixXf*> computeParallel(std::vector<Eigen::MatrixXf*> matrixes, std::vector<Eigen::MatrixXf*> k);
-};
diff --git a/meson-migration.org b/meson-migration.org
new file mode 100644
index 0000000000000000000000000000000000000000..c7a72a1c3efc4e3e6c16a0ca16927bbae0caf4fe
--- /dev/null
+++ b/meson-migration.org
@@ -0,0 +1,6 @@
+TODO List:
+
+- Doxygen documentation
+- Use full relative paths in includes
+- public / private header split?
+- then, rm -rf scripts?
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..292ff97afa4889445416683e9b89308e79f9167f
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,21 @@
+project('EMPER', 'c', 'cpp',
+		version: '0.0.1-alpha1-SNAPSHOT',
+		default_options : [
+		  'warning_level=3',
+		  'c_std=gnu11',
+		  'cpp_std=c++17',
+		  'b_ndebug=if-release',
+		  'werror=true',
+		])
+
+# TODO: Re-enable that warning.
+add_global_arguments('-Wno-non-virtual-dtor', language: 'cpp')
+
+thread_dep = dependency('threads')
+emper_dependencies = [thread_dep]
+
+subdir('emper')
+subdir('tests')
+subdir('apps')
+subdir('eval')
+subdir('doc')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000000000000000000000000000000000000..98a9ca1502ba1b7aa5fe3a03bd7d85a587771147
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,30 @@
+option(
+  'worker_sleep',
+  type: 'boolean',
+  value: true,
+  description: 'Enable sleeping worker support',
+)
+option(
+  'locked_ws_queue',
+  type: 'boolean',
+  value: false,
+  description: 'Use a fully locked queue for work-stealing',
+)
+option(
+  'overflow_queue',
+  type: 'boolean',
+  value: true,
+  description: 'Use a overflow queue in case the primary queue is full'
+)
+option(
+  'locked_mpsc_queue',
+  type: 'boolean',
+  value: false,
+  description: 'Use the locked variant for the MPSC queue'
+)
+option(
+  'stats',
+  type: 'boolean',
+  value: false,
+  description: 'Collect stats and print them at the end of the execution'
+)
diff --git a/scripts/dependencyManager.sh b/scripts/dependencyManager.sh
deleted file mode 100755
index 6e448cf27076633f426803b629c8d30271b2d65a..0000000000000000000000000000000000000000
--- a/scripts/dependencyManager.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-# shellcheck disable=SC1090
-. "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/setup.sh"
-
-printVerbose() {
-	if ! $VERBOSE; then
-		return;
-	fi
-	echo "$@"
-}
-
-installArchive() {
-	declare -r url=$1
-	declare -r targetDir="${BASEDIR}/external-libs/$2"
-	declare -r contentSourceFile="${targetDir}/.content-source"
-
-	if [[ -f "$contentSourceFile" ]]; then
-		if [[ $(cat "$contentSourceFile") == "$url" ]]; then
-			return;
-		fi
-		rm -rf "${targetDir:?}/*"
-	elif [[ ! -d "$targetDir" ]]; then
-		mkdir "$targetDir"
-	fi
-
-	printVerbose "Fetching $url and extracting to $targetDir"
-	curl -L "$url" | tar -xj -C "$targetDir"
-
-	local dirCount
-	dirCount=$(find "$targetDir" -mindepth 1 -maxdepth 1 -type d | wc -l)
-	local fileCount
-	fileCount=$(find "$targetDir" -type f -maxdepth 1 -not -path '*/\.*' | wc -l)
-
-	if [[ $dirCount == 1 ]] && [[ $fileCount == 0 ]]; then
-		local singleDirectory
-		singleDirectory=$(find "$targetDir" -mindepth 1 -maxdepth 1 -type d )
-		mv "${singleDirectory}"/* "$targetDir"
-	fi
-
-	# Record content
-	echo "$url" > "$contentSourceFile"
-}
-
-cleanDependency() {
-	declare -r targetDir="${BASEDIR}/external-libs/$2"
-
-	printVerbose "Removing $targetDir"
-	rm -rf "$targetDir"
-}
-
-VERBOSE=false
-
-while getopts :v OPT; do
-	case $OPT in
-		v|+v)
-			VERBOSE=true
-			;;
-		*)
-			echo "usage: ${0##*/} [+-v} [--] ARGS..."
-			exit 2
-	esac
-done
-shift $(( OPTIND - 1 ))
-OPTIND=1
-
-case $1 in
-	install)
-		FUN=installArchive
-		;;
-	clean)
-		FUN=cleanDependency
-		;;
-	*)
-		echo "usage: ${0##*/} [+-v} [--] ARGS..."
-		exit 2
-esac
-
-declare -r depDb="${BASEDIR}/dependencies.db"
-while IFS=\; read -r url targetDir; do
-	$FUN "$url" "$targetDir"
-done < "$depDb"
diff --git a/scripts/versionManager.sh b/scripts/versionManager.sh
index 5d657187bf145cb33bcf246287cca1e57c559c97..73cb903cce00e9afbd3821ecea4d039e8968a84e 100755
--- a/scripts/versionManager.sh
+++ b/scripts/versionManager.sh
@@ -13,43 +13,30 @@ printVerbose() {
 }
 
 checkVersionHeader() {
-	declare -r versionFile="${BASEDIR}/version"
+	local version="${1}"
 
-	EMPER_MAJOR_VERSION=""
-	EMPER_MINOR_VERSION=""
-	EMPER_PATCH_VERSION=""
+	mapfile -t VERSION_COMPONENTS < <(echo "${version}" | grep --extended-regexp --only-matching '[^\.-]+' -)
+
+	EMPER_MAJOR_VERSION="${VERSION_COMPONENTS[0]}"
+	EMPER_MINOR_VERSION="${VERSION_COMPONENTS[1]}"
+	EMPER_PATCH_VERSION="${VERSION_COMPONENTS[2]}"
 	EMPER_EXTRA_VERSION=""
-	EMPER_IS_SNAPSHOT=""
+	EMPER_IS_SNAPSHOT=false
+
+	local numComponents=${#VERSION_COMPONENTS[@]}
 
-	while read -r line; do
-		if [[ $line != *":"* ]]; then
-			continue
+	if [[ ${numComponents} -ge 4 ]]; then
+		EMPER_EXTRA_VERSION="${VERSION_COMPONENTS[3]}"
+	fi
+
+	if [[ ${numComponents} -eq 5 ]]; then
+		if [[ "${VERSION_COMPONENTS[4]}" != SNAPSHOT ]]; then
+			echo "Invalid snapshot identifier: ${VERSION_COMPONENTS[4]}"
+			exit 2
 		fi
-		key=$(echo $line | cut -f1 -d:)
-		value=$(echo $line |\
-					   cut -f2 -d: |\
-					   tr -d '[:space:]')
-		case $key in
-			Major)
-				EMPER_MAJOR_VERSION=$value
-				;;
-			Minor)
-				EMPER_MINOR_VERSION=$value
-				;;
-			Patch)
-				EMPER_PATCH_VERSION=$value
-				;;
-			Extra)
-				EMPER_EXTRA_VERSION=$value
-				;;
-			Snapshot)
-				EMPER_IS_SNAPSHOT=$value
-				;;
-			*)
-				echo "Invalid $line in $versionFile"
-				exit 1
-		esac
-	done < "$versionFile"
+
+		EMPER_IS_SNAPSHOT=true
+	fi
 
 	if [[ -z $EMPER_MAJOR_VERSION ]]; then
 		echo "EMPER major version not set"
@@ -63,15 +50,6 @@ checkVersionHeader() {
 		echo "EMPER patch version not set"
 		exit 1
 	fi
-	case $EMPER_IS_SNAPSHOT in
-		true)
-		;&
-		false)
-		;;
-		*)
-			echo "EMPER Snapshot must be set to either 'true' or 'false', is currently ${EMPER_IS_SNAPSHOT}"
-			exit 1
-	esac
 	
 
 	pushd . > /dev/null
@@ -110,7 +88,7 @@ EOF
 }
 
 printUsageAndExit() {
-	echo "usage: ${0##*/} [+-d} [+-v} [--] ARGS..."
+	echo "usage: ${0##*/} [-d} [-v} [--] [check <version>|clean]"
 	exit 2
 }
 
@@ -118,10 +96,10 @@ VERBOSE=false
 
 while getopts :dv OPT; do
 	case $OPT in
-		d|+d)
+		d)
 			set -x
 			;;
-		v|+v)
+		v)
 			VERBOSE=true
 			;;
 		*)
@@ -136,7 +114,7 @@ declare -r versionHeader="${BASEDIR}/emper/include/emper-version.h"
 
 case $1 in
 	check)
-		checkVersionHeader
+		checkVersionHeader "${2}"
 		;;
 	clean)
 		rm -f "$versionHeader"
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
deleted file mode 100644
index 7cdd4e8258224f8e61629a30481461ed6bbb7f48..0000000000000000000000000000000000000000
--- a/tests/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-add_executable(simple_fib_test SimpleFibTest.cpp)
-target_link_libraries(simple_fib_test Threads::Threads emper)
-add_test(SimpleFibTest simple_fib_test)
-
-add_executable(simplest_fib_test SimplestFibTest.cpp)
-target_link_libraries(simplest_fib_test Threads::Threads emper)
-add_test(SimplestFibTest simplest_fib_test)
-
-add_executable(c_api_test c_api_test.c)
-target_link_libraries(c_api_test c_emper)
-add_test(CApiTest c_api_test)
-
-add_executable(cpp_api_test CppApiTest.cpp)
-target_link_libraries(cpp_api_test emper)
-add_test(CppApiTest cpp_api_test)
-
-add_executable(simple_actor_test SimpleActorTest.cpp)
-target_link_libraries(simple_actor_test emper)
-add_test(SimpleActorTest simple_actor_test)
-
-add_executable(simple_laws_test SimpleLawsTest.cpp)
-target_link_libraries(simple_laws_test emper)
-add_test(SimpleLawsTest simple_laws_test)
diff --git a/tests/SimpleLawsTest.cpp b/tests/SimpleLawsTest.cpp
index b328eaa3db423dbf77bb45794184000751c11a7a..6b305515729c043fdcefff86756ee10b6d5d4f7c 100644
--- a/tests/SimpleLawsTest.cpp
+++ b/tests/SimpleLawsTest.cpp
@@ -1,7 +1,7 @@
 #include "emper.hpp"
 
-#include "LawsStrategy.hpp"
 #include "Fiber.hpp"
+#include "strategies/laws/LawsStrategy.hpp"
 
 #include <random>
 
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..eca563f180751dea1384f3ccbf970a3ddec1abc1
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,65 @@
+tests = {
+		  'SimpleFibTest.cpp':
+		  {
+			'description': 'Simple test',
+		  },
+
+		  'SimplestFibTest.cpp':
+		  {
+			'description': 'Simplest fib test',
+			'smoke_test': true,
+		  },
+
+		  'c_api_test.c':
+		  {
+			'description': 'Test EMPER\'s C API',
+		  },
+
+		  'CppApiTest.cpp':
+		  {
+			'description': 'Test EMPER\'s C++ API',
+		  },
+
+		  'SimpleActorTest.cpp':
+		  {
+			'description': 'Simple Actor Test',
+		  },
+
+		  'SimpleLawsTest.cpp':
+		  {
+			'description': 'Simple LAWS scheduling strategy test',
+		  },
+		}
+
+undef_ndebug = '-UNDEBUG'
+test_dep = [thread_dep]
+
+foreach source, test_dict : tests
+  # TODO: Use meson fs (filesystem) module once meson >= 0.53 is in
+  # buster-backports, instead of split('.')[0]
+  # test_name = fs.replace_suffix(source, '')
+  # The test_name is the name of the source file without the file suffix.
+  test_name = source.split('.')[0]
+
+  test_exe = executable(test_name,
+						source,
+						include_directories: emper_all_include,
+						c_args: undef_ndebug,
+						cpp_args: undef_ndebug,
+						dependencies: test_dep,
+						link_with: [emper, emper_c],
+					   )
+
+  if test_dict.get('smoke_test', false)
+	test_suite = 'smoke'
+  else
+	test_suite = 'all'
+  endif
+
+  test(test_dict.get('description', ''),
+	   test_exe,
+	   is_parallel: test_dict.get('is_parallel', true),
+	   suite: test_suite,
+	   timeout: 60
+	  )
+endforeach
diff --git a/tools/prepare-build-dir b/tools/prepare-build-dir
new file mode 100755
index 0000000000000000000000000000000000000000..dc280ad682cbfcd0a1aa54a5237dd65ef206df32
--- /dev/null
+++ b/tools/prepare-build-dir
@@ -0,0 +1,92 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Pretty fancy method to get reliable the absolute path of a shell
+# script, *even if it is sourced*. Credits go to GreenFox on
+# stackoverflow: http://stackoverflow.com/a/12197518/194894
+pushd . > /dev/null
+SCRIPTDIR="${BASH_SOURCE[0]}";
+while([ -h "${SCRIPTDIR}" ]); do
+    cd "`dirname "${SCRIPTDIR}"`"
+    SCRIPTDIR="$(readlink "`basename "${SCRIPTDIR}"`")";
+done
+cd "`dirname "${SCRIPTDIR}"`" > /dev/null
+SCRIPTDIR="`pwd`";
+popd  > /dev/null
+
+QUIET=false
+while getopts :dq OPT; do
+	case $OPT in
+		d)
+			set -x
+			;;
+		q)
+			QUIET=true
+			;;
+		*)
+			echo "usage: ${0##*/} [-dq} [--] ARGS..."
+			exit 2
+	esac
+done
+shift $(( OPTIND - 1 ))
+OPTIND=1
+
+ROOTDIR=$(readlink -f "${SCRIPTDIR}/..")
+
+set +u
+if [[ ! ${BUILDTYPE} ]]; then
+	BUILDTYPE="debugoptimized"
+	echo "BUILDTYPE not explicitly set via environment variable, defaulting to ${BUILDTYPE}"
+fi
+if [[ ! ${BUILDDIR} ]]; then
+	BUILDDIR="build-${BUILDTYPE}"
+fi
+set -u
+
+readonly ABSOLUTE_BUILDDIR="${ROOTDIR}/${BUILDDIR}"
+readonly ABSOLUTE_BUILDDIR_SYMLINK="${ROOTDIR}/build"
+
+if [[ ! -d "${ABSOLUTE_BUILDDIR}" ]]; then
+	mkdir "${ABSOLUTE_BUILDDIR}"
+fi
+
+if [[ ! -d "${ABSOLUTE_BUILDDIR_SYMLINK}"
+				|| $(realpath "${ABSOLUTE_BUILDDIR}") != $(realpath "${ABSOLUTE_BUILDDIR_SYMLINK}") ]]; then
+	if [[ -e "${ABSOLUTE_BUILDDIR_SYMLINK}" ]]; then
+		if [[ ! -L "${ABSOLUTE_BUILDDIR_SYMLINK}" ]]; then
+			echo "${ABSOLUTE_BUILDDIR_SYMLINK} is not a symlink"
+			exit 1
+		fi
+		rm "${ABSOLUTE_BUILDDIR_SYMLINK}"
+	fi
+
+	ln -rs "${ABSOLUTE_BUILDDIR}" "${ABSOLUTE_BUILDDIR_SYMLINK}"
+fi
+
+# Now filter the environment variables for the configuration
+# arguments.
+readonly VARIABLE_PREFIX="EMPER_"
+MESON_ARGS=()
+for var in $(compgen -e); do
+	if [[ ${var} != ${VARIABLE_PREFIX}* ]]; then
+		continue;
+	fi
+
+	# Strip the variable prefix from the build option environment variable.
+	MESON_BUILD_OPTION_NAME="${var#${VARIABLE_PREFIX}}"
+	# Lowercase the build option name.
+	MESON_BUILD_OPTION_NAME="${MESON_BUILD_OPTION_NAME,,}"
+	MESON_BUILD_OPTION_VALUE="${!var}"
+	if [[ -z $MESON_BUILD_OPTION_VALUE ]]; then
+		echo "Environment variable ${var} is empty"
+		exit 1
+	fi
+	MESON_ARGS+=("-D${MESON_BUILD_OPTION_NAME}=${MESON_BUILD_OPTION_VALUE}")
+done
+
+if ! $QUIET; then
+	set -x
+fi
+exec meson --buildtype=${BUILDTYPE} \
+	 ${MESON_ARGS[@]} \
+	 "${ABSOLUTE_BUILDDIR}"
diff --git a/version b/version
deleted file mode 100644
index 6855a9c93816388cc191976a75ff2035b162760b..0000000000000000000000000000000000000000
--- a/version
+++ /dev/null
@@ -1,7 +0,0 @@
-# EMPER version information
-
-Major: 0
-Minor: 0
-Patch: 1
-Extra: alpha1
-Snapshot: true