예제 #1
0
    def configure_step(self):
        """Set extra configure options."""
        self.cfg.update('configopts', "--with-threads --enable-shared")

        modules_setup_dist = os.path.join(self.cfg['start_dir'], 'Modules', 'Setup.dist')

        libreadline = get_software_root('libreadline')
        if libreadline:
            ncurses = get_software_root('ncurses')
            if ncurses:
                readline_libdir = get_software_libdir('libreadline')
                ncurses_libdir = get_software_libdir('ncurses')
                readline_static_lib = os.path.join(libreadline, readline_libdir, 'libreadline.a')
                ncurses_static_lib = os.path.join(ncurses, ncurses_libdir, 'libncurses.a')
                readline = "readline readline.c %s %s" % (readline_static_lib, ncurses_static_lib)
                for line in fileinput.input(modules_setup_dist, inplace='1', backup='.readline'):
                    line = re.sub(r"^#readline readline.c.*", readline, line)
                    sys.stdout.write(line)
            else:
                self.log.error("Both libreadline and ncurses are required to ensure readline support")

        openssl = get_software_root('OpenSSL')
        if openssl:
            for line in fileinput.input(modules_setup_dist, inplace='1', backup='.ssl'):
                line = re.sub(r"^#SSL=.*", "SSL=%s" % openssl, line)
                line = re.sub(r"^#(\s*-DUSE_SSL -I)", r"\1", line)
                line = re.sub(r"^#(\s*-L\$\(SSL\)/lib )", r"\1 -L$(SSL)/lib64 ", line)
                sys.stdout.write(line)

        super(EB_Python, self).configure_step()
    def configure_step(self):
        """Set extra configure options."""
        self.cfg.update('configopts', "--with-threads --enable-shared")

        # Need to be careful to match the unicode settings to the underlying python
        if sys.maxunicode == 1114111:
            self.cfg.update('configopts', "--enable-unicode=ucs4")
        elif sys.maxunicode == 65535:
            self.cfg.update('configopts', "--enable-unicode=ucs2")
        else:
            raise EasyBuildError("Unknown maxunicode value for your python: %d" % sys.maxunicode)

        modules_setup_dist = os.path.join(self.cfg['start_dir'], 'Modules', 'Setup.dist')

        libreadline = get_software_root('libreadline')
        if libreadline:
            ncurses = get_software_root('ncurses')
            if ncurses:
                readline_libdir = get_software_libdir('libreadline')
                ncurses_libdir = get_software_libdir('ncurses')
                readline_static_lib = os.path.join(libreadline, readline_libdir, 'libreadline.a')
                ncurses_static_lib = os.path.join(ncurses, ncurses_libdir, 'libncurses.a')
                readline = "readline readline.c %s %s" % (readline_static_lib, ncurses_static_lib)
                for line in fileinput.input(modules_setup_dist, inplace='1', backup='.readline'):
                    line = re.sub(r"^#readline readline.c.*", readline, line)
                    sys.stdout.write(line)
            else:
                raise EasyBuildError("Both libreadline and ncurses are required to ensure readline support")

        openssl = get_software_root('OpenSSL')
        if openssl:
            for line in fileinput.input(modules_setup_dist, inplace='1', backup='.ssl'):
                line = re.sub(r"^#SSL=.*", "SSL=%s" % openssl, line)
                line = re.sub(r"^#(\s*-DUSE_SSL -I)", r"\1", line)
                line = re.sub(r"^#(\s*-L\$\(SSL\)/lib )", r"\1 -L$(SSL)/lib64 ", line)
                sys.stdout.write(line)

        tcl = get_software_root('Tcl')
        tk = get_software_root('Tk')
        if tcl and tk:
            tclver = get_software_version('Tcl')
            tkver = get_software_version('Tk')
            tcltk_maj_min_ver = '.'.join(tclver.split('.')[:2])
            if tcltk_maj_min_ver != '.'.join(tkver.split('.')[:2]):
                raise EasyBuildError("Tcl and Tk major/minor versions don't match: %s vs %s", tclver, tkver)

            self.cfg.update('configopts', "--with-tcltk-includes='-I%s/include -I%s/include'" % (tcl, tk))

            tcl_libdir = os.path.join(tcl, get_software_libdir('Tcl'))
            tk_libdir = os.path.join(tk, get_software_libdir('Tk'))
            tcltk_libs = "-L%(tcl_libdir)s -L%(tk_libdir)s -ltcl%(maj_min_ver)s -ltk%(maj_min_ver)s" % {
                'tcl_libdir': tcl_libdir,
                'tk_libdir': tk_libdir,
                'maj_min_ver': tcltk_maj_min_ver,
            }
            self.cfg.update('configopts', "--with-tcltk-libs='%s'" % tcltk_libs)

        super(EB_Python, self).configure_step()
예제 #3
0
    def configure_step(self):
        """Set extra configure options."""
        self.cfg.update("configopts", "--with-threads --enable-shared")

        modules_setup_dist = os.path.join(self.cfg["start_dir"], "Modules", "Setup.dist")

        libreadline = get_software_root("libreadline")
        if libreadline:
            ncurses = get_software_root("ncurses")
            if ncurses:
                readline_libdir = get_software_libdir("libreadline")
                ncurses_libdir = get_software_libdir("ncurses")
                readline_static_lib = os.path.join(libreadline, readline_libdir, "libreadline.a")
                ncurses_static_lib = os.path.join(ncurses, ncurses_libdir, "libncurses.a")
                readline = "readline readline.c %s %s" % (readline_static_lib, ncurses_static_lib)
                for line in fileinput.input(modules_setup_dist, inplace="1", backup=".readline"):
                    line = re.sub(r"^#readline readline.c.*", readline, line)
                    sys.stdout.write(line)
            else:
                raise EasyBuildError("Both libreadline and ncurses are required to ensure readline support")

        openssl = get_software_root("OpenSSL")
        if openssl:
            for line in fileinput.input(modules_setup_dist, inplace="1", backup=".ssl"):
                line = re.sub(r"^#SSL=.*", "SSL=%s" % openssl, line)
                line = re.sub(r"^#(\s*-DUSE_SSL -I)", r"\1", line)
                line = re.sub(r"^#(\s*-L\$\(SSL\)/lib )", r"\1 -L$(SSL)/lib64 ", line)
                sys.stdout.write(line)

        tcl = get_software_root("Tcl")
        tk = get_software_root("Tk")
        if tcl and tk:
            tclver = get_software_version("Tcl")
            tkver = get_software_version("Tk")
            tcltk_maj_min_ver = ".".join(tclver.split(".")[:2])
            if tcltk_maj_min_ver != ".".join(tkver.split(".")[:2]):
                raise EasyBuildError("Tcl and Tk major/minor versions don't match: %s vs %s", tclver, tkver)

            self.cfg.update("configopts", "--with-tcltk-includes='-I%s/include -I%s/include'" % (tcl, tk))

            tcl_libdir = os.path.join(tcl, get_software_libdir("Tcl"))
            tk_libdir = os.path.join(tk, get_software_libdir("Tk"))
            tcltk_libs = "-L%(tcl_libdir)s -L%(tk_libdir)s -ltcl%(maj_min_ver)s -ltk%(maj_min_ver)s" % {
                "tcl_libdir": tcl_libdir,
                "tk_libdir": tk_libdir,
                "maj_min_ver": tcltk_maj_min_ver,
            }
            self.cfg.update("configopts", "--with-tcltk-libs='%s'" % tcltk_libs)

        super(EB_Python, self).configure_step()
예제 #4
0
    def test_get_software_root_version_libdir(self):
        """Test get_software_X functions."""

        tmpdir = tempfile.mkdtemp()
        test_cases = [
            ('GCC', 'GCC'),
            ('grib_api', 'GRIB_API'),
            ('netCDF-C++', 'NETCDFMINCPLUSPLUS'),
            ('Score-P', 'SCOREMINP'),
        ]
        for (name, env_var_name) in test_cases:
            # mock stuff that get_software_X functions rely on
            root = os.path.join(tmpdir, name)
            os.makedirs(os.path.join(root, 'lib'))
            os.environ['EBROOT%s' % env_var_name] = root
            version = '0.0-%s' % root
            os.environ['EBVERSION%s' % env_var_name] = version

            self.assertEqual(get_software_root(name), root)
            self.assertEqual(get_software_version(name), version)
            self.assertEqual(get_software_libdir(name), 'lib')

            os.environ.pop('EBROOT%s' % env_var_name)
            os.environ.pop('EBVERSION%s' % env_var_name)

        # check expected result of get_software_libdir with multiple lib subdirs
        root = os.path.join(tmpdir, name)
        os.makedirs(os.path.join(root, 'lib64'))
        os.environ['EBROOT%s' % env_var_name] = root
        self.assertErrorRegex(EasyBuildError, "Multiple library subdirectories found.*", get_software_libdir, name)
        self.assertEqual(get_software_libdir(name, only_one=False), ['lib', 'lib64'])

        # only directories containing files in specified list should be retained
        open(os.path.join(root, 'lib64', 'foo'), 'w').write('foo')
        self.assertEqual(get_software_libdir(name, fs=['foo']), 'lib64')

        # clean up for previous tests
        os.environ.pop('EBROOT%s' % env_var_name)

        # if root/version for specified software package can not be found, these functions should return None
        self.assertEqual(get_software_root('foo'), None)
        self.assertEqual(get_software_version('foo'), None)
        self.assertEqual(get_software_libdir('foo'), None)

        # if no library subdir is found, get_software_libdir should return None
        os.environ['EBROOTFOO'] = tmpdir
        self.assertEqual(get_software_libdir('foo'), None)
        os.environ.pop('EBROOTFOO')

        shutil.rmtree(tmpdir)
예제 #5
0
    def configure_step(self, *args, **kwargs):
        """Configure Score-P build, set configure options for compiler, MPI and dependencies."""
        # compiler and MPI suite should always be specified -- MUCH quicker and SAVER than autodetect
        # --with-nocross-compiler-suite=(gcc|ibm|intel|pgi|studio)
        # --with-mpi=(bullxmpi|hp|ibmpoe|intel|intel2|intelpoe|lam|mpibull2|mpich|mpich2|mpich3|openmpi|
        #             platform|scali|sgimpt|sun)
        comp_opts = {
            toolchain.GCC: 'gcc',
            toolchain.INTELCOMP: 'intel',
        }
        comp_fam = self.toolchain.comp_family()
        if comp_fam in comp_opts:
            self.cfg.update('configopts', "--with-nocross-compiler-suite=%s" % comp_opts[comp_fam])
        else:
            raise EasyBuildError("Compiler family %s not supported yet (only: %s)",
                                 comp_fam, ', '.join(comp_opts.keys()))

        mpi_opts = {
            toolchain.INTELMPI: 'intel2',  # intel: Intel MPI v1.x (ancient); intelpoe: IBM POE MPI for Intel platforms
            toolchain.OPENMPI: 'openmpi',
            toolchain.MPICH: 'mpich3',  # In EB terms, MPICH means MPICH 3.x; MPICH 1.x is ancient and unsupported
            toolchain.MPICH2: 'mpich2',
        }
        mpi_fam = self.toolchain.mpi_family()
        if mpi_fam is not None:
            if mpi_fam in mpi_opts:
                self.cfg.update('configopts', "--with-mpi=%s" % mpi_opts[mpi_fam])
            else:
                raise EasyBuildError("MPI family %s not supported yet (only: %s)",
                                     mpi_fam, ', '.join(mpi_opts.keys()))

        # auto-detection for dependencies mostly works fine, but hard specify paths anyway to have full control
        deps = {
            'binutils': ['--with-libbfd=%%s/%s' % get_software_libdir('binutils', fs=['libbfd.a'])],
            'Cube': ['--with-cube=%s/bin'],
            'CUDA': ['--with-libcudart=%s'],
            'OTF2': ['--with-otf2=%s/bin'],
            'OPARI2': ['--with-opari2=%s/bin'],
            'PAPI': ['--with-papi-header=%s/include', '--with-papi-lib=%%s/%s' % get_software_libdir('PAPI')],
            'PDT': ['--with-pdt=%s/bin'],
            'Qt': ['--with-qt=%s'],
        }
        for (dep_name, dep_opts) in deps.items():
            dep_root = get_software_root(dep_name)
            if dep_root:
                for dep_opt in dep_opts:
                    self.cfg.update('configopts', dep_opt % dep_root)

        super(EB_Score_minus_P, self).configure_step(*args, **kwargs)
예제 #6
0
    def configure_step(self):
        """Custom configuration procedure for binutils: statically link to zlib, configure options."""

        # determine list of 'lib' directories to use rpath for;
        # this should 'harden' the resulting binutils to bootstrap GCC (no trouble when other libstdc++ is build etc)
        libdirs = []
        for libdir in ['/usr/lib', '/usr/lib64', '/usr/lib/x86_64-linux-gnu/']:
            # also consider /lib, /lib64
            alt_libdir = libdir.replace('usr/', '')

            if os.path.exists(libdir):
                libdirs.append(libdir)
                if os.path.exists(alt_libdir) and not os.path.samefile(libdir, alt_libdir):
                    libdirs.append(alt_libdir)

            elif os.path.exists(alt_libdir):
                libdirs.append(alt_libdir)

        libs = ' '.join('-Wl,-rpath=%s' % libdir for libdir in libdirs)

        # statically link to zlib if it is a (build) dependency
        zlibroot = get_software_root('zlib')
        if zlibroot:
            self.cfg.update('configopts', '--with-system-zlib')
            libz_path = os.path.join(zlibroot, get_software_libdir('zlib'), 'libz.a')

            # for recent binutils versions, we need to override ZLIB in Makefile.in of components
            if LooseVersion(self.version) >= LooseVersion('2.26'):
                regex_subs = [
                    (r"^(ZLIB\s*=\s*).*$", r"\1%s" % libz_path),
                    (r"^(ZLIBINC\s*=\s*).*$", r"\1-I%s" % os.path.join(zlibroot, 'include')),
                ]
                for makefile in glob.glob(os.path.join(self.cfg['start_dir'], '*', 'Makefile.in')):
                    apply_regex_substitutions(makefile, regex_subs)

            # for older versions, injecting the path to the static libz library into $LIBS works
            else:
                libs += ' ' + libz_path

        self.cfg.update('preconfigopts', "env LIBS='%s'" % libs)
        self.cfg.update('prebuildopts', "env LIBS='%s'" % libs)

        # use correct sysroot, to make sure 'ld' also considers system libraries
        self.cfg.update('configopts', '--with-sysroot=/')

        # build both static and shared libraries for recent binutils versions (default is only static)
        if LooseVersion(self.version) > LooseVersion('2.24'):
            self.cfg.update('configopts', "--enable-shared --enable-static")

        # enable gold linker with plugin support, use ld as default linker (for recent versions of binutils)
        if LooseVersion(self.version) > LooseVersion('2.24'):
            self.cfg.update('configopts', "--enable-gold --enable-plugins --enable-ld=default")

        # complete configuration with configure_method of parent
        super(EB_binutils, self).configure_step()
예제 #7
0
    def configure_step(self):
        """
        Set the CMake options for SuperLU
        """
        self.cfg['separate_build_dir'] = True

        if self.cfg['build_shared_libs']:
            self.cfg.update('configopts', '-DBUILD_SHARED_LIBS=ON')
            self.lib_ext = get_shared_lib_ext()

        else:
            self.cfg.update('configopts', '-DBUILD_SHARED_LIBS=OFF')
            self.lib_ext = 'a'

        # Add -fPIC flag if necessary
        pic_flag = ('OFF', 'ON')[self.toolchain.options['pic']]
        self.cfg.update('configopts', '-DCMAKE_POSITION_INDEPENDENT_CODE=%s' % pic_flag)

        # Make sure not to build the slow BLAS library included in the package
        self.cfg.update('configopts', '-Denable_blaslib=OFF')

        # Set the BLAS library to use
        # For this, use the BLA_VENDOR option from the FindBLAS module of CMake
        # Check for all possible values at https://cmake.org/cmake/help/latest/module/FindBLAS.html
        toolchain_blas = self.toolchain.definition().get('BLAS', None)[0]
        if toolchain_blas == 'imkl':
            imkl_version = get_software_version('imkl')
            if LooseVersion(imkl_version) >= LooseVersion('10'):
                # 'Intel10_64lp' -> For Intel mkl v10 64 bit,lp thread model, lp64 model
                # It should work for Intel MKL 10 and above, as long as the library names stay the same
                # SuperLU requires thread, 'Intel10_64lp_seq' will not work!
                self.cfg.update('configopts', '-DBLA_VENDOR="Intel10_64lp"')

            else:
                # 'Intel' -> For older versions of mkl 32 and 64 bit
                self.cfg.update('configopts', '-DBLA_VENDOR="Intel"')

        elif toolchain_blas in ['ACML', 'ATLAS']:
            self.cfg.update('configopts', '-DBLA_VENDOR="%s"' % toolchain_blas)

        elif toolchain_blas == 'OpenBLAS':
            # Unfortunately, OpenBLAS is not recognized by FindBLAS from CMake,
            # we have to specify the OpenBLAS library manually
            openblas_lib = os.path.join( get_software_root('OpenBLAS'), get_software_libdir('OpenBLAS'), "libopenblas.a" )
            self.cfg.update('configopts', '-DBLAS_LIBRARIES="%s;-pthread"' % openblas_lib)

        elif toolchain_blas == None:
            # This toolchain has no BLAS library
            raise EasyBuildError("No BLAS library found in the toolchain")

        else:
            # This BLAS library is not supported yet
            raise EasyBuildError("BLAS library '%s' is not supported yet", toolchain_blas)

        super(EB_SuperLU, self).configure_step()
    def prepare_step(self, *args, **kwargs):
        """Custom prepare step for Paraver: check required dependencies and collect information on them."""
        super(EB_Paraver, self).prepare_step(*args, **kwargs)

        # determine value to pass to --with-wxpropgrid (library name)
        self.wxpropgrid = None
        wxpropertygrid_root = get_software_root('wxPropertyGrid')
        if wxpropertygrid_root:
            wxpropertygrid_libdir = os.path.join(wxpropertygrid_root, get_software_libdir('wxPropertyGrid'))
            libname_pattern = 'libwxcode_*_propgrid-*.so'
            wxpropgrid_libs = glob.glob(os.path.join(wxpropertygrid_libdir, libname_pattern))
            if len(wxpropgrid_libs) == 1:
                # exclude the 'lib' prefix and '.so' suffix to determine value to be passed to --with-wxpropgrid
                self.wxpropgrid = os.path.basename(wxpropgrid_libs[0])[3:-3]
            else:
                tup = (libname_pattern, wxpropertygrid_libdir, wxpropgrid_libs)
                raise EasyBuildError("Expected to find exactly one %s library in %s, found %s" % tup)
예제 #9
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:
            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)
예제 #10
0
    def configure_step(self):
        """Custom configuration procedure for NWChem."""

        # check whether a (valid) symlink to a .nwchemrc config file exists (via a dummy file if necessary)
        # fail early if the link is not what's we expect, since running the test cases will likely fail in this case
        try:
            if os.path.exists(self.home_nwchemrc) or os.path.islink(
                    self.home_nwchemrc):
                # create a dummy file to check symlink
                if not os.path.exists(self.local_nwchemrc):
                    write_file(self.local_nwchemrc, 'dummy')

                self.log.debug(
                    "Contents of %s: %s", os.path.dirname(self.local_nwchemrc),
                    os.listdir(os.path.dirname(self.local_nwchemrc)))

                if os.path.islink(self.home_nwchemrc):
                    home_nwchemrc_target = os.readlink(self.home_nwchemrc)
                    if home_nwchemrc_target != self.local_nwchemrc:
                        raise EasyBuildError(
                            "Found %s, but it's not a symlink to %s. "
                            "Please (re)move %s while installing NWChem; it can be restored later",
                            self.home_nwchemrc, self.local_nwchemrc,
                            self.home_nwchemrc)
                # ok to remove, we'll recreate it anyway
                remove_file(self.local_nwchemrc)
        except (IOError, OSError) as err:
            raise EasyBuildError("Failed to validate %s symlink: %s",
                                 self.home_nwchemrc, err)

        # building NWChem in a long path name is an issue, so let's try to make sure we have a short one
        try:
            # NWChem insists that version is in name of build dir
            tmpdir = tempfile.mkdtemp(suffix='-%s-%s' %
                                      (self.name, self.version))
            # remove created directory, since we're not going to use it as is
            os.rmdir(tmpdir)
            # avoid having '['/']' characters in build dir name, NWChem doesn't like that
            start_dir = tmpdir.replace('[', '_').replace(']', '_')
            mkdir(os.path.dirname(start_dir), parents=True)
            symlink(self.cfg['start_dir'], start_dir)
            change_dir(start_dir)
            self.cfg['start_dir'] = start_dir
        except OSError as err:
            raise EasyBuildError(
                "Failed to symlink build dir to a shorter path name: %s", err)

        # change to actual build dir
        change_dir('src')

        nwchem_modules = self.cfg['modules']

        # set required NWChem environment variables
        env.setvar('NWCHEM_TOP', self.cfg['start_dir'])
        if len(self.cfg['start_dir']) > 64:
            # workaround for:
            # "The directory name chosen for NWCHEM_TOP is longer than the maximum allowed value of 64 characters"
            # see also https://svn.pnl.gov/svn/nwchem/trunk/src/util/util_nwchem_srcdir.F
            self.setvar_env_makeopt('NWCHEM_LONG_PATHS', 'Y')

        env.setvar('NWCHEM_TARGET', self.cfg['target'])

        garoot = get_software_root('GlobalArrays')
        if garoot:
            self.setvar_env_makeopt('EXTERNAL_GA_PATH', garoot)
        else:
            env.setvar('MSG_COMMS', self.cfg['msg_comms'])
            env.setvar('ARMCI_NETWORK', self.cfg['armci_network'])
            if self.cfg['armci_network'] in ["OPENIB"]:
                env.setvar('IB_INCLUDE', "/usr/include")
                env.setvar('IB_LIB', "/usr/lib64")
                env.setvar('IB_LIB_NAME', "-libumad -libverbs -lpthread")

        if 'python' in self.cfg['modules']:
            python_root = get_software_root('Python')
            if not python_root:
                raise EasyBuildError(
                    "Python module not loaded, you should add Python as a dependency."
                )
            env.setvar('PYTHONHOME', python_root)
            pyver = '.'.join(get_software_version('Python').split('.')[0:2])
            env.setvar('PYTHONVERSION', pyver)
            # if libreadline is loaded, assume it was a dependency for Python
            # pass -lreadline to avoid linking issues (libpython2.7.a doesn't include readline symbols)
            libreadline = get_software_root('libreadline')
            if libreadline:
                libreadline_libdir = os.path.join(
                    libreadline, get_software_libdir('libreadline'))
                ncurses = get_software_root('ncurses')
                if not ncurses:
                    raise EasyBuildError(
                        "ncurses is not loaded, but required to link with libreadline"
                    )
                ncurses_libdir = os.path.join(ncurses,
                                              get_software_libdir('ncurses'))
                readline_libs = ' '.join([
                    os.path.join(libreadline_libdir, 'libreadline.a'),
                    os.path.join(ncurses_libdir, 'libcurses.a'),
                ])
                extra_libs = os.environ.get('EXTRA_LIBS', '')
                env.setvar('EXTRA_LIBS', ' '.join([extra_libs, readline_libs]))

        env.setvar('LARGE_FILES', 'TRUE')
        env.setvar('USE_NOFSCHECK', 'TRUE')
        env.setvar('CCSDTLR', 'y')  # enable CCSDTLR
        env.setvar(
            'CCSDTQ',
            'y')  # enable CCSDTQ (compilation is long, executable is big)

        if LooseVersion(self.version) >= LooseVersion("6.2"):
            env.setvar('MRCC_METHODS',
                       'y')  # enable multireference coupled cluster capability

        if LooseVersion(self.version) >= LooseVersion("6.5"):
            env.setvar(
                'EACCSD', 'y'
            )  # enable EOM electron-attachemnt coupled cluster capability
            env.setvar(
                'IPCCSD', 'y'
            )  # enable EOM ionization-potential coupled cluster capability
            env.setvar(
                'USE_NOIO',
                'TRUE')  # avoid doing I/O for the ddscf, mp2 and ccsd modules

        for var in ['USE_MPI', 'USE_MPIF', 'USE_MPIF4']:
            env.setvar(var, 'y')
        for var in ['CC', 'CXX', 'F90']:
            env.setvar('MPI_%s' % var, os.getenv('MPI%s' % var))

        libmpi = ""

        # for NWChem 6.6 and newer, $LIBMPI & co should no longer be
        # set, the correct values are determined by the NWChem build
        # procedure automatically, see
        # http://www.nwchem-sw.org/index.php/Compiling_NWChem#MPI_variables
        if LooseVersion(self.version) < LooseVersion("6.6"):
            env.setvar('MPI_LOC', os.path.dirname(os.getenv('MPI_INC_DIR')))
            env.setvar('MPI_LIB', os.getenv('MPI_LIB_DIR'))
            env.setvar('MPI_INCLUDE', os.getenv('MPI_INC_DIR'))

            mpi_family = self.toolchain.mpi_family()
            if mpi_family in toolchain.OPENMPI:
                ompi_ver = get_software_version('OpenMPI')
                if LooseVersion(ompi_ver) < LooseVersion("1.10"):
                    if LooseVersion(ompi_ver) < LooseVersion("1.8"):
                        libmpi = "-lmpi_f90 -lmpi_f77 -lmpi -ldl -Wl,--export-dynamic -lnsl -lutil"
                    else:
                        libmpi = "-lmpi_usempi -lmpi_mpifh -lmpi"
                else:
                    libmpi = "-lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lmpi"
            elif mpi_family in [toolchain.INTELMPI]:
                if self.cfg['armci_network'] in ["MPI-MT"]:
                    libmpi = "-lmpigf -lmpigi -lmpi_ilp64 -lmpi_mt"
                else:
                    libmpi = "-lmpigf -lmpigi -lmpi_ilp64 -lmpi"
            elif mpi_family in [toolchain.MPICH, toolchain.MPICH2]:
                libmpi = "-lmpichf90 -lmpich -lopa -lmpl -lrt -lpthread"
            else:
                raise EasyBuildError("Don't know how to set LIBMPI for %s",
                                     mpi_family)
            env.setvar('LIBMPI', libmpi)

        if not garoot:
            if self.cfg['armci_network'] in ["OPENIB"]:
                libmpi += " -libumad -libverbs -lpthread"

        # compiler optimization flags: set environment variables _and_ add them to list of make options
        self.setvar_env_makeopt('COPTIMIZE', os.getenv('CFLAGS'))
        self.setvar_env_makeopt('FOPTIMIZE', os.getenv('FFLAGS'))

        # BLAS and ScaLAPACK
        mpi_lib_dirs = ' '.join('-L' + d
                                for d in os.getenv('MPI_LIB_DIR').split())
        self.setvar_env_makeopt(
            'BLASOPT', ' '.join([
                os.getenv('LDFLAGS'), mpi_lib_dirs,
                os.getenv('LIBSCALAPACK_MT'), libmpi
            ]))

        # Setting LAPACK_LIB is required from 7.0.0 onwards.
        self.setvar_env_makeopt('LAPACK_LIB', os.getenv('LIBLAPACK'))

        self.setvar_env_makeopt(
            'SCALAPACK',
            '%s %s' % (os.getenv('LDFLAGS'), os.getenv('LIBSCALAPACK_MT')))
        if self.toolchain.options['i8']:
            size = 8
            self.setvar_env_makeopt('USE_SCALAPACK_I8', 'y')
            self.cfg.update('lib_defines', '-DSCALAPACK_I8')
        else:
            self.setvar_env_makeopt('HAS_BLAS', 'yes')
            self.setvar_env_makeopt('USE_SCALAPACK', 'y')
            size = 4

        # set sizes
        for lib in ['BLAS', 'LAPACK', 'SCALAPACK']:
            self.setvar_env_makeopt('%s_SIZE' % lib, str(size))

        env.setvar('NWCHEM_MODULES', nwchem_modules)

        env.setvar('LIB_DEFINES', self.cfg['lib_defines'])

        # clean first (why not)
        run_cmd("make clean", simple=True, log_all=True, log_ok=True)

        # configure build
        cmd = "make %s nwchem_config" % self.cfg['buildopts']
        run_cmd(cmd, simple=True, log_all=True, log_ok=True, log_output=True)
예제 #11
0
            env.setvar('IB_INCLUDE', "/usr/include")
            env.setvar('IB_LIB', "/usr/lib64")
            env.setvar('IB_LIB_NAME', "-libumad -libverbs -lpthread")

        if 'python' in self.cfg['modules']:
            python_root = get_software_root('Python')
            if not python_root:
                raise EasyBuildError("Python module not loaded, you should add Python as a dependency.")
            env.setvar('PYTHONHOME', python_root)
            pyver = '.'.join(get_software_version('Python').split('.')[0:2])
            env.setvar('PYTHONVERSION', pyver)
            # if libreadline is loaded, assume it was a dependency for Python
            # pass -lreadline to avoid linking issues (libpython2.7.a doesn't include readline symbols)
            libreadline = get_software_root('libreadline')
            if libreadline:
                libreadline_libdir = os.path.join(libreadline, get_software_libdir('libreadline'))
                ncurses = get_software_root('ncurses')
                if not ncurses:
                    raise EasyBuildError("ncurses is not loaded, but required to link with libreadline")
                ncurses_libdir = os.path.join(ncurses, get_software_libdir('ncurses'))
                readline_libs = ' '.join([
                    os.path.join(libreadline_libdir, 'libreadline.a'),
                    os.path.join(ncurses_libdir, 'libcurses.a'),
                ])
                extra_libs = os.environ.get('EXTRA_LIBS', '')
                env.setvar('EXTRA_LIBS', ' '.join([extra_libs, readline_libs]))

        env.setvar('LARGE_FILES', 'TRUE')
        env.setvar('USE_NOFSCHECK', 'TRUE')
        env.setvar('CCSDTLR', 'y')  # enable CCSDTLR 
        env.setvar('CCSDTQ', 'y') # enable CCSDTQ (compilation is long, executable is big)
예제 #12
0
    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

                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
                self.cfg['build_shared_libs'] = True
                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")

            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:
                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
            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)
예제 #13
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:
            if self.toolchain.options['debug']:
                self.cfg.update('configopts', '-DCMAKE_BUILD_TYPE=DEBUG ')
            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'),
                                   ('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)
예제 #14
0
    def configure_step(self):
        """Configure build by patching UFconfig.mk or SuiteSparse_config.mk."""

        if LooseVersion(self.version) < LooseVersion('4.0'):
            self.config_name = 'UFconfig'
        else:
            self.config_name = 'SuiteSparse_config'

        cfgvars = {
            'CC': os.getenv('MPICC'),
            'CFLAGS': os.getenv('CFLAGS'),
            'CXX': os.getenv('MPICXX'),
            'F77': os.getenv('MPIF77'),
            'F77FLAGS': os.getenv('F77FLAGS'),
        }

        # Set BLAS and LAPACK libraries as specified in SuiteSparse README.txt
        self.cfg.update('buildopts', 'BLAS="%s"' % os.getenv('LIBBLAS_MT'))
        self.cfg.update('buildopts', 'LAPACK="%s"' % os.getenv('LIBLAPACK_MT'))

        # Get METIS or ParMETIS settings
        metis = get_software_root('METIS')
        parmetis = get_software_root('ParMETIS')
        if parmetis:
            metis_path = parmetis
            metis_include = os.path.join(parmetis, 'include')
            metis_libs = os.path.join(parmetis,
                                      get_software_libdir('ParMETIS'),
                                      'libmetis.a')

        elif metis:
            metis_path = metis
            metis_include = os.path.join(metis, 'include')
            metis_libs = os.path.join(metis, get_software_libdir('METIS'),
                                      'libmetis.a')

        else:
            raise EasyBuildError("Neither METIS or ParMETIS module loaded.")

        if LooseVersion(self.version) >= LooseVersion('4.5.1'):
            cfgvars.update({
                'MY_METIS_LIB': metis_libs,
                'MY_METIS_INC': metis_include,
            })
        else:
            cfgvars.update({
                'METIS_PATH': metis_path,
                'METIS': metis_libs,
            })

        # patch file
        fp = os.path.join(self.cfg['start_dir'], self.config_name,
                          '%s.mk' % self.config_name)

        try:
            for line in fileinput.input(fp, inplace=1, backup='.orig'):
                for (var, val) in cfgvars.items():
                    orig_line = line
                    # for variables in cfgvars, substiture lines assignment
                    # in the file, whatever they are, by assignments to the
                    # values in cfgvars
                    line = re.sub(r"^\s*(%s\s*=\s*).*\n$" % var,
                                  r"\1 %s # patched by EasyBuild\n" % val,
                                  line)
                    if line != orig_line:
                        cfgvars.pop(var)
                sys.stdout.write(line)
        except IOError, err:
            raise EasyBuildError("Failed to patch %s in: %s", fp, err)
예제 #15
0
            env.setvar('IB_INCLUDE', "/usr/include")
            env.setvar('IB_LIB', "/usr/lib64")
            env.setvar('IB_LIB_NAME', "-libumad -libverbs -lpthread")

        if 'python' in self.cfg['modules']:
            python_root = get_software_root('Python')
            if not python_root:
                raise EasyBuildError("Python module not loaded, you should add Python as a dependency.")
            env.setvar('PYTHONHOME', python_root)
            pyver = '.'.join(get_software_version('Python').split('.')[0:2])
            env.setvar('PYTHONVERSION', pyver)
            # if libreadline is loaded, assume it was a dependency for Python
            # pass -lreadline to avoid linking issues (libpython2.7.a doesn't include readline symbols)
            libreadline = get_software_root('libreadline')
            if libreadline:
                libreadline_libdir = os.path.join(libreadline, get_software_libdir('libreadline'))
                ncurses = get_software_root('ncurses')
                if not ncurses:
                    raise EasyBuildError("ncurses is not loaded, but required to link with libreadline")
                ncurses_libdir = os.path.join(ncurses, get_software_libdir('ncurses'))
                readline_libs = ' '.join([
                    os.path.join(libreadline_libdir, 'libreadline.a'),
                    os.path.join(ncurses_libdir, 'libcurses.a'),
                ])
                extra_libs = os.environ.get('EXTRA_LIBS', '')
                env.setvar('EXTRA_LIBS', ' '.join([extra_libs, readline_libs]))

        env.setvar('LARGE_FILES', 'TRUE')
        env.setvar('USE_NOFSCHECK', 'TRUE')
        env.setvar('CCSDTLR', 'y')  # enable CCSDTLR 
        env.setvar('CCSDTQ', 'y') # enable CCSDTQ (compilation is long, executable is big)
    def configure_step(self):
        """Set extra configure options."""
        # Check for and report distutils user configs which may make the installation fail
        # See https://github.com/easybuilders/easybuild-easyconfigs/issues/11009
        for cfg in [
                os.path.join(os.path.expanduser('~'), name)
                for name in ('.pydistutils.cfg', 'pydistutils.cfg')
        ]:
            if os.path.exists(cfg):
                raise EasyBuildError(
                    "Legacy distutils user configuration file found at %s. Aborting.",
                    cfg)

        self.cfg.update('configopts', "--enable-shared")

        # Explicitely enable thread support on < 3.7 (always on 3.7+)
        if LooseVersion(self.version) < LooseVersion('3.7'):
            self.cfg.update('configopts', "--with-threads")

        # Explicitely enable unicode on Python 2, always on for Python 3
        # Need to be careful to match the unicode settings to the underlying python
        if LooseVersion(self.version) < LooseVersion('3.0'):
            if sys.maxunicode == 1114111:
                self.cfg.update('configopts', "--enable-unicode=ucs4")
            elif sys.maxunicode == 65535:
                self.cfg.update('configopts', "--enable-unicode=ucs2")
            else:
                raise EasyBuildError(
                    "Unknown maxunicode value for your python: %d" %
                    sys.maxunicode)

        # LTO introduced in 3.7.0
        if LooseVersion(self.version) >= LooseVersion('3.7.0'):
            use_lto = self.cfg['use_lto']
            if use_lto is None:
                use_lto = self.auto_detect_lto_support()
            if use_lto:
                self.cfg.update('configopts', "--with-lto")

        # Enable further optimizations at the cost of a longer build
        # Introduced in 3.5.3, fixed in 3.5.4: https://docs.python.org/3.5/whatsnew/changelog.html
        if self.cfg['optimized'] and LooseVersion(
                self.version) >= LooseVersion('3.5.4'):
            # only configure with --enable-optimizations when compiling Python with (recent) GCC compiler
            if self.toolchain.comp_family() == toolchain.GCC:
                gcc_ver = get_software_version(
                    'GCCcore') or get_software_version('GCC')
                if LooseVersion(gcc_ver) >= LooseVersion('8.0'):
                    self.cfg.update('configopts', "--enable-optimizations")

        # When ensurepip is available we explicitely set this.
        # E.g. in 3.4 it is by default "upgrade", i.e. on which is unexpected when we did set it to off
        if self._has_ensure_pip():
            self.cfg.update(
                'configopts',
                "--with-ensurepip=" + ('no', 'upgrade')[self.install_pip])

        modules_setup = os.path.join(self.cfg['start_dir'], 'Modules', 'Setup')
        if LooseVersion(self.version) < LooseVersion('3.8.0'):
            modules_setup += '.dist'

        libreadline = get_software_root('libreadline')
        if libreadline:
            ncurses = get_software_root('ncurses')
            if ncurses:
                readline_libdir = get_software_libdir('libreadline')
                ncurses_libdir = get_software_libdir('ncurses')
                readline_static_lib = os.path.join(libreadline,
                                                   readline_libdir,
                                                   'libreadline.a')
                ncurses_static_lib = os.path.join(ncurses, ncurses_libdir,
                                                  'libncurses.a')
                readline = "readline readline.c %s %s" % (readline_static_lib,
                                                          ncurses_static_lib)
                for line in fileinput.input(modules_setup,
                                            inplace='1',
                                            backup='.readline'):
                    line = re.sub(r"^#readline readline.c.*", readline, line)
                    sys.stdout.write(line)
            else:
                raise EasyBuildError(
                    "Both libreadline and ncurses are required to ensure readline support"
                )

        openssl = get_software_root('OpenSSL')
        if openssl:
            for line in fileinput.input(modules_setup,
                                        inplace='1',
                                        backup='.ssl'):
                line = re.sub(r"^#SSL=.*", "SSL=%s" % openssl, line)
                line = re.sub(r"^#(\s*-DUSE_SSL -I)", r"\1", line)
                line = re.sub(r"^#(\s*-L\$\(SSL\)/lib )",
                              r"\1 -L$(SSL)/lib64 ", line)
                sys.stdout.write(line)

        tcl = get_software_root('Tcl')
        tk = get_software_root('Tk')
        if tcl and tk:
            tclver = get_software_version('Tcl')
            tkver = get_software_version('Tk')
            tcltk_maj_min_ver = '.'.join(tclver.split('.')[:2])
            if tcltk_maj_min_ver != '.'.join(tkver.split('.')[:2]):
                raise EasyBuildError(
                    "Tcl and Tk major/minor versions don't match: %s vs %s",
                    tclver, tkver)

            self.cfg.update(
                'configopts',
                "--with-tcltk-includes='-I%s/include -I%s/include'" %
                (tcl, tk))

            tcl_libdir = os.path.join(tcl, get_software_libdir('Tcl'))
            tk_libdir = os.path.join(tk, get_software_libdir('Tk'))
            tcltk_libs = "-L%(tcl_libdir)s -L%(tk_libdir)s -ltcl%(maj_min_ver)s -ltk%(maj_min_ver)s" % {
                'tcl_libdir': tcl_libdir,
                'tk_libdir': tk_libdir,
                'maj_min_ver': tcltk_maj_min_ver,
            }
            self.cfg.update('configopts',
                            "--with-tcltk-libs='%s'" % tcltk_libs)

        # don't add user site directory to sys.path (equivalent to python -s)
        # This matters e.g. when python installs the bundled pip & setuptools (for >= 3.4)
        env.setvar('PYTHONNOUSERSITE', '1')

        super(EB_Python, self).configure_step()
예제 #17
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)
            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)

            # 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 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")

            # 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)
예제 #18
0
        if 'python' in self.cfg['modules']:
            python_root = get_software_root('Python')
            if not python_root:
                self.log.error(
                    "Python module not loaded, you should add Python as a dependency."
                )
            env.setvar('PYTHONHOME', python_root)
            pyver = '.'.join(get_software_version('Python').split('.')[0:2])
            env.setvar('PYTHONVERSION', pyver)
            # if libreadline is loaded, assume it was a dependency for Python
            # pass -lreadline to avoid linking issues (libpython2.7.a doesn't include readline symbols)
            libreadline = get_software_root('libreadline')
            if libreadline:
                libreadline_libdir = os.path.join(
                    libreadline, get_software_libdir('libreadline'))
                ncurses = get_software_root('ncurses')
                if not ncurses:
                    self.log.error(
                        "ncurses is not loaded, but required to link with libreadline"
                    )
                ncurses_libdir = os.path.join(ncurses,
                                              get_software_libdir('ncurses'))
                readline_libs = ' '.join([
                    os.path.join(libreadline_libdir, 'libreadline.a'),
                    os.path.join(ncurses_libdir, 'libcurses.a'),
                ])
                extra_libs = os.environ.get('EXTRA_LIBS', '')
                env.setvar('EXTRA_LIBS', ' '.join([extra_libs, readline_libs]))

        env.setvar('LARGE_FILES', 'TRUE')
예제 #19
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)
예제 #20
0
    def configure_step(self):
        """Set extra configure options."""
        self.cfg.update('configopts', "--with-threads --enable-shared")

        # Need to be careful to match the unicode settings to the underlying python
        if sys.maxunicode == 1114111:
            self.cfg.update('configopts', "--enable-unicode=ucs4")
        elif sys.maxunicode == 65535:
            self.cfg.update('configopts', "--enable-unicode=ucs2")
        else:
            raise EasyBuildError(
                "Unknown maxunicode value for your python: %d" %
                sys.maxunicode)

        modules_setup_dist = os.path.join(self.cfg['start_dir'], 'Modules',
                                          'Setup.dist')

        libreadline = get_software_root('libreadline')
        if libreadline:
            ncurses = get_software_root('ncurses')
            if ncurses:
                readline_libdir = get_software_libdir('libreadline')
                ncurses_libdir = get_software_libdir('ncurses')
                readline_static_lib = os.path.join(libreadline,
                                                   readline_libdir,
                                                   'libreadline.a')
                ncurses_static_lib = os.path.join(ncurses, ncurses_libdir,
                                                  'libncurses.a')
                readline = "readline readline.c %s %s" % (readline_static_lib,
                                                          ncurses_static_lib)
                for line in fileinput.input(modules_setup_dist,
                                            inplace='1',
                                            backup='.readline'):
                    line = re.sub(r"^#readline readline.c.*", readline, line)
                    sys.stdout.write(line)
            else:
                raise EasyBuildError(
                    "Both libreadline and ncurses are required to ensure readline support"
                )

        openssl = get_software_root('OpenSSL')
        if openssl:
            for line in fileinput.input(modules_setup_dist,
                                        inplace='1',
                                        backup='.ssl'):
                line = re.sub(r"^#SSL=.*", "SSL=%s" % openssl, line)
                line = re.sub(r"^#(\s*-DUSE_SSL -I)", r"\1", line)
                line = re.sub(r"^#(\s*-L\$\(SSL\)/lib )",
                              r"\1 -L$(SSL)/lib64 ", line)
                sys.stdout.write(line)

        tcl = get_software_root('Tcl')
        tk = get_software_root('Tk')
        if tcl and tk:
            tclver = get_software_version('Tcl')
            tkver = get_software_version('Tk')
            tcltk_maj_min_ver = '.'.join(tclver.split('.')[:2])
            if tcltk_maj_min_ver != '.'.join(tkver.split('.')[:2]):
                raise EasyBuildError(
                    "Tcl and Tk major/minor versions don't match: %s vs %s",
                    tclver, tkver)

            self.cfg.update(
                'configopts',
                "--with-tcltk-includes='-I%s/include -I%s/include'" %
                (tcl, tk))

            tcl_libdir = os.path.join(tcl, get_software_libdir('Tcl'))
            tk_libdir = os.path.join(tk, get_software_libdir('Tk'))
            tcltk_libs = "-L%(tcl_libdir)s -L%(tk_libdir)s -ltcl%(maj_min_ver)s -ltk%(maj_min_ver)s" % {
                'tcl_libdir': tcl_libdir,
                'tk_libdir': tk_libdir,
                'maj_min_ver': tcltk_maj_min_ver,
            }
            self.cfg.update('configopts',
                            "--with-tcltk-libs='%s'" % tcltk_libs)

        super(EB_Python, self).configure_step()
예제 #21
0
        aux_lib_gribex = os.path.join(tmp_installroot, gribdir, 'lib', 'libgribex.a')
        aux_lib_ibm = os.path.join(tmp_installroot, gribdir, 'lib', 'libibmdummy.a')
        grib_api_lib = os.path.join(get_software_root('grib_api'), 'lib', 'libgrib_api.a')
        grib_api_f90_lib = os.path.join(get_software_root('grib_api'), 'lib', 'libgrib_api_f90.a')
        grib_api_inc = os.path.join(get_software_root('grib_api'), 'include')
        jasperlib = os.path.join(get_software_root('JasPer'), 'lib', 'libjasper.a')
        mpilib = os.path.join(os.getenv('MPI_LIB_DIR'), os.getenv('MPI_LIB_SHARED'))

        # netCDF
        netcdf = get_software_root('netCDF')
        netcdf_fortran = get_software_root('netCDF-Fortran')
        if netcdf:
            netcdfinc = os.path.join(netcdf, 'include')
            if netcdf_fortran:
                netcdflib = os.path.join(netcdf_fortran, get_software_libdir('netCDF-Fortran'), 'libnetcdff.a')
            else:
                netcdflib = os.path.join(netcdf, get_software_libdir('netCDF'), 'libnetcdff.a')
            if not os.path.exists(netcdflib):
                raise EasyBuildError("%s does not exist", netcdflib)
        else:
            raise EasyBuildError("netCDF(-Fortran) not available")

        ldpaths = [ldflag[2:] for ldflag in os.getenv('LDFLAGS').split(' ')]  # LDFLAGS have form '-L/path/to'

        lapacklibs = []
        for lib in os.getenv('LAPACK_STATIC_LIBS').split(','):
            libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths]
            lapacklibs.append([libpath for libpath in libpaths if os.path.exists(libpath)][0])
        lapacklib = ' '.join(lapacklibs)
        blaslibs = []
예제 #22
0
    def configure_step(self):
        """Custom configuration procedure for ALADIN."""

        # unset $LIBRARY_PATH set by modules of dependencies, because it may screw up linking
        if 'LIBRARY_PATH' in os.environ:
            self.log.debug("Unsetting $LIBRARY_PATH (was: %s)" % os.environ['LIBRARY_PATH'])
            self.orig_library_path = os.environ.pop('LIBRARY_PATH')

        # build auxiliary libraries
        auxlibs_dir = None

        my_gnu = None
        if self.toolchain.comp_family() == toolchain.GCC:
            my_gnu = 'y'  # gfortran
            for var in ['CFLAGS', 'CXXFLAGS', 'F90FLAGS', 'FFLAGS']:
                flags = os.getenv(var)
                env.setvar(var, "%s -fdefault-real-8 -fdefault-double-8" % flags)
                self.log.info("Updated %s to '%s'" % (var, os.getenv(var)))
        elif self.toolchain.comp_family() == toolchain.INTELCOMP:
            my_gnu = 'i'  # icc/ifort
        else:
            raise EasyBuildError("Don't know how to set 'my_gnu' variable in auxlibs build script.")
        self.log.info("my_gnu set to '%s'" % my_gnu)

        tmp_installroot = tempfile.mkdtemp(prefix='aladin_auxlibs_')

        try:
            cwd = os.getcwd()

            os.chdir(self.builddir)
            builddirs = os.listdir(self.builddir)

            auxlibs_dir = [x for x in builddirs if x.startswith('auxlibs_installer')][0]

            os.chdir(auxlibs_dir)

            auto_driver = 'driver_automatic'
            for line in fileinput.input(auto_driver, inplace=1, backup='.orig.eb'):

                line = re.sub(r"^(my_gnu\s*=\s*).*$", r"\1%s" % my_gnu, line)
                line = re.sub(r"^(my_r32\s*=\s*).*$", r"\1n", line)  # always 64-bit real precision
                line = re.sub(r"^(my_readonly\s*=\s*).*$", r"\1y", line)  # make libs read-only after build
                line = re.sub(r"^(my_installroot\s*=\s*).*$", r"\1%s" % tmp_installroot, line)

                sys.stdout.write(line)

            run_cmd("./%s" % auto_driver)

            os.chdir(cwd)

        except OSError as err:
            raise EasyBuildError("Failed to build ALADIN: %s", err)

        # build gmkpack, update PATH and set GMKROOT
        # we build gmkpack here because a config file is generated in the gmkpack isntall path
        try:
            gmkpack_dir = [x for x in builddirs if x.startswith('gmkpack')][0]
            os.chdir(os.path.join(self.builddir, gmkpack_dir))

            qa = {
                  'Do you want to run the configuration file maker assistant now (y) or later [n] ?': 'n',
                 }

            run_cmd_qa("./build_gmkpack", qa)

            os.chdir(cwd)

            paths = os.getenv('PATH').split(':')
            paths.append(os.path.join(self.builddir, gmkpack_dir, 'util'))
            env.setvar('PATH', ':'.join(paths))

            env.setvar('GMKROOT', os.path.join(self.builddir, gmkpack_dir))

        except OSError as err:
            raise EasyBuildError("Failed to build gmkpack: %s", err)

        # generate gmkpack configuration file
        self.conf_file = 'ALADIN_%s' % self.version
        self.conf_filepath = os.path.join(self.builddir, 'gmkpack_support', 'arch', '%s.x' % self.conf_file)

        try:
            if os.path.exists(self.conf_filepath):
                os.remove(self.conf_filepath)
                self.log.info("Removed existing gmpack config file %s" % self.conf_filepath)

            archdir = os.path.dirname(self.conf_filepath)
            if not os.path.exists(archdir):
                mkdir(archdir, parents=True)

        except OSError as err:
            raise EasyBuildError("Failed to remove existing file %s: %s", self.conf_filepath, err)

        mpich = 'n'
        known_mpi_libs = [toolchain.MPICH, toolchain.MPICH2, toolchain.INTELMPI]
        if self.toolchain.options.get('usempi', None) and self.toolchain.mpi_family() in known_mpi_libs:
            mpich = 'y'

        qpref = 'Please type the ABSOLUTE name of '
        qsuff = ', or ignore (environment variables allowed) :'
        qsuff2 = ', or ignore : (environment variables allowed) :'

        comp_fam = self.toolchain.comp_family()
        if comp_fam == toolchain.GCC:
            gribdir = 'GNU'
        elif comp_fam == toolchain.INTELCOMP:
            gribdir = 'INTEL'
        else:
            raise EasyBuildError("Don't know which grib lib dir to use for compiler %s", comp_fam)

        aux_lib_gribex = os.path.join(tmp_installroot, gribdir, 'lib', 'libgribex.a')
        aux_lib_ibm = os.path.join(tmp_installroot, gribdir, 'lib', 'libibmdummy.a')
        grib_api_lib = os.path.join(get_software_root('grib_api'), 'lib', 'libgrib_api.a')
        grib_api_f90_lib = os.path.join(get_software_root('grib_api'), 'lib', 'libgrib_api_f90.a')
        grib_api_inc = os.path.join(get_software_root('grib_api'), 'include')
        jasperlib = os.path.join(get_software_root('JasPer'), 'lib', 'libjasper.a')
        mpilib = os.path.join(os.getenv('MPI_LIB_DIR'), os.getenv('MPI_LIB_SHARED'))

        # netCDF
        netcdf = get_software_root('netCDF')
        netcdf_fortran = get_software_root('netCDF-Fortran')
        if netcdf:
            netcdfinc = os.path.join(netcdf, 'include')
            if netcdf_fortran:
                netcdflib = os.path.join(netcdf_fortran, get_software_libdir('netCDF-Fortran'), 'libnetcdff.a')
            else:
                netcdflib = os.path.join(netcdf, get_software_libdir('netCDF'), 'libnetcdff.a')
            if not os.path.exists(netcdflib):
                raise EasyBuildError("%s does not exist", netcdflib)
        else:
            raise EasyBuildError("netCDF(-Fortran) not available")

        ldpaths = [ldflag[2:] for ldflag in os.getenv('LDFLAGS').split(' ')]  # LDFLAGS have form '-L/path/to'

        lapacklibs = []
        for lib in os.getenv('LAPACK_STATIC_LIBS').split(','):
            libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths]
            lapacklibs.append([libpath for libpath in libpaths if os.path.exists(libpath)][0])
        lapacklib = ' '.join(lapacklibs)
        blaslibs = []
        for lib in os.getenv('BLAS_STATIC_LIBS').split(','):
            libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths]
            blaslibs.append([libpath for libpath in libpaths if os.path.exists(libpath)][0])
        blaslib = ' '.join(blaslibs)

        qa = {
            'Do you want to run the configuration file maker assistant now (y) or later [n] ?': 'y',
            'Do you want to setup your configuration file for MPICH (y/n) [n] ?': mpich,
            'Please type the directory name where to find a dummy file mpif.h or ignore :': os.getenv('MPI_INC_DIR'),
            '%sthe library gribex or emos%s' % (qpref, qsuff2): aux_lib_gribex,
            '%sthe library ibm%s' % (qpref, qsuff): aux_lib_ibm,
            '%sthe library grib_api%s' % (qpref, qsuff): grib_api_lib,
            '%sthe library grib_api_f90%s' % (qpref, qsuff): grib_api_f90_lib,
            '%sthe JPEG auxilary library if enabled by Grib_api%s' % (qpref, qsuff2): jasperlib,
            '%sthe library netcdf%s' % (qpref, qsuff): netcdflib,
            '%sthe library lapack%s' % (qpref, qsuff): lapacklib,
            '%sthe library blas%s' % (qpref, qsuff): blaslib,
            '%sthe library mpi%s' % (qpref, qsuff): mpilib,
            '%sa MPI dummy library for serial executions, or ignore :' % qpref: '',
            'Please type the directory name where to find grib_api headers, or ignore :': grib_api_inc,
            'Please type the directory name where to find fortint.h or ignore :': '',
            'Please type the directory name where to find netcdf headers, or ignore :': netcdfinc,
            'Do you want to define CANARI (y/n) [y] ?': 'y',
            'Please type the name of the script file used to generate a preprocessed blacklist file, or ignore :': '',
            'Please type the name of the script file used to recover local libraries (gget), or ignore :': '',
            'Please type the options to tune the gnu compilers, or ignore :': os.getenv('F90FLAGS'),
        }

        f90_seq = os.getenv('F90_SEQ')
        if not f90_seq:
            # F90_SEQ is only defined when usempi is enabled
            f90_seq = os.getenv('F90')

        stdqa = OrderedDict([
            (r'Confirm library .* is .*', 'y'),  # this one needs to be tried first!
            (r'.*fortran 90 compiler name .*\s*:\n\(suggestions\s*: .*\)', f90_seq),
            (r'.*fortran 90 compiler interfaced with .*\s*:\n\(suggestions\s*: .*\)', f90_seq),
            (r'Please type the ABSOLUTE name of .*library.*, or ignore\s*[:]*\s*[\n]*.*', ''),
            (r'Please .* to save this draft configuration file :\n.*', '%s.x' % self.conf_file),
        ])

        no_qa = [
            ".*ignored.",
        ]

        env.setvar('GMKTMP', self.builddir)
        env.setvar('GMKFILE', self.conf_file)

        run_cmd_qa("gmkfilemaker", qa, std_qa=stdqa, no_qa=no_qa)

        # set environment variables for installation dirs
        env.setvar('ROOTPACK', os.path.join(self.installdir, 'rootpack'))
        env.setvar('ROOTBIN', os.path.join(self.installdir, 'rootpack'))
        env.setvar('HOMEPACK', os.path.join(self.installdir, 'pack'))
        env.setvar('HOMEBIN', os.path.join(self.installdir, 'pack'))

        # patch config file to include right Fortran compiler flags
        regex_subs = [(r"^(FRTFLAGS\s*=.*)$", r"\1 %s" % os.getenv('FFLAGS'))]
        apply_regex_substitutions(self.conf_filepath, regex_subs)
예제 #23
0
    def configure_step(self, *args, **kwargs):
        """Configure the build, set configure options for compiler, MPI and dependencies."""
        # On non-cross-compile platforms, specify compiler and MPI suite explicitly.  This is much quicker and safer
        # than autodetection.  In Score-P build-system terms, the following platforms are considered cross-compile
        # architectures:
        #
        #   - Cray XT/XE/XK/XC series
        #   - Fujitsu FX10, FX100 & K computer
        #   - IBM Blue Gene series
        #
        # Of those, only Cray is supported right now.
        tc_fam = self.toolchain.toolchain_family()
        if tc_fam != toolchain.CRAYPE:
            # --with-nocross-compiler-suite=(gcc|ibm|intel|pgi|studio)
            comp_opts = {
                toolchain.DUMMY: 'gcc',  # Assume that dummy toolchain uses a system-provided GCC
                toolchain.GCC: 'gcc',
                toolchain.IBMCOMP: 'ibm',
                toolchain.INTELCOMP: 'intel',
                toolchain.PGI: 'pgi',
            }
            comp_fam = self.toolchain.comp_family()
            if comp_fam in comp_opts:
                self.cfg.update('configopts', "--with-nocross-compiler-suite=%s" % comp_opts[comp_fam])
            else:
                raise EasyBuildError("Compiler family %s not supported yet (only: %s)",
                                     comp_fam, ', '.join(comp_opts.keys()))

            # --with-mpi=(bullxmpi|hp|ibmpoe|intel|intel2|intelpoe|lam|mpibull2|mpich|mpich2|mpich3|openmpi|
            #             platform|scali|sgimpt|sun)
            #
            # Notes:
            #   - intel:    Intel MPI v1.x (ancient & unsupported)
            #   - intel2:   Intel MPI v2.x and higher
            #   - intelpoe: IBM POE MPI for Intel platforms
            #   - mpich:    MPICH v1.x (ancient & unsupported)
            #   - mpich2:   MPICH2 v1.x
            #   - mpich3:   MPICH v3.x & MVAPICH2
            #               This setting actually only affects options passed to the MPI (Fortran) compiler wrappers.
            #               And since MPICH v3.x-compatible options were already supported in MVAPICH2 v1.7, it is
            #               safe to use 'mpich3' for all supported versions although MVAPICH2 is based on MPICH v3.x
            #               only since v1.9b.
            #
            # With minimal toolchains, packages using this easyblock may be built with a non-MPI toolchain (e.g., OTF2).
            # In this case, skip passing the '--with-mpi' option.
            mpi_opts = {
                toolchain.INTELMPI: 'intel2',
                toolchain.OPENMPI: 'openmpi',
                toolchain.MPICH: 'mpich3',     # In EB terms, MPICH means MPICH 3.x
                toolchain.MPICH2: 'mpich2',
                toolchain.MVAPICH2: 'mpich3',
            }
            mpi_fam = self.toolchain.mpi_family()
            if mpi_fam is not None:
                if mpi_fam in mpi_opts:
                    self.cfg.update('configopts', "--with-mpi=%s" % mpi_opts[mpi_fam])
                else:
                    raise EasyBuildError("MPI family %s not supported yet (only: %s)",
                                         mpi_fam, ', '.join(mpi_opts.keys()))

        # Auto-detection for dependencies mostly works fine, but hard specify paths anyway to have full control
        #
        # Notes:
        #   - binutils: Pass include/lib directories separately, as different directory layouts may break Score-P's
        #               configure, see https://github.com/geimer/easybuild-easyblocks/pull/4#issuecomment-219284755
        deps = {
            'binutils': ['--with-libbfd-include=%s/include',
                         '--with-libbfd-lib=%%s/%s' % get_software_libdir('binutils', fs=['libbfd.a'])],
            'libunwind': ['--with-libunwind=%s'],
            'Cube': ['--with-cube=%s/bin'],
            'CUDA': ['--with-libcudart=%s'],
            'OTF2': ['--with-otf2=%s/bin'],
            'OPARI2': ['--with-opari2=%s/bin'],
            'PAPI': ['--with-papi-header=%s/include', '--with-papi-lib=%%s/%s' % get_software_libdir('PAPI')],
            'PDT': ['--with-pdt=%s/bin'],
            'Qt': ['--with-qt=%s'],
            'SIONlib': ['--with-sionlib=%s/bin'],
        }
        for (dep_name, dep_opts) in deps.items():
            dep_root = get_software_root(dep_name)
            if dep_root:
                for dep_opt in dep_opts:
                    self.cfg.update('configopts', dep_opt % dep_root)

        super(EB_Score_minus_P, self).configure_step(*args, **kwargs)
예제 #24
0
    def configure_step(self):
        """Custom configuration procedure for OpenCV."""

        # enable Python support if unspecified and Python is a dependency
        if 'BUILD_PYTHON_SUPPORT' not in self.cfg['configopts']:
            if get_software_root('Python'):
                self.cfg.update(
                    'configopts',
                    "-DBUILD_PYTHON_SUPPORT=ON -DBUILD_NEW_PYTHON_SUPPORT=ON")

                # recent OpenCV 3.x versions (and newer) use an alternative configure option to specify the location
                # where the OpenCV Python bindings should be installed
                py_pkgs_path = os.path.join(self.installdir, self.pylibdir)
                if LooseVersion(self.version) >= LooseVersion('3.4.4'):
                    self.cfg.update(
                        'configopts',
                        '-DOPENCV_PYTHON_INSTALL_PATH=%s' % py_pkgs_path)
                else:
                    self.cfg.update('configopts',
                                    '-DPYTHON_PACKAGES_PATH=%s' % py_pkgs_path)
            else:
                self.cfg.update(
                    'configopts',
                    "-DBUILD_PYTHON_SUPPORT=OFF -DBUILD_NEW_PYTHON_SUPPORT=OFF"
                )

        # enable CUDA support if CUDA is a dependency
        if 'WITH_CUDA' not in self.cfg['configopts']:
            if get_software_root('CUDA'):
                self.cfg.update('configopts', '-DWITH_CUDA=ON')
            else:
                self.cfg.update('configopts', '-DWITH_CUDA=OFF')

        # configure for dependency libraries
        for dep in ['JasPer', 'libjpeg-turbo', 'libpng', 'LibTIFF', 'zlib']:
            if dep in ['libpng', 'LibTIFF']:
                # strip off 'lib'
                opt_name = dep[3:].upper()
            elif dep == 'libjpeg-turbo':
                opt_name = 'JPEG'
            else:
                opt_name = dep.upper()

            shlib_ext = get_shared_lib_ext()
            if dep == 'zlib':
                lib_file = 'libz.%s' % shlib_ext
            else:
                lib_file = 'lib%s.%s' % (opt_name.lower(), shlib_ext)

            dep_root = get_software_root(dep)
            if dep_root:
                self.cfg.update(
                    'configopts', '-D%s_INCLUDE_DIR=%s' %
                    (opt_name, os.path.join(dep_root, 'include')))
                libdir = get_software_libdir(dep, only_one=True)
                self.cfg.update(
                    'configopts', '-D%s_LIBRARY=%s' %
                    (opt_name, os.path.join(dep_root, libdir, lib_file)))

        # configure optimisation for CPU architecture
        # see https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options
        if self.toolchain.options.get(
                'optarch') and 'CPU_BASELINE' not in self.cfg['configopts']:
            optarch = build_option('optarch')
            if optarch is None:
                # optimize for host arch (let OpenCV detect it)
                self.cfg.update('configopts', '-DCPU_BASELINE=DETECT')
            elif optarch == OPTARCH_GENERIC:
                # optimize for generic x86 architecture (lowest supported by OpenCV is SSE3)
                self.cfg.update('configopts', '-DCPU_BASELINE=SSE3')
            else:
                raise EasyBuildError(
                    "Don't know how to configure OpenCV in accordance with --optarch='%s'",
                    optarch)

        if self.cfg['cpu_dispatch']:
            # using 'NONE' as value is equivalent with disabling the build of fat binaries (which is done by default)
            self.cfg.update('configopts',
                            '-DCPU_DISPATCH=%s' % self.cfg['cpu_dispatch'])

        # make sure that host CPU supports FP16 (unless -DCPU_BASELINE_DISABLE is already specified)
        # Intel Sandy Bridge does not support FP16!
        if 'CPU_BASELINE_DISABLE' not in self.cfg['configopts']:
            avail_cpu_features = get_cpu_features()
            if 'f16c' not in avail_cpu_features:
                self.cfg.update('configopts', '-DCPU_BASELINE_DISABLE=FP16')

        super(EB_OpenCV, self).configure_step()
예제 #25
0
    def configure_step(self):
        """Configure build by patching UFconfig.mk or SuiteSparse_config.mk."""

        if LooseVersion(self.version) < LooseVersion('4.0'):
            self.config_name = 'UFconfig'
        else:
            self.config_name = 'SuiteSparse_config'

        cfgvars = {
            'CC': os.getenv('MPICC'),
            'CFLAGS': os.getenv('CFLAGS'),
            'CXX': os.getenv('MPICXX'),
            'F77': os.getenv('MPIF77'),
            'F77FLAGS': os.getenv('F77FLAGS'),
        }

        # Set BLAS and LAPACK libraries as specified in SuiteSparse README.txt
        self.cfg.update('buildopts', 'BLAS="%s"' % os.getenv('LIBBLAS_MT'))
        self.cfg.update('buildopts', 'LAPACK="%s"' % os.getenv('LIBLAPACK_MT'))

        # Get METIS or ParMETIS settings
        metis = get_software_root('METIS')
        parmetis = get_software_root('ParMETIS')
        if parmetis:
            metis_path = parmetis
            metis_include = os.path.join(parmetis, 'include')
            metis_libs = os.path.join(parmetis, get_software_libdir('ParMETIS'), 'libmetis.a')

        elif metis:
            metis_path = metis
            metis_include = os.path.join(metis, 'include')
            metis_libs = os.path.join(metis, get_software_libdir('METIS'), 'libmetis.a')

        else:
            raise EasyBuildError("Neither METIS or ParMETIS module loaded.")

        if LooseVersion(self.version) >= LooseVersion('4.5.1'):
            cfgvars.update({
                'MY_METIS_LIB': metis_libs,
                'MY_METIS_INC': metis_include,
            })
        else:
            cfgvars.update({
                'METIS_PATH': metis_path,
                'METIS': metis_libs,
            })

        # patch file
        fp = os.path.join(self.cfg['start_dir'], self.config_name, '%s.mk' % self.config_name)

        try:
            for line in fileinput.input(fp, inplace=1, backup='.orig'):
                for (var, val) in cfgvars.items():
                    orig_line = line
                    # for variables in cfgvars, substiture lines assignment 
                    # in the file, whatever they are, by assignments to the
                    # values in cfgvars
                    line = re.sub(r"^\s*(%s\s*=\s*).*\n$" % var,
                                  r"\1 %s # patched by EasyBuild\n" % val,
                                  line)
                    if line != orig_line:
                        cfgvars.pop(var)
                sys.stdout.write(line)
        except IOError, err:
            raise EasyBuildError("Failed to patch %s in: %s", fp, err)
예제 #26
0
    def configure_step(self):
        """Custom configuration procedure for ALADIN."""

        # unset $LIBRARY_PATH set by modules of dependencies, because it may screw up linking
        if 'LIBRARY_PATH' in os.environ:
            self.log.debug("Unsetting $LIBRARY_PATH (was: %s)" %
                           os.environ['LIBRARY_PATH'])
            self.orig_library_path = os.environ.pop('LIBRARY_PATH')

        # build auxiliary libraries
        auxlibs_dir = None

        my_gnu = None
        if self.toolchain.comp_family() == toolchain.GCC:
            my_gnu = 'y'  # gfortran
            for var in ['CFLAGS', 'CXXFLAGS', 'F90FLAGS', 'FFLAGS']:
                flags = os.getenv(var)
                env.setvar(var,
                           "%s -fdefault-real-8 -fdefault-double-8" % flags)
                self.log.info("Updated %s to '%s'" % (var, os.getenv(var)))
        elif self.toolchain.comp_family() == toolchain.INTELCOMP:
            my_gnu = 'i'  # icc/ifort
        else:
            raise EasyBuildError(
                "Don't know how to set 'my_gnu' variable in auxlibs build script."
            )
        self.log.info("my_gnu set to '%s'" % my_gnu)

        tmp_installroot = tempfile.mkdtemp(prefix='aladin_auxlibs_')

        try:
            cwd = os.getcwd()

            os.chdir(self.builddir)
            builddirs = os.listdir(self.builddir)

            auxlibs_dir = [
                x for x in builddirs if x.startswith('auxlibs_installer')
            ][0]

            os.chdir(auxlibs_dir)

            auto_driver = 'driver_automatic'
            for line in fileinput.input(auto_driver,
                                        inplace=1,
                                        backup='.orig.eb'):

                line = re.sub(r"^(my_gnu\s*=\s*).*$", r"\1%s" % my_gnu, line)
                line = re.sub(r"^(my_r32\s*=\s*).*$", r"\1n",
                              line)  # always 64-bit real precision
                line = re.sub(r"^(my_readonly\s*=\s*).*$", r"\1y",
                              line)  # make libs read-only after build
                line = re.sub(r"^(my_installroot\s*=\s*).*$",
                              r"\1%s" % tmp_installroot, line)

                sys.stdout.write(line)

            run_cmd("./%s" % auto_driver)

            os.chdir(cwd)

        except OSError as err:
            raise EasyBuildError("Failed to build ALADIN: %s", err)

        # build gmkpack, update PATH and set GMKROOT
        # we build gmkpack here because a config file is generated in the gmkpack isntall path
        try:
            gmkpack_dir = [x for x in builddirs if x.startswith('gmkpack')][0]
            os.chdir(os.path.join(self.builddir, gmkpack_dir))

            qa = {
                'Do you want to run the configuration file maker assistant now (y) or later [n] ?':
                'n',
            }

            run_cmd_qa("./build_gmkpack", qa)

            os.chdir(cwd)

            paths = os.getenv('PATH').split(':')
            paths.append(os.path.join(self.builddir, gmkpack_dir, 'util'))
            env.setvar('PATH', ':'.join(paths))

            env.setvar('GMKROOT', os.path.join(self.builddir, gmkpack_dir))

        except OSError as err:
            raise EasyBuildError("Failed to build gmkpack: %s", err)

        # generate gmkpack configuration file
        self.conf_file = 'ALADIN_%s' % self.version
        self.conf_filepath = os.path.join(self.builddir, 'gmkpack_support',
                                          'arch', '%s.x' % self.conf_file)

        try:
            if os.path.exists(self.conf_filepath):
                os.remove(self.conf_filepath)
                self.log.info("Removed existing gmpack config file %s" %
                              self.conf_filepath)

            archdir = os.path.dirname(self.conf_filepath)
            if not os.path.exists(archdir):
                mkdir(archdir, parents=True)

        except OSError as err:
            raise EasyBuildError("Failed to remove existing file %s: %s",
                                 self.conf_filepath, err)

        mpich = 'n'
        known_mpi_libs = [
            toolchain.MPICH, toolchain.MPICH2, toolchain.INTELMPI
        ]
        if self.toolchain.options.get(
                'usempi',
                None) and self.toolchain.mpi_family() in known_mpi_libs:
            mpich = 'y'

        qpref = 'Please type the ABSOLUTE name of '
        qsuff = ', or ignore (environment variables allowed) :'
        qsuff2 = ', or ignore : (environment variables allowed) :'

        comp_fam = self.toolchain.comp_family()
        if comp_fam == toolchain.GCC:
            gribdir = 'GNU'
        elif comp_fam == toolchain.INTELCOMP:
            gribdir = 'INTEL'
        else:
            raise EasyBuildError(
                "Don't know which grib lib dir to use for compiler %s",
                comp_fam)

        aux_lib_gribex = os.path.join(tmp_installroot, gribdir, 'lib',
                                      'libgribex.a')
        aux_lib_ibm = os.path.join(tmp_installroot, gribdir, 'lib',
                                   'libibmdummy.a')
        grib_api_lib = os.path.join(get_software_root('grib_api'), 'lib',
                                    'libgrib_api.a')
        grib_api_f90_lib = os.path.join(get_software_root('grib_api'), 'lib',
                                        'libgrib_api_f90.a')
        grib_api_inc = os.path.join(get_software_root('grib_api'), 'include')
        jasperlib = os.path.join(get_software_root('JasPer'), 'lib',
                                 'libjasper.a')
        mpilib = os.path.join(os.getenv('MPI_LIB_DIR'),
                              os.getenv('MPI_LIB_SHARED'))

        # netCDF
        netcdf = get_software_root('netCDF')
        netcdf_fortran = get_software_root('netCDF-Fortran')
        if netcdf:
            netcdfinc = os.path.join(netcdf, 'include')
            if netcdf_fortran:
                netcdflib = os.path.join(netcdf_fortran,
                                         get_software_libdir('netCDF-Fortran'),
                                         'libnetcdff.a')
            else:
                netcdflib = os.path.join(netcdf, get_software_libdir('netCDF'),
                                         'libnetcdff.a')
            if not os.path.exists(netcdflib):
                raise EasyBuildError("%s does not exist", netcdflib)
        else:
            raise EasyBuildError("netCDF(-Fortran) not available")

        ldpaths = [ldflag[2:] for ldflag in os.getenv('LDFLAGS').split(' ')
                   ]  # LDFLAGS have form '-L/path/to'

        lapacklibs = []
        for lib in os.getenv('LAPACK_STATIC_LIBS').split(','):
            libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths]
            lapacklibs.append([
                libpath for libpath in libpaths if os.path.exists(libpath)
            ][0])
        lapacklib = ' '.join(lapacklibs)
        blaslibs = []
        for lib in os.getenv('BLAS_STATIC_LIBS').split(','):
            libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths]
            blaslibs.append([
                libpath for libpath in libpaths if os.path.exists(libpath)
            ][0])
        blaslib = ' '.join(blaslibs)

        qa = {
            'Do you want to run the configuration file maker assistant now (y) or later [n] ?':
            'y',
            'Do you want to setup your configuration file for MPICH (y/n) [n] ?':
            mpich,
            'Please type the directory name where to find a dummy file mpif.h or ignore :':
            os.getenv('MPI_INC_DIR'),
            '%sthe library gribex or emos%s' % (qpref, qsuff2):
            aux_lib_gribex,
            '%sthe library ibm%s' % (qpref, qsuff):
            aux_lib_ibm,
            '%sthe library grib_api%s' % (qpref, qsuff):
            grib_api_lib,
            '%sthe library grib_api_f90%s' % (qpref, qsuff):
            grib_api_f90_lib,
            '%sthe JPEG auxilary library if enabled by Grib_api%s' % (qpref, qsuff2):
            jasperlib,
            '%sthe library netcdf%s' % (qpref, qsuff):
            netcdflib,
            '%sthe library lapack%s' % (qpref, qsuff):
            lapacklib,
            '%sthe library blas%s' % (qpref, qsuff):
            blaslib,
            '%sthe library mpi%s' % (qpref, qsuff):
            mpilib,
            '%sa MPI dummy library for serial executions, or ignore :' % qpref:
            '',
            'Please type the directory name where to find grib_api headers, or ignore :':
            grib_api_inc,
            'Please type the directory name where to find fortint.h or ignore :':
            '',
            'Please type the directory name where to find netcdf headers, or ignore :':
            netcdfinc,
            'Do you want to define CANARI (y/n) [y] ?':
            'y',
            'Please type the name of the script file used to generate a preprocessed blacklist file, or ignore :':
            '',
            'Please type the name of the script file used to recover local libraries (gget), or ignore :':
            '',
            'Please type the options to tune the gnu compilers, or ignore :':
            os.getenv('F90FLAGS'),
        }

        f90_seq = os.getenv('F90_SEQ')
        if not f90_seq:
            # F90_SEQ is only defined when usempi is enabled
            f90_seq = os.getenv('F90')

        stdqa = OrderedDict([
            (r'Confirm library .* is .*',
             'y'),  # this one needs to be tried first!
            (r'.*fortran 90 compiler name .*\s*:\n\(suggestions\s*: .*\)',
             f90_seq),
            (r'.*fortran 90 compiler interfaced with .*\s*:\n\(suggestions\s*: .*\)',
             f90_seq),
            (r'Please type the ABSOLUTE name of .*library.*, or ignore\s*[:]*\s*[\n]*.*',
             ''),
            (r'Please .* to save this draft configuration file :\n.*',
             '%s.x' % self.conf_file),
        ])

        no_qa = [
            ".*ignored.",
        ]

        env.setvar('GMKTMP', self.builddir)
        env.setvar('GMKFILE', self.conf_file)

        run_cmd_qa("gmkfilemaker", qa, std_qa=stdqa, no_qa=no_qa)

        # set environment variables for installation dirs
        env.setvar('ROOTPACK', os.path.join(self.installdir, 'rootpack'))
        env.setvar('ROOTBIN', os.path.join(self.installdir, 'rootpack'))
        env.setvar('HOMEPACK', os.path.join(self.installdir, 'pack'))
        env.setvar('HOMEBIN', os.path.join(self.installdir, 'pack'))

        # patch config file to include right Fortran compiler flags
        regex_subs = [(r"^(FRTFLAGS\s*=.*)$", r"\1 %s" % os.getenv('FFLAGS'))]
        apply_regex_substitutions(self.conf_filepath, regex_subs)
    def configure_step(self):
        """Custom configuration procedure for OpenCV."""

        if 'CMAKE_BUILD_TYPE' not in self.cfg['configopts']:
            self.cfg.update('configopts', '-DCMAKE_BUILD_TYPE=Release')

        # enable Python support if unspecified and Python is a dependency
        if 'BUILD_PYTHON_SUPPORT' not in self.cfg['configopts']:
            if get_software_root('Python'):
                self.cfg.update('configopts', "-DBUILD_PYTHON_SUPPORT=ON -DBUILD_NEW_PYTHON_SUPPORT=ON")
                py_pkgs_path = os.path.join(self.installdir, self.pylibdir)
                self.cfg.update('configopts', '-DPYTHON_PACKAGES_PATH=%s' % py_pkgs_path)
            else:
                self.cfg.update('configopts', "-DBUILD_PYTHON_SUPPORT=OFF -DBUILD_NEW_PYTHON_SUPPORT=OFF")

        # enable CUDA support if CUDA is a dependency
        if 'WITH_CUDA' not in self.cfg['configopts']:
            if get_software_root('CUDA'):
                self.cfg.update('configopts', '-DWITH_CUDA=ON')
            else:
                self.cfg.update('configopts', '-DWITH_CUDA=OFF')

        # configure for dependency libraries
        for dep in ['JasPer', 'libjpeg-turbo', 'libpng', 'LibTIFF', 'zlib']:
            if dep in ['libpng', 'LibTIFF']:
                # strip off 'lib'
                opt_name = dep[3:].upper()
            elif dep == 'libjpeg-turbo':
                opt_name = 'JPEG'
            else:
                opt_name = dep.upper()

            shlib_ext = get_shared_lib_ext()
            if dep == 'zlib':
                lib_file = 'libz.%s' % shlib_ext
            else:
                lib_file = 'lib%s.%s' % (opt_name.lower(), shlib_ext)

            dep_root = get_software_root(dep)
            if dep_root:
                self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s' % (opt_name, os.path.join(dep_root, 'include')))
                libdir = get_software_libdir(dep, only_one=True)
                self.cfg.update('configopts', '-D%s_LIBRARY=%s' % (opt_name, os.path.join(dep_root, libdir, lib_file)))

        # configure optimisation for CPU architecture
        # see https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options
        if self.toolchain.options.get('optarch') and 'CPU_BASELINE' not in self.cfg['configopts']:
            optarch = build_option('optarch')
            if optarch is None:
                # optimize for host arch (let OpenCV detect it)
                self.cfg.update('configopts', '-DCPU_BASELINE=DETECT')
            elif optarch == OPTARCH_GENERIC:
                # optimize for generic x86 architecture (lowest supported by OpenCV is SSE3)
                self.cfg.update('configopts', '-DCPU_BASELINE=SSE3')
            else:
                raise EasyBuildError("Don't know how to configure OpenCV in accordance with --optarch='%s'", optarch)

        if self.cfg['cpu_dispatch']:
            # using 'NONE' as value is equivalent with disabling the build of fat binaries (which is done by default)
            self.cfg.update('configopts', '-DCPU_DISPATCH=%s' % self.cfg['cpu_dispatch'])

        # make sure that host CPU supports FP16 (unless -DCPU_BASELINE_DISABLE is already specified)
        # Intel Sandy Bridge does not support FP16!
        if 'CPU_BASELINE_DISABLE' not in self.cfg['configopts']:
            avail_cpu_features = get_cpu_features()
            if 'f16c' not in avail_cpu_features:
                self.cfg.update('configopts', '-DCPU_BASELINE_DISABLE=FP16')

        super(EB_OpenCV, self).configure_step()
예제 #28
0
    def configure_step(self):
        """Custom configuration procedure for binutils: statically link to zlib, configure options."""

        libs = ''

        if self.toolchain.name == DUMMY_TOOLCHAIN_NAME:
            # determine list of 'lib' directories to use rpath for;
            # this should 'harden' the resulting binutils to bootstrap GCC
            # (no trouble when other libstdc++ is build etc)
            libdirs = []
            for libdir in ['/usr/lib', '/usr/lib64', '/usr/lib/x86_64-linux-gnu/']:
                # also consider /lib, /lib64
                alt_libdir = libdir.replace('usr/', '')

                if os.path.exists(libdir):
                    libdirs.append(libdir)
                    if os.path.exists(alt_libdir) and not os.path.samefile(libdir, alt_libdir):
                        libdirs.append(alt_libdir)

                elif os.path.exists(alt_libdir):
                    libdirs.append(alt_libdir)

            libs += ' '.join('-Wl,-rpath=%s' % libdir for libdir in libdirs)

        # statically link to zlib if it is a (build) dependency
        zlibroot = get_software_root('zlib')
        if zlibroot:
            self.cfg.update('configopts', '--with-system-zlib')
            libz_path = os.path.join(zlibroot, get_software_libdir('zlib'), 'libz.a')

            # for recent binutils versions, we need to override ZLIB in Makefile.in of components
            if LooseVersion(self.version) >= LooseVersion('2.26'):
                regex_subs = [
                    (r"^(ZLIB\s*=\s*).*$", r"\1%s" % libz_path),
                    (r"^(ZLIBINC\s*=\s*).*$", r"\1-I%s" % os.path.join(zlibroot, 'include')),
                ]
                for makefile in glob.glob(os.path.join(self.cfg['start_dir'], '*', 'Makefile.in')):
                    apply_regex_substitutions(makefile, regex_subs)

            # for older versions, injecting the path to the static libz library into $LIBS works
            else:
                libs += ' ' + libz_path

        self.cfg.update('preconfigopts', "env LIBS='%s'" % libs)
        self.cfg.update('prebuildopts', "env LIBS='%s'" % libs)

        # use correct sysroot, to make sure 'ld' also considers system libraries
        self.cfg.update('configopts', '--with-sysroot=/')

        # build both static and shared libraries for recent binutils versions (default is only static)
        if LooseVersion(self.version) > LooseVersion('2.24'):
            self.cfg.update('configopts', "--enable-shared --enable-static")

        # enable gold linker with plugin support, use ld as default linker (for recent versions of binutils)
        if LooseVersion(self.version) > LooseVersion('2.24'):
            self.cfg.update('configopts', "--enable-gold --enable-plugins --enable-ld=default")

        # complete configuration with configure_method of parent
        super(EB_binutils, self).configure_step()

        if self.cfg['install_libiberty']:
            cflags = os.getenv('CFLAGS')
            if cflags:
                self.cfg.update('buildopts', 'CFLAGS="$CFLAGS -fPIC"')
            else:
                # if $CFLAGS is not defined, make sure we retain "-g -O2",
                # since not specifying any optimization level implies -O0...
                self.cfg.update('buildopts', 'CFLAGS="-g -O2 -fPIC"')