Exemple #1
0
    def configure_step(self):
        """Configure build: set config options and configure"""

        if LooseVersion(self.version) < LooseVersion("4.3"):
            self.cfg.update('configopts', "--enable-shared")

            if self.toolchain.options['pic']:
                self.cfg.update('configopts', '--with-pic')

            tup = (os.getenv('FFLAGS'), os.getenv('MPICC'), os.getenv('F90'))
            self.cfg.update('configopts', 'FCFLAGS="%s" CC="%s" FC="%s"' % tup)

            # add -DgFortran to CPPFLAGS when building with GCC
            if self.toolchain.comp_family(
            ) == toolchain.GCC:  #@UndefinedVariable
                self.cfg.update(
                    'configopts',
                    'CPPFLAGS="%s -DgFortran"' % os.getenv('CPPFLAGS'))

            ConfigureMake.configure_step(self)

        else:
            hdf5 = get_software_root('HDF5')
            if hdf5:
                env.setvar('HDF5_ROOT', hdf5)

            CMakeMake.configure_step(self)
Exemple #2
0
    def configure_step(self):
        """Configure build: set config options and configure"""

        if LooseVersion(self.version) < LooseVersion("4.3"):
            self.cfg.update('configopts', "--enable-shared")

            if self.toolchain.options['pic']:
                self.cfg.update('configopts', '--with-pic')

#            tup = (os.getenv('FFLAGS'), os.getenv('MPICC'), os.getenv('F90'))
            tup = (os.getenv('FFLAGS'), os.getenv('CC'), os.getenv('F90'))
            self.cfg.update('configopts', 'FCFLAGS="%s" CC="%s" FC="%s"' % tup)

            # add -DgFortran to CPPFLAGS when building with GCC
            if self.toolchain.comp_family() == toolchain.GCC:  #@UndefinedVariable
                self.cfg.update('configopts', 'CPPFLAGS="%s -DgFortran"' % os.getenv('CPPFLAGS'))

            ConfigureMake.configure_step(self)

        else:
            hdf5 = get_software_root('HDF5')
            if hdf5:
                env.setvar('HDF5_ROOT', hdf5)

            CMakeMake.configure_step(self)
    def install_step(self):
        """Custom install procedure for EggLib: first build/install C++ library, then build Python library."""

        # build/install C++ library
        cpp_subdir = os.path.join(self.builddir, 'egglib-cpp-%s' % self.version)
        try:
            os.chdir(cpp_subdir)
        except OSError as err:
            raise EasyBuildError("Failed to move to: %s", err)

        ConfigureMake.configure_step(self)
        ConfigureMake.build_step(self)
        ConfigureMake.install_step(self)

        # header files and libraries must be found when building Python library
        for varname, subdir in [('CPATH', 'include'), ('LIBRARY_PATH', 'lib')]:
            env.setvar(varname, '%s:%s' % (os.path.join(self.installdir, subdir), os.environ.get(varname, '')))

        # build/install Python package
        py_subdir = os.path.join(self.builddir, 'egglib-py-%s' % self.version)
        try:
            os.chdir(py_subdir)
        except OSError as err:
            raise EasyBuildError("Failed to move to: %s", err)

        PythonPackage.build_step(self)

        self.cfg.update('installopts', "--install-lib %s" % os.path.join(self.installdir, self.pylibdir))
        self.cfg.update('installopts', "--install-scripts %s" % os.path.join(self.installdir, 'bin'))

        PythonPackage.install_step(self)
Exemple #4
0
    def configure_step(self):
        """Configure build: set config options and configure"""

        shlib_ext = get_shared_lib_ext()

        if LooseVersion(self.version) < LooseVersion("4.3"):
            self.cfg.update('configopts', "--enable-shared")

            if self.toolchain.options['pic']:
                self.cfg.update('configopts', '--with-pic')

            tup = (os.getenv('FFLAGS'), os.getenv('MPICC'), os.getenv('F90'))
            self.cfg.update('configopts', 'FCFLAGS="%s" CC="%s" FC="%s"' % tup)

            # add -DgFortran to CPPFLAGS when building with GCC
            if self.toolchain.comp_family() == toolchain.GCC:  #@UndefinedVariable
                self.cfg.update('configopts', 'CPPFLAGS="%s -DgFortran"' % os.getenv('CPPFLAGS'))

            ConfigureMake.configure_step(self)

        else:
            for (dep, libname) in [('cURL', 'curl'), ('HDF5', 'hdf5'), ('Szip', 'sz'), ('zlib', 'z'),
                                   ('PnetCDF', 'pnetcdf')]:
                dep_root = get_software_root(dep)
                dep_libdir = get_software_libdir(dep)

                if dep_root:
                    incdir = os.path.join(dep_root, 'include')
                    self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s ' % (dep.upper(), incdir))

                    if dep == 'HDF5':
                        env.setvar('HDF5_ROOT', dep_root)
                        self.cfg.update('configopts', '-DUSE_HDF5=ON')

                        hdf5cmvars = {
                            # library name: (cmake option suffix in netcdf<4.4, cmake option suffix in netcfd>=4.4)
                            'hdf5': ('LIB', 'C_LIBRARY'),
                            'hdf5_hl': ('HL_LIB', 'HL_LIBRARY'),
                        }

                        for libname in hdf5cmvars:
                            if LooseVersion(self.version) < LooseVersion("4.4"):
                                cmvar = hdf5cmvars[libname][0]
                            else:
                                cmvar = hdf5cmvars[libname][1]
                            libhdf5 = os.path.join(dep_root, dep_libdir, 'lib%s.%s' % (libname, shlib_ext))
                            self.cfg.update('configopts', '-DHDF5_%s=%s ' % (cmvar, libhdf5))
                            # 4.4 forgot to set HDF5_<lang>_LIBRARIES
                            if LooseVersion(self.version) == LooseVersion("4.4.0"):
                                lang = 'HL' if cmvar[0] == 'H' else 'C'
                                self.cfg.update('configopts', '-DHDF5_%s_LIBRARIES=%s ' % (lang, libhdf5))

                    elif dep == 'PnetCDF':
                        self.cfg.update('configopts', '-DENABLE_PNETCDF=ON')

                    else:
                        libso = os.path.join(dep_root, dep_libdir, 'lib%s.%s' % (libname, shlib_ext))
                        self.cfg.update('configopts', '-D%s_LIBRARY=%s ' % (dep.upper(), libso))

            CMakeMake.configure_step(self)
 def configure_step(self):
     """
     Configure and 
     Test if python module is loaded
     """
     if not get_software_root('Python'):
         raise EasyBuildError("Python module not loaded")
     # We will do the python bindings ourselves so force them off
     self.cfg.update('configopts', '--without-python')
     ConfigureMake.configure_step(self)
 def configure_step(self):
     """
     Configure and 
     Test if python module is loaded
     """
     if not get_software_root('Python'):
         raise EasyBuildError("Python module not loaded")
     # We will do the python bindings ourselves so force them off
     self.cfg.update('configopts', '--without-python')
     ConfigureMake.configure_step(self)
    def configure_step(self):
        """Configure build: set config options and configure"""

        shlib_ext = get_shared_lib_ext()

        if LooseVersion(self.version) < LooseVersion("4.3"):
            self.cfg.update('configopts', "--enable-shared")

            if self.toolchain.options['pic']:
                self.cfg.update('configopts', '--with-pic')

            tup = (os.getenv('FFLAGS'), os.getenv('MPICC'), os.getenv('F90'))
            self.cfg.update('configopts', 'FCFLAGS="%s" CC="%s" FC="%s"' % tup)

            # add -DgFortran to CPPFLAGS when building with GCC
            if self.toolchain.comp_family(
            ) == toolchain.GCC:  #@UndefinedVariable
                self.cfg.update(
                    'configopts',
                    'CPPFLAGS="%s -DgFortran"' % os.getenv('CPPFLAGS'))

            ConfigureMake.configure_step(self)

        else:
            self.cfg.update(
                'configopts',
                '-DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG " '
            )
            for (dep, libname) in [('cURL', 'curl'), ('HDF5', 'hdf5'),
                                   ('Szip', 'sz'), ('zlib', 'z')]:
                dep_root = get_software_root(dep)
                dep_libdir = get_software_libdir(dep)
                if dep_root:
                    incdir = os.path.join(dep_root, 'include')
                    self.cfg.update(
                        'configopts',
                        '-D%s_INCLUDE_DIR=%s ' % (dep.upper(), incdir))
                    if dep == 'HDF5':
                        env.setvar('HDF5_ROOT', dep_root)
                        libhdf5 = os.path.join(dep_root, dep_libdir,
                                               'libhdf5.%s' % shlib_ext)
                        self.cfg.update('configopts',
                                        '-DHDF5_LIB=%s ' % libhdf5)
                        libhdf5_hl = os.path.join(dep_root, dep_libdir,
                                                  'libhdf5_hl.%s' % shlib_ext)
                        self.cfg.update('configopts',
                                        '-DHDF5_HL_LIB=%s ' % libhdf5_hl)
                    else:
                        libso = os.path.join(dep_root, dep_libdir,
                                             'lib%s.%s' % (libname, shlib_ext))
                        self.cfg.update(
                            'configopts',
                            '-D%s_LIBRARY=%s ' % (dep.upper(), libso))

            CMakeMake.configure_step(self)
Exemple #8
0
    def configure_step(self):
        """Configuration step, we set FC, F77 is already set by EasyBuild to the right compiler,
        FC is used for Fortan90"""
        environment.setvar('FC', self.toolchain.get_variable('F90'))

        # make sure correct config script is used for Tcl/Tk
        for dep in ['Tcl', 'Tk']:
            root = get_software_root(dep)
            if root:
                dep_config = os.path.join(root, 'lib', '%sConfig.sh' % dep.lower())
                self.cfg.update('configopts', '-with-%s-config=%s' % (dep.lower(), dep_config))

        ConfigureMake.configure_step(self)
Exemple #9
0
    def configure_step(self):
        """Configuration step, we set FC, F77 is already set by EasyBuild to the right compiler,
        FC is used for Fortan90"""
        environment.setvar('FC', self.toolchain.get_variable('F90'))

        # make sure correct config script is used for Tcl/Tk
        for dep in ['Tcl', 'Tk']:
            root = get_software_root(dep)
            if root:
                dep_config = os.path.join(root, 'lib', '%sConfig.sh' % dep.lower())
                self.cfg.update('configopts', '-with-%s-config=%s' % (dep.lower(), dep_config))

        ConfigureMake.configure_step(self)
    def configure_step(self):
        """
        Configure and 
        Test if python module is loaded
        """
        if not get_software_root('Python'):
            self.log.error("Python module not loaded")
       
        ConfigureMake.configure_step(self)

        try:
            os.chdir('python')
            PythonPackage.configure_step(self)
            os.chdir('..')
        except OSError, err:
            self.log.error("Failed to configure libxml2 Python bindings: %s" % err)
    def configure_step(self):
        """
        Configure libxml2 build
        """
        # only build with Python bindings if Python is listed as a dependency
        python = get_software_root('Python')
        if python:
            self.with_python_bindings = True
            self.require_python = True

        if not self.toolchain.is_system_toolchain():
            self.cfg.update(
                'configopts',
                "CC='%s' CXX='%s'" % (os.getenv('CC'), os.getenv('CXX')))

        if self.toolchain.options.get('pic', False):
            self.cfg.update('configopts', '--with-pic')

        zlib = get_software_root('zlib')
        if zlib:
            self.cfg.update('configopts', '--with-zlib=%s' % zlib)

        xz_root = get_software_root('XZ')
        if xz_root:
            self.cfg.update('configopts', '--with-lzma=%s' % xz_root)

        # enable building of Python bindings if Python is a dependency (or build them ourselves for old versions)
        # disable building of Python bindings if Python is not a dependency
        if self.with_python_bindings and LooseVersion(
                self.version) >= LooseVersion('2.9.2'):
            libxml2_pylibdir = os.path.join(self.installdir, self.pylibdir)
            self.cfg.update(
                'configopts',
                "--with-python=%s" % os.path.join(python, 'bin', 'python'))
            self.cfg.update('configopts',
                            "--with-python-install-dir=%s" % libxml2_pylibdir)
        else:
            self.cfg.update('configopts', '--without-python')

        ConfigureMake.configure_step(self)

        if self.with_python_bindings:
            # prepare for installing Python package
            PythonPackage.prepare_python(self)

        # test using 'make check' (done via test_step)
        self.cfg['runtest'] = 'check'
Exemple #12
0
    def configure_step(self):
        """
        Configure and 
        Test if python module is loaded
        """
        if not get_software_root('Python'):
            raise EasyBuildError("Python module not loaded")

        ConfigureMake.configure_step(self)

        try:
            os.chdir('python')
            PythonPackage.configure_step(self)
            os.chdir('..')
        except OSError, err:
            raise EasyBuildError(
                "Failed to configure libxml2 Python bindings: %s", err)
Exemple #13
0
    def configure_step(self):
        """Custom configuration for R."""

        # define $BLAS_LIBS to build R correctly against BLAS/LAPACK library
        # $LAPACK_LIBS should *not* be specified since that may lead to using generic LAPACK
        # see https://github.com/easybuilders/easybuild-easyconfigs/issues/1435
        env.setvar('BLAS_LIBS', os.getenv('LIBBLAS'))
        self.cfg.update('configopts', "--with-blas --with-lapack")

        # make sure correct config script is used for Tcl/Tk
        for dep in ['Tcl', 'Tk']:
            root = get_software_root(dep)
            if root:
                dep_config = os.path.join(root, 'lib',
                                          '%sConfig.sh' % dep.lower())
                self.cfg.update(
                    'configopts',
                    '--with-%s-config=%s' % (dep.lower(), dep_config))

        if "--with-x=" not in self.cfg['configopts'].lower():
            if get_software_root('X11'):
                self.cfg.update('configopts', '--with-x=yes')
            else:
                self.cfg.update('configopts', '--with-x=no')

        # enable graphic capabilities for plotting, based on available dependencies
        for dep in ['Cairo', 'libjpeg-turbo', 'libpng', 'libtiff']:
            if get_software_root(dep):
                if dep == 'libjpeg-turbo':
                    conf_opt = 'jpeglib'
                else:
                    conf_opt = dep.lower()
                self.cfg.update('configopts', '--with-%s' % conf_opt)

        out = ConfigureMake.configure_step(self)

        # check output of configure command to verify BLAS/LAPACK settings
        ext_libs_regex = re.compile(
            "External libraries:.*BLAS\((?P<BLAS>.*)\).*LAPACK\((?P<LAPACK>.*)\)"
        )
        res = ext_libs_regex.search(out)
        if res:
            for lib in ['BLAS', 'LAPACK']:
                if res.group(lib) == 'generic':
                    warn_msg = "R will be built with generic %s, which will result in poor performance." % lib
                    self.log.warning(warn_msg)
                    print_warning(warn_msg)
                else:
                    self.log.info("R is configured to use non-generic %s: %s",
                                  lib, res.group(lib))
        else:
            warn_msg = "R is configured to be built without BLAS/LAPACK, which will result in (very) poor performance"
            self.log.warning(warn_msg)
            print_warning(warn_msg)
    def configure_step(self):
        """Configure build: set config options and configure"""

        shlib_ext = get_shared_lib_ext()

        if LooseVersion(self.version) < LooseVersion("4.3"):
            self.cfg.update('configopts', "--enable-shared")

            if self.toolchain.options['pic']:
                self.cfg.update('configopts', '--with-pic')

            tup = (os.getenv('FFLAGS'), os.getenv('MPICC'), os.getenv('F90'))
            self.cfg.update('configopts', 'FCFLAGS="%s" CC="%s" FC="%s"' % tup)

            # add -DgFortran to CPPFLAGS when building with GCC
            if self.toolchain.comp_family() == toolchain.GCC:  #@UndefinedVariable
                self.cfg.update('configopts', 'CPPFLAGS="%s -DgFortran"' % os.getenv('CPPFLAGS'))

            ConfigureMake.configure_step(self)

        else:
            self.cfg.update('configopts', '-DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG " ')
            for (dep, libname) in [('cURL', 'curl'), ('HDF5', 'hdf5'), ('Szip', 'sz'), ('zlib', 'z')]:
                dep_root = get_software_root(dep)
                dep_libdir = get_software_libdir(dep)
                if dep_root:
                    incdir = os.path.join(dep_root, 'include')
                    self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s ' % (dep.upper(), incdir))
                    if dep == 'HDF5':
                        env.setvar('HDF5_ROOT', dep_root)
                        libhdf5 = os.path.join(dep_root, dep_libdir, 'libhdf5.%s' % shlib_ext)
                        self.cfg.update('configopts', '-DHDF5_LIB=%s ' % libhdf5)
                        libhdf5_hl = os.path.join(dep_root, dep_libdir, 'libhdf5_hl.%s' % shlib_ext)
                        self.cfg.update('configopts', '-DHDF5_HL_LIB=%s ' % libhdf5_hl)
                    else:
                        libso = os.path.join(dep_root, dep_libdir, 'lib%s.%s' % (libname, shlib_ext))
                        self.cfg.update('configopts', '-D%s_LIBRARY=%s ' % (dep.upper(), libso))

            CMakeMake.configure_step(self)
    def install_step(self):
        """Custom install procedure for EggLib: first build/install C++ library, then build Python library."""

        # build/install C++ library
        cpp_subdir = os.path.join(self.builddir,
                                  'egglib-cpp-%s' % self.version)
        try:
            os.chdir(cpp_subdir)
        except OSError as err:
            raise EasyBuildError("Failed to move to: %s", err)

        ConfigureMake.configure_step(self)
        ConfigureMake.build_step(self)
        ConfigureMake.install_step(self)

        # header files and libraries must be found when building Python library
        for varname, subdir in [('CPATH', 'include'), ('LIBRARY_PATH', 'lib')]:
            env.setvar(
                varname, '%s:%s' % (os.path.join(
                    self.installdir, subdir), os.environ.get(varname, '')))

        # build/install Python package
        py_subdir = os.path.join(self.builddir, 'egglib-py-%s' % self.version)
        try:
            os.chdir(py_subdir)
        except OSError as err:
            raise EasyBuildError("Failed to move to: %s", err)

        PythonPackage.build_step(self)

        self.cfg.update(
            'installopts',
            "--install-lib %s" % os.path.join(self.installdir, self.pylibdir))
        self.cfg.update(
            'installopts',
            "--install-scripts %s" % os.path.join(self.installdir, 'bin'))

        PythonPackage.install_step(self)
Exemple #16
0
    def configure_step(self):
        """
        Configure libxml2 build
        """
        # only build with Python bindings if Python is listed as a dependency
        python = get_software_root('Python')
        if python:
            self.with_python_bindings = True

        if self.toolchain.name != DUMMY_TOOLCHAIN_NAME:
            self.cfg.update('configopts', "CC='%s' CXX='%s'" % (os.getenv('CC'), os.getenv('CXX')))

        if self.toolchain.options.get('pic', False):
            self.cfg.update('configopts', '--with-pic')

        zlib = get_software_root('zlib')
        if zlib:
            self.cfg.update('configopts', '--with-zlib=%s' % zlib)

        # enable building of Python bindings if Python is a dependency (or build them ourselves for old versions)
        # disable building of Python bindings if Python is not a dependency
        if self.with_python_bindings and LooseVersion(self.version) >= LooseVersion('2.9.2'):
                libxml2_pylibdir = os.path.join(self.installdir, self.pylibdir)
                self.cfg.update('configopts', "--with-python=%s" % os.path.join(python, 'bin', 'python'))
                self.cfg.update('configopts', "--with-python-install-dir=%s" % libxml2_pylibdir)
        else:
            self.cfg.update('configopts', '--without-python')

        ConfigureMake.configure_step(self)

        if self.with_python_bindings:
            # prepare for installing Python package
            PythonPackage.prepare_python(self)

        # test using 'make check' (done via test_step)
        self.cfg['runtest'] = 'check'
Exemple #17
0
    def configure_step(self):
        """Custom configuration for R."""

        # define $BLAS_LIBS to build R correctly against BLAS/LAPACK library
        # $LAPACK_LIBS should *not* be specified since that may lead to using generic LAPACK
        # see https://github.com/easybuilders/easybuild-easyconfigs/issues/1435
        env.setvar('BLAS_LIBS', os.getenv('LIBBLAS'))
        self.cfg.update('configopts', "--with-blas --with-lapack")

        # make sure correct config script is used for Tcl/Tk
        for dep in ['Tcl', 'Tk']:
            root = get_software_root(dep)
            if root:
                dep_config = os.path.join(root, 'lib', '%sConfig.sh' % dep.lower())
                self.cfg.update('configopts', '--with-%s-config=%s' % (dep.lower(), dep_config))

        if "--with-x=" not in self.cfg['configopts'].lower():
            if get_software_root('X11'):
                self.cfg.update('configopts', '--with-x=yes')
            else:
                self.cfg.update('configopts', '--with-x=no')

        # enable graphic capabilities for plotting, based on available dependencies
        for dep in ['Cairo', 'libjpeg-turbo', 'libpng', 'libtiff']:
            if get_software_root(dep):
                if dep == 'libjpeg-turbo':
                    conf_opt = 'jpeglib'
                else:
                    conf_opt = dep.lower()
                self.cfg.update('configopts', '--with-%s' % conf_opt)

        out = ConfigureMake.configure_step(self)

        # check output of configure command to verify BLAS/LAPACK settings
        ext_libs_regex = re.compile("External libraries:.*BLAS\((?P<BLAS>.*)\).*LAPACK\((?P<LAPACK>.*)\)")
        res = ext_libs_regex.search(out)
        if res:
            for lib in ['BLAS', 'LAPACK']:
                if res.group(lib) == 'generic':
                    warn_msg = "R will be built with generic %s, which will result in poor performance." % lib
                    self.log.warning(warn_msg)
                    print_warning(warn_msg)
                else:
                    self.log.info("R is configured to use non-generic %s: %s", lib, res.group(lib))
        else:
            warn_msg = "R is configured to be built without BLAS/LAPACK, which will result in (very) poor performance"
            self.log.warning(warn_msg)
            print_warning(warn_msg)
Exemple #18
0
class EB_EggLib(PythonPackage, ConfigureMake):
    """Support for building/installing EggLib."""
    def configure_step(self):
        """Configure EggLib build/install procedure."""
        # only need to configure Python library here, configuration of C++ library is done in install step
        PythonPackage.configure_step(self)

    def build_step(self):
        """No custom build procedure for EggLib; build/install is done in install_step."""
        pass

    def install_step(self):
        """Custom install procedure for EggLib: first build/install C++ library, then build Python library."""

        # build/install C++ library
        cpp_subdir = os.path.join(self.builddir,
                                  'egglib-cpp-%s' % self.version)
        try:
            os.chdir(cpp_subdir)
        except OSError, err:
            raise EasyBuildError("Failed to move to: %s", err)

        ConfigureMake.configure_step(self)
        ConfigureMake.build_step(self)
        ConfigureMake.install_step(self)

        # header files and libraries must be found when building Python library
        for varname, subdir in [('CPATH', 'include'), ('LIBRARY_PATH', 'lib')]:
            env.setvar(
                varname, '%s:%s' % (os.path.join(
                    self.installdir, subdir), os.environ.get(varname, '')))

        # build/install Python package
        py_subdir = os.path.join(self.builddir, 'egglib-py-%s' % self.version)
        try:
            os.chdir(py_subdir)
        except OSError, err:
            raise EasyBuildError("Failed to move to: %s", err)
Exemple #19
0
    def configure_step(self):
        """Custom configuration procedure for NEURON."""
        if LooseVersion(self.version) < LooseVersion('7.8.1'):

            # make sure we're using the correct configure command
            # (required because custom easyconfig parameters from CMakeMake are picked up)
            self.cfg['configure_cmd'] = "./configure"

            # enable support for distributed simulations if desired
            if self.cfg['paranrn']:
                self.cfg.update('configopts', '--with-paranrn')

            # specify path to InterViews if it is available as a dependency
            interviews_root = get_software_root('InterViews')
            if interviews_root:
                self.cfg.update('configopts', "--with-iv=%s" % interviews_root)
            else:
                self.cfg.update('configopts', "--without-iv")

            # optionally enable support for Python as alternative interpreter
            python_root = get_software_root('Python')
            if python_root:
                self.with_python = True
                self.cfg.update('configopts', "--with-nrnpython=%s/bin/python" % python_root)

            # determine host CPU type
            cmd = "./config.guess"
            (out, ec) = run_cmd(cmd, simple=False)

            self.hostcpu = out.split('\n')[0].split('-')[0]
            self.log.debug("Determined host CPU type as %s" % self.hostcpu)

            # determine Python lib dir
            self.pylibdir = det_pylibdir()

            # complete configuration with configure_method of parent
            ConfigureMake.configure_step(self)
        else:
            # enable support for distributed simulations if desired
            if self.cfg['paranrn']:
                self.cfg.update('configopts', '-DNRN_ENABLE_MPI=ON')
            else:
                self.cfg.update('configopts', '-DNRN_ENABLE_MPI=OFF')

            # specify path to InterViews if it is available as a dependency
            interviews_root = get_software_root('InterViews')
            if interviews_root:
                self.cfg.update('configopts', "-DIV_DIR=%s -DNRN_ENABLE_INTERVIEWS=ON" % interviews_root)
            else:
                self.cfg.update('configopts', "-DNRN_ENABLE_INTERVIEWS=OFF")

            # no longer used it seems
            self.hostcpu = ''

            # optionally enable support for Python as alternative interpreter
            python_root = get_software_root('Python')
            if python_root:
                self.with_python = True
                self.cfg.update('configopts', "-DNRN_ENABLE_PYTHON=ON -DPYTHON_EXECUTABLE=%s/bin/python" % python_root)
                self.cfg.update('configopts', "-DNRN_ENABLE_MODULE_INSTALL=ON "
                                "-DNRN_MODULE_INSTALL_OPTIONS='--prefix=%s'" % self.installdir)
            else:
                self.cfg.update('configopts', "-DNRN_ENABLE_PYTHON=OFF")

            # determine Python lib dir
            self.pylibdir = det_pylibdir()

            # complete configuration with configure_method of parent
            CMakeMake.configure_step(self)
Exemple #20
0
    def configure_step(self):
        """Dedicated configure step for Mono: install Mono from RPM (if provided), then run configure."""

        # install Mono from RPMs if provided (because we need Mono to build Mono)
        if self.rpms:

            # prepare path for installing RPMs in
            monorpms_path = os.path.join(self.builddir, "monorpms")
            try:
                os.makedirs(os.path.join(monorpms_path, 'rpm'))
            except OSError as err:
                raise EasyBuildError(
                    "Failed to create directories for installing Mono RPMs in: %s",
                    err)

            self.src = self.rpms
            self.rebuildRPM = True

            # rebuild RPMs to make them relocatable
            Rpm.configure_step(self)

            # prepare to install RPMs
            self.log.debug(
                "Initializing temporary RPM repository to install to...")
            cmd = "rpm --initdb --dbpath /rpm --root %s" % monorpms_path
            run_cmd(cmd, log_all=True, simple=True)

            # install RPMs one by one
            for rpm in self.src:
                self.log.debug("Installing RPM %s ..." % rpm['name'])
                if os.path.exists(rpm['path']):
                    cmd = ' '.join([
                        "rpm -i",
                        "--dbpath %(inst)s/rpm",
                        "--force",
                        "--relocate /=%(inst)s",
                        "--badreloc",
                        "--nodeps --nopost",
                        "%(rpm)s",
                    ]) % {
                        'inst': monorpms_path,
                        'rpm': rpm['path'],
                    }
                    run_cmd(cmd, log_all=True, simple=True)
                else:
                    raise EasyBuildError("RPM file %s not found", rpm['path'])

            # create patched version of gmcs command
            self.log.debug("Making our own copy of gmcs (one that works).")

            mygmcs_path = os.path.join(monorpms_path, 'usr', 'bin', 'mygmcs')
            try:
                shutil.copy(os.path.join(monorpms_path, 'usr', 'bin', 'gmcs'),
                            mygmcs_path)
            except OSError as err:
                raise EasyBuildError("Failed to copy gmcs to %s: %s",
                                     mygmcs_path, err)

            rpls = [
                ("exec /usr/bin/mono", "exec %s/usr/bin/mono" % monorpms_path),
                ("`/usr/bin/monodir`", "%s/usr/lib64/mono" % monorpms_path),
            ]
            apply_regex_substitutions(mygmcs_path, rpls)

            self.log.debug("Patched version of gmcs (%s): %s" %
                           (mygmcs_path, read_file(mygmcs_path)))

            # initiate bootstrap: build/install Mono with installed RPMs to temporary path
            tmp_mono_path = os.path.join(self.builddir, "tmp_mono")
            self.log.debug(
                "Build/install temporary Mono version in %s using installed RPMs..."
                % tmp_mono_path)

            par = ''
            if self.cfg['parallel']:
                par = "-j %s" % self.cfg['parallel']

            config_cmd = "%s ./configure --prefix=%s %s" % (
                self.cfg['preconfigopts'], tmp_mono_path,
                self.cfg['configopts'])
            build_cmd = ' '.join([
                "%(prebuildopts)s"
                "make %(par)s",
                "EXTERNAL_MCS=%(path)s/usr/bin/mygmcs",
                "EXTERNAL_RUNTIME=%(path)s/usr/bin/mono",
                "%(buildopts)s",
            ]) % {
                'prebuildopts': self.cfg['prebuildopts'],
                'par': par,
                'path': monorpms_path,
                'buildopts': self.cfg['buildopts'],
            }
            install_cmd = "make install"

            for cmd in [config_cmd, build_cmd, install_cmd]:
                run_cmd(cmd, log_all=True, simple=True)

            more_buildopts = ' '.join([
                "EXTERNAL_MCS=%(path)s/bin/gmcs",
                "EXTERNAL_RUNTIME=%(path)s/bin/mono",
            ]) % {
                'path': tmp_mono_path
            }
            self.cfg.update('buildopts', more_buildopts)

            self.src = self.mono_srcs

        # continue with normal configure, and subsequent make, make install
        ConfigureMake.configure_step(self)
Exemple #21
0
    def configure_step(self):
        """
        Configure build outside of source directory.
        """
        try:
            objdir = os.path.join(self.builddir, 'obj')
            os.makedirs(objdir)
            os.chdir(objdir)
        except OSError as err:
            raise EasyBuildError(
                "Failed to prepare for configuration of PSI build: %s", err)

        env.setvar('F77FLAGS', os.getenv('F90FLAGS'))

        # In order to create new plugins with PSI, it needs to know the location of the source
        # and the obj dir after install. These env vars give that information to the configure script.
        self.psi_srcdir = os.path.basename(self.cfg['start_dir'].rstrip(
            os.sep))
        self.install_psi_objdir = os.path.join(self.installdir, 'obj')
        self.install_psi_srcdir = os.path.join(self.installdir,
                                               self.psi_srcdir)
        env.setvar('PSI_OBJ_INSTALL_DIR', self.install_psi_objdir)
        env.setvar('PSI_SRC_INSTALL_DIR', self.install_psi_srcdir)

        # explicitely specify Python binary to use
        pythonroot = get_software_root('Python')
        if not pythonroot:
            raise EasyBuildError("Python module not loaded.")

        # pre 4.0b5, they were using autotools, on newer it's CMake
        if LooseVersion(
                self.version) <= LooseVersion("4.0b5") and self.name == "PSI":
            # Use EB Boost
            boostroot = get_software_root('Boost')
            if not boostroot:
                raise EasyBuildError("Boost module not loaded.")

            self.log.info("Using configure based build")
            env.setvar('PYTHON', os.path.join(pythonroot, 'bin', 'python'))
            env.setvar('USE_SYSTEM_BOOST', 'TRUE')

            if self.toolchain.options.get('usempi', None):
                # PSI doesn't require a Fortran compiler itself, but may require it to link to BLAS/LAPACK correctly
                # we should always specify the sequential Fortran compiler,
                # to avoid problems with -lmpi vs -lmpi_mt during linking
                fcompvar = 'F77_SEQ'
            else:
                fcompvar = 'F77'

            # update configure options
            # using multi-threaded BLAS/LAPACK is important for performance,
            # cfr. http://sirius.chem.vt.edu/psi4manual/latest/installfile.html#sec-install-iii
            opt_vars = [
                ('cc', 'CC'),
                ('cxx', 'CXX'),
                ('fc', fcompvar),
                ('libdirs', 'LDFLAGS'),
                ('blas', 'LIBBLAS_MT'),
                ('lapack', 'LIBLAPACK_MT'),
            ]
            for (opt, var) in opt_vars:
                self.cfg.update('configopts',
                                "--with-%s='%s'" % (opt, os.getenv(var)))

            # -DMPICH_IGNORE_CXX_SEEK dances around problem with order of stdio.h and mpi.h headers
            # both define SEEK_SET, this makes the one for MPI be ignored
            self.cfg.update(
                'configopts', "--with-opt='%s -DMPICH_IGNORE_CXX_SEEK'" %
                os.getenv('CFLAGS'))

            # specify location of Boost
            self.cfg.update('configopts', "--with-boost=%s" % boostroot)

            # enable support for plugins
            self.cfg.update('configopts', "--with-plugins")

            ConfigureMake.configure_step(self,
                                         cmd_prefix=self.cfg['start_dir'])
        else:
            self.log.info("Using CMake based build")
            self.cfg.update(
                'configopts', ' -DPYTHON_INTERPRETER=%s' %
                os.path.join(pythonroot, 'bin', 'python'))
            if self.name == 'PSI4' and LooseVersion(
                    self.version) >= LooseVersion("1.2"):
                self.log.info(
                    "Remove the CMAKE_BUILD_TYPE test in PSI4 source and the downloaded dependencies!"
                )
                self.log.info(
                    "Use PATCH_COMMAND in the corresponding CMakeLists.txt")
                self.cfg.update('configopts',
                                ' -DCMAKE_BUILD_TYPE=EasyBuildRelease')
            else:
                self.cfg.update('configopts', ' -DCMAKE_BUILD_TYPE=Release')

            if self.toolchain.options.get('usempi', None):
                self.cfg.update('configopts', " -DENABLE_MPI=ON")

            if get_software_root('imkl'):
                self.cfg.update('configopts',
                                " -DENABLE_CSR=ON -DBLAS_TYPE=MKL")

            if self.name == 'PSI4':
                pcmsolverroot = get_software_root('PCMSolver')
                if pcmsolverroot:
                    self.cfg.update('configopts', " -DENABLE_PCMSOLVER=ON")
                    if LooseVersion(self.version) < LooseVersion("1.2"):
                        self.cfg.update('configopts',
                                        " -DPCMSOLVER_ROOT=%s" % pcmsolverroot)
                    else:
                        self.cfg.update(
                            'configopts',
                            " -DCMAKE_INSIST_FIND_PACKAGE_PCMSolver=ON "
                            "-DPCMSolver_DIR=%s/share/cmake/PCMSolver" %
                            pcmsolverroot)

                chempsroot = get_software_root('CheMPS2')
                if chempsroot:
                    self.cfg.update('configopts', " -DENABLE_CHEMPS2=ON")
                    if LooseVersion(self.version) < LooseVersion("1.2"):
                        self.cfg.update('configopts',
                                        " -DCHEMPS2_ROOT=%s" % chempsroot)
                    else:
                        self.cfg.update(
                            'configopts',
                            " -DCMAKE_INSIST_FIND_PACKAGE_CheMPS2=ON "
                            "-DCheMPS2_DIR=%s/share/cmake/CheMPS2" %
                            chempsroot)

                #  Be aware, PSI4 wants exact versions of the following deps! built with CMake!!
                #  If you want to use non-CMake build versions, the you have to provide the
                #  corresponding Find<library-name>.cmake scripts
                #  In PSI4 version 1.2.1, you can check the corresponding CMakeLists.txt file
                #  in external/upstream/<library-name>/
                if LooseVersion(self.version) >= LooseVersion("1.2"):
                    for dep in ['libxc', 'Libint', 'pybind11', 'gau2grid']:
                        deproot = get_software_root(dep)
                        if deproot:
                            self.cfg.update(
                                'configopts',
                                " -DCMAKE_INSIST_FIND_PACKAGE_%s=ON" % dep)
                            dep_dir = os.path.join(deproot, 'share', 'cmake',
                                                   dep)
                            self.cfg.update('configopts',
                                            " -D%s_DIR=%s " % (dep, dep_dir))

            CMakeMake.configure_step(self, srcdir=self.cfg['start_dir'])
    def configure_step(self):
        """Custom configuration procedure for GROMACS: set configure options for configure or cmake."""

        if LooseVersion(self.version) >= LooseVersion('4.6'):
            cuda = get_software_root('CUDA')
            if cuda:
                # CUDA with double precision is currently not supported in GROMACS yet
                # If easyconfig explicitly have double_precision=True error out,
                # otherwise warn about it and skip the double precision build
                if self.cfg.get('double_precision'):
                    raise EasyBuildError("Double precision is not available for GPU build. " +
                                         "Please explicitly set \"double_precision = False\" " +
                                         "or remove it in the easyconfig file.")
                if self.double_prec_pattern in self.cfg['configopts']:
                    if self.cfg.get('double_precision') is None:
                        # Only print warning once when trying double precision
                        # build the first time
                        self.cfg['double_precision'] = False
                        self.log.info("Double precision is not available for " +
                                      "GPU build. Skipping the double precision build.")

                    self.log.info("skipping configure step")
                    return

                if LooseVersion(self.version) >= LooseVersion('2021'):
                    self.cfg.update('configopts', "-DGMX_GPU=CUDA -DCUDA_TOOLKIT_ROOT_DIR=%s" % cuda)
                else:
                    self.cfg.update('configopts', "-DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=%s" % cuda)
            else:
                # explicitly disable GPU support if CUDA is not available,
                # to avoid that GROMACS find and uses a system-wide CUDA compiler
                self.cfg.update('configopts', "-DGMX_GPU=OFF")

        # check whether PLUMED is loaded as a dependency
        plumed_root = get_software_root('PLUMED')
        if plumed_root:
            # Need to check if PLUMED has an engine for this version
            engine = 'gromacs-%s' % self.version

            (out, _) = run_cmd("plumed-patch -l", log_all=True, simple=False)
            if not re.search(engine, out):
                raise EasyBuildError("There is no support in PLUMED version %s for GROMACS %s: %s",
                                     get_software_version('PLUMED'), self.version, out)

            # PLUMED patching must be done at different stages depending on
            # version of GROMACS. Just prepare first part of cmd here
            plumed_cmd = "plumed-patch -p -e %s" % engine

        if LooseVersion(self.version) < LooseVersion('4.6'):
            self.log.info("Using configure script for configuring GROMACS build.")

            if self.cfg['build_shared_libs']:
                self.cfg.update('configopts', "--enable-shared --disable-static")
            else:
                self.cfg.update('configopts', "--enable-static")

            # Use external BLAS and LAPACK
            self.cfg.update('configopts', "--with-external-blas --with-external-lapack")
            env.setvar('LIBS', "%s %s" % (os.environ['LIBLAPACK'], os.environ['LIBS']))

            # Don't use the X window system
            self.cfg.update('configopts', "--without-x")

            # OpenMP is not supported for versions older than 4.5.
            if LooseVersion(self.version) >= LooseVersion('4.5'):
                # enable OpenMP support if desired
                if self.toolchain.options.get('openmp', None):
                    self.cfg.update('configopts', "--enable-threads")
                else:
                    self.cfg.update('configopts', "--disable-threads")
            elif self.toolchain.options.get('openmp', None):
                raise EasyBuildError("GROMACS version %s does not support OpenMP" % self.version)

            # GSL support
            if get_software_root('GSL'):
                self.cfg.update('configopts', "--with-gsl")
            else:
                self.cfg.update('configopts', "--without-gsl")

            # actually run configure via ancestor (not direct parent)
            self.cfg['configure_cmd'] = "./configure"
            ConfigureMake.configure_step(self)

            # Now patch GROMACS for PLUMED between configure and build
            if plumed_root:
                run_cmd(plumed_cmd, log_all=True, simple=True)

        else:
            if '-DGMX_MPI=ON' in self.cfg['configopts']:
                mpi_numprocs = self.cfg.get('mpi_numprocs', 0)
                if mpi_numprocs == 0:
                    self.log.info("No number of test MPI tasks specified -- using default: %s",
                                  self.cfg['parallel'])
                    mpi_numprocs = self.cfg['parallel']

                elif mpi_numprocs > self.cfg['parallel']:
                    self.log.warning("Number of test MPI tasks (%s) is greater than value for 'parallel': %s",
                                     mpi_numprocs, self.cfg['parallel'])

                mpiexec = self.cfg.get('mpiexec')
                if mpiexec:
                    mpiexec_path = which(mpiexec)
                    if mpiexec_path:
                        self.cfg.update('configopts', "-DMPIEXEC=%s" % mpiexec_path)
                        self.cfg.update('configopts', "-DMPIEXEC_NUMPROC_FLAG=%s" %
                                        self.cfg.get('mpiexec_numproc_flag'))
                        self.cfg.update('configopts', "-DNUMPROC=%s" % mpi_numprocs)
                    elif self.cfg['runtest']:
                        raise EasyBuildError("'%s' not found in $PATH", mpiexec)
                else:
                    raise EasyBuildError("No value found for 'mpiexec'")
                self.log.info("Using %s as MPI executable when testing, with numprocs flag '%s' and %s tasks",
                              mpiexec_path, self.cfg.get('mpiexec_numproc_flag'),
                              mpi_numprocs)

            if LooseVersion(self.version) >= LooseVersion('2019'):
                # Building the gmxapi interface requires shared libraries,
                # this is handled in the class initialisation so --module-only works
                self.cfg.update('configopts', "-DGMXAPI=ON")

                if LooseVersion(self.version) >= LooseVersion('2020'):
                    # build Python bindings if Python is loaded as a dependency
                    python_root = get_software_root('Python')
                    if python_root:
                        bin_python = os.path.join(python_root, 'bin', 'python')
                        self.cfg.update('configopts', "-DPYTHON_EXECUTABLE=%s" % bin_python)
                        self.cfg.update('configopts', "-DGMX_PYTHON_PACKAGE=ON")

            # Now patch GROMACS for PLUMED before cmake
            if plumed_root:
                if LooseVersion(self.version) >= LooseVersion('5.1'):
                    # Use shared or static patch depending on
                    # setting of self.cfg['build_shared_libs']
                    # and adapt cmake flags accordingly as per instructions
                    # from "plumed patch -i"
                    if self.cfg['build_shared_libs']:
                        mode = 'shared'
                    else:
                        mode = 'static'
                    plumed_cmd = plumed_cmd + ' -m %s' % mode

                run_cmd(plumed_cmd, log_all=True, simple=True)

            # prefer static libraries, if available
            if self.cfg['build_shared_libs']:
                self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=OFF")
            else:
                self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=ON")

            # always specify to use external BLAS/LAPACK
            self.cfg.update('configopts', "-DGMX_EXTERNAL_BLAS=ON -DGMX_EXTERNAL_LAPACK=ON")

            # disable GUI tools
            self.cfg.update('configopts', "-DGMX_X11=OFF")

            # convince to build for an older architecture than present on the build node by setting GMX_SIMD CMake flag
            # it does not make sense for Cray, because OPTARCH is defined by the Cray Toolchain
            if self.toolchain.toolchain_family() != toolchain.CRAYPE:
                gmx_simd = self.get_gromacs_arch()
                if gmx_simd:
                    if LooseVersion(self.version) < LooseVersion('5.0'):
                        self.cfg.update('configopts', "-DGMX_CPU_ACCELERATION=%s" % gmx_simd)
                    else:
                        self.cfg.update('configopts', "-DGMX_SIMD=%s" % gmx_simd)

            # set regression test path
            prefix = 'regressiontests'
            if any([src['name'].startswith(prefix) for src in self.src]):
                self.cfg.update('configopts', "-DREGRESSIONTEST_PATH='%%(builddir)s/%s-%%(version)s' " % prefix)

            # enable OpenMP support if desired
            if self.toolchain.options.get('openmp', None):
                self.cfg.update('configopts', "-DGMX_OPENMP=ON")
            else:
                self.cfg.update('configopts', "-DGMX_OPENMP=OFF")

            imkl_root = get_software_root('imkl')
            if imkl_root:
                # using MKL for FFT, so it will also be used for BLAS/LAPACK
                imkl_include = os.path.join(os.getenv('MKLROOT'), 'mkl', 'include')
                self.cfg.update('configopts', '-DGMX_FFT_LIBRARY=mkl -DMKL_INCLUDE_DIR="%s" ' % imkl_include)
                libs = os.getenv('LAPACK_STATIC_LIBS').split(',')
                mkl_libs = [os.path.join(os.getenv('LAPACK_LIB_DIR'), lib) for lib in libs if lib != 'libgfortran.a']
                mkl_libs = ['-Wl,--start-group'] + mkl_libs + ['-Wl,--end-group -lpthread -lm -ldl']
                self.cfg.update('configopts', '-DMKL_LIBRARIES="%s" ' % ';'.join(mkl_libs))
            else:
                for libname in ['BLAS', 'LAPACK']:
                    libdir = os.getenv('%s_LIB_DIR' % libname)
                    if self.toolchain.toolchain_family() == toolchain.CRAYPE:
                        libsci_mpi_mp_lib = glob.glob(os.path.join(libdir, 'libsci_*_mpi_mp.a'))
                        if libsci_mpi_mp_lib:
                            self.cfg.update('configopts', '-DGMX_%s_USER=%s' % (libname, libsci_mpi_mp_lib[0]))
                        else:
                            raise EasyBuildError("Failed to find libsci library to link with for %s", libname)
                    else:
                        # -DGMX_BLAS_USER & -DGMX_LAPACK_USER require full path to library
                        # prefer shared libraries when using FlexiBLAS-based toolchain
                        if self.toolchain.blas_family() == toolchain.FLEXIBLAS:
                            libs = os.getenv('%s_SHARED_LIBS' % libname).split(',')
                        else:
                            libs = os.getenv('%s_STATIC_LIBS' % libname).split(',')

                        libpaths = [os.path.join(libdir, lib) for lib in libs if not lib.startswith('libgfortran')]
                        self.cfg.update('configopts', '-DGMX_%s_USER="******"' % (libname, ';'.join(libpaths)))
                        # if libgfortran.a is listed, make sure it gets linked in too to avoiding linking issues
                        if 'libgfortran.a' in libs:
                            env.setvar('LDFLAGS', "%s -lgfortran -lm" % os.environ.get('LDFLAGS', ''))

            # no more GSL support in GROMACS 5.x, see http://redmine.gromacs.org/issues/1472
            if LooseVersion(self.version) < LooseVersion('5.0'):
                # enable GSL when it's provided
                if get_software_root('GSL'):
                    self.cfg.update('configopts', "-DGMX_GSL=ON")
                else:
                    self.cfg.update('configopts', "-DGMX_GSL=OFF")

            # include flags for linking to zlib/XZ in $LDFLAGS if they're listed as a dep;
            # this is important for the tests, to correctly link against libxml2
            for dep, link_flag in [('XZ', '-llzma'), ('zlib', '-lz')]:
                root = get_software_root(dep)
                if root:
                    libdir = get_software_libdir(dep)
                    ldflags = os.environ.get('LDFLAGS', '')
                    env.setvar('LDFLAGS', "%s -L%s %s" % (ldflags, os.path.join(root, libdir), link_flag))

            # complete configuration with configure_method of parent
            out = super(EB_GROMACS, self).configure_step()

            # for recent GROMACS versions, make very sure that a decent BLAS, LAPACK and FFT is found and used
            if LooseVersion(self.version) >= LooseVersion('4.6.5'):
                patterns = [
                    r"Using external FFT library - \S*",
                    r"Looking for dgemm_ - found",
                    r"Looking for cheev_ - found",
                ]
                for pattern in patterns:
                    regex = re.compile(pattern, re.M)
                    if not regex.search(out):
                        raise EasyBuildError("Pattern '%s' not found in GROMACS configuration output.", pattern)
Exemple #23
0
    def configure_step(self):
        """
        Configure build outside of source directory.
        """
        try:
            objdir = os.path.join(self.builddir, 'obj')
            os.makedirs(objdir)
            os.chdir(objdir)
        except OSError as err:
            raise EasyBuildError("Failed to prepare for configuration of PSI build: %s", err)

        env.setvar('F77FLAGS', os.getenv('F90FLAGS'))

        # In order to create new plugins with PSI, it needs to know the location of the source
        # and the obj dir after install. These env vars give that information to the configure script.
        self.psi_srcdir = os.path.basename(self.cfg['start_dir'].rstrip(os.sep))
        self.install_psi_objdir = os.path.join(self.installdir, 'obj')
        self.install_psi_srcdir = os.path.join(self.installdir, self.psi_srcdir)
        env.setvar('PSI_OBJ_INSTALL_DIR', self.install_psi_objdir)
        env.setvar('PSI_SRC_INSTALL_DIR', self.install_psi_srcdir)

        # explicitely specify Python binary to use
        pythonroot = get_software_root('Python')
        if not pythonroot:
            raise EasyBuildError("Python module not loaded.")

        # pre 4.0b5, they were using autotools, on newer it's CMake
        if LooseVersion(self.version) <= LooseVersion("4.0b5") and self.name == "PSI":
            # Use EB Boost
            boostroot = get_software_root('Boost')
            if not boostroot:
                raise EasyBuildError("Boost module not loaded.")

            self.log.info("Using configure based build")
            env.setvar('PYTHON', os.path.join(pythonroot, 'bin', 'python'))
            env.setvar('USE_SYSTEM_BOOST', 'TRUE')

            if self.toolchain.options.get('usempi', None):
                # PSI doesn't require a Fortran compiler itself, but may require it to link to BLAS/LAPACK correctly
                # we should always specify the sequential Fortran compiler,
                # to avoid problems with -lmpi vs -lmpi_mt during linking
                fcompvar = 'F77_SEQ'
            else:
                fcompvar = 'F77'

            # update configure options
            # using multi-threaded BLAS/LAPACK is important for performance,
            # cfr. http://sirius.chem.vt.edu/psi4manual/latest/installfile.html#sec-install-iii
            opt_vars = [
                ('cc', 'CC'),
                ('cxx', 'CXX'),
                ('fc', fcompvar),
                ('libdirs', 'LDFLAGS'),
                ('blas', 'LIBBLAS_MT'),
                ('lapack', 'LIBLAPACK_MT'),
            ]
            for (opt, var) in opt_vars:
                self.cfg.update('configopts', "--with-%s='%s'" % (opt, os.getenv(var)))

            # -DMPICH_IGNORE_CXX_SEEK dances around problem with order of stdio.h and mpi.h headers
            # both define SEEK_SET, this makes the one for MPI be ignored
            self.cfg.update('configopts', "--with-opt='%s -DMPICH_IGNORE_CXX_SEEK'" % os.getenv('CFLAGS'))

            # specify location of Boost
            self.cfg.update('configopts', "--with-boost=%s" % boostroot)

            # enable support for plugins
            self.cfg.update('configopts', "--with-plugins")

            ConfigureMake.configure_step(self, cmd_prefix=self.cfg['start_dir'])
        else:
            self.log.info("Using CMake based build")
            self.cfg.update('configopts', ' -DPYTHON_INTERPRETER=%s' % os.path.join(pythonroot, 'bin', 'python'))
            if self.name == 'PSI4' and LooseVersion(self.version) >= LooseVersion("1.2"):
                self.log.info("Remove the CMAKE_BUILD_TYPE test in PSI4 source and the downloaded dependencies!")
                self.log.info("Use PATCH_COMMAND in the corresponding CMakeLists.txt")
                self.cfg.update('configopts', ' -DCMAKE_BUILD_TYPE=EasyBuildRelease')
            else:
                self.cfg.update('configopts', ' -DCMAKE_BUILD_TYPE=Release')

            if self.toolchain.options.get('usempi', None):
                self.cfg.update('configopts', " -DENABLE_MPI=ON")

            if get_software_root('imkl'):
                self.cfg.update('configopts', " -DENABLE_CSR=ON -DBLAS_TYPE=MKL")

            if self.name == 'PSI4':
                pcmsolverroot = get_software_root('PCMSolver')
                if pcmsolverroot:
                    self.cfg.update('configopts', " -DENABLE_PCMSOLVER=ON")
                    if LooseVersion(self.version) < LooseVersion("1.2"):
                        self.cfg.update('configopts', " -DPCMSOLVER_ROOT=%s" % pcmsolverroot)
                    else:
                        self.cfg.update('configopts', " -DCMAKE_INSIST_FIND_PACKAGE_PCMSolver=ON "
                                        "-DPCMSolver_DIR=%s/share/cmake/PCMSolver" % pcmsolverroot)

                chempsroot = get_software_root('CheMPS2')
                if chempsroot:
                    self.cfg.update('configopts', " -DENABLE_CHEMPS2=ON")
                    if LooseVersion(self.version) < LooseVersion("1.2"):
                        self.cfg.update('configopts', " -DCHEMPS2_ROOT=%s" % chempsroot)
                    else:
                        self.cfg.update('configopts', " -DCMAKE_INSIST_FIND_PACKAGE_CheMPS2=ON "
                                        "-DCheMPS2_DIR=%s/share/cmake/CheMPS2" % chempsroot)

                #  Be aware, PSI4 wants exact versions of the following deps! built with CMake!!
                #  If you want to use non-CMake build versions, the you have to provide the
                #  corresponding Find<library-name>.cmake scripts
                #  In PSI4 version 1.2.1, you can check the corresponding CMakeLists.txt file
                #  in external/upstream/<library-name>/
                if LooseVersion(self.version) >= LooseVersion("1.2"):
                    for dep in ['libxc', 'Libint', 'pybind11', 'gau2grid']:
                        deproot = get_software_root(dep)
                        if deproot:
                            self.cfg.update('configopts', " -DCMAKE_INSIST_FIND_PACKAGE_%s=ON" % dep)
                            dep_dir = os.path.join(deproot, 'share', 'cmake', dep)
                            self.cfg.update('configopts', " -D%s_DIR=%s " % (dep, dep_dir))

            CMakeMake.configure_step(self, srcdir=self.cfg['start_dir'])
Exemple #24
0
    def configure_step(self):
        """Custom configuration procedure for GROMACS: set configure options for configure or cmake."""

        # check whether PLUMED is loaded as a dependency
        plumed_root = get_software_root('PLUMED')
        if plumed_root:
            # Need to check if PLUMED has an engine for this version
            engine = 'gromacs-%s' % self.version

            (out, _) = run_cmd("plumed-patch -l", log_all=True, simple=False)
            if not re.search(engine, out):
                raise EasyBuildError(
                    "There is no support in PLUMED version %s for GROMACS %s: %s",
                    get_software_version('PLUMED'), self.version, out)

            # PLUMED patching must be done at different stages depending on
            # version of GROMACS. Just prepare first part of cmd here
            plumed_cmd = "plumed-patch -p -e %s" % engine

        if LooseVersion(self.version) < LooseVersion('4.6'):
            self.log.info(
                "Using configure script for configuring GROMACS build.")
            # Use static libraries if possible
            self.cfg.update('configopts', "--enable-static")

            # Use external BLAS and LAPACK
            self.cfg.update('configopts',
                            "--with-external-blas --with-external-lapack")
            env.setvar('LIBS',
                       "%s %s" % (os.environ['LIBLAPACK'], os.environ['LIBS']))

            # Don't use the X window system
            self.cfg.update('configopts', "--without-x")

            # OpenMP is not supported for versions older than 4.5.
            if LooseVersion(self.version) >= LooseVersion('4.5'):
                # enable OpenMP support if desired
                if self.toolchain.options.get('openmp', None):
                    self.cfg.update('configopts', "--enable-threads")
                else:
                    self.cfg.update('configopts', "--disable-threads")
            elif self.toolchain.options.get('openmp', None):
                raise EasyBuildError(
                    "GROMACS version %s does not support OpenMP" %
                    self.version)

            # GSL support
            if get_software_root('GSL'):
                self.cfg.update('configopts', "--with-gsl")
            else:
                self.cfg.update('configopts', "--without-gsl")

            # actually run configure via ancestor (not direct parent)
            self.cfg['configure_cmd'] = "./configure"
            ConfigureMake.configure_step(self)

            # Now patch GROMACS for PLUMED between configure and build
            if plumed_root:
                run_cmd(plumed_cmd, log_all=True, simple=True)

        else:
            # Now patch GROMACS for PLUMED before cmake
            if plumed_root:
                if LooseVersion(self.version) >= LooseVersion('5.1'):
                    # Use shared or static patch depending on
                    # setting of self.toolchain.options.get('dynamic')
                    # and adapt cmake flags accordingly as per instructions
                    # from "plumed patch -i"
                    if self.toolchain.options.get('dynamic', False):
                        mode = 'shared'
                    else:
                        mode = 'static'
                    plumed_cmd = plumed_cmd + ' -m %s' % mode

                run_cmd(plumed_cmd, log_all=True, simple=True)

            # Select debug or release build
            if self.toolchain.options.get('debug', None):
                self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE=Debug")
            else:
                self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE=Release")

            # prefer static libraries, if available
            if self.toolchain.options.get('dynamic', False):
                self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=OFF")
            else:
                self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=ON")
                if plumed_root:
                    self.cfg.update('configopts', "-DBUILD_SHARED_LIBS=OFF")

            if self.cfg['double_precision']:
                self.cfg.update('configopts', "-DGMX_DOUBLE=ON")

            # always specify to use external BLAS/LAPACK
            self.cfg.update('configopts',
                            "-DGMX_EXTERNAL_BLAS=ON -DGMX_EXTERNAL_LAPACK=ON")

            # disable GUI tools
            self.cfg.update('configopts', "-DGMX_X11=OFF")

            # convince to build for an older architecture than present on the build node by setting GMX_SIMD CMake flag
            gmx_simd = self.get_gromacs_arch()
            if gmx_simd:
                if LooseVersion(self.version) < LooseVersion('5.0'):
                    self.cfg.update('configopts',
                                    "-DGMX_CPU_ACCELERATION=%s" % gmx_simd)
                else:
                    self.cfg.update('configopts', "-DGMX_SIMD=%s" % gmx_simd)

            # set regression test path
            prefix = 'regressiontests'
            if any([src['name'].startswith(prefix) for src in self.src]):
                major_minor_version = '.'.join(self.version.split('.')[:2])
                self.cfg.update(
                    'configopts',
                    "-DREGRESSIONTEST_PATH='%%(builddir)s/%s-%%(version)s' " %
                    prefix)

            # enable OpenMP support if desired
            if self.toolchain.options.get('openmp', None):
                self.cfg.update('configopts', "-DGMX_OPENMP=ON")
            else:
                self.cfg.update('configopts', "-DGMX_OPENMP=OFF")

            # disable MPI support for initial, serial/SMP build; actual MPI build is done later
            self.cfg.update('configopts', "-DGMX_MPI=OFF")

            # explicitly disable GPU support if CUDA is not available,
            # to avoid that GROMACS find and uses a system-wide CUDA compiler
            cuda = get_software_root('CUDA')
            if cuda:
                self.cfg.update(
                    'configopts',
                    "-DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=%s" % cuda)
            else:
                self.cfg.update('configopts', "-DGMX_GPU=OFF")

            if get_software_root('imkl'):
                # using MKL for FFT, so it will also be used for BLAS/LAPACK
                self.cfg.update(
                    'configopts',
                    '-DGMX_FFT_LIBRARY=mkl -DMKL_INCLUDE_DIR="$EBROOTMKL/mkl/include" '
                )
                libs = os.getenv('LAPACK_STATIC_LIBS').split(',')
                mkl_libs = [
                    os.path.join(os.getenv('LAPACK_LIB_DIR'), lib)
                    for lib in libs if lib != 'libgfortran.a'
                ]
                mkl_libs = ['-Wl,--start-group'
                            ] + mkl_libs + ['-Wl,--end-group']
                self.cfg.update('configopts',
                                '-DMKL_LIBRARIES="%s" ' % ';'.join(mkl_libs))
            else:
                shlib_ext = get_shared_lib_ext()
                for libname in ['BLAS', 'LAPACK']:
                    libdir = os.getenv('%s_LIB_DIR' % libname)
                    if self.toolchain.toolchain_family() == toolchain.CRAYPE:
                        libsci_mpi_mp_lib = glob.glob(
                            os.path.join(libdir, 'libsci_*_mpi_mp.a'))
                        if libsci_mpi_mp_lib:
                            self.cfg.update(
                                'configopts', '-DGMX_%s_USER=%s' %
                                (libname, libsci_mpi_mp_lib[0]))
                        else:
                            raise EasyBuildError(
                                "Failed to find libsci library to link with for %s",
                                libname)
                    else:
                        # -DGMX_BLAS_USER & -DGMX_LAPACK_USER require full path to library
                        libs = os.getenv('%s_STATIC_LIBS' % libname).split(',')
                        libpaths = [
                            os.path.join(libdir, lib) for lib in libs
                            if lib != 'libgfortran.a'
                        ]
                        self.cfg.update(
                            'configopts', '-DGMX_%s_USER="******"' %
                            (libname, ';'.join(libpaths)))
                        # if libgfortran.a is listed, make sure it gets linked in too to avoiding linking issues
                        if 'libgfortran.a' in libs:
                            env.setvar(
                                'LDFLAGS', "%s -lgfortran -lm" %
                                os.environ.get('LDFLAGS', ''))

            # no more GSL support in GROMACS 5.x, see http://redmine.gromacs.org/issues/1472
            if LooseVersion(self.version) < LooseVersion('5.0'):
                # enable GSL when it's provided
                if get_software_root('GSL'):
                    self.cfg.update('configopts', "-DGMX_GSL=ON")
                else:
                    self.cfg.update('configopts', "-DGMX_GSL=OFF")

            # include flags for linking to zlib/XZ in $LDFLAGS if they're listed as a dep;
            # this is important for the tests, to correctly link against libxml2
            for dep, link_flag in [('XZ', '-llzma'), ('zlib', '-lz')]:
                root = get_software_root(dep)
                if root:
                    libdir = get_software_libdir(dep)
                    ldflags = os.environ.get('LDFLAGS', '')
                    env.setvar(
                        'LDFLAGS', "%s -L%s %s" %
                        (ldflags, os.path.join(root, libdir), link_flag))

            # complete configuration with configure_method of parent
            self.cfg['separate_build_dir'] = True
            out = super(EB_GROMACS, self).configure_step()

            # for recent GROMACS versions, make very sure that a decent BLAS, LAPACK and FFT is found and used
            if LooseVersion(self.version) >= LooseVersion('4.6.5'):
                patterns = [
                    r"Using external FFT library - \S*",
                    r"Looking for dgemm_ - found",
                    r"Looking for cheev_ - found",
                ]
                for pattern in patterns:
                    regex = re.compile(pattern, re.M)
                    if not regex.search(out):
                        raise EasyBuildError(
                            "Pattern '%s' not found in GROMACS configuration output.",
                            pattern)
Exemple #25
0
    def install_step(self):
        """
        Custom install step for GROMACS; figure out where libraries were installed to.
        Also, install the MPI version of the executable in a separate step.
        """
        # run 'make install' in parallel since it involves more compilation
        self.cfg.update('installopts', "-j %s" % self.cfg['parallel'])
        super(EB_GROMACS, self).install_step()

        # the GROMACS libraries get installed in different locations (deeper subdirectory), depending on the platform;
        # this is determined by the GNUInstallDirs CMake module;
        # rather than trying to replicate the logic, we just figure out where the library was placed

        if self.toolchain.options.get('dynamic', False):
            self.libext = get_shared_lib_ext()
        else:
            self.libext = 'a'

        if LooseVersion(self.version) < LooseVersion('5.0'):
            libname = 'libgmx*.%s' % self.libext
        else:
            libname = 'libgromacs*.%s' % self.libext

        for libdir in ['lib', 'lib64']:
            if os.path.exists(os.path.join(self.installdir, libdir)):
                for subdir in [libdir, os.path.join(libdir, '*')]:
                    libpaths = glob.glob(
                        os.path.join(self.installdir, subdir, libname))
                    if libpaths:
                        self.lib_subdir = os.path.dirname(
                            libpaths[0])[len(self.installdir) + 1:]
                        self.log.info(
                            "Found lib subdirectory that contains %s: %s",
                            libname, self.lib_subdir)
                        break
        if not self.lib_subdir:
            raise EasyBuildError("Failed to determine lib subdirectory in %s",
                                 self.installdir)

        # Install a version with the MPI suffix
        if self.toolchain.options.get('usempi', None):
            if LooseVersion(self.version) < LooseVersion('4.6'):

                cmd = "make distclean"
                (out, _) = run_cmd(cmd, log_all=True, simple=False)

                self.cfg.update(
                    'configopts', "--enable-mpi --program-suffix={0}".format(
                        self.cfg['mpisuffix']))
                ConfigureMake.configure_step(self)

                super(EB_GROMACS, self).build_step()

                super(EB_GROMACS, self).install_step()

            else:
                self.cfg['configopts'] = re.sub(r'-DGMX_MPI=OFF', r'',
                                                self.cfg['configopts'])

                if self.cfg['mpi_numprocs'] == 0:
                    self.log.info(
                        "No number of test MPI tasks specified -- using default: %s"
                        % self.cfg['parallel'])
                    self.cfg['mpi_numprocs'] = self.cfg['parallel']

                elif self.cfg['mpi_numprocs'] > self.cfg['parallel']:
                    self.log.warning(
                        "Number of test MPI tasks (%s) is greater than value for 'parallel': %s",
                        self.cfg['mpi_numprocs'], self.cfg['parallel'])

                self.cfg.update('configopts',
                                "-DGMX_MPI=ON -DGMX_THREAD_MPI=OFF")

                mpiexec = which(self.cfg['mpiexec'])
                if mpiexec:
                    self.cfg.update('configopts', "-DMPIEXEC=%s" % mpiexec)
                    self.cfg.update(
                        'configopts', "-DMPIEXEC_NUMPROC_FLAG=%s" %
                        self.cfg['mpiexec_numproc_flag'])
                    self.cfg.update('configopts',
                                    "-DNUMPROC=%s" % self.cfg['mpi_numprocs'])
                elif self.cfg['runtest']:
                    raise EasyBuildError("'%s' not found in $PATH",
                                         self.cfg['mpiexec'])

                self.log.info(
                    "Using %s as MPI executable when testing, with numprocs flag '%s' and %s tasks",
                    self.cfg['mpiexec'], self.cfg['mpiexec_numproc_flag'],
                    self.cfg['mpi_numprocs'])

                # clean up obj dir before reconfiguring
                shutil.rmtree(os.path.join(self.builddir, 'easybuild_obj'))

                # rebuild/test/install with MPI options
                super(EB_GROMACS, self).configure_step()
                super(EB_GROMACS, self).build_step()
                super(EB_GROMACS, self).test_step()
                super(EB_GROMACS, self).install_step()

                self.log.info(
                    "A full regression test suite is available from the GROMACS web site"
                )
Exemple #26
0
    def configure_step(self):
        """Add some extra configure options."""

        if LooseVersion(self.version) >= LooseVersion('2.6.0'):
            # Libint 2.6.0 requires first compiling the Libint compiler,
            # by running configure with appropriate options, followed by 'make export'
            # and unpacking the resulting source tarball;
            # see https://github.com/evaleev/libint/wiki#compiling-libint-compiler

            # CMake is recommended, but configuring with Fortran support doesn't work correctly yet in Libint 2.6.0
            # so stick to traditional configure script for now
            print_msg("configuring Libint compiler...")

            # first run autogen.sh script to generate initial configure script
            run_cmd("./autogen.sh")

            cmd = ' '.join([
                self.cfg['preconfigopts'],
                './configure',
                self.cfg['configopts'],
                self.cfg['libint_compiler_configopts'],
            ])
            run_cmd(cmd)

            print_msg("generating Libint library...")
            run_cmd("make export")

            source_fn = 'libint-%s.tgz' % self.version
            if os.path.exists(source_fn):
                extract_file(source_fn, os.getcwd(), change_into_dir=False)
                change_dir('libint-%s' % self.version)
            else:
                raise EasyBuildError(
                    "Could not find generated source tarball after 'make export'!"
                )

        # Libint < 2.7.0 can be configured using configure script,
        # Libint >= 2.7.0 should be configured via cmake
        if LooseVersion(self.version) < LooseVersion('2.7.0'):

            # also build shared libraries (not enabled by default)
            self.cfg.update('configopts', "--enable-shared")

            if self.toolchain.options['pic']:
                # Enforce consistency.
                self.cfg.update('configopts', "--with-pic")

            if LooseVersion(
                    self.version) >= LooseVersion('2.0') and LooseVersion(
                        self.version) < LooseVersion('2.1'):
                # the code in libint is automatically generated and hence it is in some
                # parts so complex that -O2 or -O3 compiler optimization takes forever
                self.cfg.update('configopts', "--with-cxx-optflags='-O1'")

            elif LooseVersion(self.version) >= LooseVersion('2.1'):
                # pass down $CXXFLAGS to --with-cxxgen-optflags configure option;
                # mainly to avoid warning about it not being set (but $CXXFLAGS is picked up anyway in practice)
                self.cfg.update(
                    'configopts',
                    "--with-cxxgen-optflags='%s'" % os.getenv('CXXFLAGS'))

            # --enable-fortran is only a known configure option for Libint library, not for Libint compiler,
            # so only add --enable-fortran *after* configuring & generating Libint compiler
            if self.cfg['with_fortran']:
                self.cfg.update('configopts', '--enable-fortran')

            self.cfg['configure_cmd'] = DEFAULT_CONFIGURE_CMD
            ConfigureMake.configure_step(self)

        else:
            if self.cfg['with_fortran']:
                self.cfg.update('configopts', '-DENABLE_FORTRAN=ON')

            # also build shared libraries (not enabled by default)
            self.cfg.update('configopts',
                            "-DLIBINT2_BUILD_SHARED_AND_STATIC_LIBS=ON")

            # specify current directory as source directory (that contains CMakeLists.txt),
            # since that's the path to the unpacked source tarball for Libint library (created by 'make export')
            super(EB_Libint, self).configure_step(srcdir=os.getcwd())
    def configure_step(self):
        """Dedicated configure step for Mono: install Mono from RPM (if provided), then run configure."""

        # install Mono from RPMs if provided (because we need Mono to build Mono)
        if self.rpms:

            # prepare path for installing RPMs in
            monorpms_path = os.path.join(self.builddir, "monorpms")
            try:
                os.makedirs(os.path.join(monorpms_path, 'rpm'))
            except OSError as err:
                raise EasyBuildError("Failed to create directories for installing Mono RPMs in: %s", err)

            self.src = self.rpms
            self.rebuildRPM = True

            # rebuild RPMs to make them relocatable
            Rpm.configure_step(self)

            # prepare to install RPMs
            self.log.debug("Initializing temporary RPM repository to install to...")
            cmd = "rpm --initdb --dbpath /rpm --root %s" % monorpms_path
            run_cmd(cmd, log_all=True, simple=True)

            # install RPMs one by one
            for rpm in self.src:
                self.log.debug("Installing RPM %s ..." % rpm['name'])
                if os.path.exists(rpm['path']):
                    cmd = ' '.join([
                        "rpm -i",
                        "--dbpath %(inst)s/rpm",
                        "--force",
                        "--relocate /=%(inst)s",
                        "--badreloc",
                        "--nodeps --nopost",
                        "%(rpm)s",
                    ]) % {
                        'inst': monorpms_path,
                        'rpm': rpm['path'],
                    }
                    run_cmd(cmd,log_all=True,simple=True)
                else:
                    raise EasyBuildError("RPM file %s not found", rpm['path'])

            # create patched version of gmcs command
            self.log.debug("Making our own copy of gmcs (one that works).")

            mygmcs_path = os.path.join(monorpms_path, 'usr', 'bin', 'mygmcs')
            try:
                shutil.copy(os.path.join(monorpms_path, 'usr' ,'bin', 'gmcs'), mygmcs_path)
            except OSError as err:
                raise EasyBuildError("Failed to copy gmcs to %s: %s", mygmcs_path, err)

            rpls = [
                ("exec /usr/bin/mono", "exec %s/usr/bin/mono" % monorpms_path),
                ("`/usr/bin/monodir`", "%s/usr/lib64/mono" % monorpms_path),
            ]
            apply_regex_substitutions(mygmcs_path, rpls)

            self.log.debug("Patched version of gmcs (%s): %s" % (mygmcs_path, read_file(mygmcs_path)))

            # initiate bootstrap: build/install Mono with installed RPMs to temporary path
            tmp_mono_path = os.path.join(self.builddir, "tmp_mono")
            self.log.debug("Build/install temporary Mono version in %s using installed RPMs..." % tmp_mono_path)

            par = ''
            if self.cfg['parallel']:
                par = "-j %s" % self.cfg['parallel']

            config_cmd = "%s ./configure --prefix=%s %s" % (self.cfg['preconfigopts'], tmp_mono_path, self.cfg['configopts'])
            build_cmd = ' '.join([
                "%(prebuildopts)s"
                "make %(par)s",
                "EXTERNAL_MCS=%(path)s/usr/bin/mygmcs",
                "EXTERNAL_RUNTIME=%(path)s/usr/bin/mono",
                "%(buildopts)s",
            ]) %{
                'prebuildopts': self.cfg['prebuildopts'],
                'par': par,
                'path': monorpms_path,
                'buildopts': self.cfg['buildopts'],
            }
            install_cmd = "make install"

            for cmd in [config_cmd, build_cmd, install_cmd]:
                run_cmd(cmd, log_all=True, simple=True)

            more_buildopts = ' '.join([
                "EXTERNAL_MCS=%(path)s/bin/gmcs",
                "EXTERNAL_RUNTIME=%(path)s/bin/mono",
            ]) % {'path': tmp_mono_path}
            self.cfg.update('buildopts', more_buildopts)

            self.src = self.mono_srcs

        # continue with normal configure, and subsequent make, make install
        ConfigureMake.configure_step(self)
Exemple #28
0
 def configure_step(self):
     """Configuration step, we set FC, F77 is already set by EasyBuild to the right compiler,
     FC is used for Fortan90"""
     environment.setvar("FC", self.toolchain.get_variable('F90'))
     ConfigureMake.configure_step(self)
Exemple #29
0
class EB_PSI(CMakeMake):
    """
    Support for building and installing PSI
    """

    def __init__(self, *args, **kwargs):
        """Initialize class variables custom to PSI."""
        super(EB_PSI, self).__init__(*args, **kwargs)

        self.psi_srcdir = None
        self.install_psi_objdir = None
        self.install_psi_srcdir = None

    @staticmethod
    def extra_options():
        """Extra easyconfig parameters specific to PSI."""

        extra_vars = {
            # always include running PSI unit tests (takes about 2h or less)
            'runtest': ["tests TESTFLAGS='-u -q'", "Run tests included with PSI, without interruption.", BUILD],
        }
        return CMakeMake.extra_options(extra_vars)

    def configure_step(self):
        """
        Configure build outside of source directory.
        """
        try:
            objdir = os.path.join(self.builddir, 'obj')
            os.makedirs(objdir)
            os.chdir(objdir)
        except OSError, err:
            raise EasyBuildError("Failed to prepare for configuration of PSI build: %s", err)

        env.setvar('F77FLAGS', os.getenv('F90FLAGS'))

        # In order to create new plugins with PSI, it needs to know the location of the source
        # and the obj dir after install. These env vars give that information to the configure script.
        self.psi_srcdir = os.path.basename(self.cfg['start_dir'].rstrip(os.sep))
        self.install_psi_objdir = os.path.join(self.installdir, 'obj')
        self.install_psi_srcdir = os.path.join(self.installdir, self.psi_srcdir)
        env.setvar('PSI_OBJ_INSTALL_DIR', self.install_psi_objdir)
        env.setvar('PSI_SRC_INSTALL_DIR', self.install_psi_srcdir)

        # explicitely specify Python binary to use
        pythonroot = get_software_root('Python')
        if not pythonroot:
            raise EasyBuildError("Python module not loaded.")

        # Use EB Boost
        boostroot = get_software_root('Boost')
        if not boostroot:
            raise EasyBuildError("Boost module not loaded.")

        # pre 4.0b5, they were using autotools, on newer it's CMake
        if LooseVersion(self.version) <= LooseVersion("4.0b5"):
            env.setvar('PYTHON', os.path.join(pythonroot, 'bin', 'python'))
            env.setvar('USE_SYSTEM_BOOST', 'TRUE')

            if self.toolchain.options.get('usempi', None):
                # PSI doesn't require a Fortran compiler itself, but may require it to link to BLAS/LAPACK correctly
                # we should always specify the sequential Fortran compiler,
                # to avoid problems with -lmpi vs -lmpi_mt during linking
                fcompvar = 'F77_SEQ'
            else:
                fcompvar = 'F77'

            # update configure options
            # using multi-threaded BLAS/LAPACK is important for performance,
            # cfr. http://sirius.chem.vt.edu/psi4manual/latest/installfile.html#sec-install-iii
            opt_vars = [
                ('cc', 'CC'),
                ('cxx', 'CXX'),
                ('fc', fcompvar),
                ('libdirs', 'LDFLAGS'),
                ('blas', 'LIBBLAS_MT'),
                ('lapack', 'LIBLAPACK_MT'),
            ]
            for (opt, var) in opt_vars:
                self.cfg.update('configopts', "--with-%s='%s'" % (opt, os.getenv(var)))

            # -DMPICH_IGNORE_CXX_SEEK dances around problem with order of stdio.h and mpi.h headers
            # both define SEEK_SET, this makes the one for MPI be ignored
            self.cfg.update('configopts', "--with-opt='%s -DMPICH_IGNORE_CXX_SEEK'" % os.getenv('CFLAGS'))

            # specify location of Boost
            self.cfg.update('configopts', "--with-boost=%s" % boostroot)

            # enable support for plugins
            self.cfg.update('configopts', "--with-plugins")

            ConfigureMake.configure_step(self, cmd_prefix=self.cfg['start_dir'])
        else:
            self.cfg['configopts'] += "-DPYTHON_INTERPRETER=%s " % os.path.join(pythonroot, 'bin', 'python')
            self.cfg['configopts'] += "-DCMAKE_BUILD_TYPE=Release "

            if self.toolchain.options.get('usempi', None):
                self.cfg['configopts'] += "-DENABLE_MPI=ON "

            if get_software_root('impi'):
                self.cfg['configopts'] += "-DENABLE_CSR=ON -DBLAS_TYPE=MKL "

            CMakeMake.configure_step(self, srcdir=self.cfg['start_dir'])
Exemple #30
0
 def configure_step(self):
     """Configuration step, we set FC, F77 is already set by EasyBuild to the right compiler,
     FC is used for Fortan90"""
     environment.setvar("FC", self.toolchain.get_variable('F90'))
     ConfigureMake.configure_step(self)
Exemple #31
0
    def install_step(self):
        """
        Custom install step for GROMACS; figure out where libraries were installed to.
        Also, install the MPI version of the executable in a separate step.
        """
        # run 'make install' in parallel since it involves more compilation
        self.cfg.update('installopts', "-j %s" % self.cfg['parallel'])
        super(EB_GROMACS, self).install_step()

        # the GROMACS libraries get installed in different locations (deeper subdirectory), depending on the platform;
        # this is determined by the GNUInstallDirs CMake module;
        # rather than trying to replicate the logic, we just figure out where the library was placed

        if self.toolchain.options.get('dynamic', False):
            self.libext = get_shared_lib_ext()
        else:
            self.libext = 'a'

        if LooseVersion(self.version) < LooseVersion('5.0'):
            libname = 'libgmx*.%s' % self.libext
        else:
            libname = 'libgromacs*.%s' % self.libext

        for libdir in ['lib', 'lib64']:
            if os.path.exists(os.path.join(self.installdir, libdir)):
                for subdir in [libdir, os.path.join(libdir, '*')]:
                    libpaths = glob.glob(os.path.join(self.installdir, subdir, libname))
                    if libpaths:
                        self.lib_subdir = os.path.dirname(libpaths[0])[len(self.installdir)+1:]
                        self.log.info("Found lib subdirectory that contains %s: %s", libname, self.lib_subdir)
                        break
        if not self.lib_subdir:
            raise EasyBuildError("Failed to determine lib subdirectory in %s", self.installdir)

        # Install a version with the MPI suffix
        if self.toolchain.options.get('usempi', None):
            if LooseVersion(self.version) < LooseVersion('4.6'):

                cmd = "make distclean"
                (out, _) = run_cmd(cmd, log_all=True, simple=False)

                self.cfg.update('configopts', "--enable-mpi --program-suffix={0}".format(self.cfg['mpisuffix']))
                ConfigureMake.configure_step(self)

                super(EB_GROMACS, self).build_step()

                super(EB_GROMACS, self).install_step()

            else:
                self.cfg['configopts'] = re.sub(r'-DGMX_MPI=OFF', r'', self.cfg['configopts'])

                if self.cfg['mpi_numprocs'] == 0:
                    self.log.info("No number of test MPI tasks specified -- using default: %s" % self.cfg['parallel'])
                    self.cfg['mpi_numprocs'] = self.cfg['parallel']

                elif self.cfg['mpi_numprocs'] > self.cfg['parallel']:
                    self.log.warning("Number of test MPI tasks (%s) is greater than value for 'parallel': %s",
                                     self.cfg['mpi_numprocs'], self.cfg['parallel'])

                self.cfg.update('configopts', "-DGMX_MPI=ON -DGMX_THREAD_MPI=OFF")

                mpiexec = which(self.cfg['mpiexec'])
                if mpiexec:
                    self.cfg.update('configopts', "-DMPIEXEC=%s" % mpiexec)
                    self.cfg.update('configopts', "-DMPIEXEC_NUMPROC_FLAG=%s" % self.cfg['mpiexec_numproc_flag'])
                    self.cfg.update('configopts', "-DNUMPROC=%s" % self.cfg['mpi_numprocs'])
                elif self.cfg['runtest']:
                    raise EasyBuildError("'%s' not found in $PATH", self.cfg['mpiexec'])


                self.log.info("Using %s as MPI executable when testing, with numprocs flag '%s' and %s tasks",
                              self.cfg['mpiexec'], self.cfg['mpiexec_numproc_flag'], self.cfg['mpi_numprocs'])

                # clean up obj dir before reconfiguring
                shutil.rmtree(os.path.join(self.builddir, 'easybuild_obj'))

                # rebuild/test/install with MPI options
                super(EB_GROMACS, self).configure_step()
                super(EB_GROMACS, self).build_step()
                super(EB_GROMACS, self).test_step()
                super(EB_GROMACS, self).install_step()

                self.log.info("A full regression test suite is available from the GROMACS web site")
Exemple #32
0
    def configure_step(self):
        """Custom configuration procedure for GROMACS: set configure options for configure or cmake."""

        if LooseVersion(self.version) < LooseVersion('4.6'):
            self.log.info("Using configure script for configuring GROMACS build.")
            # Use static libraries if possible
            self.cfg.update('configopts', "--enable-static")

            # Use external BLAS and LAPACK
            self.cfg.update('configopts', "--with-external-blas --with-external-lapack")
            env.setvar('LIBS', "%s %s" % (os.environ['LIBLAPACK'], os.environ['LIBS']))

            # Don't use the X window system
            self.cfg.update('configopts', "--without-x")

            # OpenMP is not supported for versions older than 4.5.
            if LooseVersion(self.version) >= LooseVersion('4.5'):
                # enable OpenMP support if desired
                if self.toolchain.options.get('openmp', None):
                    self.cfg.update('configopts', "--enable-threads")
                else:
                    self.cfg.update('configopts', "--disable-threads")
            elif self.toolchain.options.get('openmp', None):
                raise EasyBuildError("GROMACS version %s does not support OpenMP" % self.version)

            # GSL support
            if get_software_root('GSL'):
                self.cfg.update('configopts', "--with-gsl")
            else:
                self.cfg.update('configopts', "--without-gsl")

            # actually run configure via ancestor (not direct parent)
            ConfigureMake.configure_step(self)

        else:
            # build a release build
            self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE=Release")

            # prefer static libraries, if available
            if self.toolchain.options.get('dynamic', False):
                self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=OFF")
            else:
                self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=ON")

            if self.cfg['double_precision']:
                self.cfg.update('configopts', "-DGMX_DOUBLE=ON")

            # always specify to use external BLAS/LAPACK
            self.cfg.update('configopts', "-DGMX_EXTERNAL_BLAS=ON -DGMX_EXTERNAL_LAPACK=ON")

            # disable GUI tools
            self.cfg.update('configopts', "-DGMX_X11=OFF")

            # set regression test path
            prefix = 'regressiontests'
            if any([src['name'].startswith(prefix) for src in self.src]):
                major_minor_version = '.'.join(self.version.split('.')[:2])
                self.cfg.update('configopts', "-DREGRESSIONTEST_PATH='%%(builddir)s/%s-%%(version)s' " % prefix)

            # enable OpenMP support if desired
            if self.toolchain.options.get('openmp', None):
                self.cfg.update('configopts', "-DGMX_OPENMP=ON")
            else:
                self.cfg.update('configopts', "-DGMX_OPENMP=OFF")

            # disable MPI support for initial, serial/SMP build; actual MPI build is done later
            self.cfg.update('configopts', "-DGMX_MPI=OFF")

            # explicitly disable GPU support if CUDA is not available,
            # to avoid that GROMACS find and uses a system-wide CUDA compiler
            cuda = get_software_root('CUDA')
            if cuda:
                self.cfg.update('configopts', "-DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=%s" % cuda)
            else:
                self.cfg.update('configopts', "-DGMX_GPU=OFF")

            if get_software_root('imkl'):
                # using MKL for FFT, so it will also be used for BLAS/LAPACK
                self.cfg.update('configopts', '-DGMX_FFT_LIBRARY=mkl -DMKL_INCLUDE_DIR="$EBROOTMKL/mkl/include" ')
                mkl_libs = [os.path.join(os.getenv('LAPACK_LIB_DIR'), lib) for lib in ['libmkl_lapack.a']]
                self.cfg.update('configopts', '-DMKL_LIBRARIES="%s" ' % ';'.join(mkl_libs))
            else:
                shlib_ext = get_shared_lib_ext()
                for libname in ['BLAS', 'LAPACK']:
                    libdir = os.getenv('%s_LIB_DIR' % libname)
                    if self.toolchain.toolchain_family() == toolchain.CRAYPE:
                        libsci_mpi_mp_lib = glob.glob(os.path.join(libdir, 'libsci_*_mpi_mp.a'))
                        if libsci_mpi_mp_lib:
                            self.cfg.update('configopts', '-DGMX_%s_USER=%s' % (libname, libsci_mpi_mp_lib[0]))
                        else:
                            raise EasyBuildError("Failed to find libsci library to link with for %s", libname)
                    else:
                        # -DGMX_BLAS_USER & -DGMX_LAPACK_USER require full path to library
                        libs = os.getenv('%s_STATIC_LIBS' % libname).split(',')
                        libpaths = [os.path.join(libdir, lib) for lib in libs if lib != 'libgfortran.a']
                        self.cfg.update('configopts', '-DGMX_%s_USER="******"' % (libname, ';'.join(libpaths)))
                        # if libgfortran.a is listed, make sure it gets linked in too to avoiding linking issues
                        if 'libgfortran.a' in libs:
                            env.setvar('LDFLAGS', "%s -lgfortran -lm" % os.environ.get('LDFLAGS', ''))

            # no more GSL support in GROMACS 5.x, see http://redmine.gromacs.org/issues/1472
            if LooseVersion(self.version) < LooseVersion('5.0'):
                # enable GSL when it's provided
                if get_software_root('GSL'):
                    self.cfg.update('configopts', "-DGMX_GSL=ON")
                else:
                    self.cfg.update('configopts', "-DGMX_GSL=OFF")

            # include flags for linking to zlib/XZ in $LDFLAGS if they're listed as a dep;
            # this is important for the tests, to correctly link against libxml2
            for dep, link_flag in [('XZ', '-llzma'), ('zlib', '-lz')]:
                root = get_software_root(dep)
                if root:
                    libdir = get_software_libdir(dep)
                    ldflags = os.environ.get('LDFLAGS', '')
                    env.setvar('LDFLAGS', "%s -L%s %s" % (ldflags, os.path.join(root, libdir), link_flag))

            # complete configuration with configure_method of parent
            self.cfg['separate_build_dir'] = True
            out = super(EB_GROMACS, self).configure_step()

            # for recent GROMACS versions, make very sure that a decent BLAS, LAPACK and FFT is found and used
            if LooseVersion(self.version) >= LooseVersion('4.6.5'):
                patterns = [
                    r"Using external FFT library - \S*",
                    r"Looking for dgemm_ - found",
                    r"Looking for cheev_ - found",
                ]
                for pattern in patterns:
                    regex = re.compile(pattern, re.M)
                    if not regex.search(out):
                        raise EasyBuildError("Pattern '%s' not found in GROMACS configuration output.", pattern)