about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorMartin Nowack <m.nowack@imperial.ac.uk>2019-02-28 11:56:19 +0000
committerCristian Cadar <c.cadar@imperial.ac.uk>2019-03-10 20:10:32 +0000
commitcf930214e12b49e89be4674043d9f461d667baae (patch)
tree90de5ea1c643d0d7ad2c5cf55e862d309e605d48
parentb4d8fe0301b82e8abff0336bf6d1347dff11a853 (diff)
downloadklee-cf930214e12b49e89be4674043d9f461d667baae.tar.gz
Updated dependency build system for KLEE
Provide a single `scripts/build/build.sh` file to build KLEE and its
dependencies.
-rw-r--r--.codecov.yml2
-rw-r--r--.travis.yml137
-rw-r--r--scripts/build/Dockerfile_base15
-rw-r--r--scripts/build/Dockerfile_klee58
-rw-r--r--scripts/build/Dockerfile_klee_deps33
-rw-r--r--scripts/build/Dockerfile_llvm_build27
-rw-r--r--scripts/build/Dockerfile_solver_build33
-rwxr-xr-xscripts/build/build-docker.sh100
-rwxr-xr-xscripts/build/build-travis-containers.sh58
-rwxr-xr-xscripts/build/build.sh803
-rw-r--r--scripts/build/common-defaults.sh53
-rw-r--r--scripts/build/common-functions211
-rw-r--r--scripts/build/d-klee-linux-ubuntu.inc23
-rwxr-xr-xscripts/build/dependencies-ubuntu.sh43
-rwxr-xr-xscripts/build/install-klee-deps.sh26
-rwxr-xr-xscripts/build/install-local.sh17
-rwxr-xr-xscripts/build/klee.sh219
-rwxr-xr-xscripts/build/llvm.sh193
-rw-r--r--scripts/build/p-clang-linux-ubuntu-16.04.inc66
-rw-r--r--scripts/build/p-clang-osx.inc13
-rw-r--r--scripts/build/p-gtest-linux-ubuntu-16.04.inc12
-rw-r--r--scripts/build/p-gtest-osx.inc5
-rw-r--r--scripts/build/p-gtest.inc45
-rw-r--r--scripts/build/p-klee-linux-ubuntu-16.04.inc21
-rw-r--r--[-rwxr-xr-x]scripts/build/p-klee-osx.inc (renamed from scripts/build/build-travis.sh)19
-rw-r--r--scripts/build/p-klee.inc198
-rw-r--r--scripts/build/p-llvm-linux-ubuntu-16.04.inc98
-rw-r--r--scripts/build/p-llvm-linux-ubuntu-18.04.inc49
-rw-r--r--scripts/build/p-llvm-osx.inc21
-rw-r--r--scripts/build/p-llvm.inc366
-rw-r--r--scripts/build/p-metasmt-linux-ubuntu-16.04.inc27
-rw-r--r--scripts/build/p-metasmt.inc64
-rw-r--r--scripts/build/p-stp-linux-ubuntu-16.04.inc19
-rw-r--r--scripts/build/p-stp-osx.inc7
-rw-r--r--scripts/build/p-stp.inc113
-rw-r--r--scripts/build/p-tcmalloc-linux-ubuntu-16.04.inc13
-rw-r--r--scripts/build/p-tcmalloc.inc49
-rw-r--r--scripts/build/p-uclibc-linux-ubuntu-16.04.inc17
-rw-r--r--scripts/build/p-uclibc.inc49
-rw-r--r--scripts/build/p-z3-linux-ubuntu-16.04.inc16
-rw-r--r--scripts/build/p-z3-osx.inc13
-rw-r--r--scripts/build/p-z3.inc68
-rw-r--r--scripts/build/patches/llvm40.patch77
-rwxr-xr-xscripts/build/run-coverage.sh25
-rwxr-xr-xscripts/build/run-tests.sh153
-rwxr-xr-xscripts/build/solver-metasmt.sh39
-rwxr-xr-xscripts/build/solver-stp.sh57
-rwxr-xr-xscripts/build/solver-z3.sh34
-rwxr-xr-xscripts/build/solvers.sh30
-rwxr-xr-xscripts/build/tcmalloc.sh35
-rwxr-xr-xscripts/build/testing-utils.sh14
-rwxr-xr-xscripts/build/uclibc.sh37
-rw-r--r--scripts/build/v-clang.inc15
-rw-r--r--scripts/build/v-gtest.inc7
-rw-r--r--scripts/build/v-klee.inc42
-rw-r--r--scripts/build/v-llvm.inc34
-rw-r--r--scripts/build/v-metasmt.inc7
-rw-r--r--scripts/build/v-sanitizer.inc88
-rw-r--r--scripts/build/v-sanitizer_compiler.inc21
-rw-r--r--scripts/build/v-solvers.inc63
-rw-r--r--scripts/build/v-stp.inc8
-rw-r--r--scripts/build/v-tcmalloc.inc5
-rw-r--r--scripts/build/v-uclibc.inc17
-rw-r--r--scripts/build/v-z3.inc7
64 files changed, 2857 insertions, 1377 deletions
diff --git a/.codecov.yml b/.codecov.yml
index c4a12ef7..bccacde0 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -11,7 +11,7 @@ coverage:
   range: "70...100"
 
 fixes:
-  - "home/travis/build/klee/klee::"
+  - "/tmp/klee_src::"
 ignore:
   - "usr/"
   - "test/"
diff --git a/.travis.yml b/.travis.yml
index 8abf5f14..9ea616cd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,16 +1,7 @@
-dist: trusty
-language: cpp
+#dist: xenial
 services:
     - docker
-compiler:
-    # FIXME: For now, building with Clang is disabled because the STP built with
-    # it hits an assertion failure during some tests. We should sort this out
-    # eventually and file the bug against STP or Clang whichever is appropriate,
-    # but for now it is easier to just reduce the number of configs we test
-    # anyway.
-    # - clang
-
-    - gcc
+language: cpp
 env:
     ###########################################################################
     # Configurations
@@ -32,85 +23,97 @@ env:
     #   ENABLE_OPTIMIZED: {0, 1}
     #   COVERAGE: {0, 1}
     #   USE_TCMALLOC: {0, 1}
-
     # COVERAGE when set indicates that coverage data should be uploaded to the service
 
-    matrix:
+    # Define default values - they are overwritten by each matrix entry if needed
+    global:
+    - secure: EF/WAc4BdIRUchF3mjATN3/UwtGWtGaRgb5oIIJHjKhgZFdPsgWsXFgaOB0jaK2hfO/svj/LvlasuRIGxeePVjeaiX8ZlVpuHiX67vdYLY+0kCDRwkusRjm60/GbPU9O/Xjgb/d4aWAEkoq5OnsprVTEvU8iY2JHtAqgwR+wW9I=
+    - secure: Hrp1MRSxDUH2GTQg3QR/yUttY/3KmgbFb5e+zyy551dKpHjxJdsNe8bquY9oFoT7KmPQYl0HNNjEv4qWW8RK+HWHOCB55nL1KlGpOG7vAJcUEZg7ScbliGgiovMB6jIQVfeP9FhYngfc13vNZQ5PGlqzfSsHSAbvkwEogBToHVw=
+    - secure: DQAEQWJblXvIztN/sgH63OtFncI+Qju6wRy1zIV/iLf5KbAmLs1h3itU7EsE/+3+LgV1MVQ5QNJDBUj17A6VHRKNaQ5qnIllTAcC3o0nPDohQkQoCgDG8HZ+M4wtVfr7q2K6byEPB2UbSH+mEjSMTihJufgBBVfKyyozAfYycjg=
 
-    # TODO: Add Doxygen build
+    # Default configuration for all Travis-CI jobs. They are overriden by each job.
+    - BASE_IMAGE: ubuntu:xenial-20181005
+    - REPOSITORY: klee
 
-    # Check newer LLVMs
-    - LLVM_VERSION=7.0 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=6.0 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=5.0 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=4.0 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.9 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.8 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.7 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.6 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.5 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.4 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
-    - LLVM_VERSION=3.4 SOLVERS=metaSMT METASMT_VERSION=v4.rc1 METASMT_DEFAULT=STP KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1 REQUIRES_RTTI=1
-
-    # ASan build. Do unoptimized build otherwise the optimizer might remove problematic code
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=2.1.2 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=0 COVERAGE=0 USE_TCMALLOC=0 SANITIZER_BUILD=address
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=2.1.2 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=0 COVERAGE=0 USE_TCMALLOC=0 SANITIZER_BUILD=undefined
-
-    # Test just using Z3
-    - LLVM_VERSION=3.4 SOLVERS=Z3 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0
+    - COVERAGE: 0
+    - DISABLE_ASSERTIONS: 0
+    - ENABLE_OPTIMIZED: 1
+    - ENABLE_DEBUG: 1
+    - GTEST_VERSION: 1.7.0
+    - LLVM_VERSION: 6.0
+    - METASMT_VERSION: v4.rc1
+    - MINISAT_VERSION: "master"
+    - REQUIRES_RTTI: 0
+    - SANITIZER_BUILD:
+    - SOLVERS: STP:Z3
+    - STP_VERSION: 2.3.2
+    - TCMALLOC_VERSION: 2.7
+    - UCLIBC_VERSION: klee_uclibc_v1.0.0
+    - USE_TCMALLOC: 1
+    - Z3_VERSION: 4.8.4
+
+    matrix:
+    # Check supported LLVM versions
+    - LLVM_VERSION=7.0
+    - LLVM_VERSION=6.0
+    - LLVM_VERSION=5.0
+    - LLVM_VERSION=4.0
+    - LLVM_VERSION=3.9
+    - LLVM_VERSION=3.8
+    - LLVM_VERSION=3.7
+    - LLVM_VERSION=3.6
+    - LLVM_VERSION=3.5
+    - LLVM_VERSION=3.4
+
+    # *Sanitizer builds. Do unoptimized build otherwise the optimizer might remove problematic code
+    - SANITIZER_BUILD=address ENABLE_OPTIMIZED=0 USE_TCMALLOC=0
+    - SANITIZER_BUILD=undefined ENABLE_OPTIMIZED=0 USE_TCMALLOC=0
+
+    # Test just using Z3 only
+    - SOLVERS=Z3
+
+    # Test just using metaSMT
+    - SOLVERS=metaSMT METASMT_DEFAULT=STP REQUIRES_RTTI=1
+    - SOLVERS=metaSMT METASMT_DEFAULT=BTOR REQUIRES_RTTI=1
 
     # Test we can build against STP master
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=master KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0
+    - SOLVERS=STP STP_VERSION=master
 
     # Check we can build latest klee-uclibc branch
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=2.1.2 KLEE_UCLIBC=klee_0_9_29 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0
-
-    # Test metaSMT support
-    - LLVM_VERSION=3.4 SOLVERS=metaSMT METASMT_VERSION=v4.rc1 METASMT_DEFAULT=BTOR KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 REQUIRES_RTTI=1
+    - UCLIBC_VERSION=klee_0_9_29
 
     # Check at least one build with Asserts disabled.
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=2.1.2 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=1 ENABLE_OPTIMIZED=1 COVERAGE=0
+    - SOLVERS=STP DISABLE_ASSERTIONS=1
 
-    # Check at least one Debug+Asserts build
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=2.1.2 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=0 COVERAGE=0
-
-    # Check with TCMALLOC
-    - LLVM_VERSION=3.4 SOLVERS=STP STP_VERSION=2.1.2 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=1
+    # Check without TCMALLOC
+    - USE_TCMALLOC=0
 
     # Coverage build
-    - LLVM_VERSION=3.4 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=klee_uclibc_v1.0.0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=0 COVERAGE=1 USE_TCMALLOC=0
-    global:
-    - secure: EF/WAc4BdIRUchF3mjATN3/UwtGWtGaRgb5oIIJHjKhgZFdPsgWsXFgaOB0jaK2hfO/svj/LvlasuRIGxeePVjeaiX8ZlVpuHiX67vdYLY+0kCDRwkusRjm60/GbPU9O/Xjgb/d4aWAEkoq5OnsprVTEvU8iY2JHtAqgwR+wW9I=
-    - secure: Hrp1MRSxDUH2GTQg3QR/yUttY/3KmgbFb5e+zyy551dKpHjxJdsNe8bquY9oFoT7KmPQYl0HNNjEv4qWW8RK+HWHOCB55nL1KlGpOG7vAJcUEZg7ScbliGgiovMB6jIQVfeP9FhYngfc13vNZQ5PGlqzfSsHSAbvkwEogBToHVw=
-    - secure: DQAEQWJblXvIztN/sgH63OtFncI+Qju6wRy1zIV/iLf5KbAmLs1h3itU7EsE/+3+LgV1MVQ5QNJDBUj17A6VHRKNaQ5qnIllTAcC3o0nPDohQkQoCgDG8HZ+M4wtVfr7q2K6byEPB2UbSH+mEjSMTihJufgBBVfKyyozAfYycjg=
-    - KLEE_TRAVIS_BUILD: 1
-    - REPOSITORY: klee
+    - ENABLE_OPTIMIZED=0 COVERAGE=1
 
+    # TODO: Add Doxygen build
+
+#stop
 matrix:
   include:
     - os: osx
       osx_image: xcode8.3
-      env: LLVM_VERSION=4.0 SOLVERS=STP:Z3 STP_VERSION=2.1.2 Z3_VERSION=4.4.1 KLEE_UCLIBC=0 DISABLE_ASSERTIONS=0 ENABLE_OPTIMIZED=1 COVERAGE=0 USE_TCMALLOC=0
-
+      env: SOLVERS=STP UCLIBC_VERSION=0 USE_TCMALLOC=0
+addons:
+  apt:
+    packages:
+      - docker-ce
 cache:
   ccache: true
   apt: true
   directories:
     - $HOME/Library/Caches/Homebrew
-
 before_install:
-    ###########################################################################
-    # Set up the locations to get various packages from
-    # We assume the Travis image uses Ubuntu 14.04 LTS
-    ###########################################################################
-    # Update package information
-    - export KLEE_SRC=`pwd`
-    - export KLEE_SRC_TRAVIS=`pwd`
-    - cd ../
-    - export BASE=`pwd`
-    - ${KLEE_SRC_TRAVIS}/scripts/build/build-travis.sh
+   - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; brew install bash ; fi
+
 script:
     # Build KLEE and run tests
-    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH="/usr/local/opt/ccache/libexec:$PATH"; ${KLEE_SRC_TRAVIS}/scripts/build/klee.sh; fi
-    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ${KLEE_SRC_TRAVIS}/scripts/build/build-docker.sh; fi
-    - if [[ "$COVERAGE" == "1" ]]; then ${KLEE_SRC_TRAVIS}/scripts/build/run-coverage.sh; fi
+    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export BASE=/tmp && export PATH="/usr/local/opt/ccache/libexec:/usr/local/bin:$PATH"; scripts/build/build.sh klee --debug --install-system-deps; export DYLD_LIBRARY_PATH=="$(cd ${BASE}/metaSMT-*-deps/stp-git-basic/lib/ && pwd)"; scripts/build/run-tests.sh /tmp/klee_build* --debug; fi
+    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then scripts/build/build.sh klee --docker --debug --push-docker-deps --create-final-image; fi
+    - if [[ "$COVERAGE" == "1" && "$TRAVIS_OS_NAME" == "linux" ]]; then scripts/build/run-tests.sh --coverage --upload-coverage --run-docker --debug; fi
+    - if [[ "$COVERAGE" == "0" && "$TRAVIS_OS_NAME" == "linux" ]]; then scripts/build/run-tests.sh --run-docker --debug; fi
diff --git a/scripts/build/Dockerfile_base b/scripts/build/Dockerfile_base
deleted file mode 100644
index 8daee330..00000000
--- a/scripts/build/Dockerfile_base
+++ /dev/null
@@ -1,15 +0,0 @@
-# Build dependencies for LLVM
-FROM ubuntu:16.04
-LABEL maintainer="Martin Nowack <m.nowack@imperial.ac.uk>"
-
-ENV DOCKER_BUILD=1
-
-# Define all variables that can be changed as argument to docker build
-ARG BASE=/tmp
-
-# Copy across all source files
-ADD /scripts/build/* scripts/build/
-
-# Install packages
-RUN scripts/build/dependencies-ubuntu.sh && rm -rf /var/lib/apt/lists/*
-WORKDIR $BASE
diff --git a/scripts/build/Dockerfile_klee b/scripts/build/Dockerfile_klee
deleted file mode 100644
index 1872fca6..00000000
--- a/scripts/build/Dockerfile_klee
+++ /dev/null
@@ -1,58 +0,0 @@
-# Build the final KLEE layer
-ARG REPOSITORY
-ARG LLVM_VERSION_SHORT
-ARG LLVM_SUFFIX
-ARG SOLVER_SUFFIX
-ARG DEPS_SUFFIX
-FROM ${REPOSITORY}/klee_deps:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX}${DEPS_SUFFIX}
-LABEL maintainer="Martin Nowack <m.nowack@imperial.ac.uk>"
-
-# Define all variables that can be changed as argument to the docker build
-ARG BASE=/tmp
-ARG COVERAGE=0
-ARG DEPS_SUFFIX
-ARG DISABLE_ASSERTIONS
-ARG ENABLE_OPTIMIZED
-ARG ENABLE_DEBUG
-ARG KLEE_TRAVIS_BUILD
-ARG KLEE_UCLIBC
-ARG LLVM_VERSION
-ARG LLVM_SUFFIX
-ARG METASMT_BOOST_VERSION
-ARG METASMT_DEFAULT
-ARG METASMT_VERSION
-ARG REQUIRES_RTTI
-ARG SANITIZER_BUILD
-ARG SANITIZER_SUFFIX
-ARG SOLVER_SUFFIX
-ARG SOLVERS
-ARG STP_VERSION
-ARG TRAVIS_OS_NAME
-ARG USE_TCMALLOC
-ARG Z3_VERSION
-
-ENV DOCKER_BUILD=1
-
-# Copy across source files needed for build
-ADD / ${BASE}/klee_src
-
-# TODO Remove when STP is fixed
-RUN export LD_LIBRARY_PATH=${BASE}/metaSMT/deps/stp-git-basic/lib/ && export KLEE_SRC=${BASE}/klee_src && ${BASE}/klee_src/scripts/build/klee.sh && rm -rf ${BASE}/klee_src/.git && ln -s ${BASE}/klee_build* ${BASE}/klee_build
-
-# Create ``klee`` user for container with password ``klee``.
-# and give it password-less sudo access (temporarily so we can use the TravisCI scripts)
-RUN useradd -m klee && \
-    echo klee:klee | chpasswd && \
-    cp /etc/sudoers /etc/sudoers.bak && \
-    echo 'klee  ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
-
-# Set klee user to be owner
-RUN chown --recursive klee: ${BASE}/klee_src
-
-USER klee
-WORKDIR /home/klee
-
-# Add KLEE binary directory to PATH
-RUN /bin/bash -c 'DIR="${BASE}/klee_src/scripts/build" source ${BASE}/klee_src/scripts/build/common-defaults.sh && ln -s ${BASE}/klee_src /home/klee/ && ln -s ${BASE}/klee_build /home/klee/ && echo "export PATH=\"$PATH:${LLVM_BIN}:/home/klee/klee_build/bin\"" >> /home/klee/.bashrc'
-# TODO Remove when STP is fixed
-RUN /bin/bash -c 'echo "export LD_LIBRARY_PATH=${BASE}/metaSMT/deps/stp-git-basic/lib/" >> /home/klee/.bashrc'
diff --git a/scripts/build/Dockerfile_klee_deps b/scripts/build/Dockerfile_klee_deps
deleted file mode 100644
index 582d324f..00000000
--- a/scripts/build/Dockerfile_klee_deps
+++ /dev/null
@@ -1,33 +0,0 @@
-# Build KLEE dependencies except LLVM and solvers
-ARG REPOSITORY
-ARG LLVM_VERSION_SHORT
-ARG LLVM_SUFFIX
-ARG SOLVER_SUFFIX
-FROM ${REPOSITORY}/solver:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX}
-LABEL maintainer="Martin Nowack <m.nowack@imperial.ac.uk>"
-
-# Define all variables that can be changed as argument to the docker build
-ARG BASE=/tmp
-ARG DISABLE_ASSERTIONS
-ARG ENABLE_OPTIMIZED
-ARG ENABLE_DEBUG
-ARG KEEP_BUILD
-ARG KEEP_SRC
-ARG KLEE_TRAVIS_BUILD
-ARG KLEE_UCLIBC
-ARG LLVM_VERSION
-ARG LLVM_SUFFIX
-ARG REQUIRES_RTTI
-ARG SANITIZER_BUILD
-ARG TRAVIS_OS_NAME
-ARG USE_TCMALLOC
-
-ENV DOCKER_BUILD=1
-
-# Copy across source files needed for build
-ADD /scripts/build/* scripts/build/
-
-# Build KLEE (use TravisCI script)
-RUN ${BASE}/scripts/build/testing-utils.sh
-RUN ${BASE}/scripts/build/tcmalloc.sh
-RUN ${BASE}/scripts/build/uclibc.sh
diff --git a/scripts/build/Dockerfile_llvm_build b/scripts/build/Dockerfile_llvm_build
deleted file mode 100644
index 548f0d8a..00000000
--- a/scripts/build/Dockerfile_llvm_build
+++ /dev/null
@@ -1,27 +0,0 @@
-# Build LLVM
-ARG LLVM_VERSION_SHORT
-ARG REPOSITORY
-FROM ${REPOSITORY}/base
-LABEL maintainer="Martin Nowack <m.nowack@imperial.ac.uk>"
-
-ENV DOCKER_BUILD=1
-
-# Define all variables that can be changed as argument to the docker build
-ARG BASE=/tmp
-ARG DISABLE_ASSERTIONS
-ARG ENABLE_OPTIMIZED
-ARG ENABLE_DEBUG
-ARG KEEP_BUILD
-ARG KEEP_SRC
-ARG KLEE_TRAVIS_BUILD
-ARG LLVM_VERSION
-ARG PACKAGED
-ARG REQUIRES_RTTI
-ARG SANITIZER_BUILD
-ARG TRAVIS_OS_NAME
-
-WORKDIR $BASE
-
-# Copy across source files needed for build
-ADD /scripts/build/* scripts/build/
-RUN ./scripts/build/llvm.sh
diff --git a/scripts/build/Dockerfile_solver_build b/scripts/build/Dockerfile_solver_build
deleted file mode 100644
index ba2af62a..00000000
--- a/scripts/build/Dockerfile_solver_build
+++ /dev/null
@@ -1,33 +0,0 @@
-ARG REPOSITORY
-ARG LLVM_SUFFIX
-ARG LLVM_VERSION_SHORT
-FROM ${REPOSITORY}/llvm_built:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}
-LABEL maintainer="Martin Nowack <m.nowack@imperial.ac.uk>"
-
-ENV DOCKER_BUILD=1
-
-# Define all variables that can be changed as argument to docker build
-ARG BASE=/tmp
-ARG DISABLE_ASSERTIONS
-ARG ENABLE_OPTIMIZED
-ARG ENABLE_DEBUG
-ARG KEEP_BUILD
-ARG KEEP_SRC
-ARG KLEE_TRAVIS_BUILD
-ARG LLVM_VERSION
-ARG METASMT_BOOST_VERSION
-ARG METASMT_DEFAULT
-ARG METASMT_VERSION
-ARG REQUIRES_RTTI
-ARG SOLVERS
-ARG SANITIZER_BUILD
-ARG STP_VERSION
-ARG STORAGE_SPACE_OPTIMIZED=1
-ARG TRAVIS_OS_NAME
-ARG Z3_VERSION
-
-WORKDIR $BASE
-
-# Copy across source files needed for build
-ADD /scripts/build/* scripts/build/
-RUN scripts/build/solvers.sh
diff --git a/scripts/build/build-docker.sh b/scripts/build/build-docker.sh
deleted file mode 100755
index 3a031d22..00000000
--- a/scripts/build/build-docker.sh
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/bin/bash
-# Build a KLEE docker image. If needed, build all dependent layers as well.
-set -e
-
-# We are going to build docker containers
-export DOCKER_BUILD=1
-
-# All scripts are located relative to this one
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-KLEEDIR="${DIR}/../.."
-
-###############################################################################
-# Setup Docker variables needed to build layers layers
-###############################################################################
-
-add_arg_variable() {
-  name=$1
-  name_var=${!name}
-  if [[ (-z "$name_var") || ($name_var == "") ]] ; then
-    val=""
-  else
-    val="--build-arg ${name}=${name_var} "
-  fi
-  echo "$val"
-}
-
-DOCKER_OPTS=()
-for v in \
-  LLVM_VERSION \
-  LLVM_VERSION_SHORT \
-  ENABLE_OPTIMIZED \
-  DISABLE_ASSERTIONS \
-  ENABLE_DEBUG \
-  REQUIRES_RTTI \
-  LLVM_SUFFIX \
-  REPOSITORY \
-  SANITIZER_BUILD \
-  SANITIZER_SUFFIX \
-  PACKAGED \
-  KLEE_TRAVIS_BUILD \
-  TRAVIS_OS_NAME \
-  METASMT_VERSION \
-  METASMT_DEFAULT \
-  METASMT_BOOST_VERSION \
-  SOLVER_SUFFIX \
-  Z3_VERSION \
-  STP_VERSION \
-  KLEE_UCLIBC \
-  DEPS_SUFFIX \
-  USE_TCMALLOC \
-  COVERAGE \
-  KEEP_SRC \
-  KEEP_BUILD \
-  TCMALLOC_VERSION \
-  GTEST_VERSION \
-  SOLVERS \
-  ; do
-  DOCKER_OPTS+=($(add_arg_variable $v))
-done
-
-echo "DOCKER_OPTS: ${DOCKER_OPTS[@]}"
-docker_build_and_push() {
-  merge=$1
-  image=$2
-  script=$3
-  set +e
-  # Get or build layer
-  echo "$image"
-  if ! docker pull $image ;  then
-    set -e
-    # Update if needed
-    echo "BUILD IMAGE"
-    merge_arg=""
-  #  if [[ "${merge}x" == "1x" ]]; then
-  #    #merge_arg="--squash"
-  #  fi
-    docker build ${merge_arg} -f "${DIR}/$script" ${@:4} -t "$image" "${KLEEDIR}"
-    set +e
-    docker push "$image"
-  fi
-  return 0
-}
-
-###############################################################################
-# Build different layers
-###############################################################################
-
-# Check if the build of dependencies only has been requested
-if [[ -z ${DOCKER_BUILD_DEPS_ONLY} || "${DOCKER_BUILD_DEPS_ONLY}x" == "1x" ]]; then
-  echo "Build dependencies"
-  docker_build_and_push 1 ${REPOSITORY}/base Dockerfile_base "${DOCKER_OPTS[@]}"
-  docker_build_and_push 1 ${REPOSITORY}/llvm_built:${LLVM_VERSION_SHORT}${LLVM_SUFFIX} Dockerfile_llvm_build "${DOCKER_OPTS[@]}"
-  docker_build_and_push 1 ${REPOSITORY}/solver:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX} Dockerfile_solver_build "${DOCKER_OPTS[@]}"
-  docker_build_and_push 1 ${REPOSITORY}/klee_deps:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX}${DEPS_SUFFIX} Dockerfile_klee_deps "${DOCKER_OPTS[@]}"
-fi
-
-if [[ -z ${DOCKER_BUILD_DEPS_ONLY} || "${DOCKER_BUILD_DEPS_ONLY}x" != "1x" ]]; then
-  docker build -f "${DIR}/Dockerfile_klee" "${DOCKER_OPTS[@]}" -t ${REPOSITORY}/klee:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX}${DEPS_SUFFIX} "${KLEEDIR}"
-fi
diff --git a/scripts/build/build-travis-containers.sh b/scripts/build/build-travis-containers.sh
index ad2ac73a..fe80e29f 100755
--- a/scripts/build/build-travis-containers.sh
+++ b/scripts/build/build-travis-containers.sh
@@ -3,20 +3,62 @@
 # also build by TravisCI.
 #
 # Every line starting with " - LLVM_VERSION=" is a single setup
+
 set -e
+#set -x
 DIR="$(cd "$(dirname "$0")" && pwd)"
 
-# Build dependencies only
-export DOCKER_BUILD_DEPS_ONLY=1
-export KLEE_TRAVIS_BUILD="1"
-export REPOSITORY="klee"
-export TRAVIS_OS_NAME="linux"
+trim() {
+    local var="$*"
+    # remove leading whitespace characters
+    var="${var#"${var%%[![:space:]]*}"}"
+    # remove trailing whitespace characters
+    var="${var%"${var##*[![:space:]]}"}"   
+    echo -n "$var"
+}
 
+# Build dependencies only
+isGlobal=0
+isEnv=0
+commons=()
+experiments=()
 while read -r line
 do
-    name=$(echo $line| grep "\- LLVM" | xargs -L 1 | cut -d "-" -f 2)
-    if [[ "x$name" == "x" ]]; then
+    [[ "${line}" == "env:"* ]] && isEnv=1 && continue
+    [[ "${line}" == "#stop"* ]] && isEnv=0 && break
+ 
+    
+    [[ "${isEnv}" -eq 0 ]] && continue
+    
+    line="$(trim "${line}")"
+
+    # Ignore empty lines
+    [[ -z "${line}" ]] && continue
+    [[ "${line}" == "#"* ]] && continue 
+    
+    [[ "${line}" == "global:"* ]] && isGlobal=1 && continue
+    [[ "${line}" == "matrix:"* ]] && isGlobal=0 && continue
+
+    
+    
+    if [[ "${isGlobal}" -eq 1 ]]; then
+      tmp="${line#*-}"
+      IFS=: read -r key value <<< "${tmp}"
+      key=$(trim "${key}")
+      [[ "${key}" == "secure" ]] && continue
+      [[ -z "${key}" ]] && continue
+      commons+=("${key}=$(trim "${value}")")
       continue
     fi
-    /bin/bash -c "$name ./scripts/build/build-docker.sh"
+
+    experiment=$(echo "$line"| grep "\- " | xargs -L 1 | cut -d "-" -f 2)
+    if [[ "x$experiment" == "x" ]]; then
+      continue
+    fi
+    experiments+=("${experiment}")
 done < "${DIR}/../../.travis.yml"
+
+for experiment in "${experiments[@]}"; do
+  [[ -z "${experiment}" ]] && continue
+  /bin/bash -c "${commons[*]} ${experiment} ${DIR}/build.sh klee --docker --push-docker-deps --debug --create-final-image"
+done
\ No newline at end of file
diff --git a/scripts/build/build.sh b/scripts/build/build.sh
new file mode 100755
index 00000000..feda6bfe
--- /dev/null
+++ b/scripts/build/build.sh
@@ -0,0 +1,803 @@
+#!/usr/bin/env bash
+set -e
+set -u
+# Build script for different components that are needed
+
+DIR="$(cd "$(dirname "$0")" && pwd)"
+
+show_help() {
+  local name="$1"
+  echo "$name [--docker] [--keep-dockerfile] [--install-system-deps] component*" 
+  echo "Available components:"
+  for component_path in "$DIR/v-"*.inc; do
+    [ -e "$component_path" ] || continue
+
+    component_path=${component_path#"$DIR/v-"}
+    component=${component_path%".inc"}
+
+    echo "$component"
+  done
+
+  return 0
+}
+
+function to_upper() {
+  echo "$1" | tr '[:lower:]' '[:upper:]'
+}
+
+function to_lower() {
+  echo "$1" | tr '[:upper:]' '[:lower:]'
+}
+
+to_bool() {
+  [[ "$1" == "1" || "$1" == "ON" || "$1" == "YES" || "$1" == "TRUE" || "$1" == "T" ]] && echo 1 && return 0
+  [[ "$1" == "0" || "$1" == "OFF" || "$1" == "NO" || "$1" == "FALSE" || "$1" == "F" ]] && echo 0 && return 0
+  # Error case - value unknown
+  exit 1
+}
+
+check_bool() {
+  local v="$1"
+  local result
+  result=$(to_bool "${!v}" ) || { echo "${v} has invalid boolean value: ${!v}"; exit 1; }
+}
+
+validate_build_variables() {
+  # Check general default variables
+  if [[ -z ${BASE+x} ]] || [[ -z "${BASE}" ]]; then
+    echo "BASE not set. - BASE directory defines target where every component should be installed"
+    exit 1
+  fi
+}
+
+validate_component() {
+  local component="$1"
+  local c_type="$2"
+
+  local component_path="$DIR/${c_type}-${component}.inc"
+  if [[ ! -f "${component_path}" ]]; then
+    echo "Component ${component} not found."
+    return 1
+  fi
+}
+
+load_component() {
+  local component="$1"
+  local c_type="$2"
+
+  local component_path="$DIR/${c_type}-${component}.inc"
+  if [[ ! -f "${component_path}" ]]; then
+    echo "Component ${component} not found."
+    return 2 # File not found
+  fi
+  source "${component_path}" || { echo "Error in file ${component_path}"; return 1; }
+}
+
+
+check_docker_os() {
+  local docker_base=$1
+  local os_info=""
+  # start docker using the base image, link this directory and get the os information
+  os_info=$(docker run -v "${DIR}:/tmp" "${docker_base}" /tmp/build.sh --check-os) || { echo "Docker execution failed: $os_info"; exit 1;}
+
+  local line
+  while read -r line; do
+  case $line in
+    OS=*)
+    OS="${line#*=}"
+    ;;
+    DISTRIBUTION=*)
+      DISTRIBUTION="${line#*=}"
+    ;;
+    DISTRIBUTION_VER=*)
+      DISTRIBUTION_VER="${line#*=}"
+    ;;
+  esac
+  done <<< "$os_info"
+
+  echo "Docker OS=${OS}"
+  echo "Docker DISTRIBUTION=${DISTRIBUTION}"
+  echo "Docker DISTRIBUTION_VER=${DISTRIBUTION_VER}"
+}
+
+
+build_docker() {
+  local component=$1
+  local is_dependency=$2
+  
+  load_component "${component}" "v" || { echo "Loading component failed ${component}"; return 1; }
+
+  # Extract repository, image, tag from base image
+  local base_repository="${BASE_IMAGE%/*}"
+  [[ "${base_repository}" == "${BASE_IMAGE}" ]] && base_repository="" # No base repository provided
+  local base_image="${BASE_IMAGE##*/}"
+  local base_tag="${base_image##*:}"
+  if [[ "${base_tag}" == "${base_image}" ]]; then
+    base_tag="" # No tag provided
+  else
+    base_image="${base_image%:*}"
+  fi
+
+  local BASE="/tmp"
+
+  # Check all input variables
+  validate_required_variables "${component}" "required_variables"
+
+  # Get the list of build dependencies and check them
+  local depending_artifact_components=("")
+  check_list artifact_dependency_"${component}"
+  mapfile -t depending_artifact_components <<< "$(get_list artifact_dependency_"${component}")"
+  local v
+  for v in "${depending_artifact_components[@]}"; do
+    [[ -z "${v}" ]] && continue
+    { build_docker "${v}" 1; } || { echo "Not all compile dependencies are available: ${v}"; return 1; }
+  done
+
+  # Get the list of runtime dependencies
+  local depending_runtime_artifact_components=("")
+  mapfile -t depending_runtime_artifact_components <<< "$(get_list runtime_artifact_dependency_"${component}")"
+  local v
+  for v in "${depending_runtime_artifact_components[@]}"; do
+    [[ -z "${v}" ]] && continue
+    { build_docker "${v}" 1;} || { echo "Not all runtime dependencies are available: ${v}"; return 1; }
+  done
+
+  echo "Build component: ${component}"
+
+  # Setup general component variables
+  gather_dependencies "${component}" "artifact" "setup_variables"
+
+  # Get the docker image id if available
+  local config_id=""
+  config_id=$(execution_action "get_docker_config_id" "${component}")
+  res="$?"
+  [[ "$res" -eq 1 ]] && echo "Building docker dependency ${component} failed: get_docker_config_id_${component}" && return 1
+
+  # An empty config id indicates nothing to build
+  [[ -z "${config_id}" ]] && return 0
+
+  # Use the config id to find a pre-build docker image
+  local target_image="${component}:${config_id}_${base_image}_${base_tag}"
+  [[ -z $(docker images -q "${REPOSITORY}/${target_image}") ]] || { echo "Docker image exists: ${REPOSITORY}/${target_image}"; return 0; }
+  docker pull "${REPOSITORY}/${target_image}" || /bin/true
+  [[ -z $(docker images -q "${REPOSITORY}/${target_image}") ]] || { echo "Docker image exists: ${REPOSITORY}/${target_image}"; return 0; }
+
+  # Gather all indirect depending components
+  local all_depending_artifact_components=("")
+  mapfile -t all_depending_artifact_components <<< "$(get_all_dependencies "${component}" "artifact")"
+
+  local all_depending_runtime_artifact_components=("")
+  mapfile -t all_depending_runtime_artifact_components <<< "$(get_all_dependencies "${component}" "runtime_artifact")"
+
+  local docker_dependencies=("")
+  docker_dependencies+=("${all_depending_artifact_components[@]}")
+
+  for c in "${depending_runtime_artifact_components[@]}"; do
+    local found=0
+    for i in "${docker_dependencies[@]}"; do
+      [[ -z "$i" ]] && continue
+      [[ "$i" == "$c" ]] && found=1 && break
+    done
+
+    # Attach item if new
+    [[ "$found" -eq 0 ]] && docker_dependencies+=("$c")
+  done
+
+  # Start to build image
+  local temp_dir
+  temp_dir="$(mktemp -d)"
+  [[ -d "${temp_dir}" ]] || (echo "Could not create temp_dir"; exit 1)
+
+  local docker_context=""
+  docker_context=$(execution_action "get_docker_context" "${component}") || docker_context=""
+
+  local docker_container_context=""
+  docker_container_context=$(execution_action "get_docker_container_context" "${component}") || docker_container_context=""
+  
+  # Prepare Dockerfile
+  local dockerfile="${temp_dir}/Dockerfile"
+
+  {
+    # Add all depending images as layers
+    for v in "${docker_dependencies[@]}"; do
+      [[ -z "${v}" ]] && continue
+      local dep_config_id
+      dep_config_id=$(execution_action "get_docker_config_id" "${v}") || true
+      # An empty config id indicates nothing to build
+      [[ -z "${dep_config_id}" ]] && continue
+
+      echo "FROM ${REPOSITORY}/${v}:${dep_config_id}_${base_image}_${base_tag} as ${v}_base"
+    done
+
+    # If multiple source images are available use the first one as a base image
+    local hasBaseImage=0
+    for v in "${all_depending_artifact_components[@]}"; do
+      [[ -z "${v}" ]] && continue
+      dep_config_id=$(execution_action "get_docker_config_id" "${v}") || true
+
+      # An empty config id indicates nothing to build
+      [[ -z "${dep_config_id}" ]] && continue
+      
+      if [[ "${hasBaseImage}" -eq 0 ]]; then
+        hasBaseImage=1
+        # Use base image as building base
+        echo "FROM ${v}_base as intermediate"
+      else
+        # Copy artifacts
+        # TODO: maybe get list of specific directories to copys
+        echo "COPY --from=${v}_base ${BASE} ${BASE}/"
+      fi
+    done
+
+    if [[ "${hasBaseImage}" -eq 0 ]]; then
+      hasBaseImage=1
+      # Use base image as building base
+      echo "FROM ${BASE_IMAGE} as intermediate"
+    fi
+
+    # Retrieve list of required variables and make them available in Docker
+    local docker_vars=[]
+    mapfile -t docker_vars <<< "$(get_list required_variables_"$component")"
+    docker_vars+=("BASE")
+    for v in "${all_depending_artifact_components[@]}"; do
+      [[ -z "${v}" ]] && continue
+      local dep_docker_vars=()
+      mapfile -t dep_docker_vars <<< "$(get_list required_variables_"${v}")"
+      docker_vars+=("${dep_docker_vars[@]}")
+    done
+
+    # Export docker variables explicitly
+    for d_v in "${docker_vars[@]}"; do
+      [[ -z "${d_v}" ]] && continue
+      local d_v_value
+      d_v_value=${!d_v}
+      echo "ENV ${d_v}=${d_v_value}"
+    done
+
+    # Run the build script
+    if [[ -z "${docker_context}" ]]; then
+      # Copy content from the temporary directory to the docker image
+      echo "COPY . ."
+      echo "RUN ./build.sh --debug --install-system-deps ${component}"
+    else
+      echo "COPY . ${docker_container_context}"
+      # TODO: this is quite specific to this script: should use common value
+      echo "RUN ${docker_container_context}/scripts/build/build.sh --debug --install-system-deps ${component}"
+    fi
+
+    # Copy all the build artifacts to the final image: build artifact is the full path
+    # and will be the same in the destination docker image
+    if [[ "${is_dependency}" -eq 1 || "${CREATE_FINAL_IMAGE}" -eq 0 ]]; then
+      echo "FROM ${BASE_IMAGE} as final"
+      local build_artifacts
+      mapfile -t build_artifacts <<< "$(execution_action "get_build_artifacts" "${component}")"
+      for artifact in "${build_artifacts[@]}"; do
+        [[ -z "${artifact}" ]] && continue
+        echo "COPY --from=intermediate ${artifact} ${artifact}"
+      done
+    
+      # Copy all the runtime dependencies
+      for dep_component in "${all_depending_runtime_artifact_components[@]}"; do
+        [[ -z "${dep_component}" ]] && continue
+        local build_artifacts
+        mapfile -t build_artifacts <<< "$(execution_action "get_build_artifacts" "${dep_component}")"
+        for artifact in "${build_artifacts[@]}"; do
+          [[ -z "${artifact}" ]] && continue
+          echo "COPY --from=intermediate ${artifact} ${artifact}"
+        done
+      done
+    fi
+    # TODO Add description labels
+    echo "LABEL maintainer=\"KLEE Developers\""
+  } >> "${dockerfile}"
+
+  # Append template file if exists
+  docker_template_files=(
+      "${DIR}/d-${component}-${OS}-${DISTRIBUTION}-${DISTRIBUTION_VER}.inc"
+      "${DIR}/d-${component}-${OS}-${DISTRIBUTION}.inc"
+      "${DIR}/d-${component}-${OS}.inc"
+      "${DIR}/d-${component}.inc"
+    )
+  for f in "${docker_template_files[@]}"; do
+     [[ ! -f "$f" ]] && continue
+     cat "$f" >> "${dockerfile}"
+     break
+  done
+
+  # Copy docker context and dependencies
+  shopt -s nullglob # allow nullglobing
+  echo "${all_depending_artifact_components[@]}"
+  for v in "${all_depending_artifact_components[@]}" "${component}"; do
+    [[ -z "${v}" ]] && continue
+    local files=(
+      "${DIR}/"*"-${v}.inc" \
+      "${DIR}/"*"-${v}-${OS}.inc" \
+      "${DIR}/"*"-${v}-${OS}-${DISTRIBUTION}.inc" \
+      "${DIR}/"*"-${v}-${OS}-${DISTRIBUTION}-${DISTRIBUTION_VER}.inc" \
+      "${DIR}/build.sh" \
+      "${DIR}/common-functions"
+    )
+    local f
+    for f in  "${files[@]}"; do
+      [ -f "$f" ] || continue
+      cp -r "$f" "${temp_dir}/"
+    done
+
+    mkdir -p "${temp_dir}/patches"
+    for f in "${DIR}/patches/${v}"*.patch; do
+      cp -r "$f" "${temp_dir}/patches/"
+    done
+  done
+  shopt -u nullglob # disallow nullglobing
+
+  if [[ -z "${docker_context}" ]]; then
+    docker_context="${temp_dir}"
+  fi
+
+  # Build Docker container
+  docker build -t "${REPOSITORY}/${target_image}" -f "${temp_dir}"/Dockerfile "${docker_context}" || return 1
+  if [[ "${PUSH_DOCKER_DEPS}" -eq 1 && "${is_dependency}" -eq 1 ]]; then
+    docker push "${REPOSITORY}/${target_image}" || /usr/bin/true
+  fi
+
+  if [[ "${KEEP_DOCKERFILE}" -eq 0 ]]; then
+    # Clean-up docker build directory
+    rm -rf "${temp_dir}"
+  else
+    echo "Preserved docker directory: ${temp_dir}"
+  fi
+}
+
+check_os() {
+  if [[ "$OSTYPE" == "linux-gnu" ]]; then
+    # Host is Linux
+    OS="linux"
+    DISTRIBUTION="$(grep ^ID= /etc/os-release)"
+    DISTRIBUTION=${DISTRIBUTION#"ID="}
+    DISTRIBUTION_VER="$(grep ^VERSION_ID= /etc/os-release || echo "")"
+    DISTRIBUTION_VER=${DISTRIBUTION_VER#"VERSION_ID="}
+    # Remove `"`, if exists
+    DISTRIBUTION_VER=${DISTRIBUTION_VER#\"}
+    DISTRIBUTION_VER=${DISTRIBUTION_VER%\"}
+
+  elif [[ "$OSTYPE" == "darwin"* ]]; then
+    # Host is Mac OS X
+    OS="osx"
+    DISTRIBUTION="$(sw_vers -productName)"
+    DISTRIBUTION_VER="$(sw_vers -productVersion)"
+  else
+    echo "Operating System unknown $OSTYPE"
+    exit 1
+  fi
+  echo "Detected OS: ${OS}"
+  echo "OS=${OS}"
+  echo "Detected distribution: ${DISTRIBUTION}"
+  echo "DISTRIBUTION=${DISTRIBUTION}"
+  echo "Detected version: ${DISTRIBUTION_VER}"
+  echo "DISTRIBUTION_VER=${DISTRIBUTION_VER}"
+}
+
+
+#
+try_execute() {
+  # Check if a function exists and execute it
+  fct=$1
+  # promote that function does not exist
+  [[ "$(type -t "${fct}")" != "function" ]] && return 2
+
+  # promote the return value of the function
+  local failed=0
+  "${fct}" || failed=1
+  return "${failed}"
+}
+
+try_execute_if_exists() {
+  # Check if a function exists and execute it
+  fct=$1
+  # Ignore if function does not exist
+  [[ "$(type -t "${fct}")" != "function" ]] && return 0
+
+  # promote the return value of the function
+  local failed=0
+  "${fct}" || failed=1
+  return "${failed}"
+}
+
+# Execute the most system specific action possible.
+# If an action executed successfuly, return 0
+# The function will return 1 if an action was not successful
+execution_action() {
+    local action="$1"
+    local component="$2"
+    local found=0
+
+    # Execute most specific action: os + distribution + distribution version
+    if [[ -f "${DIR}/p-${component}-${OS}-${DISTRIBUTION}-${DISTRIBUTION_VER}.inc" ]]; then
+        found=1
+        source "${DIR}/p-${component}-${OS}-${DISTRIBUTION}-${DISTRIBUTION_VER}.inc"
+        local failed=0
+        try_execute "${action}"_"${component}" || failed=1
+        [[ "$failed" -eq 0 ]] && return 0
+    fi
+
+    # Execute most specific action: os + distribution
+    if [[ -f "${DIR}/p-${component}-${OS}-${DISTRIBUTION}.inc" ]]; then
+        found=1
+        source "${DIR}/p-${component}-${OS}-${DISTRIBUTION}.inc"
+        local failed=0
+        try_execute "${action}"_"${component}" || failed=1
+        [[ "$failed" -eq 0 ]] && return 0
+    fi
+
+    # Execute most specific action: os
+    if [[ -f "${DIR}/p-${component}-${OS}.inc" ]]; then
+        found=1
+        source "${DIR}/p-${component}-${OS}.inc";
+        local failed=0
+        try_execute "${action}"_"${component}" || failed=1
+        [[ "$failed" -eq 0 ]] && return 0
+    fi
+
+    # Execute package specific action:
+    if [[ -f "${DIR}/p-${component}.inc" ]]; then
+        found=1
+        source "${DIR}/p-${component}.inc";
+        local failed=0
+        try_execute "${action}"_"${component}" || failed=1
+        [[ "$failed" -eq 0 ]] && return 0
+    fi
+
+    # Found an action file but something didn't work
+    [[ "${found}" -eq 1 ]] && return 1
+
+    # No action found
+    return 2
+}
+
+##
+# Returns a list that is the result of either an array or function call
+get_list(){
+  local list_name=$1
+  local result=("")
+
+  if [[ "$(type -t "${list_name}")" == "function" ]]; then
+    mapfile -t result <<< "$("${list_name}")"
+  elif [[ -n ${!list_name+x} ]]; then
+    list_array="${list_name}[@]"
+    result=("${!list_array}")
+  fi
+
+  for i in "${result[@]}"; do
+    [[ -z "${i}" ]] && continue
+    echo "${i}"
+  done
+
+  return 0
+}
+
+##
+# Check if a lists exist
+##
+check_list(){
+  local list_name=$1
+  if [[ "$(type -t "${list_name}")" == "function" ]]; then
+    return 0
+  fi
+  local list_array="${list_name}[@]"
+  if [[ ${!list_array+x} ]]; then
+    return 0
+  fi
+  echo "Variable or function \"${list_name}\" not found"
+  exit 1
+}
+
+validate_required_variables() {
+    local component="$1"
+    local type="$2"
+    local variables
+    check_list required_variables_"${component}"
+    mapfile -t variables <<< "$(get_list "${type}"_"${component}")"
+
+    if [[ -n "${variables[*]}" ]]; then
+        # Check if variables are defined
+        for v in "${variables[@]}"; do
+            if [[ -z ${!v+x} ]]; then
+                echo "${v} Required but unset"
+                exit 1
+            fi
+        done
+    fi
+
+    try_execute_if_exists required_variables_check_"${component}"
+}
+
+get_all_dependencies_rec() {
+  local component="$1"
+  local type="$2"
+  local depending_components
+  # Get the list of dependencies
+  mapfile -t depending_components <<< "$(get_list "${type}"_dependency_"${component}")"
+  for v in "${depending_components[@]}"; do
+    [[ -z "${v}" ]] && continue
+    get_all_dependencies_rec "$v" "$type"
+  done
+  echo "$component"
+}
+
+get_all_dependencies() {
+  local component="$1"
+  local type="$2"
+  local depending_components=("")
+  # Get the list of dependencies
+  mapfile -t depending_components <<< "$(get_list "${type}"_dependency_"${component}")"
+  local final_list=("${depending_components[@]}")
+  for v in "${depending_components[@]}"; do
+    [[ -z "${v}" ]] && continue
+    local deps_list=("")
+    local failed=0
+    mapfile -t deps_list <<< "$(get_all_dependencies_rec "$v" "$type")"
+    [[ "${failed}" -eq 1 ]] && continue
+
+    # Make sure items are unique and keep the order of occurence
+    for di in "${deps_list[@]}"; do
+      local found=0
+      for f in "${final_list[@]}"; do
+        [[ -z "$f" ]] && continue
+        [[ "$di" == "$f" ]] && found=1 && break
+      done
+      [[ "$found" -eq 0 ]] && final_list+=("${di}")
+    done
+  done
+
+  for v in "${final_list[@]}"; do
+    echo "${v}"
+  done
+}
+
+gather_dependencies_rec() {
+  local component="$1"
+  local type="$2"
+  local action="$3"
+
+  load_component "${component}" "v" || { echo "Loading component failed ${component}"; return 1; }
+  validate_required_variables "${component}" "required_variables"
+
+  # Get the list of dependencies
+  local variables
+  check_list "${type}"_dependency_"${component}"
+  mapfile -t variables <<< "$(get_list "${type}"_dependency_"${component}")"
+  for v in "${variables[@]}"; do
+    [[ -z "${v}" ]] && continue
+    gather_dependencies_rec "$v" "${type}" "${action}"
+  done
+
+  try_execute_if_exists "${action}"_"${component}"
+}
+
+gather_dependencies() {
+  local component="$1"
+  local dependency_type="$2"
+  local action="$3"
+
+  local depending_components
+  # Get the list of dependencies
+  check_list "${dependency_type}"_dependency_"${component}"
+  mapfile -t depending_components <<< "$(get_list "${dependency_type}"_dependency_"${component}")"
+
+  for v in "${depending_components[@]}"; do
+    [[ -z "${v}" ]] && continue
+    gather_dependencies_rec "$v" "${dependency_type}" "${action}"
+  done
+  try_execute_if_exists "${action}"_"${component}"
+}
+
+check_module() {
+  local module="$1"
+  # Validate module if different functions or arrays exist
+  (
+    load_component "${module}" "v" || return 1
+    list_or_functions=(
+      required_variables
+      artifact_dependency
+    )
+    for item in "${list_or_functions[@]}"; do
+      check_list "${item}_${module}"
+    done
+
+  ) || { echo "Module $1 not valid"; return 1; }
+
+  # Validate build instructions
+  (
+    validate_component "${module}" "p" || { echo "No build instructions found for ${module}"; return 0; }
+    load_component "${module}" "p"
+
+    list_or_functions=(
+      setup_build_variables
+      download
+      build
+      install
+      is_installed
+      setup_artifact_variables
+      get_build_artifacts
+      get_docker_config_id
+    )
+    for item in "${list_or_functions[@]}"; do
+      check_list "${item}_${module}"
+    done
+
+  ) || { echo "Build instructions for ${module} are not valid"; return 1; }
+
+}
+
+##
+## Install the specified component
+install_component() {
+  local component="$1"
+
+  # Load general component information
+  load_component "${component}" "v" || { echo "Loading component failed ${component}"; return 1; }
+
+  # Get the list of dependencies
+  local depending_artifact_components
+  check_list artifact_dependency_"${component}"
+  mapfile -t depending_artifact_components <<< "$(get_list artifact_dependency_"${component}")"
+
+  # Make sure an artefact is available for the depending component
+  for v in "${depending_artifact_components[@]}"; do
+    [[ -z "${v}" ]] && continue
+    install_component "${v}"
+  done
+
+  # Setup general component variables
+  validate_required_variables "${component}" "required_variables"
+
+  # Handle dependencies of required artifacts
+  gather_dependencies "${component}" "artifact" "setup_variables"
+
+  # Check if the artifact is installed ablready
+  execution_action is_installed "${component}" && execution_action setup_artifact_variables "${component}" && validate_required_variables "${component}"  "export_variables" && { echo "Already installed ${component}"; return 0; }
+
+  # Install package if available
+  execution_action install_binary_artifact "${component}" && execution_action setup_artifact_variables "${component}" && validate_required_variables "${component}"  "export_variables" && { echo "Package installed ${component}"; return 0 ;}
+
+  # Validate general build variables
+  validate_build_variables
+
+  # Check if there is build information, if not - this is a meta package, return
+  validate_component "${component}" "p" || return 0
+
+  # Load build description
+  load_component "${component}" "p" || { echo "Loading component failed ${component}"; return 1; }
+
+  # Setup build variables
+  setup_build_variables_"${component}"
+
+  # Check and install runtime-dependencies if needed
+  execution_action "install_runtime_dependencies" "${component}" || true
+
+  # Validate configuration
+  try_execute_if_exists validate_build_config_"${component}"
+
+  # Install build dependencies
+  if [[ "${INSTALL_SYSTEM_DEPS}" == "1" ]]; then
+    execution_action "install_build_dependencies" "${component}" || {
+      echo "Could not install build dependencies for ${component}";
+      return 1;
+    }
+  fi
+
+  # Install build source
+  try_execute_if_exists download_"${component}"
+
+  # Build the package
+  try_execute_if_exists build_"${component}"
+
+  # Install to its final destination
+  try_execute_if_exists install_"${component}"
+}
+
+
+main() {
+  local NAME
+  NAME=$(basename "${0}")
+  local USAGE="usage: ${NAME} "
+  local COMPONENTS=()
+  local BUILD_DOCKER=0
+  local INSTALL_SYSTEM_DEPS=0
+  local KEEP_DOCKERFILE=0
+  local CHECK_MODULE=0
+  local PUSH_DOCKER_DEPS=0
+  local CREATE_FINAL_IMAGE=0
+
+  for i in "$@" ;do
+  case $i in
+    --debug)
+      set -x
+    ;;
+    --docker)
+    BUILD_DOCKER=1
+    ;;
+    --keep-dockerfile)
+      KEEP_DOCKERFILE=1
+    ;;
+    --push-docker-deps)
+      PUSH_DOCKER_DEPS=1
+    ;;
+    --create-final-image)
+      CREATE_FINAL_IMAGE=1
+    ;;
+    --install-system-deps)
+      INSTALL_SYSTEM_DEPS=1
+    ;;
+    --help)
+      show_help "${NAME}"
+      exit 0
+    ;;
+    --check-os)
+      # Checks the operating sytem used
+      check_os
+      exit 0
+    ;;
+    --check-module)
+      # Check the validity of the module
+      CHECK_MODULE=1
+    ;;
+    -*)
+      echo "${NAME}: unknown argument: $i"
+      show_help "${NAME}"
+      exit 1
+    ;;
+    *)
+      COMPONENTS+=("$i")
+    ;;
+  esac
+  done
+
+  if [[ ${#COMPONENTS[@]} -eq 0 ]]; then
+    show_help "${NAME}"
+    exit 1
+  fi
+
+
+  if [[ "${CHECK_MODULE}" -eq 1 ]]; then
+    for m in "${COMPONENTS[@]}"; do
+      check_module "${m}"
+    done
+    exit 0
+  fi
+
+  # Validate selected components: check if they have a v-"component".inc file
+  for c in "${COMPONENTS[@]}"; do
+    validate_component "$c" "v"
+  done
+
+  if [[ "${BUILD_DOCKER}" == "1" ]]; then
+    if [[ -z ${BASE_IMAGE+X} ]]; then
+      echo "No BASE_IMAGE provided"
+      exit 1
+    fi
+    if [[ -z ${REPOSITORY+X} ]]; then
+      echo "No REPOSITORY provided"
+      exit 1
+    fi
+    
+    # Gather information about the base image
+    check_docker_os "${BASE_IMAGE}"
+
+    # Install components
+    for c in "${COMPONENTS[@]}"; do
+      build_docker "$c" 0 || { echo "Building docker image ${c} failed"; return 1; }
+    done
+  else
+    # General Setup
+    check_os
+
+    # Install components
+    for c in "${COMPONENTS[@]}"; do
+      install_component "$c"
+      try_execute_if_exists check_export_variables_"$c"
+    done
+  fi
+}
+
+main "$@"
diff --git a/scripts/build/common-defaults.sh b/scripts/build/common-defaults.sh
deleted file mode 100644
index 5cefef19..00000000
--- a/scripts/build/common-defaults.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-# This file is meant to be included by shell scripts to provide common default
-# values.
-# It is used by: travis builds; docker builds and local builds
-# Change defaults to setup different development environment
-# Defines defaults used to build a default docker image outside of Travis
-if [[ "${DOCKER_BUILD}x" == "1x" ]]; then
-  # Default for docker: Do not keep build and source files for small images
-  : "${KEEP_BUILD:=0}"
-  : "${KEEP_SRC:=0}"
-  echo "DOCKER_BUILD"
-fi
-if [[ "${KLEE_TRAVIS_BUILD}x" != "1x" ]]; then
-: "${REPOSITORY:=klee}"
-: "${LLVM_VERSION:=3.4}"
-: "${DISABLE_ASSERTIONS:=0}"
-: "${ENABLE_DEBUG:=1}"
-: "${ENABLE_OPTIMIZED:=1}"
-: "${SOLVERS:=STP}"
-: "${STP_VERSION:=2.1.2}"
-: "${Z3_VERSION:=4.4.1}"
-: "${METASMT_VERSION:=v4.rc1}"
-: "${METASMT_DEFAULT:=STP}"
-: "${METASMT_BOOST_VERSION:=}"
-: "${REQUIRES_RTTI:=0}"
-: "${KLEE_UCLIBC:=klee_uclibc_v1.0.0}"
-: "${USE_TCMALLOC:=1}"
-: "${PACKAGED:=0}"
-# undefined, address, memory
-: "${SANITIZER_BUILD:=}"
-# Defines if source and build artifacts should be preserved
-: "${KEEP_BUILD:=1}"
-: "${KEEP_SRC:=1}"
-OS="$(uname)"
-case $OS in
-  'Linux')
-    TRAVIS_OS_NAME='linux'
-    ;;
-  'Darwin')
-    TRAVIS_OS_NAME='osx'
-    ;;
-  *) ;;
-esac
-fi
-
-# General default values
-: "${TCMALLOC_VERSION:=2.4}"
-: "${GTEST_VERSION:=1.7.0}"
-
-if [[ "${DIR}x" == "x" ]]; then
-  echo "\${DIR} not set"
-  exit 1
-fi
-source "${DIR}/common-functions"
diff --git a/scripts/build/common-functions b/scripts/build/common-functions
index 499b51b7..6d810d73 100644
--- a/scripts/build/common-functions
+++ b/scripts/build/common-functions
@@ -16,203 +16,18 @@ function git_clone_or_update() {
   fi
 }
 
-function to_upper() {
-  echo "$1" | tr '[:lower:]' '[:upper:]'
-}
-
-function to_lower() {
-  echo "$1" | tr '[:upper:]' '[:lower:]'
-}
-
-# This file is meant to be included by shell scripts
-# that need to do a sanitized build.
-
-# Users of this script can use this variable
-# to detect if a Sanitized build was enabled.
-IS_SANITIZED_BUILD=0
-
-# Remove ":" separator
-sanitizers=(${SANITIZER_BUILD//:/ })
-# Sort sanitizers
-IFS=$'\n' sorted_sanitizers=($(sort <<<"${sanitizers[*]}"))
-unset IFS
-
-# Set variables used by clients.
-## Build variables
-SANITIZER_CXX_FLAGS=""
-SANITIZER_C_FLAGS=""
-SANITIZER_LD_FLAGS=""
-# Docker_suffix
-SANITIZER_SUFFIX=""
-
-#
-for sanitizer in ${sorted_sanitizers[@]}; do
-  # AddressSanitizer
-  if [ "X${sanitizer}" == "Xaddress" ]; then
-    echo "Using ASan"
-    flags=" -fsanitize=address -fno-omit-frame-pointer -g"
-    SANITIZER_CXX_FLAGS+=" ${flags}"
-    SANITIZER_C_FLAGS+=" ${flags}"
-    SANITIZER_LD_FLAGS+=" ${flags}"
-    SANITIZER_SUFFIX+="_asan"
-    IS_SANITIZED_BUILD=1
-    continue
-  fi
-
-  # Undefined Behaviour Sanitizer
-  if [ "X${sanitizer}" == "Xundefined" ]; then
-    echo "Using UBSan"
-    flags="-fsanitize=undefined -fno-omit-frame-pointer -g"
-    SANITIZER_CXX_FLAGS+=" ${flags}"
-    SANITIZER_C_FLAGS+=" ${flags}"
-    SANITIZER_LD_FLAGS+=" ${flags} -lubsan -fuse-ld=gold"
-    SANITIZER_SUFFIX+="_ubsan"
-    IS_SANITIZED_BUILD=1
-    continue
-  fi
-
-  # Undefined Behaviour Sanitizer
-  if [ "X${sanitizer}" == "Xmemory" ]; then
-    echo "Using Memory Sanitizer"
-    if [[ "X${PACKAGED}" == "X1" ]]; then
-      echo "simultanously memory sanitizer and packaged is not supported "
-      exit 1
-    fi
-
-    SANITIZER_SUFFIX+="_memsan"
-    SANITIZER_LLVM_UNINSTRUMENTED="${LLVM_BUILD}_uninstrumented"
-    SANITIZER_LLVM_LIBCXX="${LLVM_BUILD}_libcxx"
-
-    SANITIZER_C_COMPILER="${SANITIZER_LLVM_UNINSTRUMENTED}/bin/clang"
-    SANITIZER_CXX_COMPILER="${SANITIZER_LLVM_UNINSTRUMENTED}/bin/clang++"
-    SANITIZER_CMAKE_C_COMPILER="-DCMAKE_C_COMPILER=${SANITIZER_C_COMPILER}"
-    SANITIZER_CMAKE_CXX_COMPILER="-DCMAKE_CXX_COMPILER=${SANITIZER_CXX_COMPILER}"
-
-    MSAN_LINK_FLAGS="-lc++abi -Wl,--rpath=${SANITIZER_LLVM_LIBCXX}/lib -L${SANITIZER_LLVM_LIBCXX}/lib";
-    MSAN_FLAGS="$MSAN_LINK_FLAGS -nostdinc++ \
-       -isystem ${SANITIZER_LLVM_LIBCXX}/include \
-       -isystem ${SANITIZER_LLVM_LIBCXX}/include/c++/v1  \
-       -fsanitize=memory \
-       -fsanitize-memory-track-origins \
-       -w -fno-omit-frame-pointer -g";
-
-    SANITIZER_CXX_FLAGS+="${MSAN_FLAGS} -stdlib=libc++"
-    SANITIZER_C_FLAGS+="${MSAN_FLAGS}"
-    SANITIZER_LD_FLAGS+="${MSAN_LINK_FLAGS}"
-
-    IS_SANITIZED_BUILD=1
-    continue
-  fi
-
-  echo "Unknown sanitizer: $sanitizer"
-  exit 1
-done
-
-# This file is meant to be included by shell scripts
-# that need to retrieve llvm-specifi variables
-
-LLVM_VERSION_SHORT="${LLVM_VERSION/./}"
-LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
-LLVM_SUFFIX=""
-
-BuildMode=''
-
-# Build from source
-if [[ "${PACKAGED}x" == "1x" ]]; then
-  LLVM_SUFFIX+="_packaged"
-  set +e
-  llvm_config_path=$(which llvm-config-${LLVM_VERSION})
-  if [[ -e "${llvm_config_path}" ]]; then
-    LLVM_BIN="$(llvm-config-${LLVM_VERSION} --bindir)"
-  fi
-  set -e
-else
-  if [[ "${ENABLE_OPTIMIZED}" == "1" ]]; then
-    LLVM_SUFFIX+="_O"
-    BuildMode="Release"
-  else
-    LLVM_SUFFIX+="_NO"
-  fi
-
-  if [[ ("${ENABLE_DEBUG}" == "1") || ("${ENABLE_OPTIMIZED}" != "1") ]]; then
-    LLVM_SUFFIX+="_D"
-    [ -z "$BuildMode" ] && BuildMode="Debug" || BuildMode="$BuildMode+Debug"
-  else
-    LLVM_SUFFIX+="_ND"
-  fi
-
-  if [[ "${DISABLE_ASSERTIONS}" == "1" || -z "${DISABLE_ASSERTIONS}" ]]; then
-    LLVM_SUFFIX+="_NA"
-  else
-    LLVM_SUFFIX+="_A"
-    [ -z "$BuildMode" ] && BuildMode="Asserts" || BuildMode="$BuildMode+Asserts"
-  fi
-
-  if [[ "${REQUIRES_RTTI}" == "1" ]]; then
-    LLVM_SUFFIX+="_RTTI"
-  fi
-
-  if [[ "${SANITIZER_SUFFIX}x" != "x" ]]; then
-    LLVM_SUFFIX+="${SANITIZER_SUFFIX}"
-  fi
-
-  LLVM_BASE="${BASE}/llvm-${LLVM_VERSION_SHORT}"
-  LLVM_BUILD="${LLVM_BASE}-build${LLVM_SUFFIX}"
-  LLVM_INSTALL="${LLVM_BASE}-install${LLVM_SUFFIX}"
-  LLVM_BIN="${LLVM_INSTALL}/bin"
-  if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
-    LLVM_BUILDMODE="$BuildMode"
-    LLVM_BUILD_BIN="${LLVM_BUILD}/${LLVM_BUILDMODE}/bin"
+function get_git_hash() {
+  local url="$1"
+  local branch="$2"
+  local commit_id=""
+  
+  # List remote git branches and get the commit id of the branch
+  commit_id="$(git ls-remote -h "$url" |grep "$branch" | cut -d$'\t' -f 1)"
+  
+  # If that doesn't work use the branch instead of the commit id
+  if [[ -z "${commit_id}" ]]; then 
+    echo "${branch}"
   else
-    LLVM_BUILD_BIN="${LLVM_BUILD}/bin"
-  fi
-fi
-
-# Generate the suffix used for the solver combination
-# Every solver needs to have a version explicitly specified
-SOLVER_SUFFIX=""
-
-# Remove ":" separator
-solvers=(${SOLVERS//:/ })
-
-# Sort solvers
-IFS=$'\n' sorted_solvers=($(sort <<<"${solvers[*]}"))
-unset IFS
-
-for solver in ${sorted_solvers[@]}; do
-  # Make sure version a solver specific version variable is used
-  solver_var="$(to_upper "$solver")_VERSION"
-  SOLVER_VERSION="${!solver_var}"
-  if [[ -z "${SOLVER_VERSION}" ]] ; then
-  	echo "Solver version for $solver not defined"
-  	exit 1
-  fi
-  # Add the solver to the suffix and lower case it
-  SOLVER_SUFFIX+="_$(to_lower "$solver")$(to_lower "$SOLVER_VERSION")"
-  echo $SOLVER_SUFFIX
-  if [[ "$(to_lower "$solver")" == "metasmt" ]]; then
-    if [[ "${REQUIRES_RTTI}x" != "1x" ]]; then
-      echo "METASMT requires an RTTI build"
-      exit 1
-    fi
-    if [[ -z "${METASMT_DEFAULT}" ]]; then
-      echo "METASMT_DEFAULT not defined"
-      exit 1
-    fi
-    if [[ -z "${METASMT_BOOST_VERSION}" ]] ; then
-      echo "METASMT_BOOST_VERSION not defined - use default"
-      SOLVER_SUFFIX+="_$(to_lower "$METASMT_DEFAULT")_boost-dev"
-    else
-      SOLVER_SUFFIX+="_$(to_lower "$METASMT_DEFAULT")_$(to_lower "$METASMT_BOOST_VERSION")"
-    fi
+    echo "${commit_id:0:7}"
   fi
-done
-
-# This file is meant to be included by shell scripts that handle dependencies by
-# KLEE beside LLVM and solvers
-#
-# Generate the suffix used for direct dependencies of KLEE like uclibc
-DEPS_SUFFIX=""
-if [[ "${KLEE_UCLIBC}" != "0" ]]; then
-  DEPS_SUFFIX+="_${KLEE_UCLIBC}"
-fi
+}
\ No newline at end of file
diff --git a/scripts/build/d-klee-linux-ubuntu.inc b/scripts/build/d-klee-linux-ubuntu.inc
new file mode 100644
index 00000000..38b8dce5
--- /dev/null
+++ b/scripts/build/d-klee-linux-ubuntu.inc
@@ -0,0 +1,23 @@
+# TODO remove adding sudo package
+# Create ``klee`` user for container with password ``klee``.
+# and give it password-less sudo access (temporarily so we can use the TravisCI scripts)
+RUN apt update && apt -y --no-install-recommends install sudo && \
+    rm -rf /var/lib/apt/lists/* && \
+    useradd -m klee && \
+    echo klee:klee | chpasswd && \
+    cp /etc/sudoers /etc/sudoers.bak && \
+    echo 'klee  ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
+
+ENV BASE=/tmp
+# Copy across source files needed for build
+# Set klee user to be owner
+ADD --chown=klee:klee / ${BASE}/klee_src
+
+USER klee
+WORKDIR /home/klee
+
+# Add KLEE binary directory to PATH
+RUN /bin/bash -c 'ln -s ${BASE}/klee_src /home/klee/ && ln -s ${BASE}/klee_build* /home/klee/klee_build && echo "export PATH=\"$PATH:$(cd /tmp/llvm-*install*/bin && pwd):/home/klee/klee_build/bin\"" >> /home/klee/.bashrc'
+
+# TODO Remove when STP is fixed
+RUN /bin/bash -c 'echo "export LD_LIBRARY_PATH=$(cd ${BASE}/metaSMT-*-deps/stp-git-basic/lib/ && pwd)" >> /home/klee/.bashrc'
diff --git a/scripts/build/dependencies-ubuntu.sh b/scripts/build/dependencies-ubuntu.sh
deleted file mode 100755
index d5d4a36a..00000000
--- a/scripts/build/dependencies-ubuntu.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-# Installs ubuntu dependencies
-set -e
-
-# Update packages
-apt update
-
-# Install essential build tools
-apt -y --no-install-recommends install build-essential software-properties-common wget
-
-# Add repository for additional compilers
-add-apt-repository ppa:ubuntu-toolchain-r/test -y
-add-apt-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial main"
-wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add -
-apt update -y
-
-#Install essential dependencies
-apt -y --no-install-recommends install \
-  binutils \
-  bison \
-  cmake \
-  curl \
-  flex \
-  git \
-  groff-base \
-  libboost-program-options-dev \
-  libncurses-dev \
-  ninja-build \
-  patch \
-  perl \
-	python \
-  python3-dev \
-  python3-pip \
-	python3-setuptools \
-  subversion \
-	sudo \
-  unzip \
-  wget \
-  zlib1g-dev
-apt clean
-
-# Install lit for testing
-pip3 install wheel && pip3 install lit==0.6.0
diff --git a/scripts/build/install-klee-deps.sh b/scripts/build/install-klee-deps.sh
deleted file mode 100755
index 622e621f..00000000
--- a/scripts/build/install-klee-deps.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-set -e
-###########################################################################
-# Install KLEE dependencies
-###########################################################################
-DIR="$(cd "$(dirname "$0")" && pwd)"
-
-if [[ "${BASE}x" == "x" ]]; then
-  echo "\${BASE} not set"
-  exit 1
-fi
-
-# Install LLVM and the LLVM bitcode compiler we require to build KLEE
-"${DIR}/llvm.sh"
-
-# Install allocators
-"${DIR}/tcmalloc.sh"
-
-# Get SMT solvers
-"${DIR}/solvers.sh"
-
-# Get needed utlities/libraries for testing KLEE
-"${DIR}/testing-utils.sh"
-
-# Install uclibc
-"${DIR}/uclibc.sh"
diff --git a/scripts/build/install-local.sh b/scripts/build/install-local.sh
deleted file mode 100755
index 50dfb612..00000000
--- a/scripts/build/install-local.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-# Install all dependencies to build KLEE in a directory ${BASE}
-set -e
-if [[ "${BASE}x" == "x" ]]; then
-  echo "\${BASE} not set"
-  exit 1
-fi
-
-# Create base directory if not exists
-mkdir -p "${BASE}"
-DIR=$(dirname "$(readlink -f "$0" || stat -f "$0")")
-
-# Install dependencies
-"${DIR}/install-klee-deps.sh"
-
-# Build KLEE
-"${DIR}/klee.sh"
diff --git a/scripts/build/klee.sh b/scripts/build/klee.sh
deleted file mode 100755
index 84d7bd63..00000000
--- a/scripts/build/klee.sh
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/bin/bash -x
-# Compile KLEE
-# Make sure we exit if there is a failure
-set -e
-
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-: ${SOLVERS?"Solvers must be specified"}
-if [[ -z "${KLEE_UCLIBC}" ]]; then
-  echo "KLEE_UCLIBC must be specified: 0 or branch/tag"
-  exit 1
-fi
-if [[ -z "${KLEE_SRC}" ]]; then
-  # Assumeption: this build script is part of the KLEE source tree
-  KLEE_SRC="${DIR}/../.."
-fi
-
-CMAKE_PREFIX_PATH=""
-###############################################################################
-# Handling LLVM configuration
-###############################################################################
-if [[ "$TRAVIS_OS_NAME" = "linux" ]] ; then
-  LLVM_CONFIG="${LLVM_BIN}/llvm-config"
-  LLVM_BUILD_DIR="/usr/lib/llvm-${LLVM_VERSION_SHORT}/build"
-  KLEE_CC="${LLVM_BIN}/clang"
-  KLEE_CXX="${LLVM_BIN}/clang++"
-elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
-  LLVM_BIN="/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/bin"
-  LLVM_CONFIG="${LLVM_BIN}/llvm-config"
-  LLVM_BUILD_DIR="$(${LLVM_CONFIG} --src-root)"
-  KLEE_CC="${LLVM_BIN}/clang"
-  KLEE_CXX="${LLVM_BIN}/clang++"
-else
-  echo "Unhandled TRAVIS_OS_NAME \"${TRAVIS_OS_NAME}\""
-  exit 1
-fi
-
-###############################################################################
-# klee-uclibc
-###############################################################################
-if [ "${KLEE_UCLIBC}" != "0" ]; then
-    KLEE_UCLIBC_CONFIGURE_OPTION=(-DENABLE_KLEE_UCLIBC=TRUE -DKLEE_UCLIBC_PATH="${BASE}/klee-uclibc-${LLVM_VERSION_SHORT}" -DENABLE_POSIX_RUNTIME=TRUE)
-else
-    KLEE_UCLIBC_CONFIGURE_OPTION=(-DENABLE_KLEE_UCLIBC=FALSE -DENABLE_POSIX_RUNTIME=FALSE)
-fi
-
-COVERAGE_FLAGS=""
-if [ ${COVERAGE} -eq 1 ]; then
-    COVERAGE_FLAGS='-fprofile-arcs -ftest-coverage'
-fi
-
-
-###############################################################################
-# Handle setting up solver configure flags for KLEE
-###############################################################################
-SOLVER_LIST=$(echo "${SOLVERS}" | sed 's/:/ /g')
-
-# Set CMake configure options
-KLEE_Z3_CONFIGURE_OPTION=(-DENABLE_SOLVER_Z3=OFF)
-KLEE_STP_CONFIGURE_OPTION=(-DENABLE_SOLVER_STP=OFF)
-KLEE_METASMT_CONFIGURE_OPTION=(-DENABLE_SOLVER_METASMT=OFF)
-for solver in ${SOLVER_LIST}; do
-  echo "Setting CMake configuration option for ${solver}"
-  case ${solver} in
-  STP)
-    KLEE_STP_CONFIGURE_OPTION=(-DENABLE_SOLVER_STP=TRUE -DSTP_DIR="${BASE}/stp-${STP_VERSION}-install")
-    ;;
-  Z3)
-    echo "Z3"
-    KLEE_Z3_CONFIGURE_OPTION=(-DENABLE_SOLVER_Z3=TRUE)
-    if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-    	KLEE_Z3_CONFIGURE_OPTION+=(-DZ3_INCLUDE_DIRS="${BASE}/z3-${Z3_VERSION}-install/include" -DZ3_LIBRARIES="${BASE}/z3-${Z3_VERSION}-install/lib/libz3.so")
-    fi
-    ;;
-  metaSMT)
-    echo "metaSMT"
-    if [ "X${METASMT_DEFAULT}" == "X" ]; then
-      METASMT_DEFAULT=STP
-    fi
-    KLEE_METASMT_CONFIGURE_OPTION=(-DENABLE_SOLVER_METASMT=TRUE -DmetaSMT_DIR="${BASE}/metaSMT/build" -DMETASMT_DEFAULT_BACKEND="${METASMT_DEFAULT}")
-    ;;
-  *)
-    echo "Unknown solver ${solver}"
-    exit 1
-  esac
-done
-
-###############################################################################
-# Handle additional configure flags
-###############################################################################
-
-TCMALLOC_OPTION=$([ "${USE_TCMALLOC:-0}" == 1 ] && echo "-DENABLE_TCMALLOC=TRUE" || echo "-DENABLE_TCMALLOC=FALSE")
-if [[ "$TCMALLOC_OPTION" != "0" ]] ; then
-  if [[ ! -z "${CMAKE_PREFIX_PATH}" ]]; then
-    CMAKE_PREFIX_PATH+=":"
-  fi
-  CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}$BASE/tcmalloc-install"
-fi
-
-###############################################################################
-# KLEE
-###############################################################################
-KLEE_BUILD="${BASE}/klee_build${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX}${DEPS_SUFFIX}"
-mkdir -p "${KLEE_BUILD}"
-cd "${KLEE_BUILD}"
-GTEST_SRC_DIR="${BASE}/googletest-release-${GTEST_VERSION}/"
-if [ "X${DISABLE_ASSERTIONS}" == "X1" ]; then
-  KLEE_ASSERTS_OPTION="-DENABLE_KLEE_ASSERTS=FALSE"
-else
-  KLEE_ASSERTS_OPTION="-DENABLE_KLEE_ASSERTS=TRUE"
-fi
-
-if [ "X${ENABLE_OPTIMIZED}" == "X1" ]; then
-  CMAKE_BUILD_TYPE="RelWithDebInfo"
-else
-  CMAKE_BUILD_TYPE="Debug"
-fi
-
-# TODO: We should support Ninja too
-# Configure KLEE
-echo "CXXFLAGS=\"${COVERAGE_FLAGS} ${SANITIZER_CXX_FLAGS}\" \
-CFLAGS=\"${COVERAGE_FLAGS} ${SANITIZER_C_FLAGS}\" \
-LDFLAGS=\"${COVERAGE_LDFLAGS} ${SANITIZER_LD_FLAGS}\" \
-cmake \
-  -DLLVM_CONFIG_BINARY=\"${LLVM_CONFIG}\" \
-  -DLLVMCC=\"${KLEE_CC}\" \
-  -DLLVMCXX=\"${KLEE_CXX}\" \
-  ${KLEE_STP_CONFIGURE_OPTION[@]} \
-  ${KLEE_Z3_CONFIGURE_OPTION[@]} \
-  ${KLEE_METASMT_CONFIGURE_OPTION[@]} \
-  ${KLEE_UCLIBC_CONFIGURE_OPTION[@]} \
-  ${TCMALLOC_OPTION[@]} \
-  -DGTEST_SRC_DIR=${GTEST_SRC_DIR} \
-  -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
-  ${KLEE_ASSERTS_OPTION[@]} \
-  -DENABLE_UNIT_TESTS=TRUE \
-  -DENABLE_SYSTEM_TESTS=TRUE \
-  -DLIT_ARGS=\"-v\" \
-  ${SANITIZER_CMAKE_C_COMPILER[@]} \
-  ${SANITIZER_CMAKE_CXX_COMPILER[@]} \
-  -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \
-  ${KLEE_SRC}" > "${KLEE_BUILD}/.build_command"
-source "${KLEE_BUILD}/.build_command"
-make -j$(nproc)
-
-###############################################################################
-# Prepare Coverage functionality
-###############################################################################
-coverage_setup()
-{
-  # TODO Remove it and put it to the proper package install section
-  apt update && apt -y --no-install-recommends install lcov
-  # Zero coverage for any file, e.g. previous tests
-  lcov --directory . --no-external --zerocounters
-  # Create a baseline by capturing any file used for compilation, no execution yet
-  lcov --rc lcov_branch_coverage=1 --directory . --base-directory="${KLEE_SRC}" --no-external --capture --initial --output-file coverage_base.info
-  lcov --rc lcov_branch_coverage=1 --remove coverage_base.info 'test/*' --output-file coverage_base.info
-  lcov --rc lcov_branch_coverage=1 --remove coverage_base.info 'unittests/*' --output-file coverage_base.info
-}
-
-coverageup()
-{
-  tags=$1
-  codecov_suffix=(${tags// /})
-  # Create report
-  # (NOTE: "--rc lcov_branch_coverage=1" needs to be added in all calls, otherwise branch coverage gets dropped)
-  lcov --rc lcov_branch_coverage=1 --directory . --base-directory="${KLEE_SRC}" --no-external --capture --output-file coverage.info
-  # Exclude uninteresting coverage goals (LLVM, googletest, and KLEE system and unit tests)
-  lcov --rc lcov_branch_coverage=1 --remove coverage.info 'test/*' --output-file coverage.info
-  lcov --rc lcov_branch_coverage=1 --remove coverage.info 'unittests/*' --output-file coverage.info
-  # Combine baseline and measured coverage
-  lcov --rc lcov_branch_coverage=1 -a coverage_base.info -a coverage.info -o coverage_all.info.${codecov_suffix}
-  # Debug info
-  lcov --rc lcov_branch_coverage=1 --list coverage_all.info.${codecov_suffix}
-}
-
-COVERAGE=${COVERAGE:=0}
-
-###############################################################################
-# Unit tests
-###############################################################################
-# Prepare coverage information if COVERAGE is set
-if [ ${COVERAGE} -eq 1 ]; then
-  coverage_setup
-fi
-make unittests
-
-# Generate and upload coverage if COVERAGE is set
-if [ ${COVERAGE} -eq 1 ]; then
-  coverageup "unittests"
-fi
-
-###############################################################################
-# lit tests
-###############################################################################
-if [ ${COVERAGE} -eq 1 ]; then
-  coverage_setup
-fi
-make systemtests
-
-# If metaSMT is the only solver, then rerun lit tests with non-default metaSMT backends
-if [ "X${SOLVERS}" == "XmetaSMT" ]; then
-  metasmt_default=$(to_lower $METASMT_DEFAULT) # klee_opts and kleaver_opts use lowercase
-  available_metasmt_backends="btor stp z3 yices2 cvc4"
-  for backend in $available_metasmt_backends; do
-    if [ "X${metasmt_default}" != "X$backend" ]; then
-      if [ "$backend" == "cvc4" ]; then
-        for num in {1..5}; do sleep 120; echo 'Keep Travis alive'; done &
-      fi
-      lit -v --param klee_opts=-metasmt-backend=$backend --param kleaver_opts=-metasmt-backend=$backend test/
-    fi
-  done
-fi
-
-# Generate and upload coverage if COVERAGE is set
-if [ ${COVERAGE} -eq 1 ]; then
-  coverageup "systemtests"
-fi
diff --git a/scripts/build/llvm.sh b/scripts/build/llvm.sh
deleted file mode 100755
index 92370159..00000000
--- a/scripts/build/llvm.sh
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/bin/bash -x
-set -ev
-STAGE="$1"
-
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-if [[ "${LLVM_VERSION_SHORT}" == "" ]]; then
-  echo "LLVM_VERSION_SHORT not set"
-  exit 1
-fi
-
-if [[ "${BASE}" == "" ]]; then
-  echo "BASE not set"
-  exit 1
-fi
-
-# Install packages if possible
-if [[ "${PACKAGED}x" == "1x" ]]; then
-  apt update
-  apt install -y llvm-${LLVM_VERSION} llvm-${LLVM_VERSION}-dev
-  apt install -y clang-${LLVM_VERSION}
-  exit 0
-fi
-
-if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-  LLVM_BASE="${BASE}/llvm-${LLVM_VERSION_SHORT}"
-  # Checkout LLVM code
-  svn co http://llvm.org/svn/llvm-project/llvm/branches/release_${LLVM_VERSION_SHORT} "${LLVM_BASE}"
-  cd "${LLVM_BASE}/tools"
-  svn co http://llvm.org/svn/llvm-project/cfe/branches/release_${LLVM_VERSION_SHORT} clang
-  cd "${LLVM_BASE}/projects"
-  svn co http://llvm.org/svn/llvm-project/compiler-rt/branches/release_${LLVM_VERSION_SHORT} compiler-rt
-
-  if [[ ${LLVM_VERSION_SHORT} -gt 37 ]]; then
-    cd "${LLVM_BASE}/projects"
-    svn co http://llvm.org/svn/llvm-project/libcxx/branches/release_${LLVM_VERSION_SHORT} libcxx
-    cd "${LLVM_BASE}/projects"
-    svn co http://llvm.org/svn/llvm-project/libcxxabi/branches/release_${LLVM_VERSION_SHORT} libcxxabi
-  fi
-
-  # Apply existing patches if needed
-  if [ -f "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch" ]; then
-     cd "${LLVM_BASE}"
-     patch -p0 -i "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch"
-  fi
-fi
-
-
-# For memory sanitizer, we have a multi-stage build process
-if [[ "${SANITIZER_BUILD}" == "memory" ]]; then
-   if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
-     echo "Memory sanitizer builds for <= LLVM 3.7 are not supported"
-     exit 1
-   fi
-   # Build uninstrumented compiler
-   mkdir "${SANITIZER_LLVM_UNINSTRUMENTED}"
-   cd "${SANITIZER_LLVM_UNINSTRUMENTED}"
-   cmake -GNinja -DCMAKE_BUILD_TYPE=Release "${LLVM_BASE}"
-   ninja
-
-   # Build instrumented libc/libc++
-   mkdir "${SANITIZER_LLVM_LIBCXX}"
-   cd "${SANITIZER_LLVM_LIBCXX}"
-   cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-    -DLLVM_USE_SANITIZER=MemoryWithOrigins \
-    ${SANITIZER_CMAKE_C_COMPILER} \
-    ${SANITIZER_CMAKE_CXX_COMPILER} \
-    "${LLVM_BASE}"
-   ninja cxx cxxabi
-
-   # Build instrumented clang
-   mkdir "${LLVM_BUILD}"
-   cd "${LLVM_BUILD}"
-   cmake -GNinja \
-      ${SANITIZER_CMAKE_C_COMPILER} \
-      ${SANITIZER_CMAKE_CXX_COMPILER} \
-      -DCMAKE_C_FLAGS="$SANITIZER_C_FLAGS" \
-      -DCMAKE_CXX_FLAGS="$SANITIZER_CXX_FLAGS" \
-      -DCMAKE_BUILD_TYPE=Release \
-      -DLLVM_USE_SANITIZER=MemoryWithOrigins \
-      -DLLVM_ENABLE_LIBCXX=ON \
-      -DCMAKE_EXE_LINKER_FLAGS="$SANITIZER_LD_FLAGS" \
-      -DCMAKE_INSTALL_PREFIX="${LLVM_INSTALL}" \
-      "${LLVM_BASE}"
-  # Build clang as a dependency and install all needed packages
-  ninja clang
-  ninja install-clang install-llvm-config install-llvm-objdump \
-      install-llvm-link install-llvm-ar install-llvm-nm install-llvm-dis \
-      install-clang-headers install-llvm-as installhdrs install-LLVMX86Disassembler \
-      install-LLVMX86AsmParser install-LLVMX86CodeGen install-LLVMSelectionDAG \
-      install-LLVMAsmPrinter install-LLVMX86Desc install-LLVMMCDisassembler \
-      install-LLVMX86Info install-LLVMX86AsmPrinter install-LLVMX86Utils \
-      install-LLVMMCJIT install-LLVMExecutionEngine install-LLVMRuntimeDyld \
-      install-LLVMipo install-LLVMVectorize install-LLVMLinker install-LLVMIRReader \
-      install-LLVMAsmParser install-LLVMCodeGen install-LLVMTarget install-LLVMScalarOpts \
-      install-LLVMInstCombine install-LLVMInstrumentation install-LLVMProfileData \
-      install-LLVMObject install-LLVMMCParser install-LLVMTransformUtils install-LLVMMC \
-      install-LLVMAnalysis install-LLVMBitWriter install-LLVMBitReader install-LLVMCore \
-      install-llvm-symbolizer install-LLVMSupport install-lli not FileCheck
-  cp "${LLVM_BUILD}/bin/FileCheck" "${LLVM_INSTALL}/bin/"
-  cp "${LLVM_BUILD}/bin/not" "${LLVM_INSTALL}/bin/"
-  exit 0
-fi
-
-if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-  # Configure; build; and install
-  mkdir -p "${LLVM_BUILD}"
-  cd "${LLVM_BUILD}"
-
-  # Skip building if already finished
-  if [[ -e "${LLVM_BUILD}/.build_finished" ]]; then
-    exit 0
-  fi
-
-
-  # Configure LLVM
-  if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
-    CONFIG=(--enable-jit --prefix="${LLVM_INSTALL}")
-    if [[ "${ENABLE_OPTIMIZED}" == "1" ]]; then
-      CONFIG+=(--enable-optimized)
-    else
-      CONFIG+=(--disable-optimized)
-    fi
-
-    if [[ "${DISABLE_ASSERTIONS}" == "1" ]]; then
-      CONFIG+=(--disable-assertions)
-    else
-      CONFIG+=(--enable-assertions)
-    fi
-
-    if [[ "${ENABLE_DEBUG}" == "1" ]]; then
-      CONFIG+=(--enable-debug-runtime --enable-debug-symbols)
-    else
-      CONFIG+=(--disable-debug-symbols)
-    fi
-    CC=${CC} CXX=${CXX} CFLAGS="${LLVM_CFLAGS}" CXXFLAGS="${LLVM_CXXFLAGS}" LDFLAGS="${LLVM_LDFLAGS}" "${LLVM_BASE}/configure" "${CONFIG[@]}"
-  else
-    CONFIG=(-DCMAKE_INSTALL_PREFIX="${LLVM_INSTALL}")
-    # cmake build
-    if [[ "${ENABLE_OPTIMIZED}" == "1" && "${ENABLE_DEBUG}" != "1" ]]; then
-      CONFIG+=(-DCMAKE_BUILD_TYPE=Release)
-    fi
-    if [[ "${ENABLE_OPTIMIZED}" == "1" && "${ENABLE_DEBUG}" == "1" ]]; then
-      CONFIG+=(-DCMAKE_BUILD_TYPE=RelWithDebInfo)
-    fi
-    if [[ "${ENABLE_OPTIMIZED}" != "1" && "${ENABLE_DEBUG}" == "1" ]]; then
-      CONFIG+=(-DCMAKE_BUILD_TYPE=Debug)
-    fi
-
-    if [[ "${DISABLE_ASSERTIONS}" == "1" ]]; then
-      CONFIG+=(-DLLVM_ENABLE_ASSERTIONS=Off)
-    else
-      CONFIG+=(-DLLVM_ENABLE_ASSERTIONS=On)
-    fi
-
-    if [[ ! -z "${LLVM_CFLAGS}" ]] ; then
-      CONFIG+=(-DCMAKE_C_FLAGS="$LLVM_CFLAGS")
-    fi
-
-    if [[ ! -z "${LLVM_CXXFLAGS}" ]] ; then
-      CONFIG+=(-DCMAKE_CXX_FLAGS="$LLVM_CXXFLAGS")
-    fi
-
-    if [[ ! -z "${LLVM_LDFLAGS}" ]]; then
-       LDFLAGS="${LLVM_LDFLAGS}"
-    fi
-
-    cmake "${CONFIG[@]}" "${LLVM_BASE}"
-  fi
-
-  make -j$(nproc)
-  make install
-
-  touch "${LLVM_BUILD}/.build_finished"
-
-  cp "${LLVM_BUILD_BIN}/FileCheck" "${LLVM_INSTALL}/bin/"
-  cp "${LLVM_BUILD_BIN}/not" "${LLVM_INSTALL}/bin/"
-
-  if [[ "${KEEP_BUILD}x" != "1x" ]]; then
-    rm -rf "${LLVM_BUILD}"
-  fi
-
-  if [[ "${KEEP_SRC}x" != "1x" ]]; then
-    rm -rf "${LLVM_BASE}"
-  fi
-elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
-  # Use the brew provided package
-  brew install "llvm\@${LLVM_VERSION_MAJOR}"
-else
-  echo "Unhandled TRAVIS_OS_NAME \"${TRAVIS_OS_NAME}\""
-  exit 1
-fi
diff --git a/scripts/build/p-clang-linux-ubuntu-16.04.inc b/scripts/build/p-clang-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..75023628
--- /dev/null
+++ b/scripts/build/p-clang-linux-ubuntu-16.04.inc
@@ -0,0 +1,66 @@
+install_binary_artifact_clang() {
+  local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
+
+  # Check versions: no support for LLVM < 3.5
+  [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]] && [[ "${LLVM_VERSION_MINOR}" -lt 5 ]] && return 1
+
+
+  local version=""
+  [[ "${LLVM_VERSION_MAJOR}" -le 6 ]] && version="-${LLVM_VERSION}"
+  [[ "${LLVM_VERSION_MAJOR}" -ge 7 ]] && version="-${LLVM_VERSION_MAJOR}"
+
+
+  if [[ "${LLVM_VERSION_MAJOR}" -eq 3 && "${LLVM_VERSION_MINOR}" -gt 7 ]]; then
+    # Add certificate
+    apt update -y
+    dependencies=(
+      ca-certificates
+      wget
+    )
+
+    apt -y --no-install-recommends install "${dependencies[@]}"
+    wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add -
+
+    # Add repository
+    echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial${version} main" >> /etc/apt/sources.list
+  fi
+
+  apt update -y
+  dependencies=(
+    "llvm${version}"
+    "clang${version}"
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
+
+setup_artifact_variables_clang() {
+  local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
+  local version=""
+  [[ "${LLVM_VERSION_MAJOR}" -le 6 ]] && version="-${LLVM_VERSION}"
+  [[ "${LLVM_VERSION_MAJOR}" -ge 7 ]] && version="-${LLVM_VERSION_MAJOR}"
+
+  # Only set LLVM_CONFIG if not set yet
+  if [[ -z ${LLVM_CONFIG+x} ]]; then
+    LLVM_CONFIG=$(which "llvm-config${version}")
+  fi
+
+  BITCODE_CC=$(which "clang${version}")
+  BITCODE_CXX=$(which "clang++${version}")
+
+  SANITIZER_C_COMPILER="${BITCODE_CC}"
+  SANITIZER_CXX_COMPILER="${BITCODE_CXX}"
+}
+
+# Check if the binary artifact is installed
+is_installed_clang() {
+    # Check if llvm-config with the right version exists    
+    which "llvm-config-${LLVM_VERSION}"
+}
+
+get_docker_config_id_clang() {
+  return 0
+}
diff --git a/scripts/build/p-clang-osx.inc b/scripts/build/p-clang-osx.inc
new file mode 100644
index 00000000..fde236ca
--- /dev/null
+++ b/scripts/build/p-clang-osx.inc
@@ -0,0 +1,13 @@
+# Package script for LLVM builds OSX
+install_binary_artifact_clang () {
+  # Use the brew provided package
+  LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  brew install "llvm\@${LLVM_VERSION_MAJOR}"
+}
+
+# Check if the binary artifact is installed
+is_installed_clang() {
+    # Check if llvm-config with the right version exists
+    LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+    [[ -f "/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/bin/llvm-config" ]]
+}
diff --git a/scripts/build/p-gtest-linux-ubuntu-16.04.inc b/scripts/build/p-gtest-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..f636d321
--- /dev/null
+++ b/scripts/build/p-gtest-linux-ubuntu-16.04.inc
@@ -0,0 +1,12 @@
+install_build_dependencies_gtest() {
+  apt update -y
+
+  dependencies=(
+    ca-certificates
+    wget
+    unzip
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
\ No newline at end of file
diff --git a/scripts/build/p-gtest-osx.inc b/scripts/build/p-gtest-osx.inc
new file mode 100644
index 00000000..3fe48e06
--- /dev/null
+++ b/scripts/build/p-gtest-osx.inc
@@ -0,0 +1,5 @@
+install_build_dependencies_gtest() {
+  # Install essential dependency
+  # Ignore if already installed
+  brew install wget || /usr/bin/true
+}
diff --git a/scripts/build/p-gtest.inc b/scripts/build/p-gtest.inc
new file mode 100644
index 00000000..d4a2d498
--- /dev/null
+++ b/scripts/build/p-gtest.inc
@@ -0,0 +1,45 @@
+setup_build_variables_gtest() {
+  GTEST_INSTALL_PATH="${BASE}/googletest-release-${GTEST_VERSION}"
+  return 0
+}
+
+download_gtest() {
+  cd "${BASE}" || exit 1
+  wget "https://github.com/google/googletest/archive/release-${GTEST_VERSION}.zip"
+  unzip -o "release-${GTEST_VERSION}.zip"
+  rm "release-${GTEST_VERSION}.zip"
+  touch "${GTEST_INSTALL_PATH}"/.is_installed
+}
+
+build_gtest() {
+  return 0
+}
+
+install_gtest() {
+  return 0
+}
+
+is_installed_gtest() {
+  (
+    setup_build_variables_gtest
+    [[ -f "${GTEST_INSTALL_PATH}"/.is_installed ]]
+  )
+}
+
+get_build_artifacts_gtest() {
+  (
+    setup_build_variables_gtest
+    echo "${GTEST_INSTALL_PATH}"
+  )
+}
+
+setup_artifact_variables_gtest() {
+  setup_build_variables_gtest
+}
+
+get_docker_config_id_gtest() {
+  (
+    setup_build_variables_gtest
+    echo "${GTEST_VERSION}"
+  )
+}
\ No newline at end of file
diff --git a/scripts/build/p-klee-linux-ubuntu-16.04.inc b/scripts/build/p-klee-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..b4ba3f33
--- /dev/null
+++ b/scripts/build/p-klee-linux-ubuntu-16.04.inc
@@ -0,0 +1,21 @@
+install_build_dependencies_klee() {
+  apt update -y
+
+  dependencies=(
+    build-essential
+    cmake
+    python-pip #for lit
+    python-setuptools #for lit
+    python-wheel #for lit
+    zlib1g-dev
+    python3
+  )
+
+  if [[ $(to_bool "${COVERAGE}") -eq 1 ]]; then
+    dependencies+=(lcov curl)
+  fi
+
+  apt -y --no-install-recommends install "${dependencies[@]}"
+
+  pip install lit
+}
\ No newline at end of file
diff --git a/scripts/build/build-travis.sh b/scripts/build/p-klee-osx.inc
index a2287a2e..2aa5c3e8 100755..100644
--- a/scripts/build/build-travis.sh
+++ b/scripts/build/p-klee-osx.inc
@@ -1,11 +1,5 @@
-#!/bin/bash
-# Build/setup all Travis dependencies if needed
-set -e
-if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-  export DOCKER_BUILD_DEPS_ONLY=1
-  "${KLEE_SRC_TRAVIS}/scripts/build/build-docker.sh"
-elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
-  brew install ccache
+# Build dependencies
+install_build_dependencies_klee() {
   set +e
   brew upgrade python               # upgrade to Python 3
   brew install python@2             # install Python 2 (OSX version outdated + pip missing)
@@ -16,10 +10,5 @@ elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
   ln -s "${py2path}" /usr/local/bin/python
   ln -s "${pip2path}" /usr/local/bin/pip
   set -e
-  pip install lit==0.6.0
-  export PATH="/usr/local/opt/ccache/libexec:$PATH"
-  "${KLEE_SRC_TRAVIS}/scripts/build/install-klee-deps.sh"
-else
-  echo "UNKNOWN OS ${TRAVIS_OS_NAME}"
-  exit 1
-fi
+  pip install lit
+}
\ No newline at end of file
diff --git a/scripts/build/p-klee.inc b/scripts/build/p-klee.inc
new file mode 100644
index 00000000..a9982fc0
--- /dev/null
+++ b/scripts/build/p-klee.inc
@@ -0,0 +1,198 @@
+validate_build_config_klee() {
+  return 0
+}
+
+setup_build_variables_klee() {
+  KLEE_SUFFIX="${LLVM_VERSION_SHORT}${SOLVER_SUFFIX}${SANITIZER_SUFFIX}"
+  KLEE_BUILD_DIR="${BASE}/klee_build${KLEE_SUFFIX}"
+  KLEE_SRC="$DIR/../../"
+}
+
+download_klee() {
+  return 0
+}
+
+build_klee() {
+  CMAKE_PREFIX_PATH=("")
+
+  local CMAKE_ARGUMENTS=(
+    -DLLVM_DIR="${LLVM_INSTALL}"
+    -DLLVM_CONFIG_BINARY="${LLVM_CONFIG}"
+    -DLLVMCC="${BITCODE_CC}"
+    -DLLVMCXX="${BITCODE_CXX}"
+    -DGTEST_SRC_DIR="${GTEST_INSTALL_PATH}"
+    -DENABLE_UNIT_TESTS="TRUE"
+    -DENABLE_SYSTEM_TESTS="TRUE"
+    -DLIT_ARGS="-v"
+  )
+
+
+###############################################################################
+# klee-uclibc
+###############################################################################
+  local KLEE_UCLIBC_CONFIGURE_OPTION
+
+  if [ "${UCLIBC_VERSION}" != "0" ]; then
+    CMAKE_ARGUMENTS+=(
+      "-DENABLE_KLEE_UCLIBC=TRUE"
+      "-DKLEE_UCLIBC_PATH=${BASE}/klee-uclibc-${LLVM_VERSION_SHORT}"
+      "-DENABLE_POSIX_RUNTIME=TRUE"
+    )
+  else
+    CMAKE_ARGUMENTS+=(
+      "-DENABLE_KLEE_UCLIBC=FALSE"
+      "-DENABLE_POSIX_RUNTIME=FALSE"
+    )
+  fi
+
+
+
+###############################################################################
+# Handle setting up solver configure flags for KLEE
+###############################################################################
+
+  local KLEE_Z3_CONFIGURE_OPTION=("-DENABLE_SOLVER_Z3=OFF")
+  local KLEE_STP_CONFIGURE_OPTION=("-DENABLE_SOLVER_STP=OFF")
+  local KLEE_METASMT_CONFIGURE_OPTION=("-DENABLE_SOLVER_METASMT=OFF")
+  
+  
+  for solver in "${SELECTED_SOLVERS[@]}"; do
+    echo "Setting CMake configuration option for ${solver}"
+    case "${solver}" in
+    stp)
+      KLEE_STP_CONFIGURE_OPTION=(
+        "-DENABLE_SOLVER_STP=TRUE"
+        "-DSTP_DIR=${STP_INSTALL_PATH}/"
+      )
+      CMAKE_PREFIX_PATH+=("${STP_INSTALL_PATH}")
+      ;;
+    z3)
+      echo "Z3"
+      KLEE_Z3_CONFIGURE_OPTION=(
+        "-DENABLE_SOLVER_Z3=TRUE"
+        "-DZ3_INCLUDE_DIRS=${Z3_INSTALL_PATH}/include"
+        "-DZ3_LIBRARIES=${Z3_INSTALL_PATH}/lib/libz3.so"
+      )
+      ;;
+    metasmt)
+      echo "metaSMT"
+      if [ "X${METASMT_DEFAULT}" == "X" ]; then
+        METASMT_DEFAULT=STP
+      fi
+      KLEE_METASMT_CONFIGURE_OPTION=(
+        -DENABLE_SOLVER_METASMT=TRUE
+        -DmetaSMT_DIR="${METASMT_BUILD_PATH}"
+        -DMETASMT_DEFAULT_BACKEND="${METASMT_DEFAULT}"
+      )
+      ;;
+    *)
+      echo "Unknown solver ${solver}"
+      exit 1
+    esac
+  done
+  
+  CMAKE_ARGUMENTS+=(
+    "${KLEE_Z3_CONFIGURE_OPTION[@]}"
+    "${KLEE_STP_CONFIGURE_OPTION[@]}"
+    "${KLEE_METASMT_CONFIGURE_OPTION[@]}"
+  )
+
+###############################################################################
+# Handle additional configure flags
+###############################################################################
+
+  if [[ $(to_bool "${USE_TCMALLOC}") -eq 1 ]] ; then
+    CMAKE_PREFIX_PATH+=("${TCMALLOC_INSTALL_PATH}")
+    CMAKE_ARGUMENTS+=("-DENABLE_TCMALLOC=TRUE")
+  else
+    CMAKE_ARGUMENTS+=("-DENABLE_TCMALLOC=FALSE")
+  fi
+
+###############################################################################
+# KLEE
+###############################################################################
+
+  if [ "X${DISABLE_ASSERTIONS}" == "X1" ]; then
+    CMAKE_ARGUMENTS+=("-DENABLE_KLEE_ASSERTS=FALSE")
+  else
+    CMAKE_ARGUMENTS+=("-DENABLE_KLEE_ASSERTS=TRUE")
+  fi
+  
+  if [ "X${ENABLE_OPTIMIZED}" == "X1" ]; then
+    CMAKE_ARGUMENTS+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo")
+  else
+    CMAKE_ARGUMENTS+=("-DCMAKE_BUILD_TYPE=Debug")
+  fi
+  
+# TODO: We should support Ninja too
+# Configure KLEE
+
+  local CXX_FLAGS=("")
+  local C_FLAGS=("")
+  local LD_FLAGS=("")
+  
+  if [ "${COVERAGE}" -eq 1 ]; then
+    CXX_FLAGS+=("-fprofile-arcs" "-ftest-coverage")
+    C_FLAGS+=("-fprofile-arcs" "-ftest-coverage")
+    LD_FLAGS+=("-fprofile-arcs" "-ftest-coverage")
+  fi
+
+  if [[ -n "${SANITIZER_BUILD}" ]]; then
+    C_FLAGS+=("${SANITIZER_C_FLAGS[@]}")
+    CXX_FLAGS+=("${SANITIZER_CXX_FLAGS[@]}")
+    LD_FLAGS+=("${SANITIZER_LD_FLAGS[@]}")
+
+    CMAKE_ARGUMENTS+=(
+      "-DCMAKE_C_COMPILER=${SANITIZER_C_COMPILER}"
+      "-DCMAKE_CXX_COMPILER=${SANITIZER_CXX_COMPILER}"
+    )
+  fi
+
+
+
+  mkdir -p "${KLEE_BUILD_DIR}" || return 1
+  cd "${KLEE_BUILD_DIR}"
+
+  {
+    echo "CXXFLAGS=\"${CXX_FLAGS[*]}\" \\"
+    echo "CFLAGS=\"${C_FLAGS[*]}\" \\"
+    echo "LDFLAGS=\"${LD_FLAGS[*]}\" \\"
+
+    if [[ -n "${CMAKE_PREFIX_PATH[*]}" ]]; then
+      cmake_concatenated=$(IFS=: ; echo "${CMAKE_PREFIX_PATH[*]}")
+      echo "CMAKE_PREFIX_PATH=\"${cmake_concatenated}\" \\"
+    fi
+
+    echo "cmake ${CMAKE_ARGUMENTS[*]} \"${KLEE_SRC}\""
+  } > "${KLEE_BUILD_DIR}/.build_command"
+
+  source "${KLEE_BUILD_DIR}/.build_command"
+  make -j$(nproc) || make || return 1
+}
+
+install_klee() {
+  return 0
+}
+
+get_docker_config_id_klee() {
+  (
+    setup_build_variables_klee
+    echo "${KLEE_SUFFIX}"
+  )
+}
+
+get_docker_context_klee() {
+  # KLEE's source code is two levels above this script
+  echo "${DIR}/../../"
+}
+
+get_docker_container_context_klee() {
+  echo "${BASE}/klee_src/"
+}
+
+get_build_artifacts_klee() {
+  (
+    setup_build_variables_klee
+    echo "${KLEE_BUILD_DIR}"
+  )
+}
\ No newline at end of file
diff --git a/scripts/build/p-llvm-linux-ubuntu-16.04.inc b/scripts/build/p-llvm-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..6bfc3105
--- /dev/null
+++ b/scripts/build/p-llvm-linux-ubuntu-16.04.inc
@@ -0,0 +1,98 @@
+# Build dependencies
+install_build_dependencies_llvm() { 
+  apt update -y
+
+  dependencies=(
+    build-essential
+    autoconf
+    automake
+    groff
+    gcc
+    g++
+    python-dev
+    make
+    subversion # To check out code
+    zlib1g-dev
+    cmake
+  )
+  
+  if [[ "${SANITIZERS[*]}" == "memory" ]]; then
+    dependencies+=(ninja-build)
+  fi
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
+
+install_binary_artifact_llvm() {
+  local enable_optimized=$(to_bool "${ENABLE_OPTIMIZED}")
+  local enable_debug=$(to_bool "${ENABLE_DEBUG}")
+  local disable_assertions=$(to_bool "${DISABLE_ASSERTIONS}")
+  local requires_rtti=$(to_bool "${REQUIRES_RTTI}")
+  local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
+
+
+  # No support for LLVM packages with debug information, incompatible if requested otherwise
+  [[ "${enable_debug}" -eq 1 ]] && return 1
+
+  # Packages are build with assertions disabled, incompatible if requested otherwise
+  [[ "${disable_assertions}" -eq 0 ]] && return 1
+
+  # Packages are build with RTTI enabled, incompatible if requested otherwise
+  [[ "${requires_rtti}" -eq 0 ]] && return 1
+
+  # Enable/Disable optimized does not matter
+  
+  # Check versions: no support for LLVM < 3.8
+  if [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]]; then
+    [[ "${LLVM_VERSION_MINOR}" -lt 8 ]] && return 1
+  fi
+  
+  # Add certificate
+  apt update -y
+  dependencies=(
+    ca-certificates
+    wget
+  )
+  apt -y --no-install-recommends install "${dependencies[@]}"
+  wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add -
+  
+  local version=""
+  [[ "${LLVM_VERSION_MAJOR}" -le 6 ]] && version="-${LLVM_VERSION}"
+  [[ "${LLVM_VERSION_MAJOR}" -ge 7 ]] && version="-${LLVM_VERSION_MAJOR}"
+  
+  # Add repository
+  echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial${version} main" >> /etc/apt/sources.list
+  apt update -y
+
+  dependencies=(
+    "llvm${version}"
+    "llvm${version}-dev"
+    "llvm${version}-runtime"
+    "clang${version}"
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
+
+# Check if the binary artifact is installed
+is_installed_llvm() {
+    local lc=""
+    # Check if llvm-config with the right version exists    
+    lc=$(which "llvm-config-${LLVM_VERSION}")
+    
+    [[ -z "${lc}" ]] && return 1
+
+    local rtti
+    rtti="$(${lc} --has-rtti)"
+    local assertion
+    assertion="$(${lc} --assertion-mode)"
+    local build_mode
+    build_mode="$(${lc} --build-mode)"
+
+    # Check requested mode with mode of the found item  
+    [[ $(to_bool "${REQUIRES_RTTI}") -eq $(to_bool "${rtti}") ]] || return 1
+    [[ $(to_bool "${DISABLE_ASSERTIONS}") -ne $(to_bool "${assertion}") ]] || return 1
+}
\ No newline at end of file
diff --git a/scripts/build/p-llvm-linux-ubuntu-18.04.inc b/scripts/build/p-llvm-linux-ubuntu-18.04.inc
new file mode 100644
index 00000000..f83112db
--- /dev/null
+++ b/scripts/build/p-llvm-linux-ubuntu-18.04.inc
@@ -0,0 +1,49 @@
+install_build_dependencies_llvm() { 
+	apt update -y
+
+	dependencies=(
+		build-essential
+
+		autoconf
+		automake
+		groff
+		gcc
+		g++
+		python-dev
+		make
+		subversion # Check out code
+		zlib1g-dev
+	)
+
+	#Install essential dependencies
+	apt -y --no-install-recommends install "${dependencies[@]}"
+}
+
+install_binary_artifact_llvm() {
+  apt update -y
+  
+  dependencies=(
+    "clang-${LLVM_VERSION}"
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
+
+# Check if the binary artifact is installed
+is_installed_llvm() {
+	local lc=""
+	# Check if llvm-config with the right version exists	
+	lc=$(which "llvm-config-${LLVM_VERSION}")
+	
+	local rtti
+	rtti="$(${lc} --has-rtti)"
+	local assertion
+	assertion="$(${lc} --assertion-mode)"
+	local build_mode
+	build_mode="$(${lc} --build-mode)"
+	
+	# Check requested mode with mode of the found item	
+	[[ $(to_bool "${REQUIRES_RTTI}") -eq $(to_bool "${rtti}") ]] || return 1
+	[[ $(to_bool "${DISABLE_ASSERTIONS}") -ne $(to_bool "${assertion}") ]] || return 1
+}
\ No newline at end of file
diff --git a/scripts/build/p-llvm-osx.inc b/scripts/build/p-llvm-osx.inc
new file mode 100644
index 00000000..05e423f3
--- /dev/null
+++ b/scripts/build/p-llvm-osx.inc
@@ -0,0 +1,21 @@
+# Package script for LLVM builds OSX
+install_binary_artifact_llvm () {
+  # Use the brew provided package
+  LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  brew install "llvm\@${LLVM_VERSION_MAJOR}"
+}
+
+# Check if the binary artifact is installed
+is_installed_llvm() {
+    # Check if llvm-config with the right version exists
+    LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+    [[ -f "/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/bin/llvm-config" ]]
+}
+
+setup_artifact_variables_llvm() {
+  LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  LLVM_CONFIG="/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/bin/llvm-config"
+  BITCODE_CC="/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/bin/clang"
+  BITCODE_CXX="/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/bin/clang++"
+  LLVM_INSTALL="/usr/local/opt/llvm@${LLVM_VERSION_MAJOR}/"
+}
diff --git a/scripts/build/p-llvm.inc b/scripts/build/p-llvm.inc
new file mode 100644
index 00000000..4e0740a2
--- /dev/null
+++ b/scripts/build/p-llvm.inc
@@ -0,0 +1,366 @@
+validate_build_config_llvm() {
+    # Check variables that are needed for building 
+    [[ -n "${LLVM_SRC_BASE}" ]] || { echo "LLVM_SRC_BASE not set"; exit 1; }
+    [[ -n "${LLVM_VERSION_SHORT}" ]] || { echo "LLVM_VERSION_SHORT not set"; exit 1; }
+}
+
+setup_build_variables_llvm() {
+    LLVM_SUFFIX=""
+
+    local BuildMode=""
+    local enable_optimized=$(to_bool "${ENABLE_OPTIMIZED}")
+    local enable_debug=$(to_bool "${ENABLE_DEBUG}")
+    local disable_assertions=$(to_bool "${DISABLE_ASSERTIONS}")
+    local requires_rtti=$(to_bool "${REQUIRES_RTTI}")
+
+    if [[ "${enable_optimized}" == "1" ]]; then
+      LLVM_SUFFIX+="_O"
+      BuildMode="Release"
+    else
+      LLVM_SUFFIX+="_NO"
+    fi
+
+    if [[ ("${enable_debug}" == "1") || ("${enable_optimized}" != "1") ]]; then
+      LLVM_SUFFIX+="_D"
+      [ -z "$BuildMode" ] && BuildMode="Debug" || BuildMode="$BuildMode+Debug"
+    else
+      LLVM_SUFFIX+="_ND"
+    fi
+
+    if [[ "${disable_assertions}" == "1" || -z "${disable_assertions}" ]]; then
+      LLVM_SUFFIX+="_NA"
+    else
+      LLVM_SUFFIX+="_A"
+      [ -z "$BuildMode" ] && BuildMode="Asserts" || BuildMode="$BuildMode+Asserts"
+    fi
+
+    if [[ "${requires_rtti}" == "1" ]]; then
+      LLVM_SUFFIX+="_RTTI"
+    fi
+
+    if [[ "${SANITIZER_SUFFIX}x" != "x" ]]; then
+      LLVM_SUFFIX+="${SANITIZER_SUFFIX}"
+    fi
+
+    LLVM_SRC_BASE="${BASE}/llvm-${LLVM_VERSION_SHORT}"
+    LLVM_BUILD="${LLVM_SRC_BASE}-build${LLVM_SUFFIX}"
+    LLVM_INSTALL="${LLVM_SRC_BASE}-install${LLVM_SUFFIX}"
+    LLVM_BIN="${LLVM_INSTALL}/bin"
+    if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
+      LLVM_BUILDMODE="$BuildMode"
+      LLVM_BUILD_BIN="${LLVM_BUILD}/${LLVM_BUILDMODE}/bin"
+    else
+      LLVM_BUILD_BIN="${LLVM_BUILD}/bin"
+    fi
+
+    LLVM_CONFIG="${LLVM_BIN}/llvm-config"
+    BITCODE_CC="${LLVM_BIN}/clang"
+    BITCODE_CXX="${LLVM_BIN}/clang++"
+
+
+    for sanitizer in "${SANITIZERS[@]}"; do
+      [[ -z "${sanitizer}" ]] && continue
+      # Undefined Behaviour Sanitizer
+      if [ "${sanitizer}" == "memory" ]; then
+        SANITIZER_LLVM_UNINSTRUMENTED="${LLVM_BUILD}_uninstrumented"
+        SANITIZER_LLVM_LIBCXX="${LLVM_BUILD}_libcxx"
+
+        SANITIZER_C_COMPILER="${SANITIZER_LLVM_UNINSTRUMENTED}/bin/clang"
+        SANITIZER_CXX_COMPILER="${SANITIZER_LLVM_UNINSTRUMENTED}/bin/clang++"
+        SANITIZER_CMAKE_C_COMPILER=("-DCMAKE_C_COMPILER=${SANITIZER_C_COMPILER}")
+        SANITIZER_CMAKE_CXX_COMPILER=("-DCMAKE_CXX_COMPILER=${SANITIZER_CXX_COMPILER}")
+
+        MSAN_LINK_FLAGS=("-lc++abi" "-Wl,--rpath=${SANITIZER_LLVM_LIBCXX}/lib" "-L${SANITIZER_LLVM_LIBCXX}/lib")
+        MSAN_FLAGS=("${MSAN_LINK_FLAGS[@]}" -nostdinc++
+           -isystem "${SANITIZER_LLVM_LIBCXX}/include"
+           -isystem "${SANITIZER_LLVM_LIBCXX}/include/c++/v1"
+           "-fsanitize=memory"
+           "-fsanitize-memory-track-origins"
+           -w -fno-omit-frame-pointer -g)
+        SANITIZER_CXX_FLAGS+=("${MSAN_FLAGS[@]}" "-stdlib=libc++")
+        SANITIZER_C_FLAGS+=("${MSAN_FLAGS[@]}")
+        SANITIZER_LD_FLAGS+=("${MSAN_LINK_FLAGS[@]}")
+
+        # Use the uninstrumented compiler
+        BITCODE_CC="${SANITIZER_C_COMPILER}"
+        BITCODE_CXX="${SANITIZER_CXX_COMPILER}"
+        # But point to the instrumented llvm-config
+        LLVM_CONFIG="${LLVM_BIN}/llvm-config"
+        continue
+      fi
+      # Setup default sanitizer arguments
+      SANITIZER_C_COMPILER="${LLVM_BIN}/clang"
+      SANITIZER_CXX_COMPILER="${LLVM_BIN}/clang++"
+    done
+}
+
+download_llvm() {
+  # Skip step if we already checked out code
+  [[ -f "${LLVM_SRC_BASE}/.src_checked_out" ]] && return 0
+
+  # Checkout LLVM code
+  svn co "http://llvm.org/svn/llvm-project/llvm/branches/release_${LLVM_VERSION_SHORT}" "${LLVM_SRC_BASE}"
+  cd "${LLVM_SRC_BASE}/tools" || (echo "Directory does not exist"; exit 1)
+  svn co "http://llvm.org/svn/llvm-project/cfe/branches/release_${LLVM_VERSION_SHORT}" clang
+  cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+  svn co "http://llvm.org/svn/llvm-project/compiler-rt/branches/release_${LLVM_VERSION_SHORT}" compiler-rt
+
+  if [[ ${LLVM_VERSION_SHORT} -gt 37 ]]; then
+    cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+    svn co "http://llvm.org/svn/llvm-project/libcxx/branches/release_${LLVM_VERSION_SHORT}" libcxx
+    cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+    svn co "http://llvm.org/svn/llvm-project/libcxxabi/branches/release_${LLVM_VERSION_SHORT}" libcxxabi
+  fi
+
+  # Apply existing patches if needed
+  if [ -f "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch" ]; then
+     cd "${LLVM_SRC_BASE}" || (echo "Directory does not exist"; exit 1)
+     patch -p0 -i "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch"
+  fi
+
+  touch "${LLVM_SRC_BASE}/.src_checked_out" 
+}
+
+build_llvm() {
+    local enable_optimized=$(to_bool "${ENABLE_OPTIMIZED}")
+    local enable_debug=$(to_bool "${ENABLE_DEBUG}")
+    local disable_assertions=$(to_bool "${DISABLE_ASSERTIONS}")
+    local requires_rtti=$(to_bool "${REQUIRES_RTTI}")
+
+    # For memory sanitizer, we have a multi-stage build process
+    if [[ "${SANITIZER_BUILD}" == "memory" ]]; then
+       if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
+         echo "Memory sanitizer builds for <= LLVM 3.7 are not supported"
+         exit 1
+       fi
+       # Build uninstrumented compiler
+       mkdir -p "${SANITIZER_LLVM_UNINSTRUMENTED}"
+       cd "${SANITIZER_LLVM_UNINSTRUMENTED}"
+       cmake -GNinja -DCMAKE_BUILD_TYPE=Release "${LLVM_SRC_BASE}"
+       ninja
+
+       # Build instrumented libc/libc++
+       mkdir -p "${SANITIZER_LLVM_LIBCXX}"
+       cd "${SANITIZER_LLVM_LIBCXX}"
+       cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+        -DLLVM_USE_SANITIZER=MemoryWithOrigins \
+        "${SANITIZER_CMAKE_C_COMPILER}" \
+        "${SANITIZER_CMAKE_CXX_COMPILER}" \
+        "${LLVM_SRC_BASE}"
+       ninja cxx cxxabi
+
+       # Build instrumented clang
+       mkdir -p "${LLVM_BUILD}"
+       cd "${LLVM_BUILD}"
+       C_F="${SANITIZER_C_FLAGS[*]}"
+       CXX_F="${SANITIZER_CXX_FLAGS[*]}"
+       LD_F="${SANITIZER_LD_FLAGS[*]}"
+       cmake -GNinja \
+          "${SANITIZER_CMAKE_C_COMPILER[*]}" \
+          "${SANITIZER_CMAKE_CXX_COMPILER[*]}" \
+          -DCMAKE_C_FLAGS="$C_F" \
+          -DCMAKE_CXX_FLAGS="${CXX_F}" \
+          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+          -DLLVM_ENABLE_ASSERTIONS=On \
+          -DLLVM_USE_SANITIZER=MemoryWithOrigins \
+          -DLLVM_ENABLE_LIBCXX=ON \
+          -DCMAKE_EXE_LINKER_FLAGS="${LD_F}" \
+          -DCMAKE_INSTALL_PREFIX="${LLVM_INSTALL}" \
+          "${LLVM_SRC_BASE}"
+      # Build clang as a dependency and install all needed packages
+      ninja clang
+      return 0
+    fi
+
+  # Configure; build; and install
+  mkdir -p "${LLVM_BUILD}"
+  cd "${LLVM_BUILD}"
+
+  # Skip building if already finished
+  [[ -e "${LLVM_BUILD}/.build_finished" ]] && return 0
+
+
+  # Configure LLVM
+  if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
+    local CONFIG=("--enable-jit" "--prefix=${LLVM_INSTALL}")
+    if [[ "${enable_optimized}" == "1" ]]; then
+      CONFIG+=(--enable-optimized)
+    else
+      CONFIG+=(--disable-optimized)
+    fi
+
+    if [[ "${disable_assertions}" == "1" ]]; then
+      CONFIG+=(--disable-assertions)
+    else
+      CONFIG+=(--enable-assertions)
+    fi
+
+    if [[ "${enable_debug}" == "1" ]]; then
+      CONFIG+=(--enable-debug-runtime --enable-debug-symbols)
+    else
+      CONFIG+=(--disable-debug-symbols)
+    fi
+
+    local variables=()
+    if [[ -n "${CC:-}" ]]; then
+        variables+=("CC=${CC}")
+    fi
+
+    if [[ -n "${CXX:-}" ]]; then
+        variables+=("CXX=${CXX}")
+    fi
+
+    if [[ -n "${LDFLAGS:-}" ]]; then
+        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+    fi
+
+    if [[ -n "${LLVM_CFLAGS:-}" ]]; then
+        variables+=("CFLAGS=${LLVM_CFLAGS}")
+    fi
+
+    if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
+        variables+=("CXXFLAGS=${LLVM_CXXFLAGS}")
+    fi
+
+    if [[ -n "${LLVM_LDFLAGS:-}" ]]; then
+        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+    fi
+    ${variables[@]+"${variables[@]}"} "${LLVM_SRC_BASE}/configure" "${CONFIG[@]}"
+
+  else
+    CONFIG=(
+        "-DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL}"
+        "-LLVM_BUILD_LLVM_DYLIB=TRUE"
+    )
+    # cmake build
+    if [[ "${enable_optimized}" == "1" && "${enable_debug}" != "1" ]]; then
+      CONFIG+=("-DCMAKE_BUILD_TYPE=Release")
+    fi
+    if [[ "${enable_optimized}" == "1" && "${enable_debug}" == "1" ]]; then
+      CONFIG+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo")
+    fi
+    if [[ "${enable_optimized}" != "1" && "${enable_debug}" == "1" ]]; then
+      CONFIG+=("-DCMAKE_BUILD_TYPE=Debug")
+    fi
+
+    if [[ "${disable_assertions}" == "1" ]]; then
+      CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=Off")
+    else
+      CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=On")
+    fi
+
+    if [[ -n "${LLVM_CFLAGS:-}" ]]; then
+      CONFIG+=("-DCMAKE_C_FLAGS=\"$LLVM_CFLAGS\"")
+    fi
+
+    if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
+      CONFIG+=("-DCMAKE_CXX_FLAGS=\"$LLVM_CXXFLAGS\"")
+    fi
+
+    if [[ "${requires_rtti}" -eq 1 ]]; then
+      CONFIG+=("-DLLVM_ENABLE_RTTI=TRUE")
+    fi
+
+    # Remove unneeded targets
+    CONFIG+=(
+       -DLLVM_INCLUDE_EXAMPLES=OFF
+#       -DLLVM_INCLUDE_TESTS=OFF
+#       -DCLANG_INCLUDE_TESTS=OFF
+       -DLLVM_INCLUDE_BENCHMARKS=OFF
+       -DBUILD_SHARED_LIBS=ON
+    )
+
+    local variables=("")
+
+    if [[ -n "${CC:-}" ]]; then
+        variables+=("CC=${CC}")
+    fi
+
+    if [[ -n "${CXX:-}" ]]; then
+        variables+=("CXX=${CXX}")
+    fi
+
+    if [[ -n "${LDFLAGS:-}" ]]; then
+        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+    fi
+
+    if [[ -n "${variables[*]}" ]]; then
+      "${variables[*]}" cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
+    else
+      cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
+    fi
+  fi
+
+  # Linking LLVM can require a lot of memory.
+  # First try multicore - if that doesn't work, try single core
+  (make "-j$(nproc)") || (make) || return 1
+  touch "${LLVM_BUILD}/.build_finished"
+}
+
+install_llvm() {
+  if [[ "${SANITIZER_BUILD}" != "memory" ]]; then
+    cd "${LLVM_BUILD}"
+    make "-j$(nproc)" install
+    cp "${LLVM_BUILD_BIN}/FileCheck" "${LLVM_INSTALL}/bin/"
+    cp "${LLVM_BUILD_BIN}/not" "${LLVM_INSTALL}/bin/"
+  
+    # Remove debug information from binaries
+    strip "${LLVM_INSTALL}/bin/"* || /bin/true
+    strip "${LLVM_INSTALL}/lib/libclang"* || /bin/true
+    strip "${LLVM_INSTALL}/lib/libLTO"* || /bin/true
+  else
+    # Handle memory sanitizer install
+    LLVM_PACKAGES=( \
+      install-clang install-llvm-config install-llvm-objdump
+      install-llvm-link install-llvm-ar install-llvm-nm install-llvm-dis
+      install-clang-headers install-llvm-as
+      install-llvm-symbolizer install-LLVMSupport install-lli not FileCheck )
+  
+    if [[ ${LLVM_VERSION_SHORT} -eq 38 ]]; then
+      LLVM_PACKAGES=("${LLVM_PACKAGES[@]}" installhdrs)
+    else
+      LLVM_PACKAGES=("${LLVM_PACKAGES[@]}" install-llvm-headers)
+    fi
+  
+    ninja "${LLVM_PACKAGES[@]}"
+
+    for i in $(ninja -t targets |grep install-LLVM | cut -d : -f 1); do ninja "$i"; done
+    
+    cp "${LLVM_BUILD}/bin/FileCheck" "${LLVM_INSTALL}/bin/"
+    cp "${LLVM_BUILD}/bin/not" "${LLVM_INSTALL}/bin/"
+  fi
+
+  touch "${LLVM_INSTALL}/.install_finished"
+}
+
+# Check if the binary artifact is installed
+is_installed_llvm() {
+  (
+    setup_build_variables_llvm
+    # Check if the specific llvm-config exists
+    [[ -f "${LLVM_BUILD_BIN}/llvm-config" ]]
+    [[ -f "${LLVM_INSTALL}/.install_finished" ]]
+  ) || return 1
+}
+
+# Returns a unique id for this configuration
+get_docker_config_id_llvm() {
+  (
+    setup_build_variables_llvm
+    echo "${LLVM_VERSION_SHORT}${LLVM_SUFFIX}"
+  )
+}
+
+setup_artifact_variables_llvm() {
+  setup_build_variables_llvm
+}
+
+get_build_artifacts_llvm() {
+  (
+    setup_build_variables_llvm
+    echo "${LLVM_INSTALL}"
+    echo "${LLVM_SRC_BASE}"
+    [[ "${sanitizer}" == "memory" ]] && echo "${SANITIZER_LLVM_UNINSTRUMENTED}"
+    [[ "${sanitizer}" == "memory" ]] && echo "${SANITIZER_LLVM_LIBCXX}"
+  )
+}
\ No newline at end of file
diff --git a/scripts/build/p-metasmt-linux-ubuntu-16.04.inc b/scripts/build/p-metasmt-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..063a5cd3
--- /dev/null
+++ b/scripts/build/p-metasmt-linux-ubuntu-16.04.inc
@@ -0,0 +1,27 @@
+setup_build_variables_metasmt() {
+  return 0
+}
+
+install_build_dependencies_metasmt() {
+  apt update -y
+
+  dependencies=(
+    # libgmp, gperf (required by yices2)
+    gperf
+    libgmp-dev
+
+    build-essential
+    git
+    wget
+    ca-certificates
+    cmake
+    zlib1g-dev
+    bison
+    flex
+    unzip
+    python
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
\ No newline at end of file
diff --git a/scripts/build/p-metasmt.inc b/scripts/build/p-metasmt.inc
new file mode 100644
index 00000000..a0b973a4
--- /dev/null
+++ b/scripts/build/p-metasmt.inc
@@ -0,0 +1,64 @@
+setup_build_variables_metasmt() {
+  METASMT_SRC_PATH="${BASE}/metaSMT-${METASMT_VERSION}"
+  METASMT_BUILD_PATH="${BASE}/metaSMT-${METASMT_VERSION}-build"
+  METASMT_INSTALL_PATH="${BASE}/metaSMT-${METASMT_VERSION}-install"
+  METASMT_DEPS_PATH="${BASE}/metaSMT-${METASMT_VERSION}-deps"
+}
+
+download_metasmt() {
+  # Clone
+  git clone --single-branch --depth 1 https://github.com/hoangmle/metaSMT.git "${METASMT_SRC_PATH}"
+  cd "${METASMT_SRC_PATH}"
+  git submodule update --init
+  # Bootstrap
+  git clone https://github.com/agra-uni-bremen/dependencies.git
+}
+
+build_metasmt() {
+  cd "${METASMT_SRC_PATH}"
+  ./bootstrap.sh -d deps -m RELEASE build -DmetaSMT_ENABLE_TESTS=off \
+    --build stp-git-basic --build boolector-2.2.0 --build minisat-git \
+    --build lingeling-ayv-86bf266-140429 --build yices-2.5.1 --build Z3-4.4.1 \
+    --build cvc4-1.5 \
+    --deps "${METASMT_DEPS_PATH}/" \
+    --install "${METASMT_INSTALL_PATH}/" \
+    -j "$(nproc)" \
+    "${METASMT_BUILD_PATH}"
+
+  # Build
+  cd "${METASMT_BUILD_PATH}"
+  make
+}
+
+install_metasmt() {
+  cd "${METASMT_BUILD_PATH}"
+  make install
+  touch "${METASMT_INSTALL_PATH}"/.is_installed
+}
+
+get_docker_config_id_metasmt() {
+  echo "${METASMT_VERSION}"
+}
+
+# Check if the binary artifact is installed
+is_installed_metasmt() {
+  (
+  setup_build_variables_metasmt
+  [[ -f "${METASMT_INSTALL_PATH}"/.is_installed ]]
+  )
+}
+
+get_docker_config_id_metasmt() {
+  (
+    echo "${METASMT_VERSION}"
+  )
+}
+
+get_build_artifacts_metasmt() {
+  (
+    setup_build_variables_metasmt
+    echo "${METASMT_INSTALL_PATH}/"
+    echo "${METASMT_BUILD_PATH}/"
+    echo "${METASMT_DEPS_PATH}/"
+  )
+}
\ No newline at end of file
diff --git a/scripts/build/p-stp-linux-ubuntu-16.04.inc b/scripts/build/p-stp-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..f4030023
--- /dev/null
+++ b/scripts/build/p-stp-linux-ubuntu-16.04.inc
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Build dependencies
+install_build_dependencies_stp() { 
+  apt update -y
+
+  dependencies=(
+    build-essential
+
+    bison
+    ca-certificates
+    cmake
+    flex
+    git
+    zlib1g-dev
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
\ No newline at end of file
diff --git a/scripts/build/p-stp-osx.inc b/scripts/build/p-stp-osx.inc
new file mode 100644
index 00000000..60214b3c
--- /dev/null
+++ b/scripts/build/p-stp-osx.inc
@@ -0,0 +1,7 @@
+install_build_dependencies_stp() {
+   dependencies=(
+     bison
+     flex
+   )
+   brew install "${dependencies[@]}"
+}
diff --git a/scripts/build/p-stp.inc b/scripts/build/p-stp.inc
new file mode 100644
index 00000000..9bbc90d9
--- /dev/null
+++ b/scripts/build/p-stp.inc
@@ -0,0 +1,113 @@
+#!/bin/bash
+# Build scripts for STP
+
+# Variables that any artifact of this package might depend on
+setup_build_variables_stp() {
+  STP_SUFFIX="${SANITIZER_SUFFIX}"
+
+  MINISAT_BUILD_PATH="${BASE}/minisat-build${STP_SUFFIX}"
+  MINISAT_INSTALL_PATH="${BASE}/minisat-install${STP_SUFFIX}"
+
+  STP_BUILD_PATH="${BASE}/stp-${STP_VERSION}-build${STP_SUFFIX}"
+  STP_INSTALL_PATH="${BASE}/stp-${STP_VERSION}-install${STP_SUFFIX}"
+  stp_url="https://github.com/stp/stp.git"
+
+  return 0
+}
+
+download_stp() {
+  source "${DIR}/common-functions"
+  # Download minisat
+  git_clone_or_update https://github.com/stp/minisat "${BASE}/minisat" "master"
+
+  # Download STP
+  git_clone_or_update "${stp_url}" "${BASE}/stp-${STP_VERSION}" "${STP_VERSION}"
+}
+
+build_stp() {
+  local CFLAGS=""
+  local CXXFLAGS=""
+  local LDFLAGS=""
+  local cmake_general_args=()
+
+  # Check if sanitizers should be used to build stp
+  if [[ "${SANITIZER_SUFFIX}x" != "x" ]]; then
+    CFLAGS="${SANITIZER_C_FLAGS[*]}"
+    CXXFLAGS="${SANITIZER_CXX_FLAGS[*]}"
+    LDFLAGS="${SANITIZER_LD_FLAGS[*]}"
+
+    cmake_general_args=(
+      "-DCMAKE_C_COMPILER=${SANITIZER_C_COMPILER}"
+      "-DCMAKE_CXX_COMPILER=${SANITIZER_CXX_COMPILER}"
+    )
+  fi
+
+  mkdir -p "${MINISAT_BUILD_PATH}"
+  cd "${MINISAT_BUILD_PATH}" || return 1
+
+  local minisat_cmake_args=(
+    ${cmake_general_args[@]+"${cmake_general_args[@]}"}
+    "-DCMAKE_INSTALL_PREFIX=${MINISAT_INSTALL_PATH}"
+  )
+  CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" \
+    cmake "${minisat_cmake_args[@]}" "${BASE}/minisat"
+
+  # Try to build parallel
+  make "-j$(nproc)" || make 
+  make install
+
+  mkdir -p "${STP_BUILD_PATH}"
+  cd "${STP_BUILD_PATH}" || return 1
+
+  local stp_cmake_args=(
+      ${cmake_general_args[@]+"${cmake_general_args[@]}"}
+      # Don't build against boost because that is broken when mixing packaged boost libraries and gcc 4.8
+      "-DNO_BOOST:BOOL=ON"
+      "-DENABLE_PYTHON_INTERFACE:BOOL=OFF"
+      "-DONLY_SIMPLE:BOOL=ON"
+      "-DCMAKE_PREFIX_PATH=${MINISAT_INSTALL_PATH}"
+      "-DCMAKE_INSTALL_PREFIX=${STP_INSTALL_PATH}"
+  )
+
+  CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" \
+  cmake "${stp_cmake_args[@]}" "${BASE}/stp-${STP_VERSION}"
+
+  # Try to build parallel
+  make "-j$(nproc)" || make
+  make install
+  touch "${STP_INSTALL_PATH}/.stp_installed"
+}
+
+install_stp() {
+  return 0
+}
+
+# Check if the binary artifact is installed
+is_installed_stp() {
+  (
+    setup_build_variables_stp
+    [[ -f "${STP_INSTALL_PATH}/.stp_installed" ]]
+  ) || return 1
+}
+
+setup_artifact_variables_stp() {
+  setup_build_variables_stp
+}
+
+get_build_artifacts_stp() {
+  (
+    setup_build_variables_stp
+    echo "${MINISAT_INSTALL_PATH}"
+    echo "${STP_INSTALL_PATH}"
+  )
+}
+
+get_docker_config_id_stp() {
+  (
+    source "${DIR}/common-functions"
+    setup_build_variables_stp
+
+    stp_remote_commit="$(get_git_hash "${stp_url}" "${STP_VERSION}")"
+    echo "${stp_remote_commit}${STP_SUFFIX}"
+  )
+}
\ No newline at end of file
diff --git a/scripts/build/p-tcmalloc-linux-ubuntu-16.04.inc b/scripts/build/p-tcmalloc-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..26bf2da9
--- /dev/null
+++ b/scripts/build/p-tcmalloc-linux-ubuntu-16.04.inc
@@ -0,0 +1,13 @@
+install_build_dependencies_tcmalloc() { 
+  apt update -y
+
+  dependencies=(
+  build-essential
+    ca-certificates
+    cmake
+    git
+    wget
+  )
+
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
\ No newline at end of file
diff --git a/scripts/build/p-tcmalloc.inc b/scripts/build/p-tcmalloc.inc
new file mode 100644
index 00000000..00a97626
--- /dev/null
+++ b/scripts/build/p-tcmalloc.inc
@@ -0,0 +1,49 @@
+setup_build_variables_tcmalloc() {
+  TCMALLOC_SRC_PATH="${BASE}/gperftools-${TCMALLOC_VERSION}"
+  TCMALLOC_INSTALL_PATH="${BASE}/tcmalloc-install-${TCMALLOC_VERSION}"
+  return 0
+}
+
+download_tcmalloc() {
+  # Get tcmalloc release
+  cd "${BASE}"
+  wget "https://github.com/gperftools/gperftools/releases/download/gperftools-${TCMALLOC_VERSION}/gperftools-${TCMALLOC_VERSION}.tar.gz"
+  tar xfz "gperftools-${TCMALLOC_VERSION}.tar.gz"
+}
+
+build_tcmalloc() { 
+  cd "${TCMALLOC_SRC_PATH}"
+  ./configure --disable-dependency-tracking --disable-cpu-profiler \
+    --disable-heap-checker --disable-debugalloc  --enable-minimal \
+    --prefix="${TCMALLOC_INSTALL_PATH}"
+  make "-j$(nproc)" || make
+}
+
+install_tcmalloc() {
+  cd "${TCMALLOC_SRC_PATH}"
+  make install
+  touch "${TCMALLOC_INSTALL_PATH}"/.is_installed
+}
+
+is_installed_tcmalloc() {
+  (
+    setup_build_variables_tcmalloc
+    [[ -f "${TCMALLOC_INSTALL_PATH}"/.is_installed ]]
+  ) || return 1
+}
+
+setup_artifact_variables_tcmalloc() {
+  setup_build_variables_tcmalloc
+}
+
+
+get_docker_config_id_tcmalloc() {
+  echo "${TCMALLOC_VERSION}"
+}
+
+get_build_artifacts_tcmalloc() {
+  (
+    setup_build_variables_tcmalloc
+    echo "${TCMALLOC_INSTALL_PATH}"
+  )
+}
\ No newline at end of file
diff --git a/scripts/build/p-uclibc-linux-ubuntu-16.04.inc b/scripts/build/p-uclibc-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..36bdce58
--- /dev/null
+++ b/scripts/build/p-uclibc-linux-ubuntu-16.04.inc
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Build dependencies
+install_build_dependencies_uclibc() { 
+  apt update -y
+
+  dependencies=(
+    build-essential
+    ca-certificates
+    git
+    python
+    libncurses5-dev
+    wget
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
\ No newline at end of file
diff --git a/scripts/build/p-uclibc.inc b/scripts/build/p-uclibc.inc
new file mode 100644
index 00000000..95af9751
--- /dev/null
+++ b/scripts/build/p-uclibc.inc
@@ -0,0 +1,49 @@
+# Build scripts for uclibc
+setup_build_variables_uclibc() {
+  UCLIBC_PATH="${BASE}/klee-uclibc-${LLVM_VERSION_SHORT}"
+  uclibc_url="https://github.com/klee/klee-uclibc.git"
+}
+
+download_uclibc() {
+  source "${DIR}/common-functions"
+  git_clone_or_update "${uclibc_url}" "${UCLIBC_PATH}" "${UCLIBC_VERSION}"
+}
+
+build_uclibc() { 
+  cd "${UCLIBC_PATH}" || return 1
+  ./configure --make-llvm-lib --with-cc "${BITCODE_CC}" --with-llvm-config "${LLVM_CONFIG}"
+  make || return 1
+  touch .is_installed
+}
+
+install_uclibc() {
+  return 0  
+}
+
+# Check if the binary artifact is installed
+is_installed_uclibc() {
+  (
+    setup_build_variables_uclibc
+    [[ -f "${UCLIBC_PATH}"/.is_installed ]]
+  ) || return 1
+}
+
+get_docker_config_id_uclibc() {
+  (
+    source "${DIR}/common-functions"
+    setup_build_variables_uclibc
+    uclibc_remote_commit="$(get_git_hash "${uclibc_url}" "${UCLIBC_VERSION}")"
+    echo "${uclibc_remote_commit}_${LLVM_VERSION_SHORT}"
+  )
+}
+
+get_build_artifacts_uclibc() {
+  (
+    setup_build_variables_uclibc
+    echo "${UCLIBC_PATH}"
+  )
+}
+
+setup_artifact_variables_uclibc() {
+  setup_build_variables_uclibc
+}
\ No newline at end of file
diff --git a/scripts/build/p-z3-linux-ubuntu-16.04.inc b/scripts/build/p-z3-linux-ubuntu-16.04.inc
new file mode 100644
index 00000000..2f5e4086
--- /dev/null
+++ b/scripts/build/p-z3-linux-ubuntu-16.04.inc
@@ -0,0 +1,16 @@
+# Build dependencies Z3
+install_build_dependencies_z3() { 
+  apt update -y
+
+  dependencies=(
+    build-essential
+
+	python
+    git
+    wget
+    ca-certificates
+  )
+
+  #Install essential dependencies
+  apt -y --no-install-recommends install "${dependencies[@]}"
+}
\ No newline at end of file
diff --git a/scripts/build/p-z3-osx.inc b/scripts/build/p-z3-osx.inc
new file mode 100644
index 00000000..bce11aab
--- /dev/null
+++ b/scripts/build/p-z3-osx.inc
@@ -0,0 +1,13 @@
+install_binary_artifact_z3 () {
+  set +e
+  brew install python@2
+  if [[ "X$?" != "X0" ]]; then
+     brew link --overwrite python@2
+  fi
+  set -e
+  brew install z3
+}
+
+is_installed_z3() {
+    [[ -f "/usr/local/opt/z3/bin/z3" ]]
+}
\ No newline at end of file
diff --git a/scripts/build/p-z3.inc b/scripts/build/p-z3.inc
new file mode 100644
index 00000000..f6db455b
--- /dev/null
+++ b/scripts/build/p-z3.inc
@@ -0,0 +1,68 @@
+setup_build_variables_z3() {
+  Z3_SUFFIX="${SANITIZER_SUFFIX}"
+  Z3_SRC_PATH="${BASE}/z3-${Z3_VERSION}"
+  Z3_INSTALL_PATH="${BASE}/z3-${Z3_VERSION}-install${Z3_SUFFIX}"
+}
+
+download_z3() {
+  mkdir -p "${Z3_SRC_PATH}"
+  cd "${Z3_SRC_PATH}"
+  wget -qO- https://github.com/Z3Prover/z3/archive/z3-${Z3_VERSION}.tar.gz | tar xz --strip-components=1
+}
+
+build_z3() {
+  local CFLAGS=""
+  local CXXFLAGS=""
+  local LDFLAGS=""
+  local CC=""
+  local CXX=""
+  
+  # Check if sanitizers should be used to build z3
+  if [[ "${SANITIZER_SUFFIX}x" != "x" ]]; then
+    CFLAGS="${SANITIZER_C_FLAGS[*]}"
+    CXXFLAGS="${SANITIZER_CXX_FLAGS[*]}"
+    LDFLAGS="${SANITIZER_LD_FLAGS[*]}"
+    
+    CC="${SANITIZER_C_COMPILER}"
+    CXX="${SANITIZER_CXX_COMPILER}"
+  fi
+  CFLAGS="${CFLAGS}" \
+  CXXFLAGS="${CXXFLAGS}" \
+  LDFLAGS="${LDFLAGS}" \
+  CC="${CC}" \
+  CXX="${CXX}" \
+  python scripts/mk_make.py --prefix "${Z3_INSTALL_PATH}" -b "build${Z3_SUFFIX}"
+  cd "build${Z3_SUFFIX}"
+  make -j$(nproc) || make
+}
+
+install_z3() {
+  cd "${Z3_SRC_PATH}/build${Z3_SUFFIX}"
+  make install
+  touch "${Z3_INSTALL_PATH}"/.is_installed
+}
+
+is_installed_z3() {
+  (
+    setup_build_variables_z3
+    [[ -f "${Z3_INSTALL_PATH}"/.is_installed ]]
+  ) || return 1
+}
+
+get_build_artifacts_z3() {
+  (
+    setup_build_variables_z3
+    echo "${Z3_INSTALL_PATH}"
+  )
+}
+
+setup_artifact_variables_z3() {
+  setup_build_variables_z3
+}
+
+get_docker_config_id_z3() {
+  (
+    setup_build_variables_z3
+    echo "${Z3_VERSION}${Z3_SUFFIX}"
+  )
+}
diff --git a/scripts/build/patches/llvm40.patch b/scripts/build/patches/llvm40.patch
new file mode 100644
index 00000000..6cc9fe41
--- /dev/null
+++ b/scripts/build/patches/llvm40.patch
@@ -0,0 +1,77 @@
+--- ./projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc  2018-12-20 22:32:09.636508226 +0000
++++ ../llvm-40-copy/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc  2018-12-20 22:36:10.752698342 +0000
+@@ -607,8 +607,7 @@ uptr internal_prctl(int option, uptr arg
+ }
+ #endif
+
+-uptr internal_sigaltstack(const struct sigaltstack *ss,
+-                         struct sigaltstack *oss) {
++uptr internal_sigaltstack(const void *ss, void *oss) {
+   return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
+ }
+
+--- ./projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h 2018-12-20 22:32:10.020508531 +0000
++++ ../llvm-40-copy/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.h 2018-12-20 22:36:10.752698342 +0000
+@@ -21,7 +21,6 @@
+ #include "sanitizer_platform_limits_posix.h"
+
+ struct link_map;  // Opaque type returned by dlopen().
+-struct sigaltstack;
+
+ namespace __sanitizer {
+ // Dirent structure for getdents(). Note that this structure is different from
+@@ -30,8 +29,7 @@ struct linux_dirent;
+
+ // Syscall wrappers.
+ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
+-uptr internal_sigaltstack(const struct sigaltstack* ss,
+-                          struct sigaltstack* oss);
++uptr internal_sigaltstack(const void* ss, void* oss);
+ uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
+     __sanitizer_sigset_t *oldset);
+
+--- ./projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc 2018-12-20 22:32:09.456508085 +0000
++++ ../llvm-40-copy/projects/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc 2018-12-20 22:36:10.756698345 +0000
+@@ -275,7 +275,7 @@ static int TracerThread(void* argument)
+
+   // Alternate stack for signal handling.
+   InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize);
+-  struct sigaltstack handler_stack;
++  stack_t handler_stack;
+   internal_memset(&handler_stack, 0, sizeof(handler_stack));
+   handler_stack.ss_sp = handler_stack_memory.data();
+   handler_stack.ss_size = kHandlerStackSize;
+--- ./projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc  2018-12-20 22:32:15.780513072 +0000
++++ ../llvm-40-copy/projects/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc  2018-12-20 22:36:10.756698345 +0000
+@@ -289,7 +289,7 @@ void InitializePlatform() {
+ int ExtractResolvFDs(void *state, int *fds, int nfd) {
+ #if SANITIZER_LINUX && !SANITIZER_ANDROID
+   int cnt = 0;
+-  __res_state *statp = (__res_state*)state;
++  struct __res_state *statp = (struct __res_state*)state;
+   for (int i = 0; i < MAXNS && cnt < nfd; i++) {
+     if (statp->_u._ext.nsaddrs[i] && statp->_u._ext.nssocks[i] != -1)
+       fds[cnt++] = statp->_u._ext.nssocks[i];
+diff -rup ./projects/libcxx/include/__locale ../llvm-40-copy/projects/libcxx/include/__locale
+--- ./projects/libcxx/include/__locale  2018-12-20 22:33:14.484559356 +0000
++++ ../llvm-40-copy/projects/libcxx/include/__locale  2018-12-20 22:34:34.432622394 +0000
+@@ -34,7 +34,7 @@
+ # include <support/solaris/xlocale.h>
+ #elif defined(_NEWLIB_VERSION)
+ # include <support/newlib/xlocale.h>
+-#elif (defined(__GLIBC__) || defined(__APPLE__)      || defined(__FreeBSD__) \
++#elif (defined(__APPLE__)      || defined(__FreeBSD__) \
+     || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
+ # include <xlocale.h>
+ #elif defined(_LIBCPP_HAS_MUSL_LIBC)
+--- ./projects/compiler-rt/lib/esan/esan_sideline_linux.cpp  2018-12-20 22:32:12.368510380 +0000
++++ ../llvm-40-copy/projects/compiler-rt/lib/esan/esan_sideline_linux.cpp 2018-12-21 09:15:03.721823179 +0000
+@@ -70,7 +70,7 @@ int SidelineThread::runSideline(void *Ar
+
+   // Set up a signal handler on an alternate stack for safety.
+   InternalScopedBuffer<char> StackMap(SigAltStackSize);
+-  struct sigaltstack SigAltStack;
++  stack_t SigAltStack;
+   SigAltStack.ss_sp = StackMap.data();
+   SigAltStack.ss_size = SigAltStackSize;
+   SigAltStack.ss_flags = 0;
diff --git a/scripts/build/run-coverage.sh b/scripts/build/run-coverage.sh
deleted file mode 100755
index ceba8216..00000000
--- a/scripts/build/run-coverage.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# We are going to build docker containers
-export DOCKER_BUILD=1
-
-# All scripts are located relative to this one
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-if [[ "a$COVERAGE" != "a1" ]]; then
-  exit 0
-fi
-
-function upload_coverage() {
-  file=$1
-  tags=$2
-  ci_env=$(bash <(curl -s https://codecov.io/env))
-  docker run ${ci_env} -ti ${REPOSITORY}/klee:${LLVM_VERSION_SHORT}${LLVM_SUFFIX}${SOLVER_SUFFIX}${DEPS_SUFFIX} /bin/bash -c "cd /home/klee/klee_src && bash <(curl -s https://codecov.io/bash) -X gcov -y /home/klee/klee_src/.codecov.yml -f /home/klee/klee_build/coverage_all.info.${file} -F $tags"
-}
-
-# FIXME Enable separated coverage tags again
-upload_coverage systemtests systemtests_unittests
-upload_coverage unittests systemtests_unittests
diff --git a/scripts/build/run-tests.sh b/scripts/build/run-tests.sh
new file mode 100755
index 00000000..f39dcad8
--- /dev/null
+++ b/scripts/build/run-tests.sh
@@ -0,0 +1,153 @@
+#!/bin/bash
+set -e
+set -u
+DIR="$(cd "$(dirname "$0")" && pwd)"
+
+
+coverage_setup() {
+  local build_dir="$1"
+  # Zero coverage for any file, e.g. previous tests
+  lcov -q --directory "${build_dir}" --no-external --zerocounters
+  # Create a baseline by capturing any file used for compilation, no execution yet
+  lcov -q --rc lcov_branch_coverage=1 --directory "${build_dir}" --base-directory="${KLEE_SRC}" --no-external --capture --initial --output-file coverage_base.info
+  lcov -q --rc lcov_branch_coverage=1 --remove coverage_base.info 'test/*' --output-file coverage_base.info
+  lcov -q --rc lcov_branch_coverage=1 --remove coverage_base.info 'unittests/*' --output-file coverage_base.info
+}
+
+coverage_update() {
+  tags="$2"
+  codecov_suffix=(${tags// /})
+  build_dir="$1"
+  # Create report
+  # (NOTE: "--rc lcov_branch_coverage=1" needs to be added in all calls, otherwise branch coverage gets dropped)
+  lcov -q --rc lcov_branch_coverage=1 --directory "${build_dir}" --base-directory="${KLEE_SRC}" --no-external --capture --output-file coverage.info
+  # Exclude uninteresting coverage goals (LLVM, googletest, and KLEE system and unit tests)
+  lcov -q --rc lcov_branch_coverage=1 --remove coverage.info 'test/*' --output-file coverage.info
+  lcov -q --rc lcov_branch_coverage=1 --remove coverage.info 'unittests/*' --output-file coverage.info
+  # Combine baseline and measured coverage
+  lcov -q --rc lcov_branch_coverage=1 -a coverage_base.info -a coverage.info -o coverage_all.info."${codecov_suffix}"
+  # Debug info
+  lcov -q --rc lcov_branch_coverage=1 --list coverage_all.info."${codecov_suffix}"
+}
+
+run_tests() {
+  build_dir="$1"
+  KLEE_SRC="$(cd "${DIR}"/../../ && pwd)"
+
+  # TODO change to pinpoint specific directory
+  cd "${build_dir}"
+
+  ###############################################################################
+  # Unit tests
+  ###############################################################################
+  # Prepare coverage information if COVERAGE is set
+  if [ "${COVERAGE}" -eq 1 ]; then
+    coverage_setup "${build_dir}"
+  fi
+  make unittests
+  
+  # Generate and upload coverage if COVERAGE is set
+  if [ "${COVERAGE}" -eq 1 ]; then
+    coverage_update "${build_dir}" "unittests"
+  fi
+
+  ###############################################################################
+  # lit tests
+  ###############################################################################
+  if [ "${COVERAGE}" -eq 1 ]; then
+    coverage_setup "${build_dir}"
+  fi
+  make systemtests || return 1
+  
+  # If metaSMT is the only solver, then rerun lit tests with non-default metaSMT backends
+  if [ "X${SOLVERS}" == "XmetaSMT" ]; then
+    available_metasmt_backends="btor stp z3 yices2 cvc4"
+    for backend in $available_metasmt_backends; do
+      if [ "X${METASMT_DEFAULT}" != "X$backend" ]; then
+        if [ "$backend" == "cvc4" ]; then
+          for num in {1..5}; do sleep 120; echo 'Keep Travis alive'; done &
+        fi
+        lit -v --param klee_opts=-metasmt-backend="$backend" --param kleaver_opts=-metasmt-backend="$backend" test/
+      fi
+    done
+  fi
+  
+  # Generate and upload coverage if COVERAGE is set
+  if [ "${COVERAGE}" -eq 1 ]; then
+    coverage_update "${build_dir}" "systemtests"
+  fi
+}
+
+
+
+function upload_coverage() {
+  file="$1"
+  tags="$2"
+  cd /home/klee/klee_src
+  bash <(curl -s https://codecov.io/bash) -X gcov -R /tmp/klee_src/ -y .codecov.yml -f /home/klee/klee_build/coverage_all.info."${file}" -F "$tags"
+}
+
+function run_docker() {
+ docker_arguments=(docker run -u root --cap-add SYS_PTRACE -ti)
+ script_arguments=("--debug" '"/tmp/klee_build"*')
+ if [[ "${COVERAGE}" -eq 1 ]]; then
+   script_arguments+=("--coverage")
+ fi
+ 
+ if [[ "${UPLOAD_COVERAGE}" -eq 1 ]]; then
+   docker_arguments+=($(bash <(curl -s https://codecov.io/env)))
+   script_arguments+=("--upload-coverage")
+ fi
+
+ # Run the image that was build last with extended capabilities to allow tracing tests
+ "${docker_arguments[@]}" "$(docker images -q | head -n 1)" /bin/bash -i -c "ulimit -s 16384; source /home/klee/.bashrc; export; /tmp/klee_src/scripts/build/run-tests.sh ${script_arguments[*]}"
+}
+
+main() {
+  local NAME
+  NAME=$(basename "${0}")
+  local RUN_DOCKER=0
+  local COVERAGE=0
+  local UPLOAD_COVERAGE=0
+  local directory=""
+
+  for i in "$@" ;do
+  case $i in
+    --debug)
+      set -x
+    ;;
+    --run-docker)
+    RUN_DOCKER=1
+    ;;
+    --coverage)
+    COVERAGE=1
+    ;;
+    --upload-coverage)
+    UPLOAD_COVERAGE=1
+    ;;
+    -*)
+      echo "${NAME}: unknown argument: $i"
+      exit 1
+    ;;
+    *)
+    directory="${i}"
+    ;;
+  esac
+  done
+
+
+  if [[ "${RUN_DOCKER}" -eq 1 ]]; then
+    run_docker "${COVERAGE}"
+    return 0
+  fi
+
+  run_tests "${directory}"
+  
+  # FIXME Enable separated coverage tags again
+  if [[ "${UPLOAD_COVERAGE}" -eq 1 ]]; then
+    upload_coverage systemtests systemtests_unittests
+    upload_coverage unittests systemtests_unittests
+  fi
+ }
+
+main "$@"
\ No newline at end of file
diff --git a/scripts/build/solver-metasmt.sh b/scripts/build/solver-metasmt.sh
deleted file mode 100755
index d8626149..00000000
--- a/scripts/build/solver-metasmt.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash -x
-set -e
-
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-: ${METASMT_VERSION?"METASMT_VERSION not specified"}
-
-# Get Z3, libgmp, gperf (required by yices2)
-apt update
-apt -y --no-install-recommends install gperf libgmp-dev
-apt clean
-rm -rf /var/lib/apt/lists/*
-
-# Clone
-git clone --single-branch --depth 1 https://github.com/hoangmle/metaSMT.git "${BASE}/metaSMT"
-cd "${BASE}/metaSMT"
-git submodule update --init
-
-if [ "X${IS_SANITIZED_BUILD}" != "X0" ]; then
-  echo "Error: Requested Sanitized build but sanitized build of metaSMT is not implemented"
-  exit 1
-fi
-
-# Bootstrap
-git clone https://github.com/agra-uni-bremen/dependencies.git
-./bootstrap.sh -d deps -m RELEASE build -DmetaSMT_ENABLE_TESTS=off \
-  --build stp-git-basic --build boolector-2.2.0 --build minisat-git \
-  --build lingeling-ayv-86bf266-140429 --build yices-2.5.1 --build Z3-4.4.1 \
-  --build cvc4-1.5
-
-# Build
-make -C build install
-
-# Cleanup
-if [[ "${STORAGE_SPACE_OPTIMIZED}x" == "1x" ]]; then
-  rm -rf deps/build
-  rm -rf deps/cache
-fi
diff --git a/scripts/build/solver-stp.sh b/scripts/build/solver-stp.sh
deleted file mode 100755
index 2e65ca30..00000000
--- a/scripts/build/solver-stp.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash -x
-
-# TODO: For OSX we can prepare bottled formulas for STP and minisat
-
-# Make sure we exit if there is a failure
-set -e
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-cd ${BASE}
-if [ "x${STP_VERSION}" != "x" ]; then
-  # Build minisat
-  git_clone_or_update https://github.com/stp/minisat "${BASE}/minisat"
-  mkdir -p "${BASE}/minisat/build"
-  cd "${BASE}/minisat/build"
-  MINISAT_DIR="$(pwd)"
-  if [[ "$TRAVIS_OS_NAME" == "linux" || "$TRAVIS_OS_NAME" == "osx" ]]; then
-    CFLAGS="${SANITIZER_C_FLAGS}" \
-    CXXFLAGS="${SANITIZER_CXX_FLAGS}" \
-    LDFLAGS="${SANITIZER_LD_FLAGS}" \
-    cmake -DCMAKE_INSTALL_PREFIX="${BASE}/minisat-install" \
-      ${SANITIZER_CMAKE_C_COMPILER} \
-      ${SANITIZER_CMAKE_CXX_COMPILER} \
-      "${BASE}/minisat"
-  else
-    echo "Unhandled TRAVIS_OS_NAME \"${TRAVIS_OS_NAME}\""
-    exit 1
-  fi
-  make
-  make install
-
-  # Build STP
-  git_clone_or_update git://github.com/stp/stp.git "${BASE}/stp-${STP_VERSION}" ${STP_VERSION}
-  mkdir -p "${BASE}/stp-${STP_VERSION}-build"
-  cd "${BASE}/stp-${STP_VERSION}-build"
-
-  STP_CMAKE_FLAGS=( \
-     "-DENABLE_PYTHON_INTERFACE:BOOL=OFF" \
-     -DNO_BOOST:BOOL=ON \
-     -DENABLE_PYTHON_INTERFACE:BOOL=OFF \
-     ${SANITIZER_CMAKE_C_COMPILER} \
-     ${SANITIZER_CMAKE_CXX_COMPILER} \
-  )
-  # Disabling building of shared libs is a workaround.
-  # Don't build against boost because that is broken when mixing packaged boost libraries and gcc 4.8
-  CFLAGS="${SANITIZER_C_FLAGS}" \
-  CXXFLAGS="${SANITIZER_CXX_FLAGS}" \
-  LDFLAGS="${SANITIZER_LD_FLAGS}" \
-  cmake ${STP_CMAKE_FLAGS} \
-        -DCMAKE_PREFIX_PATH="${BASE}/minisat-install" "${BASE}/stp-${STP_VERSION}" \
-        -DCMAKE_INSTALL_PREFIX="${BASE}/stp-${STP_VERSION}-install"
-  make
-  make install
-else
-  echo "No STP_VERSION given or empty"
-  exit 1
-fi
diff --git a/scripts/build/solver-z3.sh b/scripts/build/solver-z3.sh
deleted file mode 100755
index c6c3381d..00000000
--- a/scripts/build/solver-z3.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash -x
-
-# Make sure we exit if there is a failure
-set -e
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-if [[ -z "${Z3_VERSION}" ]] ; then
-  echo "Z3_VERSION is not defined"
-  exit 1
-fi
-
-if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-  mkdir -p "${BASE}/z3-${Z3_VERSION}"
-  cd "${BASE}/z3-${Z3_VERSION}"
-  wget -qO- https://github.com/Z3Prover/z3/archive/z3-${Z3_VERSION}.tar.gz | tar xz --strip-components=1
-  LDFLAGS="${SANITIZER_LD_FLAGS}" \
-  CXXFLAGS="${SANITIZER_CXX_FLAGS}" \
-  python scripts/mk_make.py --prefix "${BASE}/z3-${Z3_VERSION}-install"
-  cd build
-  make -j$(nproc)
-  make install
-elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
-  set +e
-  brew install python@2
-  if [[ "X$?" != "X0" ]]; then
-     brew link --overwrite python@2
-  fi
-  set -e
-  brew install z3
-else
-  echo "Unhandled TRAVIS_OS_NAME \"${TRAVIS_OS_NAME}\""
-  exit 1
-fi
diff --git a/scripts/build/solvers.sh b/scripts/build/solvers.sh
deleted file mode 100755
index 71ad0c2d..00000000
--- a/scripts/build/solvers.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash -x
-# Make sure we exit if there is a failure
-set -e
-
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-: ${SOLVERS?"Solvers must be specified"}
-SOLVER_LIST=$(echo "${SOLVERS}" | sed 's/:/ /g')
-
-for solver in ${SOLVER_LIST}; do
-  echo "Getting solver ${solver}"
-  case ${solver} in
-  STP)
-    echo "STP"
-    "${DIR}/solver-stp.sh"
-    ;;
-  Z3)
-    echo "Z3"
-    "${DIR}/solver-z3.sh"
-    ;;
-  metaSMT)
-    echo "metaSMT"
-    "${DIR}/solver-metasmt.sh"
-    ;;
-  *)
-    echo "Unknown solver ${solver}"
-    exit 1
-  esac
-done
diff --git a/scripts/build/tcmalloc.sh b/scripts/build/tcmalloc.sh
deleted file mode 100755
index ea5596d0..00000000
--- a/scripts/build/tcmalloc.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash -x
-set -ev
-
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-  # Get tcmalloc release
-  if [[ ! -e "${BASE}/gperftools-${TCMALLOC_VERSION}" ]]; then
-    cd "${BASE}"
-    wget "https://github.com/gperftools/gperftools/releases/download/gperftools-${TCMALLOC_VERSION}/gperftools-${TCMALLOC_VERSION}.tar.gz"
-    tar xfz "gperftools-${TCMALLOC_VERSION}.tar.gz"
-  fi
-  cd "${BASE}/gperftools-${TCMALLOC_VERSION}"
-  ./configure --disable-dependency-tracking --disable-cpu-profiler \
-    --disable-heap-checker --disable-debugalloc  --enable-minimal \
-    --prefix="${BASE}/tcmalloc-install"
-  make
-  make install
-  if [[ "${KEEP_BUILD}x" != "1x" ]]; then
-    rm -rf "${BASE}/gperftools-${TCMALLOC_VERSION}"
-  fi
-
-  if [[ "${KEEP_SRC}x" != "1x" ]]; then
-    rm -f "${BASE}/gperftools-${TCMALLOC_VERSION}.tar.gz"
-  fi
-elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
-  if [ ${USE_TCMALLOC:-0} -eq 1 ] ; then
-    echo "Error: Requested to install TCMalloc on macOS, which is not supported"
-    exit 1
-  fi
-else
-  echo "Unhandled TRAVIS_OS_NAME \"${TRAVIS_OS_NAME}\""
-  exit 1
-fi
diff --git a/scripts/build/testing-utils.sh b/scripts/build/testing-utils.sh
deleted file mode 100755
index 8a855291..00000000
--- a/scripts/build/testing-utils.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash -x
-# Make sure we exit if there is a failure
-set -e
-
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-# The New CMake build system just needs the GTest sources regardless
-# of LLVM version.
-cd "${BASE}"
-
-wget https://github.com/google/googletest/archive/release-${GTEST_VERSION}.zip
-unzip -o release-${GTEST_VERSION}.zip
-rm release-${GTEST_VERSION}.zip
diff --git a/scripts/build/uclibc.sh b/scripts/build/uclibc.sh
deleted file mode 100755
index 3440bedb..00000000
--- a/scripts/build/uclibc.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash -x
-# Build the uclibc library
-# Make sure we exit if there is a failure
-set -e
-DIR="$(cd "$(dirname "$0")" && pwd)"
-source "${DIR}/common-defaults.sh"
-
-if [[ -z "${KLEE_UCLIBC}" ]]; then
-  echo "KLEE_UCLIBC must be specified: 0 or branch/tag"
-  exit 1
-fi
-
-###############################################################################
-# Handling LLVM configuration
-###############################################################################
-if [[ "$TRAVIS_OS_NAME" = "linux"  ||  "$TRAVIS_OS_NAME" = "osx" ]] ; then
-  LLVM_CONFIG="${LLVM_BIN}/llvm-config"
-  KLEE_CC="${LLVM_BIN}/clang"
-  KLEE_CXX="${LLVM_BIN}/clang++"
-else
-  echo "Unhandled TRAVIS_OS_NAME \"${TRAVIS_OS_NAME}\""
-  exit 1
-fi
-
-###############################################################################
-# klee-uclibc
-###############################################################################
-if [ "${KLEE_UCLIBC}" != "0" ]; then
-  if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then
-    echo "UCLibc is not supported Mac OSX"
-    exit 1
-  fi
-  git_clone_or_update git://github.com/klee/klee-uclibc.git "${BASE}/klee-uclibc-${LLVM_VERSION_SHORT}" "${KLEE_UCLIBC}"
-  cd "${BASE}/klee-uclibc-${LLVM_VERSION_SHORT}"
-  ./configure --make-llvm-lib --with-cc ${KLEE_CC} --with-llvm-config ${LLVM_CONFIG}
-  make
-fi
diff --git a/scripts/build/v-clang.inc b/scripts/build/v-clang.inc
new file mode 100644
index 00000000..16036f22
--- /dev/null
+++ b/scripts/build/v-clang.inc
@@ -0,0 +1,15 @@
+required_variables_clang=(
+  "LLVM_VERSION"
+)
+
+artifact_dependency_clang=("sanitizer")
+
+setup_variables_clang() {
+  LLVM_VERSION_SHORT="${LLVM_VERSION/./}"
+}
+
+export_variables_clang=(
+  "LLVM_CONFIG"
+  "BITCODE_CC"
+  "BITCODE_CXX"
+)
\ No newline at end of file
diff --git a/scripts/build/v-gtest.inc b/scripts/build/v-gtest.inc
new file mode 100644
index 00000000..a48654f0
--- /dev/null
+++ b/scripts/build/v-gtest.inc
@@ -0,0 +1,7 @@
+# Build information for gtest
+required_variables_gtest=(
+  "GTEST_VERSION"
+)
+
+# Artifacts gtest depends on
+artifact_dependency_gtest=("")
\ No newline at end of file
diff --git a/scripts/build/v-klee.inc b/scripts/build/v-klee.inc
new file mode 100644
index 00000000..d90892f4
--- /dev/null
+++ b/scripts/build/v-klee.inc
@@ -0,0 +1,42 @@
+# Build information for KLEE
+required_variables_klee=(
+  "COVERAGE"
+  "USE_TCMALLOC"
+)
+
+required_variables_check_klee() {
+  check_bool "COVERAGE"
+  check_bool "USE_TCMALLOC"
+}
+
+# On which artifacts does KLEE depend on
+artifact_dependency_klee(){
+  local dependencies=("llvm" "solvers" "gtest")
+  if [[ "${OS}" != "osx" ]]; then
+    dependencies+=(uclibc)
+  fi
+
+  if [[ "${USE_TCMALLOC}" -eq 1 ]]; then
+    dependencies+=("tcmalloc")
+  fi
+
+  for d in "${dependencies[@]}"; do
+    echo "${d}"
+  done
+}
+
+runtime_artifact_dependency_klee(){
+  local dependencies=("")
+  if [[ "${OS}" != "osx" ]]; then
+    echo "uclibc"
+  fi
+  dependencies+=("llvm" "solvers" "gtest")
+
+  if [[ "${USE_TCMALLOC}" -eq 1 ]]; then
+    dependencies+=("tcmalloc")
+  fi
+
+  for d in "${dependencies[@]}"; do
+    echo "${d}"
+  done
+}
diff --git a/scripts/build/v-llvm.inc b/scripts/build/v-llvm.inc
new file mode 100644
index 00000000..5ec6f713
--- /dev/null
+++ b/scripts/build/v-llvm.inc
@@ -0,0 +1,34 @@
+required_variables_llvm=(
+  "LLVM_VERSION"
+  "ENABLE_OPTIMIZED"
+  "ENABLE_DEBUG"
+  "DISABLE_ASSERTIONS"
+  "REQUIRES_RTTI"
+)
+
+required_variables_check_llvm() {
+  check_bool "ENABLE_DEBUG"
+  check_bool "ENABLE_OPTIMIZED"
+  check_bool "DISABLE_ASSERTIONS"
+  check_bool "REQUIRES_RTTI"
+}
+
+export_variables_llvm=(
+  "LLVM_CONFIG"
+  "BITCODE_CC"
+  "BITCODE_CXX"
+)
+
+artifact_dependency_llvm=("sanitizer")
+
+setup_variables_llvm() {
+  LLVM_VERSION_SHORT="${LLVM_VERSION/./}"
+}
+
+check_export_variables_llvm() {
+  # Check for variables set and not empty
+  [[ -n ${LLVM_CONFIG:-} ]] || (echo "LLVM_CONFIG not set"; exit 1)
+  [[ -n ${LLVM_INSTALL:-} ]] || (echo "LLVM_INSTALL not set"; exit 1)
+  [[ -n ${BITCODE_CC:-} ]] || (echo "BITCODE_CC not set"; exit 1)
+  [[ -n ${BITCODE_CXX:-} ]] || (echo "BITCODE_CXX not set"; exit 1)
+}
\ No newline at end of file
diff --git a/scripts/build/v-metasmt.inc b/scripts/build/v-metasmt.inc
new file mode 100644
index 00000000..362126bb
--- /dev/null
+++ b/scripts/build/v-metasmt.inc
@@ -0,0 +1,7 @@
+# Build information for metaSMT solver
+required_variables_metasmt=(
+  "METASMT_VERSION"
+  "METASMT_DEFAULT"
+)
+
+artifact_dependency_metasmt=("")
\ No newline at end of file
diff --git a/scripts/build/v-sanitizer.inc b/scripts/build/v-sanitizer.inc
new file mode 100644
index 00000000..be9b3b39
--- /dev/null
+++ b/scripts/build/v-sanitizer.inc
@@ -0,0 +1,88 @@
+#!/bin/bash
+# Variables for sanitizer handling
+
+required_variables_sanitizer=(
+  "SANITIZER_BUILD"
+)
+
+artifact_dependency_sanitizer=("")
+
+required_variables_check_sanitizer() {
+  # Allowe empty sanitizer builds
+  [[ -z "${SANITIZER_BUILD}" ]] && return 0
+  
+  local sanitizers
+  IFS=":" read -r -a sanitizers <<< "${SANITIZER_BUILD}"
+  for sanitizer in "${sanitizers[@]}"; do
+    [[ -z "${sanitizer}" ]] && continue
+    [[ "${sanitizer}" == "address" ]] && continue
+    [[ "${sanitizer}" == "memory" ]] && continue
+    [[ "${sanitizer}" == "undefined" ]] && continue
+    
+    echo "Unknown sanitizer: $sanitizer"
+    exit 1
+  done
+}
+
+setup_variables_sanitizer() {
+  if [[ -z "${SANITIZER_BUILD}" ]]; then
+    SANITIZERS=("")
+    SANITIZER_SUFFIX=""
+    return 0
+  fi
+  # Remove ":" separator
+  local sanitizers
+  local e
+  local sorted_sanitizers
+  
+  IFS=":" read -r -a sanitizers <<< "${SANITIZER_BUILD}"
+  sorted_sanitizers=( $( for e in "${sanitizers[@]}"; do echo "$e"; done | sort) )
+  
+  	
+  # Set variables used by clients.
+  ## Build variables
+  [[ -z ${SANITIZER_CXX_FLAGS+x} ]] && SANITIZER_CXX_FLAGS=("")
+  [[ -z ${SANITIZER_C_FLAGS+x} ]] && SANITIZER_C_FLAGS=("")
+  [[ -z ${SANITIZER_LD_FLAGS+x} ]] && SANITIZER_LD_FLAGS=("")
+  
+  # Docker_suffix
+  SANITIZER_SUFFIX=""
+  
+  local flags
+  for sanitizer in "${sorted_sanitizers[@]}"; do
+    [[ -z "${sanitizer}" ]] && continue
+    # AddressSanitizer
+    if [ "${sanitizer}" == "address" ]; then
+      echo "Using ASan"
+      flags=( "-fsanitize=address" "-fno-omit-frame-pointer" "-g")
+      SANITIZER_CXX_FLAGS+=("${flags[@]}")
+      SANITIZER_C_FLAGS+=("${flags[@]}")
+      SANITIZER_LD_FLAGS+=("${flags[@]}")
+      SANITIZER_SUFFIX+="_asan"
+      continue
+    fi
+  
+    # Undefined Behaviour Sanitizer
+    if [ "${sanitizer}" == "undefined" ]; then
+      echo "Using UBSan"
+      flags=("-fsanitize=undefined" "-fno-omit-frame-pointer" "-g")
+      SANITIZER_CXX_FLAGS+=("${flags[@]}")
+      SANITIZER_C_FLAGS+=("${flags[@]}")
+      SANITIZER_LD_FLAGS+=("${flags[@]}" "-lubsan" "-fuse-ld=gold")
+      SANITIZER_SUFFIX+="_ubsan"
+      continue
+    fi
+  
+    # Undefined Behaviour Sanitizer
+    if [ "${sanitizer}" == "memory" ]; then
+      echo "Using Memory Sanitizer"
+      SANITIZER_SUFFIX+="_memsan"
+      continue
+    fi
+  
+    echo "Unknown sanitizer: $sanitizer"
+    exit 1
+  done
+  
+  SANITIZERS=("${sorted_sanitizers[@]}")
+  }
\ No newline at end of file
diff --git a/scripts/build/v-sanitizer_compiler.inc b/scripts/build/v-sanitizer_compiler.inc
new file mode 100644
index 00000000..e0cf2468
--- /dev/null
+++ b/scripts/build/v-sanitizer_compiler.inc
@@ -0,0 +1,21 @@
+# Meta-package for solvers
+required_variables_sanitizer_compiler=("")
+
+# On which artifacts does STP depend on
+artifact_dependency_sanitizer_compiler(){
+  echo "sanitizer"
+  if [[ -n ${SANITIZER_BUILD+x} ]]; then
+    [[ "${SANITIZER_BUILD}" == "memory" ]] && echo "llvm"
+    [[ "${SANITIZER_BUILD}" != "memory" ]] && echo "clang"
+  fi
+}
+
+
+# Setup general variables
+setup_variables_sanitizer_compiler() {
+  for sanitizer in "${SANITIZERS[@]}"; do
+    [[ -z "${sanitizer}" ]] && continue
+    SANITIZER_CMAKE_C_COMPILER=[""]
+  done
+
+}
\ No newline at end of file
diff --git a/scripts/build/v-solvers.inc b/scripts/build/v-solvers.inc
new file mode 100644
index 00000000..ad3f43f1
--- /dev/null
+++ b/scripts/build/v-solvers.inc
@@ -0,0 +1,63 @@
+# Meta-package for solvers
+required_variables_solvers=(
+  "SOLVERS"
+)
+
+required_variables_check_solvers() {
+  local solvers
+  IFS=":" read -r -a solvers <<< "${SOLVERS}"
+  [[ -z "${solvers[@]}" ]] && { echo "SOLVERS can't be empty"; exit 1; }
+  
+  for solver in "${solvers[@]}"; do
+    [[ -z "${solver}" ]] && continue
+    solver="$(to_lower ${solver})"
+
+    [[ "${solver}" == "z3" ]] && continue
+    [[ "${solver}" == "stp" ]] && continue
+    [[ "${solver}" == "metasmt" ]] && continue
+    
+    echo "Unknown solver: \"$solver\""
+    exit 1
+  done
+}
+
+# On which artifacts does SOLVERS depend on
+artifact_dependency_solvers() {
+  # Setup variables first to get selected solvers
+  setup_variables_solvers
+  for solver in "${SELECTED_SOLVERS[@]}"; do
+    echo "${solver}"
+  done
+}
+
+# On which artifacts does SOLVERS depend on
+runtime_artifact_dependency_solvers() {
+  # Setup variables first to get selected solvers
+  setup_variables_solvers
+  for solver in "${SELECTED_SOLVERS[@]}"; do
+    echo "${solver}"
+  done
+}
+
+# Setup general variables
+setup_variables_solvers() {
+  local solvers
+  IFS=":" read -r -a solvers <<< "${SOLVERS}"
+
+  SELECTED_SOLVERS=()
+  for solver in "${solvers[@]}"; do
+    [[ -z "${solver}" ]] && continue
+    solver="$(to_lower ${solver})"
+    [[ "${solver}" == "z3" ]] && SELECTED_SOLVERS+=("z3") && continue
+    [[ "${solver}" == "stp" ]] && SELECTED_SOLVERS+=("stp") && continue
+    [[ "${solver}" == "metasmt" ]] && SELECTED_SOLVERS+=("metasmt") && continue
+
+    echo "Unknown solver: \"$solver\""
+    exit 1
+  done
+
+  # Sort solvers
+  SELECTED_SOLVERS=( $( for e in "${SELECTED_SOLVERS[@]}"; do echo "$e"; done | sort|uniq) )
+# TODO Add specific suffix of each solver
+  SOLVER_SUFFIX=$(IFS=_ ; echo "${SELECTED_SOLVERS[*]}")
+}
\ No newline at end of file
diff --git a/scripts/build/v-stp.inc b/scripts/build/v-stp.inc
new file mode 100644
index 00000000..9bbc28f1
--- /dev/null
+++ b/scripts/build/v-stp.inc
@@ -0,0 +1,8 @@
+# Build information for STP solver
+required_variables_stp=(
+  "STP_VERSION"
+  "MINISAT_VERSION"
+)
+
+# On which artifacts does STP depend on
+artifact_dependency_stp=("sanitizer_compiler")
\ No newline at end of file
diff --git a/scripts/build/v-tcmalloc.inc b/scripts/build/v-tcmalloc.inc
new file mode 100644
index 00000000..e49b51c2
--- /dev/null
+++ b/scripts/build/v-tcmalloc.inc
@@ -0,0 +1,5 @@
+artifact_dependency_tcmalloc=("")
+
+required_variables_tcmalloc=(
+  "TCMALLOC_VERSION"
+)
\ No newline at end of file
diff --git a/scripts/build/v-uclibc.inc b/scripts/build/v-uclibc.inc
new file mode 100644
index 00000000..e7a2f720
--- /dev/null
+++ b/scripts/build/v-uclibc.inc
@@ -0,0 +1,17 @@
+required_variables_uclibc=(
+  "UCLIBC_VERSION"
+  "LLVM_VERSION"
+)
+
+artifact_dependency_uclibc(){
+  # Add llvm if needed; otherwise only use clang package
+# TODO this is quite distribution specific; should be handled in a more general case
+  local LLVM_VERSION_MAJOR="${LLVM_VERSION/.*/}"
+  local LLVM_VERSION_MINOR="${LLVM_VERSION/*./}"
+  # Check versions: no support for LLVM < 3.5
+  if [[ "${LLVM_VERSION_MAJOR}" -eq 3 ]]; then
+    [[ "${LLVM_VERSION_MINOR}" -lt 5 ]] && echo "llvm"
+  fi
+
+  echo "clang"
+}
\ No newline at end of file
diff --git a/scripts/build/v-z3.inc b/scripts/build/v-z3.inc
new file mode 100644
index 00000000..915336a3
--- /dev/null
+++ b/scripts/build/v-z3.inc
@@ -0,0 +1,7 @@
+# Build information for Z3 solver
+required_variables_z3=(
+  "Z3_VERSION"
+)
+
+# Artifacts Z3 depends on
+artifact_dependency_z3=("sanitizer_compiler")
\ No newline at end of file