diff --git "a/easyblocks/c/\\" "b/easyblocks/c/\\"
new file mode 100644
index 0000000000000000000000000000000000000000..e372a40480272df5fc9280f10b4c4b2696f50a54
--- /dev/null
+++ "b/easyblocks/c/\\"
@@ -0,0 +1,432 @@
+##
+# Copyright 2013 Dmitri Gribenko
+# Copyright 2013-2017 Ghent University
+# Copyright 2017 IT4Innovations
+#
+# This file is triple-licensed under GPLv2 (see below), MIT, and
+# BSD three-clause licenses.
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+##
+"""
+Support for building and installing Clang, implemented as an easyblock.
+
+@author: Dmitri Gribenko (National Technical University of Ukraine "KPI")
+@author: Ward Poelmans (Ghent University)
+@author: Josef Hrabal, Lukas Krupcik (IT4innovations, Czechia)
+"""
+
+import fileinput
+import glob
+import os
+import re
+import shutil
+import sys
+from distutils.version import LooseVersion
+
+from easybuild.easyblocks.generic.cmakemake import CMakeMake
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools import run
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.config import build_option
+from easybuild.tools.filetools import mkdir
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.run import run_cmd
+from easybuild.tools.systemtools import get_os_name, get_os_version, get_shared_lib_ext
+
+# List of all possible build targets for Clang
+CLANG_TARGETS = ["all", "AArch64", "ARM", "CppBackend", "Hexagon", "Mips",
+                 "MBlaze", "MSP430", "NVPTX", "PowerPC", "R600", "Sparc",
+                 "SystemZ", "X86", "XCore"]
+
+
+class EB_Clang(CMakeMake):
+    """Support for bootstrapping Clang."""
+
+    @staticmethod
+    def extra_options():
+        extra_vars = {
+            'assertions': [True, "Enable assertions.  Helps to catch bugs in Clang.", CUSTOM],
+            'build_targets': [["X86"], "Build targets for LLVM. Possible values: " + ', '.join(CLANG_TARGETS), CUSTOM],
+            'bootstrap': [True, "Bootstrap Clang using GCC", CUSTOM],
+            'usepolly': [False, "Build Clang with polly", CUSTOM],
+            'static_analyzer': [True, "Install the static analyser of Clang", CUSTOM],
+            # The sanitizer tests often fail on HPC systems due to the 'weird' environment.
+            'skip_sanitizer_tests': [False, "Do not run the sanitizer tests", CUSTOM],
+        }
+
+        return CMakeMake.extra_options(extra_vars)
+
+    def __init__(self, *args, **kwargs):
+        """Initialize custom class variables for Clang."""
+
+        super(EB_Clang, self).__init__(*args, **kwargs)
+        self.llvm_src_dir = None
+        self.llvm_obj_dir_stage1 = None
+        self.llvm_obj_dir_stage2 = None
+        self.llvm_obj_dir_stage3 = None
+        self.make_parallel_opts = ""
+
+        unknown_targets = [target for target in self.cfg['build_targets'] if target not in CLANG_TARGETS]
+
+        if unknown_targets:
+            raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.",
+                                 ', '.join(unknown_targets), ', '.join(CLANG_TARGETS))
+
+        if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in self.cfg['build_targets']:
+            raise EasyBuildError("Build target R600 not supported in < Clang-3.4")
+
+        if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in self.cfg['build_targets']:
+            raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3")
+
+    def check_readiness_step(self):
+        """Fail early on RHEL 5.x and derivatives because of known bug in libc."""
+        super(EB_Clang, self).check_readiness_step()
+        # RHEL 5.x have a buggy libc.  Building stage 2 will fail.
+        if get_os_name() in ['redhat', 'RHEL', 'centos', 'SL'] and get_os_version().startswith('5.'):
+            raise EasyBuildError("Can not build Clang on %s v5.x: libc is buggy, building stage 2 will fail. "
+                                 "See http://stackoverflow.com/questions/7276828/", get_os_name())
+
+    def extract_step(self):
+        """
+        Prepare a combined LLVM source tree.  The layout is:
+        llvm/                  Unpack llvm-*.tar.gz here
+          projects/
+            compiler-rt/       Unpack compiler-rt-*.tar.gz here
+            openmp/            Unpack openmp-*.tar.xz here
+            libcxx/            Unpack libcxx-*.tar.xz here
+            libcxxabi/         Unpack libcxxapbi-*.tar.xz here
+          tools/
+            clang/             Unpack cfe-*.tar.gz here
+              tools/extra  Unpack clang-*.tar.gz here
+            polly/             Unpack polly-*.tar.gz here
+        """
+
+        # Extract everything into separate directories.
+        super(EB_Clang, self).extract_step()
+
+        # Find the full path to the directory that was unpacked from llvm-*.tar.gz.
+        for tmp in self.src:
+            if tmp['name'].startswith("llvm-"):
+                self.llvm_src_dir = tmp['finalpath']
+                break
+
+        if self.llvm_src_dir is None:
+            raise EasyBuildError("Could not determine LLVM source root (LLVM source was not unpacked?)")
+
+        src_dirs = {}
+
+        def find_source_dir(globpatterns, targetdir):
+            """Search for directory with globpattern and rename it to targetdir"""
+            if not isinstance(globpatterns, list):
+                globpatterns = [globpatterns]
+
+            glob_src_dirs = [glob_dir for globpattern in globpatterns for glob_dir in glob.glob(globpattern)]
+            if len(glob_src_dirs) != 1:
+                raise EasyBuildError("Failed to find exactly one source directory for pattern %s: %s", globpatterns,
+                                     glob_src_dirs)
+            src_dirs[glob_src_dirs[0]] = targetdir
+
+        find_source_dir('compiler-rt-*', os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt'))
+
+        if self.cfg["usepolly"]:
+            find_source_dir('polly-*', os.path.join(self.llvm_src_dir, 'tools', 'polly'))
+
+        find_source_dir('cfe-*', os.path.join(self.llvm_src_dir, 'tools', 'clang'))
+
+        find_source_dir('clang-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi'))
+
+        if LooseVersion(self.version) >= LooseVersion('3.8'):
+            find_source_dir('openmp-*', os.path.join(self.llvm_src_dir, 'projects', 'openmp'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('ldd-*', os.path.join(self.llvm_src_dir, 'tools', 'ldd'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('lddb-*', os.path.join(self.llvm_src_dir, 'tools', 'lddb'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libunwind-*', os.path.join(self.llvm_src_dir, 'tools', 'libunwind'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('test-*', os.path.join(self.llvm_src_dir, 'tools', 'testsuite'))
+
+        for src in self.src:
+            for (dirname, new_path) in src_dirs.items():
+                if src['name'].startswith(dirname):
+                    old_path = os.path.join(src['finalpath'], dirname)
+                    try:
+                        shutil.move(old_path, new_path)
+                    except IOError, err:
+                        raise EasyBuildError("Failed to move %s to %s: %s", old_path, new_path, err)
+                    src['finalpath'] = new_path
+                    break
+
+    def configure_step(self):
+	if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).configure_step()
+            return
+
+        """Run CMake for stage 1 Clang."""
+        self.llvm_obj_dir_stage1 = os.path.join(self.builddir, 'llvm.obj.1')
+        if self.cfg['bootstrap']:
+            self.llvm_obj_dir_stage2 = os.path.join(self.builddir, 'llvm.obj.2')
+            self.llvm_obj_dir_stage3 = os.path.join(self.builddir, 'llvm.obj.3')
+
+        if LooseVersion(self.version) >= LooseVersion('3.3'):
+            disable_san_tests = False
+            # all sanitizer tests will fail when there's a limit on the vmem
+            # this is ugly but I haven't found a cleaner way so far
+            (vmemlim, ec) = run_cmd("ulimit -v", regexp=False)
+            if not vmemlim.startswith("unlimited"):
+                disable_san_tests = True
+                self.log.warn("There is a virtual memory limit set of %s KB. The tests of the "
+                              "sanitizers will be disabled as they need unlimited virtual "
+                              "memory unless --strict=error is used." % vmemlim.strip())
+
+            # the same goes for unlimited stacksize
+            (stacklim, ec) = run_cmd("ulimit -s", regexp=False)
+            if stacklim.startswith("unlimited"):
+                disable_san_tests = True
+                self.log.warn("The stacksize limit is set to unlimited. This causes the ThreadSanitizer "
+                              "to fail. The sanitizers tests will be disabled unless --strict=error is used.")
+
+            if (disable_san_tests or self.cfg['skip_sanitizer_tests']) and build_option('strict') != run.ERROR:
+                self.log.debug("Disabling the sanitizer tests")
+                self.disable_sanitizer_tests()
+
+        # Create and enter build directory.
+        mkdir(self.llvm_obj_dir_stage1)
+        os.chdir(self.llvm_obj_dir_stage1)
+
+        # GCC and Clang are installed in different prefixes and Clang will not
+        # find the GCC installation on its own.
+        # First try with GCCcore, as GCC built on top of GCCcore is just a wrapper for GCCcore and binutils,
+        # instead of a full-fledge compiler
+        gcc_prefix = get_software_root('GCCcore')
+
+        # If that doesn't work, try with GCC
+        if gcc_prefix is None:
+            gcc_prefix = get_software_root('GCC')
+
+        # If that doesn't work either, print error and exit
+        if gcc_prefix is None:
+            raise EasyBuildError("Can't find GCC or GCCcore to use")
+
+        self.cfg.update('configopts', "-DGCC_INSTALL_PREFIX='%s' " % gcc_prefix)
+        self.log.debug("Using %s as GCC_INSTALL_PREFIX", gcc_prefix)
+
+        self.cfg['configopts'] += "-DCMAKE_BUILD_TYPE=Release "
+        if self.cfg['assertions']:
+            self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=ON "
+        else:
+            self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=OFF "
+
+        self.cfg['configopts'] += '-DLLVM_TARGETS_TO_BUILD="%s" ' % ';'.join(self.cfg['build_targets'])
+
+        if self.cfg['parallel']:
+            self.make_parallel_opts = "-j %s" % self.cfg['parallel']
+
+        self.log.info("Configuring")
+        super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir)
+
+    def disable_sanitizer_tests(self):
+        """Disable the tests of all the sanitizers by removing the test directories from the build system"""
+        if LooseVersion(self.version) < LooseVersion('3.6'):
+            # for Clang 3.5 and lower, the tests are scattered over several CMakeLists.
+            # We loop over them, and patch out the rule that adds the sanitizers tests to the testsuite
+            patchfiles = [
+                "lib/asan",
+                "lib/dfsan",
+                "lib/lsan",
+                "lib/msan",
+                "lib/tsan",
+                "lib/ubsan",
+            ]
+
+            for patchfile in patchfiles:
+                patchfile_fp = os.path.join(self.llvm_src_dir, "projects/compiler-rt", patchfile, "CMakeLists.txt")
+                if os.path.exists(patchfile_fp):
+                    self.log.debug("Patching %s in %s" % (patchfile, self.llvm_src_dir))
+                    try:
+                        for line in fileinput.input(patchfile_fp, inplace=1, backup='.orig'):
+                            if "add_subdirectory(lit_tests)" not in line:
+                                sys.stdout.write(line)
+                    except (IOError, OSError), err:
+                        raise EasyBuildError("Failed to patch %s: %s", patchfile_fp, err)
+                else:
+                    self.log.debug("Not patching non-existent %s in %s" % (patchfile, self.llvm_src_dir))
+
+            # There is a common part seperate for the specific saniters, we disable all
+            # the common tests
+            patchfile = "projects/compiler-rt/lib/sanitizer_common/CMakeLists.txt"
+            try:
+                for line in fileinput.input("%s/%s" % (self.llvm_src_dir, patchfile), inplace=1, backup='.orig'):
+                    if "add_subdirectory(tests)" not in line:
+                        sys.stdout.write(line)
+            except IOError, err:
+                raise EasyBuildError("Failed to patch %s/%s: %s", self.llvm_src_dir, patchfile, err)
+        else:
+            # In Clang 3.6, the sanitizer tests are grouped together in one CMakeLists
+            # We patch out adding the subdirectories with the sanitizer tests
+            patchfile = "projects/compiler-rt/test/CMakeLists.txt"
+            patchfile_fp = os.path.join(self.llvm_src_dir, patchfile)
+            self.log.debug("Patching %s in %s" % (patchfile, self.llvm_src_dir))
+            patch_regex = re.compile(r'add_subdirectory\((.*san|sanitizer_common)\)')
+            try:
+                for line in fileinput.input(patchfile_fp, inplace=1, backup='.orig'):
+                    if not patch_regex.search(line):
+                        sys.stdout.write(line)
+            except IOError, err:
+                raise EasyBuildError("Failed to patch %s: %s", patchfile_fp, err)
+
+    def build_with_prev_stage(self, prev_obj, next_obj):
+        """Build Clang stage N using Clang stage N-1"""
+
+        # Create and enter build directory.
+        mkdir(next_obj)
+        os.chdir(next_obj)
+
+        # Configure.
+        CC = os.path.join(prev_obj, 'bin', 'clang')
+        CXX = os.path.join(prev_obj, 'bin', 'clang++')
+
+        options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir
+        options += "-DCMAKE_C_COMPILER='%s' " % CC
+        options += "-DCMAKE_CXX_COMPILER='%s' " % CXX
+        options += self.cfg['configopts']
+
+        self.log.info("Configuring")
+        run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True)
+
+        self.log.info("Building")
+        run_cmd("make %s" % self.make_parallel_opts, log_all=True)
+
+    def run_clang_tests(self, obj_dir):
+        os.chdir(obj_dir)
+
+        self.log.info("Running tests")
+        run_cmd("make %s check-all" % self.make_parallel_opts, log_all=True)
+
+    def build_step(self):
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).build_step()
+            return
+
+        """Build Clang stage 1, 2, 3"""
+
+        # Stage 1: build using system compiler.
+        self.log.info("Building stage 1")
+        os.chdir(self.llvm_obj_dir_stage1)
+        super(EB_Clang, self).build_step()
+
+        if self.cfg['bootstrap']:
+            # Stage 1: run tests.
+            self.run_clang_tests(self.llvm_obj_dir_stage1)
+
+            self.log.info("Building stage 2")
+            self.build_with_prev_stage(self.llvm_obj_dir_stage1, self.llvm_obj_dir_stage2)
+            self.run_clang_tests(self.llvm_obj_dir_stage2)
+
+            self.log.info("Building stage 3")
+            self.build_with_prev_stage(self.llvm_obj_dir_stage2, self.llvm_obj_dir_stage3)
+            # Don't run stage 3 tests here, do it in the test step.
+
+    def test_step(self):
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).test_step()
+            return
+
+        if self.cfg['bootstrap']:
+            self.run_clang_tests(self.llvm_obj_dir_stage3)
+        else:
+            self.run_clang_tests(self.llvm_obj_dir_stage1)
+
+    def install_step(self):
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).install_step()
+            return
+
+        """Install stage 3 binaries."""
+
+        if self.cfg['bootstrap']:
+            os.chdir(self.llvm_obj_dir_stage3)
+        else:
+            os.chdir(self.llvm_obj_dir_stage1)
+        super(EB_Clang, self).install_step()
+
+        # the static analyzer is not installed by default
+        # we do it by hand
+        if self.cfg['static_analyzer'] and LooseVersion(self.version) < LooseVersion('3.8'):
+            try:
+                tools_src_dir = os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools')
+                analyzer_target_dir = os.path.join(self.installdir, 'libexec', 'clang-analyzer')
+                bindir = os.path.join(self.installdir, 'bin')
+                for scan_dir in ['scan-build', 'scan-view']:
+                    shutil.copytree(os.path.join(tools_src_dir, scan_dir), os.path.join(analyzer_target_dir, scan_dir))
+                    os.symlink(os.path.relpath(bindir, os.path.join(analyzer_target_dir, scan_dir)),
+                               os.path.join(analyzer_target_dir, scan_dir, 'bin'))
+                    os.symlink(os.path.relpath(os.path.join(analyzer_target_dir, scan_dir, scan_dir), bindir),
+                               os.path.join(bindir, scan_dir))
+
+                mandir = os.path.join(self.installdir, 'share', 'man', 'man1')
+                os.makedirs(mandir)
+                shutil.copy2(os.path.join(tools_src_dir, 'scan-build', 'scan-build.1'), mandir)
+            except OSError, err:
+                raise EasyBuildError("Failed to copy static analyzer dirs to install dir: %s", err)
+
+    def sanity_check_step(self):
+        """Custom sanity check for Clang."""
+        shlib_ext = get_shared_lib_ext()
+        custom_paths = {
+            'files': [
+                "bin/clang", "bin/clang++", "bin/llvm-ar", "bin/llvm-nm", "bin/llvm-as", "bin/opt", "bin/llvm-link",
+                "bin/llvm-config", "bin/llvm-symbolizer", "include/llvm-c/Core.h", "include/clang-c/Index.h",
+                "lib/libclang.%s" % shlib_ext, "lib/clang/%s/include/stddef.h" % self.version,
+            ],
+            'dirs': ["include/clang", "include/llvm", "lib/clang/%s/lib" % self.version],
+        }
+        if self.cfg['static_analyzer']:
+            custom_paths['files'].extend(["bin/scan-build", "bin/scan-view"])
+
+        if self.cfg["usepolly"]:
+            custom_paths['files'].extend(["lib/LLVMPolly.%s" % shlib_ext])
+            custom_paths['dirs'].extend(["include/polly"])
+
+        if LooseVersion(self.version) >= LooseVersion('3.8'):
+            custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version])
+
+        super(EB_Clang, self).sanity_check_step(custom_paths=custom_paths)
+
+    def make_module_extra(self):
+        """Custom variables for Clang module."""
+        txt = super(EB_Clang, self).make_module_extra()
+        # we set the symbolizer path so that asan/tsan give meanfull output by default
+        asan_symbolizer_path = os.path.join(self.installdir, 'bin', 'llvm-symbolizer')
+        txt += self.module_generator.set_environment('ASAN_SYMBOLIZER_PATH', asan_symbolizer_path)
+        return txt
diff --git a/easyblocks/c/clang.py b/easyblocks/c/clang.py
new file mode 100644
index 0000000000000000000000000000000000000000..18edaee51acf8411cde3da4a46708c90cfd8f0a8
--- /dev/null
+++ b/easyblocks/c/clang.py
@@ -0,0 +1,420 @@
+##
+# Copyright 2013 Dmitri Gribenko
+# Copyright 2013-2017 Ghent University
+# Copyright 2017 IT4Innovations
+#
+# This file is triple-licensed under GPLv2 (see below), MIT, and
+# BSD three-clause licenses.
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+##
+"""
+Support for building and installing Clang, implemented as an easyblock.
+
+@author: Dmitri Gribenko (National Technical University of Ukraine "KPI")
+@author: Ward Poelmans (Ghent University)
+@author: Josef Hrabal, Lukas Krupcik (IT4innovations, Czechia)
+"""
+
+import fileinput
+import glob
+import os
+import re
+import shutil
+import sys
+from distutils.version import LooseVersion
+
+from easybuild.easyblocks.generic.cmakemake import CMakeMake
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools import run
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.config import build_option
+from easybuild.tools.filetools import mkdir
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.run import run_cmd
+from easybuild.tools.systemtools import get_os_name, get_os_version, get_shared_lib_ext
+
+# List of all possible build targets for Clang
+CLANG_TARGETS = ["all", "AArch64", "ARM", "CppBackend", "Hexagon", "Mips",
+                 "MBlaze", "MSP430", "NVPTX", "PowerPC", "R600", "Sparc",
+                 "SystemZ", "X86", "XCore"]
+
+
+class EB_Clang(CMakeMake):
+    """Support for bootstrapping Clang."""
+
+    @staticmethod
+    def extra_options():
+        extra_vars = {
+            'assertions': [True, "Enable assertions.  Helps to catch bugs in Clang.", CUSTOM],
+            'build_targets': [["X86"], "Build targets for LLVM. Possible values: " + ', '.join(CLANG_TARGETS), CUSTOM],
+            'bootstrap': [True, "Bootstrap Clang using GCC", CUSTOM],
+            'usepolly': [False, "Build Clang with polly", CUSTOM],
+            'static_analyzer': [True, "Install the static analyser of Clang", CUSTOM],
+            # The sanitizer tests often fail on HPC systems due to the 'weird' environment.
+            'skip_sanitizer_tests': [False, "Do not run the sanitizer tests", CUSTOM],
+        }
+
+        return CMakeMake.extra_options(extra_vars)
+
+    def __init__(self, *args, **kwargs):
+        """Initialize custom class variables for Clang."""
+
+        super(EB_Clang, self).__init__(*args, **kwargs)
+        self.llvm_src_dir = None
+        self.llvm_obj_dir_stage1 = None
+        self.llvm_obj_dir_stage2 = None
+        self.llvm_obj_dir_stage3 = None
+        self.make_parallel_opts = ""
+
+        unknown_targets = [target for target in self.cfg['build_targets'] if target not in CLANG_TARGETS]
+
+        if unknown_targets:
+            raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.",
+                                 ', '.join(unknown_targets), ', '.join(CLANG_TARGETS))
+
+        if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in self.cfg['build_targets']:
+            raise EasyBuildError("Build target R600 not supported in < Clang-3.4")
+
+        if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in self.cfg['build_targets']:
+            raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3")
+
+    def check_readiness_step(self):
+        """Fail early on RHEL 5.x and derivatives because of known bug in libc."""
+        super(EB_Clang, self).check_readiness_step()
+        # RHEL 5.x have a buggy libc.  Building stage 2 will fail.
+        if get_os_name() in ['redhat', 'RHEL', 'centos', 'SL'] and get_os_version().startswith('5.'):
+            raise EasyBuildError("Can not build Clang on %s v5.x: libc is buggy, building stage 2 will fail. "
+                                 "See http://stackoverflow.com/questions/7276828/", get_os_name())
+
+    def extract_step(self):
+        """
+        Prepare a combined LLVM source tree.  The layout is:
+        llvm/                  Unpack llvm-*.tar.gz here
+          projects/
+            compiler-rt/       Unpack compiler-rt-*.tar.gz here
+            openmp/            Unpack openmp-*.tar.xz here
+            libcxx/            Unpack libcxx-*.tar.xz here
+            libcxxabi/         Unpack libcxxapbi-*.tar.xz here
+          tools/
+            clang/             Unpack cfe-*.tar.gz here
+              tools/extra  Unpack clang-*.tar.gz here
+            polly/             Unpack polly-*.tar.gz here
+        """
+
+        # Extract everything into separate directories.
+        super(EB_Clang, self).extract_step()
+
+        # Find the full path to the directory that was unpacked from llvm-*.tar.gz.
+        for tmp in self.src:
+            if tmp['name'].startswith("llvm-"):
+                self.llvm_src_dir = tmp['finalpath']
+                break
+
+        if self.llvm_src_dir is None:
+            raise EasyBuildError("Could not determine LLVM source root (LLVM source was not unpacked?)")
+
+        src_dirs = {}
+
+        def find_source_dir(globpatterns, targetdir):
+            """Search for directory with globpattern and rename it to targetdir"""
+            if not isinstance(globpatterns, list):
+                globpatterns = [globpatterns]
+
+            glob_src_dirs = [glob_dir for globpattern in globpatterns for glob_dir in glob.glob(globpattern)]
+            if len(glob_src_dirs) != 1:
+                raise EasyBuildError("Failed to find exactly one source directory for pattern %s: %s", globpatterns,
+                                     glob_src_dirs)
+            src_dirs[glob_src_dirs[0]] = targetdir
+
+        find_source_dir('compiler-rt-*', os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt'))
+
+        if self.cfg["usepolly"]:
+            find_source_dir('polly-*', os.path.join(self.llvm_src_dir, 'tools', 'polly'))
+
+        find_source_dir('cfe-*', os.path.join(self.llvm_src_dir, 'tools', 'clang'))
+
+        find_source_dir('clang-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi'))
+
+        if LooseVersion(self.version) >= LooseVersion('3.8'):
+            find_source_dir('openmp-*', os.path.join(self.llvm_src_dir, 'projects', 'openmp'))
+
+        for src in self.src:
+            for (dirname, new_path) in src_dirs.items():
+                if src['name'].startswith(dirname):
+                    old_path = os.path.join(src['finalpath'], dirname)
+                    try:
+                        shutil.move(old_path, new_path)
+                    except IOError, err:
+                        raise EasyBuildError("Failed to move %s to %s: %s", old_path, new_path, err)
+                    src['finalpath'] = new_path
+                    break
+
+    def configure_step(self):
+	if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).configure_step()
+            return
+
+        """Run CMake for stage 1 Clang."""
+        self.llvm_obj_dir_stage1 = os.path.join(self.builddir, 'llvm.obj.1')
+        if self.cfg['bootstrap']:
+            self.llvm_obj_dir_stage2 = os.path.join(self.builddir, 'llvm.obj.2')
+            self.llvm_obj_dir_stage3 = os.path.join(self.builddir, 'llvm.obj.3')
+
+        if LooseVersion(self.version) >= LooseVersion('3.3'):
+            disable_san_tests = False
+            # all sanitizer tests will fail when there's a limit on the vmem
+            # this is ugly but I haven't found a cleaner way so far
+            (vmemlim, ec) = run_cmd("ulimit -v", regexp=False)
+            if not vmemlim.startswith("unlimited"):
+                disable_san_tests = True
+                self.log.warn("There is a virtual memory limit set of %s KB. The tests of the "
+                              "sanitizers will be disabled as they need unlimited virtual "
+                              "memory unless --strict=error is used." % vmemlim.strip())
+
+            # the same goes for unlimited stacksize
+            (stacklim, ec) = run_cmd("ulimit -s", regexp=False)
+            if stacklim.startswith("unlimited"):
+                disable_san_tests = True
+                self.log.warn("The stacksize limit is set to unlimited. This causes the ThreadSanitizer "
+                              "to fail. The sanitizers tests will be disabled unless --strict=error is used.")
+
+            if (disable_san_tests or self.cfg['skip_sanitizer_tests']) and build_option('strict') != run.ERROR:
+                self.log.debug("Disabling the sanitizer tests")
+                self.disable_sanitizer_tests()
+
+        # Create and enter build directory.
+        mkdir(self.llvm_obj_dir_stage1)
+        os.chdir(self.llvm_obj_dir_stage1)
+
+        # GCC and Clang are installed in different prefixes and Clang will not
+        # find the GCC installation on its own.
+        # First try with GCCcore, as GCC built on top of GCCcore is just a wrapper for GCCcore and binutils,
+        # instead of a full-fledge compiler
+        gcc_prefix = get_software_root('GCCcore')
+
+        # If that doesn't work, try with GCC
+        if gcc_prefix is None:
+            gcc_prefix = get_software_root('GCC')
+
+        # If that doesn't work either, print error and exit
+        if gcc_prefix is None:
+            raise EasyBuildError("Can't find GCC or GCCcore to use")
+
+        self.cfg.update('configopts', "-DGCC_INSTALL_PREFIX='%s' " % gcc_prefix)
+        self.log.debug("Using %s as GCC_INSTALL_PREFIX", gcc_prefix)
+
+        self.cfg['configopts'] += "-DCMAKE_BUILD_TYPE=Release "
+        if self.cfg['assertions']:
+            self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=ON "
+        else:
+            self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=OFF "
+
+        self.cfg['configopts'] += '-DLLVM_TARGETS_TO_BUILD="%s" ' % ';'.join(self.cfg['build_targets'])
+
+        if self.cfg['parallel']:
+            self.make_parallel_opts = "-j %s" % self.cfg['parallel']
+
+        self.log.info("Configuring")
+        super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir)
+
+    def disable_sanitizer_tests(self):
+        """Disable the tests of all the sanitizers by removing the test directories from the build system"""
+        if LooseVersion(self.version) < LooseVersion('3.6'):
+            # for Clang 3.5 and lower, the tests are scattered over several CMakeLists.
+            # We loop over them, and patch out the rule that adds the sanitizers tests to the testsuite
+            patchfiles = [
+                "lib/asan",
+                "lib/dfsan",
+                "lib/lsan",
+                "lib/msan",
+                "lib/tsan",
+                "lib/ubsan",
+            ]
+
+            for patchfile in patchfiles:
+                patchfile_fp = os.path.join(self.llvm_src_dir, "projects/compiler-rt", patchfile, "CMakeLists.txt")
+                if os.path.exists(patchfile_fp):
+                    self.log.debug("Patching %s in %s" % (patchfile, self.llvm_src_dir))
+                    try:
+                        for line in fileinput.input(patchfile_fp, inplace=1, backup='.orig'):
+                            if "add_subdirectory(lit_tests)" not in line:
+                                sys.stdout.write(line)
+                    except (IOError, OSError), err:
+                        raise EasyBuildError("Failed to patch %s: %s", patchfile_fp, err)
+                else:
+                    self.log.debug("Not patching non-existent %s in %s" % (patchfile, self.llvm_src_dir))
+
+            # There is a common part seperate for the specific saniters, we disable all
+            # the common tests
+            patchfile = "projects/compiler-rt/lib/sanitizer_common/CMakeLists.txt"
+            try:
+                for line in fileinput.input("%s/%s" % (self.llvm_src_dir, patchfile), inplace=1, backup='.orig'):
+                    if "add_subdirectory(tests)" not in line:
+                        sys.stdout.write(line)
+            except IOError, err:
+                raise EasyBuildError("Failed to patch %s/%s: %s", self.llvm_src_dir, patchfile, err)
+        else:
+            # In Clang 3.6, the sanitizer tests are grouped together in one CMakeLists
+            # We patch out adding the subdirectories with the sanitizer tests
+            patchfile = "projects/compiler-rt/test/CMakeLists.txt"
+            patchfile_fp = os.path.join(self.llvm_src_dir, patchfile)
+            self.log.debug("Patching %s in %s" % (patchfile, self.llvm_src_dir))
+            patch_regex = re.compile(r'add_subdirectory\((.*san|sanitizer_common)\)')
+            try:
+                for line in fileinput.input(patchfile_fp, inplace=1, backup='.orig'):
+                    if not patch_regex.search(line):
+                        sys.stdout.write(line)
+            except IOError, err:
+                raise EasyBuildError("Failed to patch %s: %s", patchfile_fp, err)
+
+    def build_with_prev_stage(self, prev_obj, next_obj):
+        """Build Clang stage N using Clang stage N-1"""
+
+        # Create and enter build directory.
+        mkdir(next_obj)
+        os.chdir(next_obj)
+
+        # Configure.
+        CC = os.path.join(prev_obj, 'bin', 'clang')
+        CXX = os.path.join(prev_obj, 'bin', 'clang++')
+
+        options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir
+        options += "-DCMAKE_C_COMPILER='%s' " % CC
+        options += "-DCMAKE_CXX_COMPILER='%s' " % CXX
+        options += self.cfg['configopts']
+
+        self.log.info("Configuring")
+        run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True)
+
+        self.log.info("Building")
+        run_cmd("make %s" % self.make_parallel_opts, log_all=True)
+
+    def run_clang_tests(self, obj_dir):
+        os.chdir(obj_dir)
+
+        self.log.info("Running tests")
+        run_cmd("make %s check-all" % self.make_parallel_opts, log_all=True)
+
+    def build_step(self):
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).build_step()
+            return
+
+        """Build Clang stage 1, 2, 3"""
+
+        # Stage 1: build using system compiler.
+        self.log.info("Building stage 1")
+        os.chdir(self.llvm_obj_dir_stage1)
+        super(EB_Clang, self).build_step()
+
+        if self.cfg['bootstrap']:
+            # Stage 1: run tests.
+            self.run_clang_tests(self.llvm_obj_dir_stage1)
+
+            self.log.info("Building stage 2")
+            self.build_with_prev_stage(self.llvm_obj_dir_stage1, self.llvm_obj_dir_stage2)
+            self.run_clang_tests(self.llvm_obj_dir_stage2)
+
+            self.log.info("Building stage 3")
+            self.build_with_prev_stage(self.llvm_obj_dir_stage2, self.llvm_obj_dir_stage3)
+            # Don't run stage 3 tests here, do it in the test step.
+
+    def test_step(self):
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).test_step()
+            return
+
+        if self.cfg['bootstrap']:
+            self.run_clang_tests(self.llvm_obj_dir_stage3)
+        else:
+            self.run_clang_tests(self.llvm_obj_dir_stage1)
+
+    def install_step(self):
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            super(EB_Clang, self).install_step()
+            return
+
+        """Install stage 3 binaries."""
+
+        if self.cfg['bootstrap']:
+            os.chdir(self.llvm_obj_dir_stage3)
+        else:
+            os.chdir(self.llvm_obj_dir_stage1)
+        super(EB_Clang, self).install_step()
+
+        # the static analyzer is not installed by default
+        # we do it by hand
+        if self.cfg['static_analyzer'] and LooseVersion(self.version) < LooseVersion('3.8'):
+            try:
+                tools_src_dir = os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools')
+                analyzer_target_dir = os.path.join(self.installdir, 'libexec', 'clang-analyzer')
+                bindir = os.path.join(self.installdir, 'bin')
+                for scan_dir in ['scan-build', 'scan-view']:
+                    shutil.copytree(os.path.join(tools_src_dir, scan_dir), os.path.join(analyzer_target_dir, scan_dir))
+                    os.symlink(os.path.relpath(bindir, os.path.join(analyzer_target_dir, scan_dir)),
+                               os.path.join(analyzer_target_dir, scan_dir, 'bin'))
+                    os.symlink(os.path.relpath(os.path.join(analyzer_target_dir, scan_dir, scan_dir), bindir),
+                               os.path.join(bindir, scan_dir))
+
+                mandir = os.path.join(self.installdir, 'share', 'man', 'man1')
+                os.makedirs(mandir)
+                shutil.copy2(os.path.join(tools_src_dir, 'scan-build', 'scan-build.1'), mandir)
+            except OSError, err:
+                raise EasyBuildError("Failed to copy static analyzer dirs to install dir: %s", err)
+
+    def sanity_check_step(self):
+        """Custom sanity check for Clang."""
+        shlib_ext = get_shared_lib_ext()
+        custom_paths = {
+            'files': [
+                "bin/clang", "bin/clang++", "bin/llvm-ar", "bin/llvm-nm", "bin/llvm-as", "bin/opt", "bin/llvm-link",
+                "bin/llvm-config", "bin/llvm-symbolizer", "include/llvm-c/Core.h", "include/clang-c/Index.h",
+                "lib/libclang.%s" % shlib_ext, "lib/clang/%s/include/stddef.h" % self.version,
+            ],
+            'dirs': ["include/clang", "include/llvm", "lib/clang/%s/lib" % self.version],
+        }
+        if self.cfg['static_analyzer']:
+            custom_paths['files'].extend(["bin/scan-build", "bin/scan-view"])
+
+        if self.cfg["usepolly"]:
+            custom_paths['files'].extend(["lib/LLVMPolly.%s" % shlib_ext])
+            custom_paths['dirs'].extend(["include/polly"])
+
+        if LooseVersion(self.version) >= LooseVersion('3.8'):
+            custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version])
+
+        super(EB_Clang, self).sanity_check_step(custom_paths=custom_paths)
+
+    def make_module_extra(self):
+        """Custom variables for Clang module."""
+        txt = super(EB_Clang, self).make_module_extra()
+        # we set the symbolizer path so that asan/tsan give meanfull output by default
+        asan_symbolizer_path = os.path.join(self.installdir, 'bin', 'llvm-symbolizer')
+        txt += self.module_generator.set_environment('ASAN_SYMBOLIZER_PATH', asan_symbolizer_path)
+        return txt
diff --git a/easyblocks/c/clang.py.old b/easyblocks/c/clang.py.old
new file mode 100644
index 0000000000000000000000000000000000000000..e0b60edd5711bfaf160e7fbb3ec52902fd149a04
--- /dev/null
+++ b/easyblocks/c/clang.py.old
@@ -0,0 +1,403 @@
+##
+# Copyright 2013 Dmitri Gribenko
+# Copyright 2013-2017 Ghent University
+#
+# This file is triple-licensed under GPLv2 (see below), MIT, and
+# BSD three-clause licenses.
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+##
+"""
+Support for building and installing Clang, implemented as an easyblock.
+
+@author: Dmitri Gribenko (National Technical University of Ukraine "KPI")
+@author: Ward Poelmans (Ghent University)
+"""
+
+import fileinput
+import glob
+import os
+import re
+import shutil
+import sys
+from distutils.version import LooseVersion
+
+from easybuild.easyblocks.generic.cmakemake import CMakeMake
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools import run
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.config import build_option
+from easybuild.tools.filetools import mkdir
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.run import run_cmd
+from easybuild.tools.systemtools import get_os_name, get_os_version, get_shared_lib_ext
+
+# List of all possible build targets for Clang
+CLANG_TARGETS = ["all", "AArch64", "ARM", "CppBackend", "Hexagon", "Mips",
+                 "MBlaze", "MSP430", "NVPTX", "PowerPC", "R600", "Sparc",
+                 "SystemZ", "X86", "XCore"]
+
+
+class EB_Clang(CMakeMake):
+    """Support for bootstrapping Clang."""
+
+    @staticmethod
+    def extra_options():
+        extra_vars = {
+            'assertions': [True, "Enable assertions.  Helps to catch bugs in Clang.", CUSTOM],
+            'build_targets': [["X86"], "Build targets for LLVM. Possible values: " + ', '.join(CLANG_TARGETS), CUSTOM],
+            'bootstrap': [True, "Bootstrap Clang using GCC", CUSTOM],
+            'usepolly': [False, "Build Clang with polly", CUSTOM],
+            'static_analyzer': [True, "Install the static analyser of Clang", CUSTOM],
+            # The sanitizer tests often fail on HPC systems due to the 'weird' environment.
+            'skip_sanitizer_tests': [False, "Do not run the sanitizer tests", CUSTOM],
+        }
+
+        return CMakeMake.extra_options(extra_vars)
+
+    def __init__(self, *args, **kwargs):
+        """Initialize custom class variables for Clang."""
+
+        super(EB_Clang, self).__init__(*args, **kwargs)
+        self.llvm_src_dir = None
+        self.llvm_obj_dir_stage1 = None
+        self.llvm_obj_dir_stage2 = None
+        self.llvm_obj_dir_stage3 = None
+        self.make_parallel_opts = ""
+
+        unknown_targets = [target for target in self.cfg['build_targets'] if target not in CLANG_TARGETS]
+
+        if unknown_targets:
+            raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.",
+                                 ', '.join(unknown_targets), ', '.join(CLANG_TARGETS))
+
+        if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in self.cfg['build_targets']:
+            raise EasyBuildError("Build target R600 not supported in < Clang-3.4")
+
+        if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in self.cfg['build_targets']:
+            raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3")
+
+    def check_readiness_step(self):
+        """Fail early on RHEL 5.x and derivatives because of known bug in libc."""
+        super(EB_Clang, self).check_readiness_step()
+        # RHEL 5.x have a buggy libc.  Building stage 2 will fail.
+        if get_os_name() in ['redhat', 'RHEL', 'centos', 'SL'] and get_os_version().startswith('5.'):
+            raise EasyBuildError("Can not build Clang on %s v5.x: libc is buggy, building stage 2 will fail. "
+                                 "See http://stackoverflow.com/questions/7276828/", get_os_name())
+
+    def extract_step(self):
+        """
+        Prepare a combined LLVM source tree.  The layout is:
+        llvm/             Unpack llvm-*.tar.gz here
+          projects/
+            compiler-rt/  Unpack compiler-rt-*.tar.gz here
+            openmp/       Unpack openmp-*.tar.xz here
+            libcxx/
+            libcxxabi/
+          tools/
+            clang/        Unpack clang-*.tar.gz here
+            clang/tools/extra
+            polly/        Unpack polly-*.tar.gz here
+        """
+
+        # Extract everything into separate directories.
+        super(EB_Clang, self).extract_step()
+
+        # Find the full path to the directory that was unpacked from llvm-*.tar.gz.
+        for tmp in self.src:
+            if tmp['name'].startswith("llvm-"):
+                self.llvm_src_dir = tmp['finalpath']
+                break
+
+        if self.llvm_src_dir is None:
+            raise EasyBuildError("Could not determine LLVM source root (LLVM source was not unpacked?)")
+
+        src_dirs = {}
+
+        def find_source_dir(globpatterns, targetdir):
+            """Search for directory with globpattern and rename it to targetdir"""
+            if not isinstance(globpatterns, list):
+                globpatterns = [globpatterns]
+
+            glob_src_dirs = [glob_dir for globpattern in globpatterns for glob_dir in glob.glob(globpattern)]
+            if len(glob_src_dirs) != 1:
+                raise EasyBuildError("Failed to find exactly one source directory for pattern %s: %s", globpatterns,
+                                     glob_src_dirs)
+            src_dirs[glob_src_dirs[0]] = targetdir
+
+        find_source_dir('compiler-rt-*', os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt'))
+
+        if self.cfg["usepolly"]:
+            find_source_dir('polly-*', os.path.join(self.llvm_src_dir, 'tools', 'polly'))
+
+        find_source_dir('cfe-*', os.path.join(self.llvm_src_dir, 'tools', 'clang'))
+
+        find_source_dir('clang-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx'))
+
+        if LooseVersion(self.version) >= LooseVersion('5.0'):
+            find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi'))
+
+        if LooseVersion(self.version) >= LooseVersion('3.8'):
+            find_source_dir('openmp-*', os.path.join(self.llvm_src_dir, 'projects', 'openmp'))
+
+        for src in self.src:
+            for (dirname, new_path) in src_dirs.items():
+                if src['name'].startswith(dirname):
+                    old_path = os.path.join(src['finalpath'], dirname)
+                    try:
+                        shutil.move(old_path, new_path)
+                    except IOError, err:
+                        raise EasyBuildError("Failed to move %s to %s: %s", old_path, new_path, err)
+                    src['finalpath'] = new_path
+                    break
+
+    def configure_step(self):
+        """Run CMake for stage 1 Clang."""
+
+        self.llvm_obj_dir_stage1 = os.path.join(self.builddir, 'llvm.obj.1')
+        if self.cfg['bootstrap']:
+            self.llvm_obj_dir_stage2 = os.path.join(self.builddir, 'llvm.obj.2')
+            self.llvm_obj_dir_stage3 = os.path.join(self.builddir, 'llvm.obj.3')
+
+        if LooseVersion(self.version) >= LooseVersion('3.3'):
+            disable_san_tests = False
+            # all sanitizer tests will fail when there's a limit on the vmem
+            # this is ugly but I haven't found a cleaner way so far
+            (vmemlim, ec) = run_cmd("ulimit -v", regexp=False)
+            if not vmemlim.startswith("unlimited"):
+                disable_san_tests = True
+                self.log.warn("There is a virtual memory limit set of %s KB. The tests of the "
+                              "sanitizers will be disabled as they need unlimited virtual "
+                              "memory unless --strict=error is used." % vmemlim.strip())
+
+            # the same goes for unlimited stacksize
+            (stacklim, ec) = run_cmd("ulimit -s", regexp=False)
+            if stacklim.startswith("unlimited"):
+                disable_san_tests = True
+                self.log.warn("The stacksize limit is set to unlimited. This causes the ThreadSanitizer "
+                              "to fail. The sanitizers tests will be disabled unless --strict=error is used.")
+
+            if (disable_san_tests or self.cfg['skip_sanitizer_tests']) and build_option('strict') != run.ERROR:
+                self.log.debug("Disabling the sanitizer tests")
+                self.disable_sanitizer_tests()
+
+        # Create and enter build directory.
+        mkdir(self.llvm_obj_dir_stage1)
+        os.chdir(self.llvm_obj_dir_stage1)
+
+        # GCC and Clang are installed in different prefixes and Clang will not
+        # find the GCC installation on its own.
+        # First try with GCCcore, as GCC built on top of GCCcore is just a wrapper for GCCcore and binutils,
+        # instead of a full-fledge compiler
+        gcc_prefix = get_software_root('GCCcore')
+
+        # If that doesn't work, try with GCC
+        if gcc_prefix is None:
+            gcc_prefix = get_software_root('GCC')
+
+        # If that doesn't work either, print error and exit
+        if gcc_prefix is None:
+            raise EasyBuildError("Can't find GCC or GCCcore to use")
+
+        self.cfg.update('configopts', "-DGCC_INSTALL_PREFIX='%s' " % gcc_prefix)
+        self.log.debug("Using %s as GCC_INSTALL_PREFIX", gcc_prefix)
+
+        self.cfg['configopts'] += "-DCMAKE_BUILD_TYPE=Release "
+        if self.cfg['assertions']:
+            self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=ON "
+        else:
+            self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=OFF "
+
+        self.cfg['configopts'] += '-DLLVM_TARGETS_TO_BUILD="%s" ' % ';'.join(self.cfg['build_targets'])
+
+        if self.cfg['parallel']:
+            self.make_parallel_opts = "-j %s" % self.cfg['parallel']
+
+        self.log.info("Configuring")
+        super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir)
+
+    def disable_sanitizer_tests(self):
+        """Disable the tests of all the sanitizers by removing the test directories from the build system"""
+        if LooseVersion(self.version) < LooseVersion('3.6'):
+            # for Clang 3.5 and lower, the tests are scattered over several CMakeLists.
+            # We loop over them, and patch out the rule that adds the sanitizers tests to the testsuite
+            patchfiles = [
+                "lib/asan",
+                "lib/dfsan",
+                "lib/lsan",
+                "lib/msan",
+                "lib/tsan",
+                "lib/ubsan",
+            ]
+
+            for patchfile in patchfiles:
+                patchfile_fp = os.path.join(self.llvm_src_dir, "projects/compiler-rt", patchfile, "CMakeLists.txt")
+                if os.path.exists(patchfile_fp):
+                    self.log.debug("Patching %s in %s" % (patchfile, self.llvm_src_dir))
+                    try:
+                        for line in fileinput.input(patchfile_fp, inplace=1, backup='.orig'):
+                            if "add_subdirectory(lit_tests)" not in line:
+                                sys.stdout.write(line)
+                    except (IOError, OSError), err:
+                        raise EasyBuildError("Failed to patch %s: %s", patchfile_fp, err)
+                else:
+                    self.log.debug("Not patching non-existent %s in %s" % (patchfile, self.llvm_src_dir))
+
+            # There is a common part seperate for the specific saniters, we disable all
+            # the common tests
+            patchfile = "projects/compiler-rt/lib/sanitizer_common/CMakeLists.txt"
+            try:
+                for line in fileinput.input("%s/%s" % (self.llvm_src_dir, patchfile), inplace=1, backup='.orig'):
+                    if "add_subdirectory(tests)" not in line:
+                        sys.stdout.write(line)
+            except IOError, err:
+                raise EasyBuildError("Failed to patch %s/%s: %s", self.llvm_src_dir, patchfile, err)
+        else:
+            # In Clang 3.6, the sanitizer tests are grouped together in one CMakeLists
+            # We patch out adding the subdirectories with the sanitizer tests
+            patchfile = "projects/compiler-rt/test/CMakeLists.txt"
+            patchfile_fp = os.path.join(self.llvm_src_dir, patchfile)
+            self.log.debug("Patching %s in %s" % (patchfile, self.llvm_src_dir))
+            patch_regex = re.compile(r'add_subdirectory\((.*san|sanitizer_common)\)')
+            try:
+                for line in fileinput.input(patchfile_fp, inplace=1, backup='.orig'):
+                    if not patch_regex.search(line):
+                        sys.stdout.write(line)
+            except IOError, err:
+                raise EasyBuildError("Failed to patch %s: %s", patchfile_fp, err)
+
+    def build_with_prev_stage(self, prev_obj, next_obj):
+        """Build Clang stage N using Clang stage N-1"""
+
+        # Create and enter build directory.
+        mkdir(next_obj)
+        os.chdir(next_obj)
+
+        # Configure.
+        CC = os.path.join(prev_obj, 'bin', 'clang')
+        CXX = os.path.join(prev_obj, 'bin', 'clang++')
+
+        options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir
+        options += "-DCMAKE_C_COMPILER='%s' " % CC
+        options += "-DCMAKE_CXX_COMPILER='%s' " % CXX
+        options += self.cfg['configopts']
+
+        self.log.info("Configuring")
+        run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True)
+
+        self.log.info("Building")
+        run_cmd("make %s" % self.make_parallel_opts, log_all=True)
+
+    def run_clang_tests(self, obj_dir):
+        os.chdir(obj_dir)
+
+        self.log.info("Running tests")
+        run_cmd("make %s check-all" % self.make_parallel_opts, log_all=True)
+
+    def build_step(self):
+        """Build Clang stage 1, 2, 3"""
+
+        # Stage 1: build using system compiler.
+        self.log.info("Building stage 1")
+        os.chdir(self.llvm_obj_dir_stage1)
+        super(EB_Clang, self).build_step()
+
+        if self.cfg['bootstrap']:
+            # Stage 1: run tests.
+            self.run_clang_tests(self.llvm_obj_dir_stage1)
+
+            self.log.info("Building stage 2")
+            self.build_with_prev_stage(self.llvm_obj_dir_stage1, self.llvm_obj_dir_stage2)
+            self.run_clang_tests(self.llvm_obj_dir_stage2)
+
+            self.log.info("Building stage 3")
+            self.build_with_prev_stage(self.llvm_obj_dir_stage2, self.llvm_obj_dir_stage3)
+            # Don't run stage 3 tests here, do it in the test step.
+
+    def test_step(self):
+        if self.cfg['bootstrap']:
+            self.run_clang_tests(self.llvm_obj_dir_stage3)
+        else:
+            self.run_clang_tests(self.llvm_obj_dir_stage1)
+
+    def install_step(self):
+        """Install stage 3 binaries."""
+
+        if self.cfg['bootstrap']:
+            os.chdir(self.llvm_obj_dir_stage3)
+        else:
+            os.chdir(self.llvm_obj_dir_stage1)
+        super(EB_Clang, self).install_step()
+
+        # the static analyzer is not installed by default
+        # we do it by hand
+        if self.cfg['static_analyzer'] and LooseVersion(self.version) < LooseVersion('3.8'):
+            try:
+                tools_src_dir = os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools')
+                analyzer_target_dir = os.path.join(self.installdir, 'libexec', 'clang-analyzer')
+                bindir = os.path.join(self.installdir, 'bin')
+                for scan_dir in ['scan-build', 'scan-view']:
+                    shutil.copytree(os.path.join(tools_src_dir, scan_dir), os.path.join(analyzer_target_dir, scan_dir))
+                    os.symlink(os.path.relpath(bindir, os.path.join(analyzer_target_dir, scan_dir)),
+                               os.path.join(analyzer_target_dir, scan_dir, 'bin'))
+                    os.symlink(os.path.relpath(os.path.join(analyzer_target_dir, scan_dir, scan_dir), bindir),
+                               os.path.join(bindir, scan_dir))
+
+                mandir = os.path.join(self.installdir, 'share', 'man', 'man1')
+                os.makedirs(mandir)
+                shutil.copy2(os.path.join(tools_src_dir, 'scan-build', 'scan-build.1'), mandir)
+            except OSError, err:
+                raise EasyBuildError("Failed to copy static analyzer dirs to install dir: %s", err)
+
+    def sanity_check_step(self):
+        """Custom sanity check for Clang."""
+        shlib_ext = get_shared_lib_ext()
+        custom_paths = {
+            'files': [
+                "bin/clang", "bin/clang++", "bin/llvm-ar", "bin/llvm-nm", "bin/llvm-as", "bin/opt", "bin/llvm-link",
+                "bin/llvm-config", "bin/llvm-symbolizer", "include/llvm-c/Core.h", "include/clang-c/Index.h",
+                "lib/libclang.%s" % shlib_ext, "lib/clang/%s/include/stddef.h" % self.version,
+            ],
+            'dirs': ["include/clang", "include/llvm", "lib/clang/%s/lib" % self.version],
+        }
+        if self.cfg['static_analyzer']:
+            custom_paths['files'].extend(["bin/scan-build", "bin/scan-view"])
+
+        if self.cfg["usepolly"]:
+            custom_paths['files'].extend(["lib/LLVMPolly.%s" % shlib_ext])
+            custom_paths['dirs'].extend(["include/polly"])
+
+        if LooseVersion(self.version) >= LooseVersion('3.8'):
+            custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version])
+
+        super(EB_Clang, self).sanity_check_step(custom_paths=custom_paths)
+
+    def make_module_extra(self):
+        """Custom variables for Clang module."""
+        txt = super(EB_Clang, self).make_module_extra()
+        # we set the symbolizer path so that asan/tsan give meanfull output by default
+        asan_symbolizer_path = os.path.join(self.installdir, 'bin', 'llvm-symbolizer')
+        txt += self.module_generator.set_environment('ASAN_SYMBOLIZER_PATH', asan_symbolizer_path)
+        return txt
diff --git a/easyblocks/d/doris.py b/easyblocks/d/doris.py
new file mode 100644
index 0000000000000000000000000000000000000000..306e31e8fd285161c4760543cb09e6c566e5c656
--- /dev/null
+++ b/easyblocks/d/doris.py
@@ -0,0 +1,131 @@
+##
+# Copyright 2009-2017 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# http://github.com/hpcugent/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+##
+"""
+EasyBuild support for building and installing Doris, implemented as an easyblock
+
+author: Kenneth Hoste (HPC-UGent)
+"""
+import os
+
+from easybuild.easyblocks.generic.configuremake import ConfigureMake
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.filetools import change_dir, mkdir
+from easybuild.tools.modules import get_software_root
+from easybuild.tools.run import run_cmd_qa
+
+
+class EB_Doris(ConfigureMake):
+    """Support for building/installing Doris."""
+
+    def configure_step(self):
+        """Custom configuration procedure for Doris."""
+        fftw = get_software_root('FFTW')
+        if fftw is None:
+            raise EasyBuildError("Required dependency FFTW is missing")
+        
+        # create installation directory (and /bin subdirectory) early, make sure it doesn't get removed later
+        self.make_installdir()
+        mkdir(os.path.join(self.installdir, 'bin'))
+        self.cfg['keeppreviousinstall'] = True
+
+        # configure/build/install should be done from 'doris_core' subdirectory
+        change_dir(os.path.join(self.cfg['start_dir'], 'doris_core'))
+
+        qa = {
+            "===> Press enter to continue.": '',
+            "===> What is your C++ compiler? [g++]": os.getenv('CXX'),
+            "===> Do you have the FFTW library (y/n)? [n]": 'y',
+            "===> What is the path to the FFTW library (libfftw3f.a or libfftw3f.so)? []": os.path.join(fftw, 'lib'),
+            "===> What is the path to the FFTW include file (fftw3.h)? []": os.path.join(fftw, 'include'),
+            "===> Do you have the VECLIB library (y/n)? [n]": 'n',
+            #"===> Do you have the LAPACK library (y/n)? [n]": 'y',
+            #"===> What is the path to the LAPACK library liblapack.a? []": os.path.join(lapack, 'lib'),
+            "==> Do you have the LAPACK library (y/n)? [n]": 'n',
+            "===> Are you working on a Little Endian (X86 PC, Intel) machine (y/n)? [y]": 'y',
+            "===> Installation of Doris in directory: /usr/local/bin (y/n)? [y]": 'n',
+            "===> Enter installation directory (use absolute path):": os.path.join(self.installdir, 'bin'),
+            "===> Press enter to continue (CTRL-C to exit).": '',
+        }
+        std_qa = {
+            "===> Do you want to compile a more verbose DEBUG version \(y/n\)\? \[n\](.|\n)*expected results\)": 'n',
+        }
+
+        run_cmd_qa('./configure', qa, std_qa=std_qa, log_all=True, simple=True)
+
+    def build_step(self):
+        """Custom build procedure for Doris."""
+        common_buildopts = self.cfg['buildopts']
+
+        # build Doris
+        change_dir(os.path.join(self.cfg['start_dir'], 'doris_core'))
+
+        super(EB_Doris, self).build_step()
+
+        # build SARtools
+        change_dir(os.path.join(self.cfg['start_dir'], 'sar_tools'))
+
+        self.cfg['buildopts'] = common_buildopts
+        self.cfg.update('buildopts', 'CC="%s"' % os.getenv('CXX'))
+        cflags = os.getenv('CXXFLAGS') + " -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
+        self.cfg.update('buildopts', 'CFLAGS="%s"' % cflags)
+
+        super(EB_Doris, self).build_step()
+
+        # build ENVISAT_TOOLS
+        change_dir(os.path.join(self.cfg['start_dir'], 'envisat_tools'))
+
+        self.cfg['buildopts'] = common_buildopts
+        self.cfg.update('buildopts', 'CC="%s"' % os.getenv('CC'))
+        self.cfg.update('buildopts', 'CFLAGS="%s"' % os.getenv('CFLAGS'))
+
+        super(EB_Doris, self).build_step()
+
+    def install_step(self):
+        """Custom build procedure for Doris."""
+        # install Doris
+        change_dir(os.path.join(self.cfg['start_dir'], 'doris_core'))
+        super(EB_Doris, self).install_step()
+
+        # install SARtools
+        self.cfg.update('installopts', 'INSTALL_DIR=%s' % os.path.join(self.installdir, 'bin'))
+        change_dir(os.path.join(self.cfg['start_dir'], 'sar_tools'))
+        super(EB_Doris, self).install_step()
+
+        # install ENVISAT_TOOLS
+        change_dir(os.path.join(self.cfg['start_dir'], 'envisat_tools'))
+        self.cfg.update('installopts', 'CC="%s"' % os.getenv('CC'))
+        self.cfg.update('installopts', 'CFLAGS="%s"' % os.getenv('CFLAGS'))
+        super(EB_Doris, self).install_step()
+
+    def sanity_check_step(self):
+        """Custom sanity check for Doris."""
+        doris_bins = ['cpx2ps', 'doris', 'plotcpm', 'run']
+        sartools_bins = ['bkconvert', 'cpxfiddle', 'flapjack', 'floatmult', 'wrap']
+        envisat_tools_bins = ['envisat_dump_header', 'envisat_dump_data']
+        custom_paths = {
+            'files': [os.path.join('bin', x) for x in doris_bins + sartools_bins + envisat_tools_bins],
+            'dirs': [],
+        }
+        super(EB_Doris, self).sanity_check_step(custom_paths=custom_paths)
diff --git a/easyblocks/i/imkl.py b/easyblocks/i/imkl.py
deleted file mode 100644
index 0fe0a33d043b107c9b9e7f102f7d65e616fa7446..0000000000000000000000000000000000000000
--- a/easyblocks/i/imkl.py
+++ /dev/null
@@ -1,396 +0,0 @@
-# #
-# Copyright 2009-2016 Ghent University
-#
-# This file is part of EasyBuild,
-# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
-# with support of Ghent University (http://ugent.be/hpc),
-# the Flemish Supercomputer Centre (VSC) (https://vscentrum.be/nl/en),
-# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
-# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
-#
-# http://github.com/hpcugent/easybuild
-#
-# EasyBuild is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation v2.
-#
-# EasyBuild is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
-# #
-"""
-EasyBuild support for installing the Intel Math Kernel Library (MKL), implemented as an easyblock
-
-@author: Stijn De Weirdt (Ghent University)
-@author: Dries Verdegem (Ghent University)
-@author: Kenneth Hoste (Ghent University)
-@author: Pieter De Baets (Ghent University)
-@author: Jens Timmerman (Ghent University)
-@author: Ward Poelmans (Ghent University)
-@author: Lumir Jasiok (IT4Innovations)
-"""
-
-import itertools
-import os
-import shutil
-import tempfile
-from distutils.version import LooseVersion
-
-import easybuild.tools.environment as env
-import easybuild.tools.toolchain as toolchain
-from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012
-from easybuild.framework.easyconfig import CUSTOM
-from easybuild.tools.build_log import EasyBuildError
-from easybuild.tools.filetools import rmtree2
-from easybuild.tools.modules import get_software_root
-from easybuild.tools.run import run_cmd
-from easybuild.tools.systemtools import get_shared_lib_ext
-
-
-class EB_imkl(IntelBase):
-    """
-    Class that can be used to install mkl
-    - tested with 10.2.1.017
-    -- will fail for all older versions (due to newer silent installer)
-    """
-
-    @staticmethod
-    def extra_options():
-        """Add easyconfig parameters custom to imkl (e.g. interfaces)."""
-        extra_vars = {
-            'interfaces': [True, "Indicates whether interfaces should be built", CUSTOM],
-        }
-        return IntelBase.extra_options(extra_vars)
-
-    def __init__(self, *args, **kwargs):
-        super(EB_imkl, self).__init__(*args, **kwargs)
-        # make sure $MKLROOT isn't set, it's known to cause problems with the installation
-        self.cfg.update('unwanted_env_vars', ['MKLROOT'])
-
-    def install_step(self):
-        """
-        Actual installation
-        - create silent cfg file
-        - execute command
-        """
-        silent_cfg_names_map = None
-        silent_cfg_extras = None
-
-        if LooseVersion(self.version) < LooseVersion('11.1'):
-            # since imkl v11.1, silent.cfg has been slightly changed to be 'more standard'
-
-            silent_cfg_names_map = {
-                'activation_name': ACTIVATION_NAME_2012,
-                'license_file_name': LICENSE_FILE_NAME_2012,
-            }
-
-        if LooseVersion(self.version) >= LooseVersion('11.1'):
-            silent_cfg_extras = {
-                'COMPONENTS': 'ALL',
-            }
-
-        super(EB_imkl, self).install_step(silent_cfg_names_map=silent_cfg_names_map, silent_cfg_extras=silent_cfg_extras)
-
-    def make_module_req_guess(self):
-        """
-        A dictionary of possible directories to look for
-        """
-        if LooseVersion(self.version) >= LooseVersion('10.3'):
-            if self.cfg['m32']:
-                raise EasyBuildError("32-bit not supported yet for IMKL v%s (>= 10.3)", self.version)
-            else:
-                retdict = {
-                    'PATH': ['bin', 'mkl/bin', 'mkl/bin/intel64', 'composerxe-2011/bin'],
-                    'LD_LIBRARY_PATH': ['lib/intel64', 'mkl/lib/intel64'],
-                    'LIBRARY_PATH': ['lib/intel64', 'mkl/lib/intel64'],
-                    'MANPATH': ['man', 'man/en_US'],
-                    'CPATH': ['mkl/include', 'mkl/include/fftw'],
-                    'FPATH': ['mkl/include', 'mkl/include/fftw'],
-                }
-                if LooseVersion(self.version) >= LooseVersion('11.0'):
-                    if LooseVersion(self.version) >= LooseVersion('11.3'):
-                        retdict['MIC_LD_LIBRARY_PATH'] = ['lib/intel64_lin_mic', 'mkl/lib/mic'];
-                    elif LooseVersion(self.version) >= LooseVersion('11.1'):
-                        retdict['MIC_LD_LIBRARY_PATH'] = ['lib/mic', 'mkl/lib/mic'];
-                    else:
-                        retdict['MIC_LD_LIBRARY_PATH'] = ['compiler/lib/mic', 'mkl/lib/mic'];
-                return retdict;
-        else:
-            if self.cfg['m32']:
-                return {
-                    'PATH': ['bin', 'bin/ia32', 'tbb/bin/ia32'],
-                    'LD_LIBRARY_PATH': ['lib', 'lib/32'],
-                    'LIBRARY_PATH': ['lib', 'lib/32'],
-                    'MANPATH': ['man', 'share/man', 'man/en_US'],
-                    'CPATH': ['include'],
-                    'FPATH': ['include']
-                }
-
-            else:
-                return {
-                    'PATH': ['bin', 'bin/intel64', 'tbb/bin/em64t'],
-                    'LD_LIBRARY_PATH': ['lib', 'lib/em64t'],
-                    'LIBRARY_PATH': ['lib', 'lib/em64t'],
-                    'MANPATH': ['man', 'share/man', 'man/en_US'],
-                    'CPATH': ['include'],
-                    'FPATH': ['include'],
-                }
-
-    def make_module_extra(self):
-        """Overwritten from Application to add extra txt"""
-        txt = super(EB_imkl, self).make_module_extra()
-        txt += self.module_generator.set_environment('MKLROOT', os.path.join(self.installdir, 'mkl'))
-        return txt
-
-    def post_install_step(self):
-        """
-        Install group libraries and interfaces (if desired).
-        """
-        super(EB_imkl, self).post_install_step()
-
-        shlib_ext = get_shared_lib_ext()
-
-        # reload the dependencies
-        self.load_dependency_modules()
-
-        if self.cfg['m32']:
-            extra = {
-                'libmkl.%s' % shlib_ext : 'GROUP (-lmkl_intel -lmkl_intel_thread -lmkl_core)',
-                'libmkl_em64t.a': 'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)',
-                'libmkl_solver.a': 'GROUP (libmkl_solver.a)',
-                'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_core.a)',
-                'libmkl_lapack.a': 'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)',
-                'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)'
-            }
-        else:
-            extra = {
-                'libmkl.%s' % shlib_ext: 'GROUP (-lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core)',
-                'libmkl_em64t.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)',
-                'libmkl_solver.a': 'GROUP (libmkl_solver_lp64.a)',
-                'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_lp64.a)',
-                'libmkl_lapack.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)',
-                'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)'
-            }
-
-        if LooseVersion(self.version) >= LooseVersion('10.3'):
-            libsubdir = os.path.join('mkl', 'lib', 'intel64')
-        else:
-            if self.cfg['m32']:
-                libsubdir = os.path.join('lib', '32')
-            else:
-                libsubdir = os.path.join('lib', 'em64t')
-
-        for fil, txt in extra.items():
-            dest = os.path.join(self.installdir, libsubdir, fil)
-            if not os.path.exists(dest):
-                try:
-                    f = open(dest, 'w')
-                    f.write(txt)
-                    f.close()
-                    self.log.info("File %s written" % dest)
-                except IOError, err:
-                    raise EasyBuildError("Can't write file %s: %s", dest, err)
-
-        # build the mkl interfaces, if desired
-        if self.cfg['interfaces']:
-
-            if LooseVersion(self.version) >= LooseVersion('10.3'):
-                intsubdir = os.path.join('mkl', 'interfaces')
-                inttarget = 'libintel64'
-            else:
-                intsubdir = 'interfaces'
-                if self.cfg['m32']:
-                    inttarget = 'lib32'
-                else:
-                    inttarget = 'libem64t'
-
-            cmd = "make -f makefile %s" % inttarget
-
-            # blas95 and lapack95 need more work, ignore for now
-            # blas95 and lapack also need include/.mod to be processed
-            fftw2libs = ['fftw2xc', 'fftw2xf']
-            fftw3libs = ['fftw3xc', 'fftw3xf']
-            cdftlibs = ['fftw2x_cdft']
-            if LooseVersion(self.version) >= LooseVersion('10.3'):
-                cdftlibs.append('fftw3x_cdft')
-
-            interfacedir = os.path.join(self.installdir, intsubdir)
-            try:
-                os.chdir(interfacedir)
-                self.log.info("Changed to interfaces directory %s" % interfacedir)
-            except OSError, err:
-                raise EasyBuildError("Can't change to interfaces directory %s", interfacedir)
-
-            compopt = None
-            # determine whether we're using a non-Intel GCC-based toolchain
-            # can't use toolchain.comp_family, because of dummy toolchain used when installing imkl
-            if get_software_root('icc') is None:
-                if get_software_root('GCC'):
-                    compopt = 'compiler=gnu'
-                else:
-                    raise EasyBuildError("Not using either Intel compilers nor GCC, "
-                                         "don't know how to build wrapper libs")
-            else:
-                compopt = 'compiler=intel'
-
-            for lib in fftw2libs + fftw3libs + cdftlibs:
-                buildopts = [compopt]
-                if lib in fftw3libs:
-                    buildopts.append('install_to=$INSTALL_DIR')
-                elif lib in cdftlibs:
-                    mpi_spec = None
-                    # check whether MPI_FAMILY constant is defined, so mpi_family() can be used
-                    if hasattr(self.toolchain, 'MPI_FAMILY') and self.toolchain.MPI_FAMILY is not None:
-                        mpi_spec_by_fam = {
-                            toolchain.MPICH: 'mpich2',  # MPICH is MPICH v3.x, which is MPICH2 compatible
-                            toolchain.MPICH2: 'mpich2',
-                            toolchain.MVAPICH2: 'mpich2',
-                            toolchain.OPENMPI: 'openmpi',
-                        }
-                        mpi_fam = self.toolchain.mpi_family()
-                        mpi_spec = mpi_spec_by_fam.get(mpi_fam)
-                        self.log.debug("Determined MPI specification based on MPI toolchain component: %s" % mpi_spec)
-                    else:
-                        # can't use toolchain.mpi_family, because of dummy toolchain
-                        if get_software_root('MPICH2') or get_software_root('MVAPICH2'):
-                            mpi_spec = 'mpich2'
-                        elif get_software_root('OpenMPI'):
-                            mpi_spec = 'openmpi'
-                        self.log.debug("Determined MPI specification based on loaded MPI module: %s" % mpi_spec)
-
-                    if mpi_spec is not None:
-                        buildopts.append('mpi=%s' % mpi_spec)
-
-                precflags = ['']
-                if lib.startswith('fftw2x') and not self.cfg['m32']:
-                    # build both single and double precision variants
-                    precflags = ['PRECISION=MKL_DOUBLE', 'PRECISION=MKL_SINGLE']
-
-                intflags = ['']
-                if lib in cdftlibs and not self.cfg['m32']:
-                    # build both 32-bit and 64-bit interfaces
-                    intflags = ['interface=lp64', 'interface=ilp64']
-
-                allopts = [list(opts) for opts in itertools.product(intflags, precflags)]
-
-                for flags, extraopts in itertools.product(['', '-fPIC'], allopts):
-                    tup = (lib, flags, buildopts, extraopts)
-                    self.log.debug("Building lib %s with: flags %s, buildopts %s, extraopts %s" % tup)
-
-                    tmpbuild = tempfile.mkdtemp(dir=self.builddir)
-                    self.log.debug("Created temporary directory %s" % tmpbuild)
-
-                    # always set INSTALL_DIR, SPEC_OPT, COPTS and CFLAGS
-                    # fftw2x(c|f): use $INSTALL_DIR, $CFLAGS and $COPTS
-                    # fftw3x(c|f): use $CFLAGS
-                    # fftw*cdft: use $INSTALL_DIR and $SPEC_OPT
-                    env.setvar('INSTALL_DIR', tmpbuild)
-                    env.setvar('SPEC_OPT', flags)
-                    env.setvar('COPTS', flags)
-                    env.setvar('CFLAGS', flags)
-
-                    try:
-                        intdir = os.path.join(interfacedir, lib)
-                        os.chdir(intdir)
-                        self.log.info("Changed to interface %s directory %s" % (lib, intdir))
-                    except OSError, err:
-                        raise EasyBuildError("Can't change to interface %s directory %s: %s", lib, intdir, err)
-
-                    fullcmd = "%s %s" % (cmd, ' '.join(buildopts + extraopts))
-                    res = run_cmd(fullcmd, log_all=True, simple=True)
-                    if not res:
-                        raise EasyBuildError("Building %s (flags: %s, fullcmd: %s) failed", lib, flags, fullcmd)
-
-                    for fn in os.listdir(tmpbuild):
-                        src = os.path.join(tmpbuild, fn)
-                        if flags == '-fPIC':
-                            # add _pic to filename
-                            ff = fn.split('.')
-                            fn = '.'.join(ff[:-1]) + '_pic.' + ff[-1]
-                        dest = os.path.join(self.installdir, libsubdir, fn)
-                        try:
-                            if os.path.isfile(src):
-                                shutil.move(src, dest)
-                                self.log.info("Moved %s to %s" % (src, dest))
-                        except OSError, err:
-                            raise EasyBuildError("Failed to move %s to %s: %s", src, dest, err)
-
-                    rmtree2(tmpbuild)
-
-    def sanity_check_step(self):
-        """Custom sanity check paths for Intel MKL."""
-        shlib_ext = get_shared_lib_ext()
-
-        mklfiles = None
-        mkldirs = None
-        ver = LooseVersion(self.version)
-        libs = ['libmkl_core.%s' % shlib_ext, 'libmkl_gnu_thread.%s' % shlib_ext,
-                'libmkl_intel_thread.%s' % shlib_ext, 'libmkl_sequential.%s' % shlib_ext]
-        extralibs = ['libmkl_blacs_intelmpi_%(suff)s.' + shlib_ext, 'libmkl_scalapack_%(suff)s.' + shlib_ext]
-
-        if self.cfg['interfaces']:
-            compsuff = '_intel'
-            if get_software_root('icc') is None:
-                if get_software_root('GCC'):
-                    compsuff = '_gnu'
-                else:
-                    raise EasyBuildError("Not using Intel/GCC, don't know compiler suffix for FFTW libraries.")
-
-            precs = ['_double', '_single']
-            if ver < LooseVersion('11'):
-                # no precision suffix in libfftw2 libs before imkl v11
-                precs = ['']
-            fftw_vers = ['2x%s%s' % (x, prec) for x in ['c', 'f'] for prec in precs] + ['3xc', '3xf']
-            pics = ['', '_pic']
-            libs = ['libfftw%s%s%s.a' % (fftwver, compsuff, pic) for fftwver in fftw_vers for pic in pics]
-
-            fftw_cdft_vers = ['2x_cdft_DOUBLE']
-            if not self.cfg['m32']:
-                fftw_cdft_vers.append('2x_cdft_SINGLE')
-            if ver >= LooseVersion('10.3'):
-                fftw_cdft_vers.append('3x_cdft')
-            if ver >= LooseVersion('11.0.2'):
-                bits = ['_lp64']
-                if not self.cfg['m32']:
-                    bits.append('_ilp64')
-            else:
-                # no bits suffix in cdft libs before imkl v11.0.2
-                bits = ['']
-            libs += ['libfftw%s%s%s.a' % x for x in itertools.product(fftw_cdft_vers, bits, pics)]
-
-        if ver >= LooseVersion('10.3'):
-            if self.cfg['m32']:
-                raise EasyBuildError("Sanity check for 32-bit not implemented yet for IMKL v%s (>= 10.3)", self.version)
-            else:
-                mkldirs = ['bin', 'mkl/bin', 'mkl/lib/intel64', 'mkl/include']
-                if ver < LooseVersion('11.3'):
-                    mkldirs.append('mkl/bin/intel64')
-                libs += [lib % {'suff': suff} for lib in extralibs for suff in ['lp64', 'ilp64']]
-                mklfiles = ['mkl/lib/intel64/libmkl.%s' % shlib_ext, 'mkl/include/mkl.h'] + \
-                           ['mkl/lib/intel64/%s' % lib for lib in libs]
-                if ver >= LooseVersion('10.3.4') and ver < LooseVersion('11.1'):
-                    mkldirs += ['compiler/lib/intel64']
-                else:
-                    mkldirs += ['lib/intel64']
-
-        else:
-            if self.cfg['m32']:
-                mklfiles = ['lib/32/libmkl.%s' % shlib_ext, 'include/mkl.h'] + \
-                           ['lib/32/%s' % lib for lib in libs]
-                mkldirs = ['lib/32', 'include/32', 'interfaces']
-            else:
-                libs += [lib % {'suff': suff} for lib in extralibs for suff in ['lp64', 'ilp64']]
-                mklfiles = ['lib/em64t/libmkl.%s' % shlib_ext, 'include/mkl.h'] + \
-                           ['lib/em64t/%s' % lib for lib in libs]
-                mkldirs = ['lib/em64t', 'include/em64t', 'interfaces']
-
-        custom_paths = {
-            'files': mklfiles,
-            'dirs': mkldirs,
-        }
-
-        super(EB_imkl, self).sanity_check_step(custom_paths=custom_paths)
diff --git a/easyblocks/i/impi.py b/easyblocks/i/impi.py
new file mode 100644
index 0000000000000000000000000000000000000000..349b6d3085d9feb2468a41e85ded3062a716e12f
--- /dev/null
+++ b/easyblocks/i/impi.py
@@ -0,0 +1,233 @@
+# #
+# Copyright 2009-2017 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+# #
+"""
+EasyBuild support for installing the Intel MPI library, implemented as an easyblock
+
+@author: Stijn De Weirdt (Ghent University)
+@author: Dries Verdegem (Ghent University)
+@author: Kenneth Hoste (Ghent University)
+@author: Pieter De Baets (Ghent University)
+@author: Jens Timmerman (Ghent University)
+@author: Damian Alvarez (Forschungszentrum Juelich GmbH)
+"""
+import fileinput
+import os
+import sys
+from distutils.version import LooseVersion
+
+from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.filetools import apply_regex_substitutions
+from easybuild.tools.run import run_cmd
+from easybuild.tools.systemtools import get_shared_lib_ext
+
+
+class EB_impi(IntelBase):
+    """
+    Support for installing Intel MPI library
+    """
+    @staticmethod
+    def extra_options():
+        extra_vars = {
+            'set_mpi_wrappers_compiler': [False, 'Override default compiler used by MPI wrapper commands', CUSTOM],
+            'set_mpi_wrapper_aliases_gcc': [False, 'Set compiler for mpigcc/mpigxx via aliases', CUSTOM],
+            'set_mpi_wrapper_aliases_intel': [False, 'Set compiler for mpiicc/mpiicpc/mpiifort via aliases', CUSTOM],
+            'set_mpi_wrappers_all': [False, 'Set (default) compiler for all MPI wrapper commands', CUSTOM],
+        }
+        return IntelBase.extra_options(extra_vars)
+
+    def prepare_step(self, *args, **kwargs):
+        if LooseVersion(self.version) >= LooseVersion('2017.2.174'):
+            kwargs['requires_runtime_license'] = False
+            super(EB_impi, self).prepare_step(*args, **kwargs)
+        else:
+            super(EB_impi, self).prepare_step(*args, **kwargs)
+
+    def install_step(self):
+        """
+        Actual installation
+        - create silent cfg file
+        - execute command
+        """
+        impiver = LooseVersion(self.version)
+        if impiver >= LooseVersion('4.0.1'):
+            # impi starting from version 4.0.1.x uses standard installation procedure.
+
+            silent_cfg_names_map = {}
+
+            if impiver < LooseVersion('4.1.1'):
+                # since impi v4.1.1, silent.cfg has been slightly changed to be 'more standard'
+                silent_cfg_names_map.update({
+                    'activation_name': ACTIVATION_NAME_2012,
+                    'license_file_name': LICENSE_FILE_NAME_2012,
+                })
+
+            super(EB_impi, self).install_step(silent_cfg_names_map=silent_cfg_names_map)
+
+            # impi v4.1.1 and v5.0.1 installers create impi/<version> subdir, so stuff needs to be moved afterwards
+            if impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'):
+                super(EB_impi, self).move_after_install()
+        else:
+            # impi up until version 4.0.0.x uses custom installation procedure.
+            silent = \
+"""
+[mpi]
+INSTALLDIR=%(ins)s
+LICENSEPATH=%(lic)s
+INSTALLMODE=NONRPM
+INSTALLUSER=NONROOT
+UPDATE_LD_SO_CONF=NO
+PROCEED_WITHOUT_PYTHON=yes
+AUTOMOUNTED_CLUSTER=yes
+EULA=accept
+[mpi-rt]
+INSTALLDIR=%(ins)s
+LICENSEPATH=%(lic)s
+INSTALLMODE=NONRPM
+INSTALLUSER=NONROOT
+UPDATE_LD_SO_CONF=NO
+PROCEED_WITHOUT_PYTHON=yes
+AUTOMOUNTED_CLUSTER=yes
+EULA=accept
+
+""" % {'lic': self.license_file, 'ins': self.installdir}
+
+            # already in correct directory
+            silentcfg = os.path.join(os.getcwd(), "silent.cfg")
+            try:
+                f = open(silentcfg, 'w')
+                f.write(silent)
+                f.close()
+            except:
+                raise EasyBuildError("Writing silent cfg file %s failed.", silent)
+            self.log.debug("Contents of %s: %s" % (silentcfg, silent))
+
+            tmpdir = os.path.join(os.getcwd(), self.version, 'mytmpdir')
+            try:
+                os.makedirs(tmpdir)
+            except:
+                raise EasyBuildError("Directory %s can't be created", tmpdir)
+
+            cmd = "./install.sh --tmp-dir=%s --silent=%s" % (tmpdir, silentcfg)
+            run_cmd(cmd, log_all=True, simple=True)
+
+    def post_install_step(self):
+        """Custom post install step for IMPI, fix broken env scripts after moving installed files."""
+        super(EB_impi, self).post_install_step()
+
+        impiver = LooseVersion(self.version)
+        if impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'):
+            if impiver >= LooseVersion('2018.0.128'):
+                script_paths = [os.path.join('intel64', 'bin')]
+            else:
+                script_paths = [os.path.join('intel64', 'bin'), os.path.join('mic', 'bin')]
+            # fix broken env scripts after the move
+            regex_subs = [(r"^setenv I_MPI_ROOT.*", r"setenv I_MPI_ROOT %s" % self.installdir)]
+            for script in [os.path.join(script_path,'mpivars.csh') for script_path in script_paths]:
+                apply_regex_substitutions(os.path.join(self.installdir, script), regex_subs)
+            regex_subs = [(r"^I_MPI_ROOT=.*", r"I_MPI_ROOT=%s; export I_MPI_ROOT" % self.installdir)]
+            for script in [os.path.join(script_path,'mpivars.sh') for script_path in script_paths]:
+                apply_regex_substitutions(os.path.join(self.installdir, script), regex_subs)
+
+    def sanity_check_step(self):
+        """Custom sanity check paths for IMPI."""
+
+        suff = "64"
+        if self.cfg['m32']:
+            suff = ""
+
+        mpi_mods = ['mpi.mod']
+        if LooseVersion(self.version) > LooseVersion('4.0'):
+            mpi_mods.extend(["mpi_base.mod", "mpi_constants.mod", "mpi_sizeofs.mod"])
+
+        custom_paths = {
+            'files': ["bin%s/mpi%s" % (suff, x) for x in ["icc", "icpc", "ifort"]] +
+                     ["include%s/mpi%s.h" % (suff, x) for x in ["cxx", "f", "", "o", "of"]] +
+                     ["include%s/%s" % (suff, x) for x in ["i_malloc.h"] + mpi_mods] +
+                     ["lib%s/libmpi.%s" % (suff, get_shared_lib_ext()), "lib%s/libmpi.a" % suff],
+            'dirs': [],
+        }
+
+        super(EB_impi, self).sanity_check_step(custom_paths=custom_paths)
+
+    def make_module_req_guess(self):
+        """
+        A dictionary of possible directories to look for
+        """
+        if self.cfg['m32']:
+            lib_dirs = ['lib', 'lib/ia32', 'ia32/lib']
+            include_dirs = ['include']
+            return {
+                'PATH': ['bin', 'bin/ia32', 'ia32/bin'],
+                'LD_LIBRARY_PATH': lib_dirs,
+                'LIBRARY_PATH': lib_dirs,
+                'CPATH': include_dirs,
+                'MIC_LD_LIBRARY_PATH' : ['mic/lib'],
+            }
+        else:
+            lib_dirs = ['lib/em64t', 'lib64']
+            include_dirs = ['include64']
+            return {
+                'PATH': ['bin/intel64', 'bin64'],
+                'LD_LIBRARY_PATH': lib_dirs,
+                'LIBRARY_PATH': lib_dirs,
+                'CPATH': include_dirs,
+                'MIC_LD_LIBRARY_PATH' : ['mic/lib'],
+            }
+
+    def make_module_extra(self):
+        """Overwritten from Application to add extra txt"""
+        txt = super(EB_impi, self).make_module_extra()
+        txt += self.module_generator.set_environment('I_MPI_ROOT', self.installdir)
+        if self.cfg['set_mpi_wrappers_compiler'] or self.cfg['set_mpi_wrappers_all']:
+            for var in ['CC', 'CXX', 'F77', 'F90', 'FC']:
+                if var == 'FC':
+                    # $FC isn't defined by EasyBuild framework, so use $F90 instead
+                    src_var = 'F90'
+                else:
+                    src_var = var
+
+                target_var = 'I_MPI_%s' % var
+
+                val = os.getenv(src_var)
+                if val:
+                    txt += self.module_generator.set_environment(target_var, val)
+                else:
+                    raise EasyBuildError("Environment variable $%s not set, can't define $%s", src_var, target_var)
+
+        if self.cfg['set_mpi_wrapper_aliases_gcc'] or self.cfg['set_mpi_wrappers_all']:
+            # force mpigcc/mpigxx to use GCC compilers, as would be expected based on their name
+            txt += self.module_generator.set_alias('mpigcc', 'mpigcc -cc=gcc')
+            txt += self.module_generator.set_alias('mpigxx', 'mpigxx -cxx=g++')
+
+        if self.cfg['set_mpi_wrapper_aliases_intel'] or self.cfg['set_mpi_wrappers_all']:
+            # do the same for mpiicc/mpiipc/mpiifort to be consistent, even if they may not exist
+            txt += self.module_generator.set_alias('mpiicc', 'mpiicc -cc=icc')
+            txt += self.module_generator.set_alias('mpiicpc', 'mpiicpc -cxx=icpc')
+            # -fc also works, but -f90 takes precedence
+            txt += self.module_generator.set_alias('mpiifort', 'mpiifort -f90=ifort')
+
+        return txt
diff --git a/easyblocks/t/trilinos.py b/easyblocks/t/trilinos.py
new file mode 100644
index 0000000000000000000000000000000000000000..de40dd0a742bfc6d05aebdb955b0b3392163161f
--- /dev/null
+++ b/easyblocks/t/trilinos.py
@@ -0,0 +1,251 @@
+##
+# Copyright 2009-2017 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+##
+"""
+EasyBuild support for Trilinos, implemented as an easyblock
+
+@author: Kenneth Hoste (Ghent University)
+"""
+import os
+import re
+
+from distutils.version import LooseVersion
+
+import easybuild.tools.toolchain as toolchain
+from easybuild.easyblocks.generic.cmakemake import CMakeMake
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.modules import get_software_root
+
+
+class EB_Trilinos(CMakeMake):
+    """Support for building Trilinos."""
+    # see http://trilinos.sandia.gov/Trilinos10CMakeQuickstart.txt
+
+    @staticmethod
+    def extra_options():
+        """Add extra config options specific to Trilinos."""
+        extra_vars = {
+            'shared_libs': [False, "Build shared libs; if False, build static libs", CUSTOM],
+            'openmp': [True, "Enable OpenMP support", CUSTOM],
+            'all_exts': [True, "Enable all Trilinos packages", CUSTOM],
+            'skip_exts': [[], "List of Trilinos packages to skip", CUSTOM],
+            'verbose': [False, "Configure for verbose output", CUSTOM],
+        }
+        return CMakeMake.extra_options(extra_vars)
+
+    def configure_step(self):
+        """Set some extra environment variables before configuring."""
+
+        # enable verbose output if desired
+        if self.cfg['verbose']:
+            for x in ["CONFIGURE", "MAKEFILE"]:
+                self.cfg.update('configopts', "-DTrilinos_VERBOSE_%s:BOOL=ON" % x)
+
+        # compiler flags
+        cflags = [os.getenv('CFLAGS')]
+        cxxflags = [os.getenv('CXXFLAGS')]
+        fflags = [os.getenv('FFLAGS')]
+
+        ignore_cxx_seek_mpis = [toolchain.INTELMPI, toolchain.MPICH, toolchain.MPICH2, toolchain.MVAPICH2]  #@UndefinedVariable
+        ignore_cxx_seek_flag = "-DMPICH_IGNORE_CXX_SEEK"
+        if self.toolchain.mpi_family() in ignore_cxx_seek_mpis:
+            cflags.append(ignore_cxx_seek_flag)
+            cxxflags.append(ignore_cxx_seek_flag)
+            fflags.append(ignore_cxx_seek_flag)
+
+        self.cfg.update('configopts', '-DCMAKE_C_FLAGS="%s"' % ' '.join(cflags))
+        self.cfg.update('configopts', '-DCMAKE_CXX_FLAGS="%s"' % ' '.join(cxxflags))
+        self.cfg.update('configopts', '-DCMAKE_Fortran_FLAGS="%s"' % ' '.join(fflags))
+
+        # OpenMP
+        if self.cfg['openmp']:
+            self.cfg.update('configopts', "-DTrilinos_ENABLE_OpenMP:BOOL=ON")
+
+        # MPI
+        if self.toolchain.options.get('usempi', None):
+            self.cfg.update('configopts', "-DTPL_ENABLE_MPI:BOOL=ON")
+
+        # shared libraries
+        if self.cfg['shared_libs']:
+            self.cfg.update('configopts', "-DBUILD_SHARED_LIBS:BOOL=ON")
+        else:
+            self.cfg.update('configopts', "-DBUILD_SHARED_LIBS:BOOL=OFF")
+
+        # release or debug get_version
+        if self.toolchain.options['debug']:
+            self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE:STRING=DEBUG")
+        else:
+            self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE:STRING=RELEASE")
+
+        # enable full testing
+        self.cfg.update('configopts', "-DTrilinos_ENABLE_TESTS:BOOL=ON")
+        self.cfg.update('configopts', "-DTrilinos_ENABLE_ALL_FORWARD_DEP_PACKAGES:BOOL=ON")
+
+        lib_re = re.compile("^lib(.*).a$")
+
+        # BLAS, LAPACK
+        for dep in ["BLAS", "LAPACK"]:
+            self.cfg.update('configopts', '-DTPL_ENABLE_%s:BOOL=ON' % dep)
+            libdirs = os.getenv('%s_LIB_DIR' % dep)
+            if self.toolchain.comp_family() == toolchain.GCC:  #@UndefinedVariable
+                libdirs += ";%s/lib64" % get_software_root('GCC')
+            self.cfg.update('configopts', '-D%s_LIBRARY_DIRS="%s"' % (dep, libdirs))
+            libs = os.getenv('%s_MT_STATIC_LIBS' % dep).split(',')
+            lib_names = ';'.join([lib_re.search(l).group(1) for l in libs])
+            if self.toolchain.comp_family() == toolchain.GCC:  #@UndefinedVariable
+                # explicitely specify static lib!
+                lib_names += ";libgfortran.a"
+            self.cfg.update('configopts', '-D%s_LIBRARY_NAMES="%s"' % (dep, lib_names))
+
+        # UMFPACK is part of SuiteSparse
+        suitesparse = get_software_root('SuiteSparse')
+        if suitesparse:
+            self.cfg.update('configopts', "-DTPL_ENABLE_UMFPACK:BOOL=ON")
+            incdirs, libdirs, libnames = [], [], []
+            for lib in ["UMFPACK", "CHOLMOD", "COLAMD", "AMD"]:
+                incdirs.append(os.path.join(suitesparse, lib, "Include"))
+                libdirs.append(os.path.join(suitesparse, lib, "Lib"))
+                libnames.append(lib.lower())
+            # add SuiteSparse config lib, it is in recent versions of suitesparse
+            libdirs.append(os.path.join(suitesparse, 'SuiteSparse_config'))
+            libnames.append('suitesparseconfig')
+            self.cfg.update('configopts', '-DUMFPACK_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
+            self.cfg.update('configopts', '-DUMFPACK_LIBRARY_DIRS:PATH="%s"' % ';'.join(libdirs))
+            self.cfg.update('configopts', '-DUMFPACK_LIBRARY_NAMES:STRING="%s"' % ';'.join(libnames))
+
+        # BLACS
+        if get_software_root('BLACS'):
+            self.cfg.update('configopts', "-DTPL_ENABLE_BLACS:BOOL=ON")
+            self.cfg.update('configopts', '-DBLACS_INCLUDE_DIRS:PATH="%s"' % os.getenv('BLACS_INC_DIR'))
+            self.cfg.update('configopts', '-DBLACS_LIBRARY_DIRS:PATH="%s"' % os.getenv('BLACS_LIB_DIR'))
+            blacs_lib_names = os.getenv('BLACS_STATIC_LIBS').split(',')
+            blacs_lib_names = [lib_re.search(x).group(1) for x in blacs_lib_names]
+            self.cfg.update('configopts', '-DBLACS_LIBRARY_NAMES:STRING="%s"' % (';'.join(blacs_lib_names)))
+
+        # ScaLAPACK
+        if get_software_root('ScaLAPACK'):
+            self.cfg.update('configopts', "-DTPL_ENABLE_SCALAPACK:BOOL=ON")
+            self.cfg.update('configopts', '-DSCALAPACK_INCLUDE_DIRS:PATH="%s"' % os.getenv('SCALAPACK_INC_DIR'))
+            self.cfg.update('configopts', '-DSCALAPACK_LIBRARY_DIRS:PATH="%s;%s"' % (os.getenv('SCALAPACK_LIB_DIR'),
+                                                                                    os.getenv('BLACS_LIB_DIR')))
+        # PETSc
+        petsc = get_software_root('PETSc')
+        if petsc:
+            self.cfg.update('configopts', "-DTPL_ENABLE_PETSC:BOOL=ON")
+            incdirs = [os.path.join(petsc, "include")]
+            self.cfg.update('configopts', '-DPETSC_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
+            petsc_libdirs = [
+                             os.path.join(petsc, "lib"),
+                             os.path.join(suitesparse, "UMFPACK", "Lib"),
+                             os.path.join(suitesparse, "CHOLMOD", "Lib"),
+                             os.path.join(suitesparse, "COLAMD", "Lib"),
+                             os.path.join(suitesparse, "AMD", "Lib"),
+                             os.getenv('FFTW_LIB_DIR'),
+                             os.path.join(get_software_root('ParMETIS'), "Lib")
+                             ]
+            self.cfg.update('configopts', '-DPETSC_LIBRARY_DIRS:PATH="%s"' % ';'.join(petsc_libdirs))
+            petsc_libnames = ["petsc", "umfpack", "cholmod", "colamd", "amd", "parmetis", "metis"]
+            petsc_libnames += [lib_re.search(x).group(1) for x in os.getenv('FFTW_STATIC_LIBS').split(',')]
+            self.cfg.update('configopts', '-DPETSC_LIBRARY_NAMES:STRING="%s"' % ';'.join(petsc_libnames))
+
+        # other Third-Party Libraries (TPLs)
+        deps = self.cfg.dependencies()
+        builddeps = self.cfg.builddependencies() + ["SuiteSparse"]
+        deps = [dep['name'] for dep in deps if not dep['name'] in builddeps]
+        for dep in deps:
+            deproot = get_software_root(dep)
+            if deproot:
+                depmap = {
+                          'SCOTCH': 'Scotch',
+                          }
+                dep = depmap.get(dep, dep)
+                self.cfg.update('configopts', "-DTPL_ENABLE_%s:BOOL=ON" % dep)
+                incdir = os.path.join(deproot, "include")
+                self.cfg.update('configopts', '-D%s_INCLUDE_DIRS:PATH="%s"' % (dep, incdir))
+                libdir = os.path.join(deproot, "lib")
+                self.cfg.update('configopts', '-D%s_LIBRARY_DIRS:PATH="%s"' % (dep, libdir))
+
+        # extensions_step
+        if self.cfg['all_exts']:
+            self.cfg.update('configopts', "-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON")
+
+        else:
+            for ext in self.cfg['exts_list']:
+                self.cfg.update('configopts', "-DTrilinos_ENABLE_%s=ON" % ext)
+
+        # packages to skip
+        skip_exts = self.cfg['skip_exts']
+        if skip_exts:
+            for ext in skip_exts:
+                self.cfg.update('configopts', "-DTrilinos_ENABLE_%s:BOOL=OFF" % ext)
+
+        # building in source dir not supported
+        try:
+            build_dir = "BUILD"
+            os.mkdir(build_dir)
+            os.chdir(build_dir)
+        except OSError, err:
+            raise EasyBuildError("Failed to create and move into build directory: %s", err)
+
+        # configure using cmake
+        super(EB_Trilinos, self).configure_step(srcdir="..")
+
+    def build_step(self):
+        """Build with make (verbose logging enabled)."""
+        super(EB_Trilinos, self).build_step(verbose=True)
+
+    def sanity_check_step(self):
+        """Custom sanity check for Trilinos."""
+
+        # selection of libraries
+        libs = ["Amesos", "Anasazi", "AztecOO", "Belos", "Epetra", "Galeri",
+                "GlobiPack", "Ifpack", "Intrepid", "Isorropia", "Kokkos",
+                "Komplex", "LOCA", "Mesquite", "ML", "Moertel", "MOOCHO", "NOX",
+                "Pamgen", "RTOp", "Rythmos", "Sacado", "Shards", "Stratimikos",
+                "Teuchos", "Tpetra", "Triutils", "Zoltan"]
+
+        libs = [l for l in libs if not l in self.cfg['skip_exts']]
+
+        # Teuchos was refactored in 11.2
+        if LooseVersion(self.version) >= LooseVersion('11.2') and  'Teuchos' in libs:
+            libs.remove('Teuchos')
+            libs.extend(['teuchoscomm', 'teuchoscore', 'teuchosnumerics', 'teuchosparameterlist', 'teuchosremainder'])
+
+        # Kokkos was refactored in 12.x, check for libkokkoscore.a rather than libkokkos.a
+        if LooseVersion(self.version) >= LooseVersion('12') and 'Kokkos' in libs:
+            libs.remove('Kokkos')
+            libs.append('kokkoscore')
+
+	if LooseVersion(self.version) >= LooseVersion('12.10') and 'Galeri' in libs:
+            libs.remove('Galeri')
+            libs.append('galeri-epetra')
+            libs.append('galeri-xpetra')
+
+        custom_paths = {
+            'files': [os.path.join('lib', 'lib%s.a' % x.lower()) for x in libs],
+            'dirs': ['bin', 'include']
+        }
+
+        super(EB_Trilinos, self).sanity_check_step(custom_paths=custom_paths)