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()
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()
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)
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)
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()
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)
def configure_step(self): """Configure build: set config options and configure""" shlib_ext = get_shared_lib_ext() if LooseVersion(self.version) < LooseVersion("4.3"): self.cfg.update('configopts', "--enable-shared") if self.toolchain.options['pic']: self.cfg.update('configopts', '--with-pic') tup = (os.getenv('FFLAGS'), os.getenv('MPICC'), os.getenv('F90')) self.cfg.update('configopts', 'FCFLAGS="%s" CC="%s" FC="%s"' % tup) # add -DgFortran to CPPFLAGS when building with GCC if self.toolchain.comp_family() == toolchain.GCC: #@UndefinedVariable self.cfg.update('configopts', 'CPPFLAGS="%s -DgFortran"' % os.getenv('CPPFLAGS')) ConfigureMake.configure_step(self) else: self.cfg.update('configopts', '-DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG " ') for (dep, libname) in [('cURL', 'curl'), ('HDF5', 'hdf5'), ('Szip', 'sz'), ('zlib', 'z')]: dep_root = get_software_root(dep) dep_libdir = get_software_libdir(dep) if dep_root: incdir = os.path.join(dep_root, 'include') self.cfg.update('configopts', '-D%s_INCLUDE_DIR=%s ' % (dep.upper(), incdir)) if dep == 'HDF5': env.setvar('HDF5_ROOT', dep_root) libhdf5 = os.path.join(dep_root, dep_libdir, 'libhdf5.%s' % shlib_ext) self.cfg.update('configopts', '-DHDF5_LIB=%s ' % libhdf5) libhdf5_hl = os.path.join(dep_root, dep_libdir, 'libhdf5_hl.%s' % shlib_ext) self.cfg.update('configopts', '-DHDF5_HL_LIB=%s ' % libhdf5_hl) else: libso = os.path.join(dep_root, dep_libdir, 'lib%s.%s' % (libname, shlib_ext)) self.cfg.update('configopts', '-D%s_LIBRARY=%s ' % (dep.upper(), libso)) CMakeMake.configure_step(self)
def 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)
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): """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)
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)
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)
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()
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)
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')
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)
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()
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 = []
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, *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)
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()
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()
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"')