def configure_step(self): """Set configure options.""" if self.toolchain.mpi_family() == toolchain.INTELMPI: mpi_bindir = os.path.join(get_software_root('impi'), 'intel64', 'bin') else: mpi_bindir = os.path.join(get_software_root(self.toolchain.MPI_MODULE_NAME[0]), 'bin') root_java = get_software_root("Java") if not get_software_root("Java"): raise EasyBuildError("Module for dependency Java not loaded.") configure_args = ' '.join([ 'profile=no fast=yes warn=no release=yes gtest=yes static=no cuda=no debug=no matlab=no', 'LINKERFORPROGRAMS=%s' % os.getenv('CXX'), 'MPI_BINDIR=%s' % mpi_bindir, 'MPI_LIB=mpi', 'JAVA_HOME=%s' % os.getenv('JAVA_HOME'), 'JAVAC=javac', 'CC=%s' % os.getenv('CC'), # pass $CXXFLAGS in Python list syntax and avoid spaces, e.g.: ['-O2','-march=native'] 'CXXFLAGS=%s' % str(os.getenv('CXXFLAGS').split(' ')).replace(' ', ''), 'CXX=%s' % os.getenv('CXX'), 'MPI_CC=%s' % os.getenv('MPICC'), # pass $CFLAGS in Python list syntax and avoid spaces, e.g.: ['-O2','-march=native'] 'CCFLAGS=%s' % str(os.getenv('CFLAGS').split(' ')).replace(' ', ''), 'MPI_CXX=%s' % os.getenv('MPICXX'), 'MPI_INCLUDE=%s' % os.getenv('MPI_INC_DIR'), 'MPI_LIBDIR=%s' % os.getenv('MPI_LIB_DIR'), 'MPI_LINKERFORPROGRAMS=%s' % os.getenv('MPICXX'), 'LIBPATH=%s' % os.getenv('LD_LIBRARY_PATH'), ]) # define list of configure options, which will be passed to Xmipp's install.sh script via --configure-args self.cfg['configopts'] = configure_args self.log.info("Configure arguments for Xmipp install.sh script: %s", self.cfg['configopts'])
def configure_step(self): """Configure build by patching UFconfig.mk.""" metis = get_software_root('METIS') parmetis = get_software_root('ParMETIS') if not metis and not parmetis: self.log.error("Neither METIS or ParMETIS module loaded.") fp = os.path.join("UFconfig","UFconfig.mk") cfgvars = { 'CC': os.getenv('MPICC'), 'CFLAGS': os.getenv('CFLAGS'), 'CXX': os.getenv('MPICXX'), 'F77': os.getenv('MPIF77'), 'F77FLAGS': os.getenv('F77FLAGS'), 'BLAS': os.getenv('LIBBLAS_MT'), 'LAPACK': os.getenv('LIBLAPACK_MT'), } if parmetis: cfgvars.update({ 'METIS_PATH': parmetis, 'METIS': "%(p)s/lib/libparmetis.a %(p)s/lib/metis.a" % {'p':parmetis} }) # patch file try: for line in fileinput.input(fp, inplace=1, backup='.orig'): for (k, v) in cfgvars.items(): line = re.sub(r"^(%s\s*=\s*).*$" % k, r"\1 %s # patched by EasyBuild" % v, line) if k in line: cfgvars.pop(k) sys.stdout.write(line) except IOError, err: self.log.error("Failed to patch %s in: %s" % (fp, err))
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): """Custom configuration procedure for Octave.""" if self.cfg['blas_lapack_mt']: libblas, liblapack = os.getenv('LIBBLAS_MT'), os.getenv('LIBLAPACK_MT') else: libblas, liblapack = os.getenv('LIBBLAS'), os.getenv('LIBLAPACK') if libblas and liblapack: self.cfg.update('configopts', '--with-blas="%s" --with-lapack="%s"' % (libblas, liblapack)) else: raise EasyBuildError("$LIBBLAS and/or $LIBLAPACK undefined, use toolchain that includes BLAS/LAPACK") qt_root = get_software_root('Qt5') or get_software_root('Qt') if qt_root: self.log.info("Found Qt included as dependency, updating configure options accordingly...") qt_vars = { 'LRELEASE': os.path.join(qt_root, 'bin', 'lrelease'), 'MOC': os.path.join(qt_root, 'bin', 'moc'), 'RCC': os.path.join(qt_root, 'bin', 'rcc'), 'UIC': os.path.join(qt_root, 'bin', 'uic'), } for key, val in sorted(qt_vars.items()): self.cfg.update('configopts', "%s=%s" % (key, val)) else: self.log.debug("No Qt included as dependency") super(EB_Octave, self).configure_step()
def configure(self): """ Configure LAPACK for build: copy make.inc and set make options """ # copy make.inc file from examples if get_software_root('gcc'): makeinc = 'gfortran' elif get_software_root('ifort'): makeinc = 'ifort' else: self.log.error("Don't know which make.inc file to pick, unknown compiler being used...") src = os.path.join(self.getcfg('startfrom'), 'INSTALL', 'make.inc.%s' % makeinc) dest = os.path.join(self.getcfg('startfrom'), 'make.inc') if not os.path.isfile(src): self.log.error("Can't find source file %s" % src) if os.path.exists(dest): self.log.error("Destination file %s exists" % dest) try: shutil.copy(src, dest) except OSError, err: self.log.error("Copying %s to %s failed: %s" % (src, dest, err))
def configure_step(self): """Configure build: <single-line description how this deviates from standard configure>""" # set generic make options self.cfg.update('buildopts', 'CC="%s" OPTFLAGS="%s"' % (os.getenv('MPICC'), os.getenv('CFLAGS'))) if LooseVersion(self.version) >= LooseVersion("3.2"): # set correct start_dir dir, and change into it # test whether it already contains 'src', since a reprod easyconfig would if os.path.basename(self.cfg['start_dir']) != 'src': self.cfg['start_dir'] = os.path.join(self.cfg['start_dir'], 'src') try: os.chdir(self.cfg['start_dir']) except OSError, err: raise EasyBuildError("Failed to change to correct source dir %s: %s", self.cfg['start_dir'], err) # run autoconf to generate configure script cmd = "autoconf" run_cmd(cmd) # set config opts beagle = get_software_root('beagle-lib') if beagle: self.cfg.update('configopts', '--with-beagle=%s' % beagle) else: if get_software_root('BEAGLE'): self.log.nosupport('BEAGLE module as dependency, should be beagle-lib', '2.0') raise EasyBuildError("beagle-lib module not loaded?") if self.toolchain.options.get('usempi', None): self.cfg.update('configopts', '--enable-mpi') # configure super(EB_MrBayes, self).configure_step()
def configure_step(self): """Custom configuration procedure for NEURON.""" # enable support for distributed simulations if desired if self.cfg['paranrn']: self.cfg.update('configopts', '--with-paranrn') # specify path to InterViews if it is available as a dependency interviews_root = get_software_root('InterViews') if interviews_root: self.cfg.update('configopts', "--with-iv=%s" % interviews_root) else: self.cfg.update('configopts', "--without-iv") # optionally enable support for Python as alternative interpreter python_root = get_software_root('Python') if python_root: self.with_python = True self.cfg.update('configopts', "--with-nrnpython=%s/bin/python" % python_root) # determine host CPU type cmd = "./config.guess" (out, ec) = run_cmd(cmd, simple=False) self.hostcpu = out.split('\n')[0].split('-')[0] self.log.debug("Determined host CPU type as %s" % self.hostcpu) # determine Python lib dir self.pylibdir = det_pylibdir() # complete configuration with configure_method of parent super(EB_NEURON, self).configure_step()
def configure_step(self): """Configure Extrae build, set configure options for compiler, MPI and dependencies.""" # MPI self.cfg.update('configopts', "--with-mpi=%s" % get_software_root(self.toolchain.MPI_MODULE_NAME[0])) # Optional dependences deps = { 'binutils': ('', '--with-binutils=%s', ''), 'Boost': ('', '--with-boost=%s', ''), 'libdwarf': ('', '--with-dwarf=%s', '--without-dwarf'), 'libunwind': ('', '--with-unwind=%s', ''), 'libxml2': (' --enable-xml --enable-merge-in-trace', '', ''), 'PAPI': ('--enable-sampling', '--with-papi=%s', '--without-papi'), } for (dep_name, (with_opts, with_root_opt, without_opt)) in deps.items(): dep_root = get_software_root(dep_name) if dep_root: if with_opts: self.cfg.update('configopts', with_opts) if with_root_opt: self.cfg.update('configopts', with_root_opt % dep_root) else: if without_opt: self.cfg.update('configopts', without_opt) # TODO: make this optional dependencies self.cfg.update('configopts', "--without-dyninst") super(EB_Extrae, self).configure_step()
def configure_step(self): """Custom configuration procedure for ESMF through environment variables.""" env.setvar('ESMF_DIR', self.cfg['start_dir']) env.setvar('ESMF_INSTALL_PREFIX', self.installdir) env.setvar('ESMF_INSTALL_BINDIR', 'bin') env.setvar('ESMF_INSTALL_LIBDIR', 'lib') env.setvar('ESMF_INSTALL_MODDIR', 'mod') # specify compiler comp_family = self.toolchain.comp_family() if comp_family in [toolchain.GCC]: compiler = 'gfortran' else: compiler = comp_family.lower() env.setvar('ESMF_COMPILER', compiler) # specify MPI communications library comm = None mpi_family = self.toolchain.mpi_family() if mpi_family in [toolchain.MPICH, toolchain.QLOGICMPI]: # MPICH family for MPICH v3.x, which is MPICH2 compatible comm = 'mpich2' else: comm = mpi_family.lower() env.setvar('ESMF_COMM', comm) # specify decent LAPACK lib env.setvar('ESMF_LAPACK', 'user') env.setvar('ESMF_LAPACK_LIBS', '%s %s' % (os.getenv('LDFLAGS'), os.getenv('LIBLAPACK_MT'))) # specify netCDF netcdf = get_software_root('netCDF') if netcdf: env.setvar('ESMF_NETCDF', 'user') netcdf_libs = ['-L%s/lib' % netcdf, '-lnetcdf'] # Fortran netcdff = get_software_root('netCDF-Fortran') if netcdff: netcdf_libs = ["-L%s/lib" % netcdff] + netcdf_libs + ["-lnetcdff"] else: netcdf_libs.append('-lnetcdff') # C++ netcdfcxx = get_software_root('netCDF-C++') if netcdfcxx: netcdf_libs = ["-L%s/lib" % netcdfcxx] + netcdf_libs + ["-lnetcdf_c++"] else: netcdfcxx = get_software_root('netCDF-C++4') if netcdfcxx: netcdf_libs = ["-L%s/lib" % netcdfcxx] + netcdf_libs + ["-lnetcdf_c++4"] else: netcdf_libs.append('-lnetcdf_c++') env.setvar('ESMF_NETCDF_LIBS', ' '.join(netcdf_libs)) # 'make info' provides useful debug info cmd = "make info" run_cmd(cmd, log_all=True, simple=True, log_ok=True)
def configure_step(self): # Use separate build directory self.cfg['separate_build_dir'] = True self.cfg['configopts'] += "-DENABLE_TESTS=ON " # Needs wxWidgets self.cfg['configopts'] += "-DBUILD_GUI=OFF " root_python = get_software_root('Python') if root_python: self.log.info("Enabling Python bindings") shortpyver = '.'.join(get_software_version('Python').split('.')[:2]) self.cfg['configopts'] += "-DPYTHON_BINDINGS=ON " self.cfg['configopts'] += "-DPYTHON_LIBRARY=%s/lib/libpython%s.so " % (root_python, shortpyver) self.cfg['configopts'] += "-DPYTHON_INCLUDE_DIR=%s/include/python%s " % (root_python, shortpyver) else: self.log.info("Not enabling Python bindings") root_eigen = get_software_root("Eigen") if root_eigen: self.log.info("Using Eigen") self.cfg['configopts'] += "-DEIGEN3_INCLUDE_DIR='%s/include' " % root_eigen else: self.log.info("Not using Eigen") super(EB_OpenBabel, self).configure_step()
def install_step(self): """Custom install procedure for RepeatMasker.""" super(EB_RepeatMasker, self).install_step() # check for required dependencies perl_root = get_software_root('Perl') if perl_root: perl = os.path.join(perl_root, 'bin', 'perl') else: raise EasyBuildError("Missing required dependency: Perl") trf_root = get_software_root('TRF') if trf_root: trf = os.path.join(trf_root, 'trf') else: raise EasyBuildError("Missing required dependency: TRF") # determine which search engine to use # see also http://www.repeatmasker.org/RMDownload.html cand_search_engines = ['CrossMatch', 'RMBlast', 'WUBlast', 'HMMER'] search_engine = None for dep in cand_search_engines: if get_software_root(dep): if search_engine is None: search_engine = dep else: raise EasyBuildError("Found multiple candidate search engines: %s and %s", search_engine, dep) if search_engine is None: raise EasyBuildError("No search engine found, one of these must be included as dependency: %s", ' '.join(cand_search_engines)) change_dir(self.installdir) patch_perl_script_autoflush('configure') search_engine_map = { 'CrossMatch': '1', 'RMBlast': '2', 'WUBlast': '3', 'HMMER': '4', } search_engine_bindir = os.path.join(get_software_root(search_engine), 'bin') cmd = "perl ./configure" qa = { '<PRESS ENTER TO CONTINUE>': '', # select search engine 'Enter Selection:': search_engine_map[search_engine], } std_qa = { r'\*\*PERL PROGRAM\*\*\n([^*]*\n)+Enter path.*': perl, r'\*\*REPEATMASKER INSTALLATION DIRECTORY\*\*\n([^*]*\n)+Enter path.*': self.installdir, r'\*\*TRF PROGRAM\*\*\n([^*]*\n)+Enter path.*': trf, # search engine installation path (location of /bin subdirectory) # also enter 'Y' to confirm + '5' ("Done") to complete selection process for search engine r'\*\*.* INSTALLATION PATH\*\*\n([^*]*\n)+Enter path.*': search_engine_bindir + '\nY\n5', } run_cmd_qa(cmd, qa, std_qa=std_qa, log_all=True, simple=True, log_ok=True)
def configure_step(self): """Configure OpenFOAM build by setting appropriate environment variables.""" # installation directory env.setvar("FOAM_INST_DIR", self.installdir) # third party directory self.thrdpartydir = "ThirdParty-%s" % self.version # only if third party stuff is actually installed if os.path.exists(self.thrdpartydir): os.symlink(os.path.join("..", self.thrdpartydir), self.thrdpartydir) env.setvar("WM_THIRD_PARTY_DIR", os.path.join(self.installdir, self.thrdpartydir)) # compiler comp_fam = self.toolchain.comp_family() if comp_fam == toolchain.GCC: #@UndefinedVariable self.wm_compiler="Gcc" elif comp_fam == toolchain.INTELCOMP: #@UndefinedVariable self.wm_compiler="Icc" # make sure -no-prec-div is used with Intel compilers self.cfg.update('premakeopts', 'CFLAGS="$CFLAGS -no-prec-div" CXXFLAGS="$CXXFLAGS -no-prec-div"') else: self.log.error("Unknown compiler family, don't know how to set WM_COMPILER") env.setvar("WM_COMPILER",self.wm_compiler) # type of MPI mpi_type = self.toolchain.mpi_family() if mpi_type == toolchain.INTELMPI: #@UndefinedVariable self.mpipath = os.path.join(get_software_root('IMPI'),'intel64') self.wm_mplib = "IMPI" elif mpi_type == toolchain.QLOGICMPI: #@UndefinedVariable self.mpipath = get_software_root('QLogicMPI') self.wm_mplib = "MPICH" elif mpi_type == toolchain.OPENMPI: #@UndefinedVariable self.mpipath = get_software_root('OpenMPI') self.wm_mplib = "MPI-MVAPICH2" else: self.mpipath = "/usr/local/packages/MPICH/3.0.3/intelcomp-14.0.2/bin" self.wm_mplib = "MPICH" print self.mpipath print self.wm_mplib #self.log.error("Unknown MPI, don't know how to set MPI_ARCH_PATH, WM_MPLIB or FOAM_MPI_LIBBIN") env.setvar("WM_MPLIB", self.wm_mplib) env.setvar("MPI_ARCH_PATH", self.mpipath) env.setvar("FOAM_MPI_LIBBIN", self.mpipath) # parallel build spec env.setvar("WM_NCOMPPROCS", str(self.cfg['parallel']))
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 _set_fftw_variables(self): if not hasattr(self, "BLAS_LIB_DIR"): raise EasyBuildError("_set_fftw_variables: IntelFFT based on IntelMKL (no BLAS_LIB_DIR found)") imklver = get_software_version(self.FFT_MODULE_NAME[0]) picsuff = "" if self.options.get("pic", None): picsuff = "_pic" bitsuff = "_lp64" if self.options.get("i8", None): bitsuff = "_ilp64" compsuff = "_intel" if get_software_root("icc") is None: if get_software_root("PGI"): compsuff = "_pgi" elif get_software_root("GCC"): compsuff = "_gnu" else: raise EasyBuildError( "Not using Intel compilers, PGI nor GCC, don't know compiler suffix for FFTW libraries." ) fftw_libs = ["fftw3xc%s%s" % (compsuff, picsuff)] if self.options["usempi"]: # add cluster interface for recent imkl versions if LooseVersion(imklver) >= LooseVersion("11.0.2"): fftw_libs.append("fftw3x_cdft%s%s" % (bitsuff, picsuff)) elif LooseVersion(imklver) >= LooseVersion("10.3"): fftw_libs.append("fftw3x_cdft%s" % picsuff) fftw_libs.append("mkl_cdft_core") # add cluster dft fftw_libs.extend(self.variables["LIBBLACS"].flatten()) # add BLACS; use flatten because ListOfList self.log.debug("fftw_libs %s" % fftw_libs.__repr__()) fftw_libs.extend(self.variables["LIBBLAS"].flatten()) # add BLAS libs (contains dft) self.log.debug("fftw_libs %s" % fftw_libs.__repr__()) self.FFT_LIB_DIR = self.BLAS_LIB_DIR self.FFT_INCLUDE_DIR = self.BLAS_INCLUDE_DIR # building the FFTW interfaces is optional, # so make sure libraries are there before FFT_LIB is set imklroot = get_software_root(self.FFT_MODULE_NAME[0]) fft_lib_dirs = [os.path.join(imklroot, d) for d in self.FFT_LIB_DIR] # filter out libraries from list of FFTW libraries to check for if they are not provided by Intel MKL check_fftw_libs = [lib for lib in fftw_libs if lib not in ["dl", "gfortran"]] fftw_lib_exists = lambda x: any([os.path.exists(os.path.join(d, "lib%s.a" % x)) for d in fft_lib_dirs]) if all([fftw_lib_exists(lib) for lib in check_fftw_libs]): self.FFT_LIB = fftw_libs else: msg = "Not all FFTW interface libraries %s are found in %s" % (check_fftw_libs, fft_lib_dirs) msg += ", can't set $FFT_LIB." if self.dry_run: dry_run_warning(msg, silent=build_option("silent")) else: raise EasyBuildError(msg)
def configure_step(self): """Configure numpy build by composing site.cfg contents.""" self.sitecfg = '\n'.join([ "[DEFAULT]", "library_dirs = %(libs)s", "include_dirs= %(includes)s", "search_static_first=True", ]) if get_software_root("IMKL"): extrasiteconfig = '\n'.join([ "[mkl]", "lapack_libs = %(lapack)s", "mkl_libs = %(blas)s", ]) elif get_software_root("ATLAS") and get_software_root("LAPACK"): extrasiteconfig = '\n'.join(["[blas_opt]", "libraries = %(blas)s", "[lapack_opt]", "libraries = %(lapack)s", ]) else: self.log.error("Could not detect BLAS/LAPACK library.") libfft = os.getenv('LIBFFT') if libfft: extrasiteconfig += "\n[fftw]\nlibraries = %s" % libfft.replace(' ', ',') self.sitecfg = '\n'.join([self.sitecfg, extrasiteconfig]) lapack_libs = os.getenv("LIBLAPACK_MT").split(" -l") blas_libs = os.getenv("LIBBLAS_MT").split(" -l") if get_software_root("IMKL"): # with IMKL, get rid of all spaces and use '-Wl:' lapack_libs.remove("pthread") lapack = ','.join(lapack_libs).replace(' ', ',').replace('Wl,', 'Wl:') blas = lapack else: lapack = ", ".join(lapack_libs) blas = ", ".join(blas_libs) self.sitecfg = self.sitecfg % { 'lapack': lapack, 'blas': blas, 'libs': ':'.join(self.toolchain.get_variable('LDFLAGS', typ=list)), 'includes': ':'.join(self.toolchain.get_variable('CPPFLAGS', typ=list)) } super(EB_numpy, self).configure_step()
def configure_step(self): """Custom configure step for NAMD, we build charm++ first (if required).""" # complete Charm ++ and NAMD architecture string with compiler family comp_fam = self.toolchain.comp_family() if self.toolchain.options["usempi"]: charm_arch_comp = "mpicxx" else: charm_arch_comps = {toolchain.GCC: "gcc", toolchain.INTELCOMP: "icc"} charm_arch_comp = charm_arch_comps.get(comp_fam, None) namd_comps = {toolchain.GCC: "g++", toolchain.INTELCOMP: "icc"} namd_comp = namd_comps.get(comp_fam, None) if charm_arch_comp is None or namd_comp is None: raise EasyBuildError("Unknown compiler family, can't complete Charm++/NAMD target architecture.") self.cfg.update("charm_arch", charm_arch_comp) self.log.info("Updated 'charm_arch': %s" % self.cfg["charm_arch"]) self.namd_arch = "%s-%s" % (self.cfg["namd_basearch"], namd_comp) self.log.info("Completed NAMD target architecture: %s" % self.namd_arch) charm_tarballs = glob.glob("charm-*.tar") if len(charm_tarballs) != 1: raise EasyBuildError("Expected to find exactly one tarball for Charm++, found: %s", charm_tarballs) extract_file(charm_tarballs[0], os.getcwd()) tup = (self.cfg["charm_arch"], self.cfg["charm_opts"], self.cfg["parallel"], os.environ["CXXFLAGS"]) cmd = "./build charm++ %s %s -j%s %s -DMPICH_IGNORE_CXX_SEEK" % tup charm_subdir = ".".join(os.path.basename(charm_tarballs[0]).split(".")[:-1]) self.log.debug("Building Charm++ using cmd '%s' in '%s'" % (cmd, charm_subdir)) run_cmd(cmd, path=charm_subdir) # compiler (options) self.cfg.update("namd_cfg_opts", '--cc "%s" --cc-opts "%s"' % (os.environ["CC"], os.environ["CFLAGS"])) self.cfg.update("namd_cfg_opts", '--cxx "%s" --cxx-opts "%s"' % (os.environ["CXX"], os.environ["CXXFLAGS"])) # NAMD dependencies: CUDA, FFTW cuda = get_software_root("CUDA") if cuda: self.cfg.update("namd_cfg_opts", "--with-cuda --cuda-prefix %s" % cuda) fftw = get_software_root("FFTW") if fftw: if LooseVersion(get_software_version("FFTW")) >= LooseVersion("3.0"): if LooseVersion(self.version) >= LooseVersion("2.9"): self.cfg.update("namd_cfg_opts", "--with-fftw3") else: raise EasyBuildError("Using FFTW v3.x only supported in NAMD v2.9 and up.") else: self.cfg.update("namd_cfg_opts", "--with-fftw") self.cfg.update("namd_cfg_opts", "--fftw-prefix %s" % fftw) namd_charm_arch = "--charm-arch %s" % "-".join(self.cfg["charm_arch"].strip().split(" ")) cmd = "./config %s %s %s " % (self.namd_arch, namd_charm_arch, self.cfg["namd_cfg_opts"]) run_cmd(cmd)
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'), 'BLAS': os.getenv('LIBBLAS_MT'), 'LAPACK': os.getenv('LIBLAPACK_MT'), } metis = get_software_root('METIS') parmetis = get_software_root('ParMETIS') if parmetis: metis_path = parmetis metis_libs = ' '.join([ os.path.join(parmetis, 'lib', 'libparmetis.a'), os.path.join(parmetis, 'lib', 'metis.a'), ]) elif metis: metis_path = metis metis_libs = os.path.join(metis, 'lib', 'metis.a') else: raise EasyBuildError("Neither METIS or ParMETIS module loaded.") 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*).*$" % var, r"\1 %s # patched by EasyBuild" % 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): """Custom configuration procedure for Bazel.""" binutils_root = get_software_root('binutils') gcc_root = get_software_root('GCCcore') or get_software_root('GCC') gcc_ver = get_software_version('GCCcore') or get_software_version('GCC') # only patch Bazel scripts if binutils & GCC installation prefix could be determined if binutils_root and gcc_root: res = glob.glob(os.path.join(gcc_root, 'lib', 'gcc', '*', gcc_ver, 'include')) if res and len(res) == 1: gcc_lib_inc = res[0] else: raise EasyBuildError("Failed to pinpoint location of GCC include files: %s", res) gcc_lib_inc_fixed = os.path.join(os.path.dirname(gcc_lib_inc), 'include-fixed') if not os.path.exists(gcc_lib_inc_fixed): raise EasyBuildError("Derived directory %s does not exist", gcc_lib_inc_fixed) gcc_cplusplus_inc = os.path.join(gcc_root, 'include', 'c++', gcc_ver) if not os.path.exists(gcc_cplusplus_inc): raise EasyBuildError("Derived directory %s does not exist", gcc_cplusplus_inc) # replace hardcoded paths in CROSSTOOL regex_subs = [ (r'-B/usr/bin', '-B%s' % os.path.join(binutils_root, 'bin')), (r'(cxx_builtin_include_directory:.*)/usr/lib/gcc', r'\1%s' % gcc_lib_inc), (r'(cxx_builtin_include_directory:.*)/usr/local/include', r'\1%s' % gcc_lib_inc_fixed), (r'(cxx_builtin_include_directory:.*)/usr/include', r'\1%s' % gcc_cplusplus_inc), ] for tool in ['ar', 'cpp', 'dwp', 'gcc', 'ld']: path = which(tool) if path: regex_subs.append((os.path.join('/usr', 'bin', tool), path)) else: raise EasyBuildError("Failed to determine path to '%s'", tool) apply_regex_substitutions(os.path.join('tools', 'cpp', 'CROSSTOOL'), regex_subs) # replace hardcoded paths in (unix_)cc_configure.bzl regex_subs = [ (r'-B/usr/bin', '-B%s' % os.path.join(binutils_root, 'bin')), (r'"/usr/bin', '"' + os.path.join(binutils_root, 'bin')), ] for conf_bzl in ['cc_configure.bzl', 'unix_cc_configure.bzl']: filepath = os.path.join('tools', 'cpp', conf_bzl) if os.path.exists(filepath): apply_regex_substitutions(filepath, regex_subs) else: self.log.info("Not patching Bazel build scripts, installation prefix for binutils/GCC not found") # enable building in parallel env.setvar('EXTRA_BAZEL_ARGS', '--jobs=%d' % self.cfg['parallel'])
def configure(self): """Configure OpenFOAM build by setting appropriate environment variables.""" # installation directory env.set("FOAM_INST_DIR", self.installdir) # third party directory self.thrdpartydir = "ThirdParty-%s" % self.version() os.symlink(os.path.join("..", self.thrdpartydir), self.thrdpartydir) env.set("WM_THIRD_PARTY_DIR", os.path.join(self.installdir, self.thrdpartydir)) # compiler comp_fam = self.toolkit().comp_family() if comp_fam == toolkit.GCC: self.wm_compiler="Gcc" elif comp_fam == toolkit.INTEL: self.wm_compiler="Icc" # make sure -no-prec-div is used with Intel compilers self.updatecfg('premakeopts', 'CFLAGS="$CFLAGS -no-prec-div" CXXFLAGS="$CXXFLAGS -no-prec-div"') else: self.log.error("Unknown compiler family, don't know how to set WM_COMPILER") env.set("WM_COMPILER",self.wm_compiler) # type of MPI mpi_type = self.toolkit().mpi_type() if mpi_type == toolkit.INTEL: self.mpipath = os.path.join(get_software_root('IMPI'),'intel64') self.wm_mplib = "IMPI" elif mpi_type == toolkit.QLOGIC: self.mpipath = get_software_root('QLogicMPI') self.wm_mplib = "MPICH" elif mpi_type == toolkit.OPENMPI: self.mpipath = get_software_root('OpenMPI') self.wm_mplib = "MPI-MVAPICH2" else: self.log.error("Unknown MPI, don't know how to set MPI_ARCH_PATH, WM_MPLIB or FOAM_MPI_LIBBIN") env.set("WM_MPLIB", self.wm_mplib) env.set("MPI_ARCH_PATH", self.mpipath) env.set("FOAM_MPI_LIBBIN", self.mpipath) # parallel build spec env.set("WM_NCOMPPROCS", str(self.getcfg('parallel')))
def _set_fftw_variables(self): if not hasattr(self, 'BLAS_LIB_DIR'): raise EasyBuildError("_set_fftw_variables: IntelFFT based on IntelMKL (no BLAS_LIB_DIR found)") imklver = get_software_version(self.FFT_MODULE_NAME[0]) picsuff = '' if self.options.get('pic', None): picsuff = '_pic' bitsuff = '_lp64' if self.options.get('i8', None): bitsuff = '_ilp64' compsuff = '_intel' if get_software_root('icc') is None: if get_software_root('GCC'): compsuff = '_gnu' else: raise EasyBuildError("Not using Intel compilers or GCC, don't know compiler suffix for FFTW libraries.") fftw_libs = ["fftw3xc%s%s" % (compsuff, picsuff)] if self.options['usempi']: # add cluster interface for recent imkl versions if LooseVersion(imklver) >= LooseVersion("11.0.2"): fftw_libs.append("fftw3x_cdft%s%s" % (bitsuff, picsuff)) elif LooseVersion(imklver) >= LooseVersion("10.3"): fftw_libs.append("fftw3x_cdft%s" % picsuff) fftw_libs.append("mkl_cdft_core") # add cluster dft fftw_libs.extend(self.variables['LIBBLACS'].flatten()) # add BLACS; use flatten because ListOfList self.log.debug('fftw_libs %s' % fftw_libs.__repr__()) fftw_libs.extend(self.variables['LIBBLAS'].flatten()) # add BLAS libs (contains dft) self.log.debug('fftw_libs %s' % fftw_libs.__repr__()) self.FFT_LIB_DIR = self.BLAS_LIB_DIR self.FFT_INCLUDE_DIR = self.BLAS_INCLUDE_DIR # building the FFTW interfaces is optional, # so make sure libraries are there before FFT_LIB is set imklroot = get_software_root(self.FFT_MODULE_NAME[0]) fft_lib_dirs = [os.path.join(imklroot, d) for d in self.FFT_LIB_DIR] # filter out gfortran from list of FFTW libraries to check for, since it's not provided by imkl check_fftw_libs = [lib for lib in fftw_libs if lib != 'gfortran'] fftw_lib_exists = lambda x: any([os.path.exists(os.path.join(d, "lib%s.a" % x)) for d in fft_lib_dirs]) if all([fftw_lib_exists(lib) for lib in check_fftw_libs]): self.FFT_LIB = fftw_libs else: msg = "Not all FFTW interface libraries %s are found in %s" % (check_fftw_libs, fft_lib_dirs) msg += ", can't set $FFT_LIB." if build_option('extended_dry_run'): dry_run_warning(msg, silent=build_option('silent')) else: raise EasyBuildError(msg)
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): """Configure SLEPc by setting configure options and running configure script.""" # check PETSc dependency if not get_software_root("PETSc"): raise EasyBuildError("PETSc module not loaded?") # set SLEPC_DIR environment variable env.setvar('SLEPC_DIR', self.cfg['start_dir']) self.log.debug('SLEPC_DIR: %s' % os.getenv('SLEPC_DIR')) # optional dependencies depfilter = self.cfg.builddependencies() + ["PETSc"] deps = [dep['name'] for dep in self.cfg.dependencies() if not dep['name'] in depfilter] for dep in deps: deproot = get_software_root(dep) if deproot: withdep = "--with-%s" % dep.lower() self.cfg.update('configopts', '%s=1 %s-dir=%s' % (withdep, withdep, deproot)) if self.cfg['sourceinstall']: # run configure without --prefix (required) cmd = "%s ./configure %s" % (self.cfg['preconfigopts'], self.cfg['configopts']) (out, _) = run_cmd(cmd, log_all=True, simple=False) else: # regular './configure --prefix=X' for non-source install # make sure old install dir is removed first self.make_installdir(dontcreate=True) out = super(EB_SLEPc, self).configure_step() # check for errors in configure error_regexp = re.compile("ERROR") if error_regexp.search(out): raise EasyBuildError("Error(s) detected in configure output!") # define $PETSC_ARCH petsc_arch = self.cfg['petsc_arch'] if self.cfg['petsc_arch'] is None: petsc_arch = 'arch-installed-petsc' env.setvar('PETSC_ARCH', petsc_arch) if self.cfg['sourceinstall']: self.slepc_subdir = os.path.join('%s-%s' % (self.name.lower(), self.version), petsc_arch) # SLEPc > 3.5, make does not accept -j if LooseVersion(self.version) >= LooseVersion("3.5"): self.cfg['parallel'] = None
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' fp = os.path.join(self.cfg['start_dir'], self.config_name, '%s.mk' % self.config_name) cfgvars = { 'CC': os.getenv('MPICC'), 'CFLAGS': os.getenv('CFLAGS'), 'CXX': os.getenv('MPICXX'), 'F77': os.getenv('MPIF77'), 'F77FLAGS': os.getenv('F77FLAGS'), 'BLAS': os.getenv('LIBBLAS_MT'), 'LAPACK': os.getenv('LIBLAPACK_MT'), } metis = get_software_root('METIS') parmetis = get_software_root('ParMETIS') if parmetis: metis_path = parmetis metis_libs = ' '.join([ os.path.join(parmetis, 'lib', 'libparmetis.a'), os.path.join(parmetis, 'lib', 'metis.a'), ]) elif metis: metis_path = metis metis_libs = os.path.join(metis, 'lib', 'metis.a') else: self.log.error("Neither METIS or ParMETIS module loaded.") cfgvars.update({ 'METIS_PATH': metis_path, 'METIS': metis_libs, }) # patch file try: for line in fileinput.input(fp, inplace=1, backup='.orig'): for (k, v) in cfgvars.items(): line = re.sub(r"^(%s\s*=\s*).*$" % k, r"\1 %s # patched by EasyBuild" % v, line) if k in line: cfgvars.pop(k) sys.stdout.write(line) except IOError, err: self.log.error("Failed to patch %s in: %s" % (fp, err))
def install_step(self): """Custom install procedure for QScintilla.""" super(EB_QScintilla, self).install_step() # also install Python bindings if Python is included as a dependency python = get_software_root('Python') if python: pydir = os.path.join(self.cfg['start_dir'], 'Python') try: os.chdir(pydir) except OSError as err: raise EasyBuildError("Failed to change to %s: %s", pydir, err) # apparently this directory has to be there qsci_sipdir = os.path.join(self.installdir, 'share', 'sip', 'PyQt4') mkdir(qsci_sipdir, parents=True) pylibdir = os.path.join(det_pylibdir(), 'PyQt4') pyqt = get_software_root('PyQt') if pyqt is None: raise EasyBuildError("Failed to determine PyQt installation prefix, PyQt not included as dependency?") cfgopts = [ '--destdir %s' % os.path.join(self.installdir, pylibdir), '--qsci-sipdir %s' % qsci_sipdir, '--qsci-incdir %s' % os.path.join(self.installdir, 'include'), '--qsci-libdir %s' % os.path.join(self.installdir, 'lib'), '--pyqt-sipdir %s' % os.path.join(pyqt, 'share', 'sip', 'PyQt4'), '--apidir %s' % os.path.join(self.installdir, 'qsci', 'api', 'python'), '--no-stubs', ] run_cmd("python configure.py %s" % ' '.join(cfgopts)) super(EB_QScintilla, self).build_step() super(EB_QScintilla, self).install_step() target_dir = os.path.join(self.installdir, pylibdir) pyqt_pylibdir = os.path.join(pyqt, pylibdir) try: os.chdir(target_dir) for entry in [x for x in os.listdir(pyqt_pylibdir) if not x.startswith('__init__.py')]: symlink(os.path.join(pyqt_pylibdir, entry), os.path.join(target_dir, entry)) except OSError as err: raise EasyBuildError("Failed to symlink PyQt Python bindings in %s: %s", target_dir, err) # also requires empty __init__.py file to ensure Python modules can be imported from this location write_file(os.path.join(target_dir, '__init__.py'), '')
def configure_step(self): """Set some extra environment variables before configuring.""" deps = ["Boost", "GMP", "MPFR"] for dep in deps: if not get_software_root(dep): self.log.error("Dependency module %s not loaded?" % dep) for lib in ["GMP", "MPFR"]: os.environ['%s_INC_DIR' % lib] = "%s%s" % (get_software_root(lib), "/include/") os.environ['%s_LIB_DIR' % lib] = "%s%s" % (get_software_root(lib), "/lib/") os.environ['BOOST_ROOT'] = get_software_root("Boost") super(EB_CGAL, self).configure_step()
def configure_step(self): """Custom configuration for R.""" # define $BLAS_LIBS to build R correctly against BLAS/LAPACK library # $LAPACK_LIBS should *not* be specified since that may lead to using generic LAPACK # see https://github.com/easybuilders/easybuild-easyconfigs/issues/1435 env.setvar('BLAS_LIBS', os.getenv('LIBBLAS')) self.cfg.update('configopts', "--with-blas --with-lapack") # make sure correct config script is used for Tcl/Tk for dep in ['Tcl', 'Tk']: root = get_software_root(dep) if root: dep_config = os.path.join(root, 'lib', '%sConfig.sh' % dep.lower()) self.cfg.update('configopts', '--with-%s-config=%s' % (dep.lower(), dep_config)) if "--with-x=" not in self.cfg['configopts'].lower(): if get_software_root('X11'): self.cfg.update('configopts', '--with-x=yes') else: self.cfg.update('configopts', '--with-x=no') # enable graphic capabilities for plotting, based on available dependencies for dep in ['Cairo', 'libjpeg-turbo', 'libpng', 'libtiff']: if get_software_root(dep): if dep == 'libjpeg-turbo': conf_opt = 'jpeglib' else: conf_opt = dep.lower() self.cfg.update('configopts', '--with-%s' % conf_opt) out = ConfigureMake.configure_step(self) # check output of configure command to verify BLAS/LAPACK settings ext_libs_regex = re.compile("External libraries:.*BLAS\((?P<BLAS>.*)\).*LAPACK\((?P<LAPACK>.*)\)") res = ext_libs_regex.search(out) if res: for lib in ['BLAS', 'LAPACK']: if res.group(lib) == 'generic': warn_msg = "R will be built with generic %s, which will result in poor performance." % lib self.log.warning(warn_msg) print_warning(warn_msg) else: self.log.info("R is configured to use non-generic %s: %s", lib, res.group(lib)) else: warn_msg = "R is configured to be built without BLAS/LAPACK, which will result in (very) poor performance" self.log.warning(warn_msg) print_warning(warn_msg)
def configure_step(self): """Configure build: - set required environment variables (for netCDF, JasPer) - patch compile script and ungrib Makefile for non-default install paths of WRF and JasPer - run configure script and figure how to select desired build option - patch configure.wps file afterwards to fix 'serial compiler' setting """ # netCDF dependency check + setting env vars (NETCDF, NETCDFF) set_netcdf_env_vars(self.log) self.netcdf_mod_cmds = get_netcdf_module_set_cmds(self.log) # WRF dependency check wrf = get_software_root('WRF') if wrf: majver = get_software_version('WRF').split('.')[0] self.wrfdir = os.path.join(wrf, "WRFV%s" % majver) else: self.log.error("WRF module not loaded?") # patch compile script so that WRF is found self.compile_script = "compile" try: for line in fileinput.input(self.compile_script, inplace=1, backup='.orig.wrf'): line = re.sub(r"^(\s*set\s*WRF_DIR_PRE\s*=\s*)\${DEV_TOP}(.*)$", r"\1%s\2" % self.wrfdir, line) sys.stdout.write(line) except IOError, err: self.log.error("Failed to patch %s script: %s" % (self.compile_script, err))
def configure(self): # configure for 64-bit build self.updatecfg('configopts', "-b 64") if self.getcfg('ignorethrottling'): # ignore CPU throttling check # this is not recommended, it will disturb the measurements done by ATLAS # used for the EasyBuild demo, to avoid requiring root privileges self.updatecfg('configopts', '-Si cputhrchk 0') # if LAPACK is found, instruct ATLAS to provide a full LAPACK library # ATLAS only provides a few LAPACK routines natively if self.getcfg('full_lapack'): lapack = get_software_root('LAPACK') if lapack: self.updatecfg('configopts', ' --with-netlib-lapack=%s/lib/liblapack.a' % lapack) else: self.log.error("netlib's LAPACK library not available,"\ " required to build ATLAS with a full LAPACK library.") # enable building of shared libraries (requires -fPIC) if self.getcfg('sharedlibs') or self.toolkit().opts['pic']: self.log.debug("Enabling -fPIC because we're building shared ATLAS libs, or just because.") self.updatecfg('configopts', '-Fa alg -fPIC') # ATLAS only wants to be configured/built in a separate dir' try: objdir = "obj" os.makedirs(objdir) os.chdir(objdir) except OSError, err: self.log.error("Failed to create obj directory to build in: %s" % err)
def configure_step(self): """Configure build: set require config and make options, and run configure script.""" # configure options for dependencies deps = [ ("Szip", "--with-szlib"), ("zlib", "--with-zlib"), ] for (dep, opt) in deps: root = get_software_root(dep) if root: self.cfg.update('configopts', '%s=%s' % (opt, root)) else: raise EasyBuildError("Dependency module %s not loaded.", dep) fcomp = 'FC="%s"' % os.getenv('F90') self.cfg.update('configopts', "--with-pic --with-pthread --enable-shared") self.cfg.update('configopts', "--enable-cxx --enable-fortran %s" % fcomp) # MPI and C++ support enabled requires --enable-unsupported, because this is untested by HDF5 # also returns False if MPI is not supported by this toolchain if self.toolchain.options.get('usempi', None): self.cfg.update('configopts', "--enable-unsupported --enable-parallel") else: self.cfg.update('configopts', "--disable-parallel") # make options self.cfg.update('buildopts', fcomp) # set RUNPARALLEL if MPI is not enabled (or not supported by this toolchain) if self.toolchain.options.get('usempi', None): env.setvar('RUNPARALLEL', 'mpirun -np \$\${NPROCS:=2}') super(EB_HDF5, self).configure_step()
def build_step(self): """Build ScaLAPACK using make after setting make options.""" # MPI compiler commands known_mpi_libs = [ toolchain.MPICH, toolchain.MPICH2, toolchain.MVAPICH2 ] #@UndefinedVariable known_mpi_libs += [toolchain.OPENMPI, toolchain.QLOGICMPI] #@UndefinedVariable if os.getenv('MPICC') and os.getenv('MPIF77') and os.getenv('MPIF90'): mpicc = os.getenv('MPICC') mpif77 = os.getenv('MPIF77') mpif90 = os.getenv('MPIF90') elif self.toolchain.mpi_family() in known_mpi_libs: mpicc = 'mpicc' mpif77 = 'mpif77' mpif90 = 'mpif90' else: raise EasyBuildError("Don't know which compiler commands to use.") # set BLAS and LAPACK libs extra_makeopts = None self.log.deprecated( "EB_ScaLAPACK.build_step doesn't use toolchain support for BLAS/LAPACK libs", '3.0') if get_software_root('LAPACK'): extra_makeopts = [ 'BLASLIB="%s -lpthread"' % lapack_get_blas_lib(self.log), 'LAPACKLIB=%s/lib/liblapack.a' % get_software_root('LAPACK') ] elif get_software_root('ACML'): root = get_software_root('ACML') acml_static_lib = os.path.join( root, os.getenv('ACML_BASEDIR', 'NO_ACML_BASEDIR'), 'lib', 'libacml.a') extra_makeopts = [ 'BLASLIB="%s -lpthread"' % acml_static_lib, 'LAPACKLIB=%s' % acml_static_lib ] elif get_software_root('OpenBLAS'): root = get_software_root('OpenBLAS') extra_makeopts = [ 'BLASLIB="%s -lpthread"' % lapack_get_blas_lib(self.log), 'LAPACKLIB="%s"' % lapack_get_blas_lib(self.log), ] else: raise EasyBuildError( "LAPACK, ACML or OpenBLAS are not available, no idea how to set BLASLIB/LAPACKLIB make options." ) # build procedure changed in v2.0.0 if self.loosever < LooseVersion("2.0.0"): blacs = get_software_root('BLACS') # determine interface interface = det_interface(self.log, os.path.join(blacs, 'bin')) # set build and BLACS dir correctly extra_makeopts.append('home=%s BLACSdir=%s' % (self.cfg['start_dir'], blacs)) # set BLACS libs correctly blacs_libs = [('BLACSFINIT', "F77init"), ('BLACSCINIT', "Cinit"), ('BLACSLIB', "")] for (var, lib) in blacs_libs: extra_makeopts.append('%s=%s/lib/libblacs%s.a' % (var, blacs, lib)) # set compilers and options noopt = '' if self.toolchain.options['noopt']: noopt += " -O0" if self.toolchain.options['pic']: noopt += " -fPIC" extra_makeopts += [ 'F77="%s"' % mpif77, 'CC="%s"' % mpicc, 'NOOPT="%s"' % noopt, 'CCFLAGS="-O3 %s"' % os.getenv('CFLAGS') ] # set interface extra_makeopts.append("CDEFS='-D%s -DNO_IEEE $(USEMPI)'" % interface) else: # determine interface if self.toolchain.mpi_family() in known_mpi_libs: interface = 'Add_' else: raise EasyBuildError( "Don't know which interface to pick for the MPI library being used." ) # set compilers and options extra_makeopts += [ 'FC="%s"' % mpif90, 'CC="%s"' % mpicc, 'CCFLAGS="%s"' % os.getenv('CFLAGS'), 'FCFLAGS="%s"' % os.getenv('FFLAGS'), ] # set interface extra_makeopts.append('CDEFS="-D%s"' % interface) # update make opts, and build_step self.cfg.update('buildopts', ' '.join(extra_makeopts)) super(EB_ScaLAPACK, self).build_step()
def configure_step(self, **kwargs): """Custom configuration procedure for LAMMPS.""" cuda = get_software_root('CUDA') # list of CUDA compute capabilities to use can be specifed in two ways (where (2) overrules (1)): # (1) in the easyconfig file, via the custom cuda_compute_capabilities; # (2) in the EasyBuild configuration, via --cuda-compute-capabilities configuration option; ec_cuda_cc = self.cfg['cuda_compute_capabilities'] cfg_cuda_cc = build_option('cuda_compute_capabilities') cuda_cc = check_cuda_compute_capabilities(cfg_cuda_cc, ec_cuda_cc) # cmake has its own folder self.cfg['srcdir'] = os.path.join(self.start_dir, 'cmake') # Enable following packages, if not configured in easyconfig default_options = [ 'BUILD_DOC', 'BUILD_EXE', 'BUILD_LIB', 'BUILD_TOOLS' ] for option in default_options: if "-D%s=" % option not in self.cfg['configopts']: self.cfg.update('configopts', '-D%s=on' % option) # enable building of shared libraries, if not specified already via configopts if self.cfg[ 'build_shared_libs'] is None and '-DBUILD_SHARED_LIBS=' not in self.cfg[ 'configopts']: self.cfg['build_shared_libs'] = True # Enable gzip, libpng and libjpeg-turbo support when its included as dependency deps = [ ('gzip', 'GZIP'), ('libpng', 'PNG'), ('libjpeg-turbo', 'JPEG'), ] for dep_name, with_name in deps: with_opt = '-DWITH_%s=' % with_name if with_opt not in self.cfg['configopts']: if get_software_root(dep_name): self.cfg.update('configopts', with_opt + 'yes') else: self.cfg.update('configopts', with_opt + 'no') # Disable auto-downloading/building Eigen dependency: if '-DDOWNLOAD_EIGEN3=' not in self.cfg['configopts']: self.cfg.update('configopts', '-DDOWNLOAD_EIGEN3=no') # Compiler complains about 'Eigen3_DIR' not beeing set, but acutally it needs 'EIGEN3_INCLUDE_DIR'. # see: https://github.com/lammps/lammps/issues/1110 # Enable Eigen when its included as dependency dependency: eigen_root = get_software_root('Eigen') if eigen_root: if '-DEIGEN3_INCLUDE_DIR=' not in self.cfg['configopts']: self.cfg.update( 'configopts', '-DEIGEN3_INCLUDE_DIR=%s/include/Eigen' % get_software_root('Eigen')) if '-DEigen3_DIR=' not in self.cfg['configopts']: self.cfg.update( 'configopts', '-DEigen3_DIR=%s/share/eigen3/cmake/' % get_software_root('Eigen')) # LAMMPS Configuration Options # https://github.com/lammps/lammps/blob/master/cmake/README.md#lammps-configuration-options if self.cfg['general_packages']: for package in self.cfg['general_packages']: self.cfg.update('configopts', '-D%s%s=on' % (PKG_PREFIX, package)) if self.cfg['user_packages']: for package in self.cfg['user_packages']: self.cfg.update('configopts', '-D%s%s=on' % (PKG_USER_PREFIX, package)) # Optimization settings pkg_opt = '-D%sOPT=' % PKG_PREFIX if pkg_opt not in self.cfg['configopts']: self.cfg.update('configopts', pkg_opt + 'on') # USER-INTEL enables optimizations on Intel processors. GCC has also partial support for some of them. pkg_user_intel = '-D%sINTEL=' % PKG_USER_PREFIX if pkg_user_intel not in self.cfg['configopts']: if self.toolchain.comp_family() in [ toolchain.GCC, toolchain.INTELCOMP ]: self.cfg.update('configopts', pkg_user_intel + 'on') # MPI/OpenMP if self.toolchain.options.get('usempi', None): self.cfg.update('configopts', '-DBUILD_MPI=yes') if self.toolchain.options.get('openmp', None): self.cfg.update('configopts', '-DBUILD_OMP=yes') self.cfg.update('configopts', '-D%sOMP=on' % PKG_USER_PREFIX) # FFTW if get_software_root("imkl") or get_software_root("FFTW"): if '-DFFT=' not in self.cfg['configopts']: if get_software_root("imkl"): self.log.info("Using the MKL") self.cfg.update('configopts', '-DFFT=MKL') else: self.log.info("Using FFTW") self.cfg.update('configopts', '-DFFT=FFTW3') if '-DFFT_PACK=' not in self.cfg['configopts']: self.cfg.update('configopts', '-DFFT_PACK=array') # https://lammps.sandia.gov/doc/Build_extras.html # KOKKOS if self.cfg['kokkos']: if self.toolchain.options.get('openmp', None): self.cfg.update('configopts', '-DKOKKOS_ENABLE_OPENMP=yes') self.cfg.update('configopts', '-D%sKOKKOS=on' % PKG_PREFIX) self.cfg.update( 'configopts', '-DKOKKOS_ARCH="%s"' % get_kokkos_arch(cuda_cc, self.cfg['kokkos_arch'])) # if KOKKOS and CUDA if cuda: nvcc_wrapper_path = os.path.join(self.start_dir, "lib", "kokkos", "bin", "nvcc_wrapper") self.cfg.update('configopts', '-DKOKKOS_ENABLE_CUDA=yes') self.cfg.update( 'configopts', '-DCMAKE_CXX_COMPILER="%s"' % nvcc_wrapper_path) self.cfg.update('configopts', '-DCMAKE_CXX_FLAGS="-ccbin $CXX $CXXFLAGS"') # CUDA only elif cuda: self.cfg.update('configopts', '-D%sGPU=on' % PKG_PREFIX) self.cfg.update('configopts', '-DGPU_API=cuda') self.cfg.update('configopts', '-DGPU_ARCH=%s' % get_cuda_gpu_arch(cuda_cc)) # avoid that pip (ab)uses $HOME/.cache/pip # cfr. https://pip.pypa.io/en/stable/reference/pip_install/#caching env.setvar('XDG_CACHE_HOME', tempfile.gettempdir()) self.log.info("Using %s as pip cache directory", os.environ['XDG_CACHE_HOME']) return super(EB_LAMMPS, self).configure_step()
def configure_step(self): """Custom configuration procedure for Quantum ESPRESSO.""" # compose list of DFLAGS (flag, value, keep_stuff) # for guidelines, see include/defs.h.README in sources dflags = [] repls = [] extra_libs = [] comp_fam_dflags = { toolchain.INTELCOMP: '-D__INTEL', toolchain.GCC: '-D__GFORTRAN -D__STD_F95', } comp_fam = self.toolchain.comp_family() if comp_fam in comp_fam_dflags: dflags.append(comp_fam_dflags[comp_fam]) else: raise EasyBuildError( "EasyBuild does not yet have support for QuantumESPRESSO with toolchain %s" % comp_fam) if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: self.cfg.update('configopts', '--enable-openmp') dflags.append(" -D__OPENMP") if self.toolchain.options.get('usempi', None): dflags.append('-D__MPI -D__PARA') else: self.cfg.update('configopts', '--disable-parallel') if self.cfg['with_scalapack']: dflags.append(" -D__SCALAPACK") if self.toolchain.options.get('usempi', None): if get_software_root("impi") and get_software_root("imkl"): self.cfg.update('configopts', '--with-scalapack=intel') else: self.cfg.update('configopts', '--without-scalapack') libxc = get_software_root("libxc") if libxc: libxc_v = get_software_version("libxc") if LooseVersion(libxc_v) < LooseVersion("3.0.1"): raise EasyBuildError("Must use libxc >= 3.0.1") dflags.append(" -D__LIBXC") repls.append( ('IFLAGS', '-I%s' % os.path.join(libxc, 'include'), True)) extra_libs.append(" -lxcf90 -lxc") hdf5 = get_software_root("HDF5") if hdf5: self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) dflags.append(" -D__HDF5") hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 repls.append(('HDF5_LIB', hdf5_lib_repl, False)) elpa = get_software_root("ELPA") if elpa: if not self.cfg['with_scalapack']: raise EasyBuildError( "ELPA requires ScaLAPACK but 'with_scalapack' is set to False" ) elpa_v = get_software_version("ELPA") if LooseVersion(self.version) >= LooseVersion("6"): elpa_min_ver = "2016.11.001.pre" dflags.append('-D__ELPA_2016') else: elpa_min_ver = "2015" dflags.append('-D__ELPA_2015 -D__ELPA') if LooseVersion(elpa_v) < LooseVersion(elpa_min_ver): raise EasyBuildError("QuantumESPRESSO %s needs ELPA to be " + "version %s or newer" % (self.version, elpa_min_ver)) elpa_include = os.path.join(elpa, 'include') repls.append( ('IFLAGS', '-I%s' % os.path.join(elpa_include, 'modules'), True)) self.cfg.update('configopts', '--with-elpa-include=%s' % elpa_include) if self.toolchain.options.get('openmp', False): elpa_lib = 'libelpa_openmp.a' else: elpa_lib = 'libelpa.a' elpa_lib = os.path.join(elpa, 'lib', elpa_lib) self.cfg.update('configopts', '--with-elpa-lib=%s' % elpa_lib) if comp_fam == toolchain.INTELCOMP: # set preprocessor command (-E to stop after preprocessing, -C to preserve comments) cpp = "%s -E -C" % os.getenv('CC') repls.append(('CPP', cpp, False)) env.setvar('CPP', cpp) # also define $FCCPP, but do *not* include -C (comments should not be preserved when preprocessing Fortran) env.setvar('FCCPP', "%s -E" % os.getenv('CC')) if comp_fam == toolchain.INTELCOMP: # Intel compiler must have -assume byterecl (see install/configure) repls.append(('F90FLAGS', '-fpp -assume byterecl', True)) repls.append(('FFLAGS', '-assume byterecl', True)) elif comp_fam == toolchain.GCC: repls.append(('F90FLAGS', '-cpp', True)) super(EB_QuantumESPRESSO, self).configure_step() if self.toolchain.options.get('openmp', False): libfft = os.getenv('LIBFFT_MT') else: libfft = os.getenv('LIBFFT') if libfft: if "fftw3" in libfft: dflags.append('-D__FFTW3') else: dflags.append('-D__FFTW') env.setvar('FFTW_LIBS', libfft) if get_software_root('ACML'): dflags.append('-D__ACML') if self.cfg['with_ace']: dflags.append(" -D__EXX_ACE") # always include -w to supress warnings dflags.append('-w') repls.append(('DFLAGS', ' '.join(dflags), False)) # complete C/Fortran compiler and LD flags if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: repls.append(('LDFLAGS', self.toolchain.get_flag('openmp'), True)) repls.append( ('(?:C|F90|F)FLAGS', self.toolchain.get_flag('openmp'), True)) # obtain library settings libs = [] num_libs = ['BLAS', 'LAPACK', 'FFT'] if self.cfg['with_scalapack']: num_libs.extend(['SCALAPACK']) for lib in num_libs: if self.toolchain.options.get('openmp', False): val = os.getenv('LIB%s_MT' % lib) else: val = os.getenv('LIB%s' % lib) if lib == 'SCALAPACK' and elpa: val = ' '.join([elpa_lib, val]) repls.append(('%s_LIBS' % lib, val, False)) libs.append(val) libs = ' '.join(libs) repls.append(('BLAS_LIBS_SWITCH', 'external', False)) repls.append(('LAPACK_LIBS_SWITCH', 'external', False)) repls.append( ('LD_LIBS', ' '.join(extra_libs + [os.getenv('LIBS')]), False)) # Do not use external FoX. # FoX starts to be used in 6.2 and they use a patched version that # is newer than FoX 4.1.2 which is the latest release. # Ake Sandgren, 20180712 if get_software_root('FoX'): raise EasyBuildError( "Found FoX external module, QuantumESPRESSO" + "must use the version they include with the source.") self.log.debug("List of replacements to perform: %s" % repls) if LooseVersion(self.version) >= LooseVersion("6"): make_ext = '.inc' else: make_ext = '.sys' # patch make.sys file fn = os.path.join(self.cfg['start_dir'], 'make' + make_ext) try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): for (k, v, keep) in repls: # need to use [ \t]* instead of \s*, because vars may be undefined as empty, # and we don't want to include newlines if keep: line = re.sub(r"^(%s\s*=[ \t]*)(.*)$" % k, r"\1\2 %s" % v, line) else: line = re.sub(r"^(%s\s*=[ \t]*).*$" % k, r"\1%s" % v, line) # fix preprocessing directives for .f90 files in make.sys if required if LooseVersion(self.version) < LooseVersion("6.0"): if comp_fam == toolchain.GCC: line = re.sub( r"^\t\$\(MPIF90\) \$\(F90FLAGS\) -c \$<", "\t$(CPP) -C $(CPPFLAGS) $< -o $*.F90\n" + "\t$(MPIF90) $(F90FLAGS) -c $*.F90 -o $*.o", line) sys.stdout.write(line) except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) self.log.debug("Contents of patched %s: %s" % (fn, open(fn, "r").read())) # patch default make.sys for wannier if LooseVersion(self.version) >= LooseVersion("5"): fn = os.path.join(self.cfg['start_dir'], 'install', 'make_wannier90' + make_ext) else: fn = os.path.join(self.cfg['start_dir'], 'plugins', 'install', 'make_wannier90.sys') try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): line = re.sub(r"^(LIBS\s*=\s*).*", r"\1%s" % libs, line) sys.stdout.write(line) except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) self.log.debug("Contents of patched %s: %s" % (fn, open(fn, "r").read())) # patch Makefile of want plugin wantprefix = 'want-' wantdirs = [ d for d in os.listdir(self.builddir) if d.startswith(wantprefix) ] if len(wantdirs) > 1: raise EasyBuildError( "Found more than one directory with %s prefix, help!", wantprefix) if len(wantdirs) != 0: wantdir = os.path.join(self.builddir, wantdirs[0]) make_sys_in_path = None cand_paths = [ os.path.join('conf', 'make.sys.in'), os.path.join('config', 'make.sys.in') ] for path in cand_paths: full_path = os.path.join(wantdir, path) if os.path.exists(full_path): make_sys_in_path = full_path break if make_sys_in_path is None: raise EasyBuildError( "Failed to find make.sys.in in want directory %s, paths considered: %s", wantdir, ', '.join(cand_paths)) try: for line in fileinput.input(make_sys_in_path, inplace=1, backup='.orig.eb'): # fix preprocessing directives for .f90 files in make.sys if required if comp_fam == toolchain.GCC: line = re.sub( "@f90rule@", "$(CPP) -C $(CPPFLAGS) $< -o $*.F90\n" + "\t$(MPIF90) $(F90FLAGS) -c $*.F90 -o $*.o", line) sys.stdout.write(line) except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) # move non-espresso directories to where they're expected and create symlinks try: dirnames = [ d for d in os.listdir(self.builddir) if d not in [self.install_subdir, 'd3q-latest'] ] targetdir = os.path.join(self.builddir, self.install_subdir) for dirname in dirnames: shutil.move(os.path.join(self.builddir, dirname), os.path.join(targetdir, dirname)) self.log.info("Moved %s into %s" % (dirname, targetdir)) dirname_head = dirname.split('-')[0] # Handle the case where the directory is preceded by 'qe-' if dirname_head == 'qe': dirname_head = dirname.split('-')[1] linkname = None if dirname_head == 'sax': linkname = 'SaX' if dirname_head == 'wannier90': linkname = 'W90' elif dirname_head in [ 'd3q', 'gipaw', 'plumed', 'want', 'yambo' ]: linkname = dirname_head.upper() if linkname: os.symlink(os.path.join(targetdir, dirname), os.path.join(targetdir, linkname)) except OSError as err: raise EasyBuildError("Failed to move non-espresso directories: %s", err)
def configure_step(self): """Configure build - build Libint wrapper - generate Makefile """ known_types = ['popt', 'psmp'] if self.cfg['type'] not in known_types: raise EasyBuildError( "Unknown build type specified: '%s', known types are %s", self.cfg['type'], known_types) # correct start dir, if needed # recent CP2K versions have a 'cp2k' dir in the unpacked 'cp2k' dir cp2k_path = os.path.join(self.cfg['start_dir'], 'cp2k') if os.path.exists(cp2k_path): self.cfg['start_dir'] = cp2k_path self.log.info("Corrected start_dir to %s" % self.cfg['start_dir']) # set compilers options according to toolchain config # full debug: -g -traceback -check all -fp-stack-check # -g links to mpi debug libs if self.toolchain.options['debug']: self.debug = '-g' self.log.info("Debug build") if self.toolchain.options['pic']: self.fpic = "-fPIC" self.log.info("Using fPIC") # report on extra flags being used if self.cfg['extracflags']: self.log.info("Using extra CFLAGS: %s" % self.cfg['extracflags']) if self.cfg['extradflags']: self.log.info("Using extra DFLAGS: %s" % self.cfg['extradflags']) # lib(x)smm support libsmm = get_software_root('libsmm') libxsmm = get_software_root('libxsmm') if libxsmm: self.cfg.update('extradflags', '-D__LIBXSMM') self.libsmm = '-lxsmm -lxsmmf' self.log.debug('Using libxsmm %s' % libxsmm) elif libsmm: libsmms = glob.glob(os.path.join(libsmm, 'lib', 'libsmm_*nn.a')) dfs = [ os.path.basename(os.path.splitext(x)[0]).replace( 'lib', '-D__HAS_') for x in libsmms ] moredflags = ' ' + ' '.join(dfs) self.cfg.update('extradflags', moredflags) self.libsmm = ' '.join(libsmms) self.log.debug('Using libsmm %s (extradflags %s)' % (self.libsmm, moredflags)) # obtain list of modinc's to use if self.cfg["modinc"]: self.modincpath = self.prepmodinc() # set typearch self.typearch = "Linux-x86-64-%s" % self.toolchain.name # extra make instructions self.make_instructions = '' # "graphcon.o: graphcon.F\n\t$(FC) -c $(FCFLAGS2) $<\n" # compiler toolchain specific configuration comp_fam = self.toolchain.comp_family() if comp_fam == toolchain.INTELCOMP: options = self.configure_intel_based() elif comp_fam == toolchain.GCC: options = self.configure_GCC_based() else: raise EasyBuildError( "Don't know how to tweak configuration for compiler family %s" % comp_fam) # BLAS/LAPACK/FFTW if get_software_root('imkl'): options = self.configure_MKL(options) else: # BLAS if get_software_root('ACML'): options = self.configure_ACML(options) else: options = self.configure_BLAS_lib(options) # FFTW (no MKL involved) if 'fftw3' in os.getenv('LIBFFT', ''): options = self.configure_FFTW3(options) # LAPACK if os.getenv('LIBLAPACK_MT', None) is not None: options = self.configure_LAPACK(options) if os.getenv('LIBSCALAPACK', None) is not None: options = self.configure_ScaLAPACK(options) # PLUMED plumed = get_software_root('PLUMED') if self.cfg['plumed'] and not plumed: raise EasyBuildError( "The PLUMED module needs to be loaded to build CP2K with PLUMED support" ) # enable PLUMED support if PLUMED is listed as a dependency # and PLUMED support is either explicitly enabled (plumed = True) or unspecified ('plumed' not defined) if plumed and (self.cfg['plumed'] or self.cfg['plumed'] is None): options['LIBS'] += ' -lplumed' options['DFLAGS'] += ' -D__PLUMED2' # ELPA elpa = get_software_root('ELPA') if elpa: options['LIBS'] += ' -lelpa' elpa_inc_dir = os.path.join( elpa, 'include', 'elpa-%s' % get_software_version('ELPA'), 'modules') options['FCFLAGSOPT'] += ' -I%s ' % elpa_inc_dir if LooseVersion(self.version) >= LooseVersion('6.1'): elpa_ver = ''.join(get_software_version('ELPA').split('.')[:2]) options['DFLAGS'] += ' -D__ELPA=%s' % elpa_ver elpa_inc_dir = os.path.join( elpa, 'include', 'elpa-%s' % get_software_version('ELPA'), 'elpa') options['FCFLAGSOPT'] += ' -I%s ' % elpa_inc_dir else: options['DFLAGS'] += ' -D__ELPA3' # CUDA cuda = get_software_root('CUDA') if cuda: options['DFLAGS'] += ' -D__ACC -D__DBCSR_ACC' options['LIBS'] += ' -lcudart -lcublas -lcufft -lrt' options['NVCC'] = ' nvcc' # avoid group nesting options['LIBS'] = options['LIBS'].replace('-Wl,--start-group', '').replace( '-Wl,--end-group', '') options[ 'LIBS'] = "-Wl,--start-group %s -Wl,--end-group" % options['LIBS'] # specify correct location for 'data' directory in final installation options['DATA_DIR'] = os.path.join(self.installdir, 'data') # create arch file using options set archfile = os.path.join(self.cfg['start_dir'], 'arch', '%s.%s' % (self.typearch, self.cfg['type'])) txt = self._generate_makefile(options) write_file(archfile, txt) self.log.info("Content of makefile (%s):\n%s" % (archfile, txt))
def configure_step(self): """ Configure VMD for building. """ # make sure required dependencies are available deps = {} for dep in ['FLTK', 'Mesa', 'netCDF', 'Python', 'Tcl', 'Tk']: deps[dep] = get_software_root(dep) if deps[dep] is None: raise EasyBuildError("Required dependency %s is missing", dep) # optional dependencies for dep in ['ACTC', 'CUDA', 'OptiX']: deps[dep] = get_software_root(dep) # specify Tcl/Tk locations & libraries tclinc = os.path.join(deps['Tcl'], 'include') tcllib = os.path.join(deps['Tcl'], 'lib') env.setvar('TCL_INCLUDE_DIR', tclinc) env.setvar('TCL_LIBRARY_DIR', tcllib) env.setvar('TK_INCLUDE_DIR', os.path.join(deps['Tk'], 'include')) env.setvar('TK_LIBRARY_DIR', os.path.join(deps['Tk'], 'lib')) tclshortver = '.'.join(get_software_version('Tcl').split('.')[:2]) self.cfg.update('buildopts', 'TCLLDFLAGS="-ltcl%s"' % tclshortver) # Python locations pyshortver = '.'.join(get_software_version('Python').split('.')[:2]) env.setvar( 'PYTHON_INCLUDE_DIR', os.path.join(deps['Python'], 'include/python%s' % pyshortver)) pylibdir = det_pylibdir() python_libdir = os.path.join(deps['Python'], os.path.dirname(pylibdir)) env.setvar('PYTHON_LIBRARY_DIR', python_libdir) # numpy include location, easiest way to determine it is via numpy.get_include() out, ec = run_cmd( "python -c 'import numpy; print numpy.get_include()'", simple=False) if ec: raise EasyBuildError( "Failed to determine numpy include directory: %s", out) else: env.setvar('NUMPY_INCLUDE_DIR', out.strip()) # compiler commands self.cfg.update('buildopts', 'CC="%s"' % os.getenv('CC')) self.cfg.update('buildopts', 'CCPP="%s"' % os.getenv('CXX')) # source tarballs contains a 'plugins' and 'vmd-<version>' directory vmddir = os.path.join(self.cfg['start_dir'], '%s-%s' % (self.name.lower(), self.version)) # plugins need to be built first (see http://www.ks.uiuc.edu/Research/vmd/doxygen/compiling.html) change_dir(os.path.join(self.cfg['start_dir'], 'plugins')) cmd = "make LINUXAMD64 TCLLIB='-F%s' TCLINC='-I%s' %s" % ( tcllib, tclinc, self.cfg['buildopts']) run_cmd(cmd, log_all=True, simple=False) # create plugins distribution plugindir = os.path.join(vmddir, 'plugins') env.setvar('PLUGINDIR', plugindir) self.log.info("Generating VMD plugins in %s", plugindir) run_cmd("make distrib %s" % self.cfg['buildopts'], log_all=True, simple=False) # explicitely mention whether or not we're building with CUDA/OptiX support if deps['CUDA']: self.log.info("Building with CUDA %s support", get_software_version('CUDA')) if deps['OptiX']: self.log.info("Building with Nvidia OptiX %s support", get_software_version('OptiX')) else: self.log.warn("Not building with Nvidia OptiX support!") else: self.log.warn("Not building with CUDA nor OptiX support!") # see http://www.ks.uiuc.edu/Research/vmd/doxygen/configure.html # LINUXAMD64: Linux 64-bit # LP64: build VMD as 64-bit binary # IMD: enable support for Interactive Molecular Dynamics (e.g. to connect to NAMD for remote simulations) # PTHREADS: enable support for POSIX threads # COLVARS: enable support for collective variables (related to NAMD/LAMMPS) # NOSILENT: verbose build command self.cfg.update('configopts', "LINUXAMD64 LP64 IMD PTHREADS COLVARS NOSILENT") # add additional configopts based on available dependencies for key in deps: if deps[key]: if key == 'Mesa': self.cfg.update('configopts', "OPENGL MESA") elif key == 'OptiX': self.cfg.update('configopts', "LIBOPTIX") elif key == 'Python': self.cfg.update('configopts', "PYTHON NUMPY") else: self.cfg.update('configopts', key.upper()) # configure for building with Intel compilers specifically if self.toolchain.comp_family() == toolchain.INTELCOMP: self.cfg.update('configopts', 'ICC') # specify install location using environment variables env.setvar('VMDINSTALLBINDIR', os.path.join(self.installdir, 'bin')) env.setvar('VMDINSTALLLIBRARYDIR', os.path.join(self.installdir, 'lib')) # configure in vmd-<version> directory change_dir(vmddir) run_cmd("%s ./configure %s" % (self.cfg['preconfigopts'], self.cfg['configopts'])) # change to 'src' subdirectory, ready for building change_dir(os.path.join(vmddir, 'src'))
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)
class EB_PSI(ConfigureMake): """ Support for building and installing PSI """ @staticmethod def extra_options(): """Extra easyconfig parameters specific to PSI.""" extra_vars = [ # always include running PSI unit tests (takes about 2h or less) ('runtest', [ "tests TESTFLAGS='-u -q'", "Run tests included with PSI, without interruption.", BUILD ]), ] return ConfigureMake.extra_options(extra_vars) def configure_step(self): """ Configure build outside of source directory. """ try: objdir = os.path.join(self.builddir, 'obj') os.makedirs(objdir) os.chdir(objdir) except OSError, err: self.log.error( "Failed to prepare for configuration of PSI build: %s" % err) if self.toolchain.options['usempi']: # PSI doesn't require a Fortran compiler itself, but may require it to link to BLAS/LAPACK correctly # we should always specify the sequential Fortran compiler, # to avoid problems with -lmpi vs -lmpi_mt during linking fcompvar = 'F77_SEQ' else: fcompvar = 'F77' # update configure options # using multi-threaded BLAS/LAPACK is important for performance, # cfr. http://sirius.chem.vt.edu/psi4manual/latest/installfile.html#sec-install-iii opt_vars = [ ('cc', 'CC'), ('cxx', 'CXX'), ('fc', fcompvar), ('libdirs', 'LDFLAGS'), ('blas', 'LIBBLAS_MT'), ('lapack', 'LIBLAPACK_MT'), ] for (opt, var) in opt_vars: self.cfg.update('configopts', "--with-%s='%s'" % (opt, os.getenv(var))) # -DMPICH_IGNORE_CXX_SEEK dances around problem with order of stdio.h and mpi.h headers # both define SEEK_SET, this makes the one for MPI be ignored self.cfg.update( 'configopts', "--with-opt='%s -DMPICH_IGNORE_CXX_SEEK'" % os.getenv('CFLAGS')) # explicitely specify Python binary to use pythonroot = get_software_root('Python') if not pythonroot: self.log.error("Python module not loaded.") env.setvar('PYTHON', os.path.join(pythonroot, 'bin', 'python')) # specify location of Boost boostroot = get_software_root('Boost') if not boostroot: self.log.error("Boost module not loaded.") self.cfg.update('configopts', "--with-boost=%s" % boostroot) # enable support for plugins self.cfg.update('configopts', "--with-plugins") super(EB_PSI, self).configure_step(cmd_prefix=self.cfg['start_dir'])
def configure_step(self): """Custom configuration procedure for GROMACS: set configure options for configure or cmake.""" # check whether PLUMED is loaded as a dependency plumed_root = get_software_root('PLUMED') if plumed_root: # Need to check if PLUMED has an engine for this version engine = 'gromacs-%s' % self.version (out, _) = run_cmd("plumed-patch -l", log_all=True, simple=False) if not re.search(engine, out): raise EasyBuildError( "There is no support in PLUMED version %s for GROMACS %s: %s", get_software_version('PLUMED'), self.version, out) # PLUMED patching must be done at different stages depending on # version of GROMACS. Just prepare first part of cmd here plumed_cmd = "plumed-patch -p -e %s" % engine if LooseVersion(self.version) < LooseVersion('4.6'): self.log.info( "Using configure script for configuring GROMACS build.") # Use static libraries if possible self.cfg.update('configopts', "--enable-static") # Use external BLAS and LAPACK self.cfg.update('configopts', "--with-external-blas --with-external-lapack") env.setvar('LIBS', "%s %s" % (os.environ['LIBLAPACK'], os.environ['LIBS'])) # Don't use the X window system self.cfg.update('configopts', "--without-x") # OpenMP is not supported for versions older than 4.5. if LooseVersion(self.version) >= LooseVersion('4.5'): # enable OpenMP support if desired if self.toolchain.options.get('openmp', None): self.cfg.update('configopts', "--enable-threads") else: self.cfg.update('configopts', "--disable-threads") elif self.toolchain.options.get('openmp', None): raise EasyBuildError( "GROMACS version %s does not support OpenMP" % self.version) # GSL support if get_software_root('GSL'): self.cfg.update('configopts', "--with-gsl") else: self.cfg.update('configopts', "--without-gsl") # actually run configure via ancestor (not direct parent) self.cfg['configure_cmd'] = "./configure" ConfigureMake.configure_step(self) # Now patch GROMACS for PLUMED between configure and build if plumed_root: run_cmd(plumed_cmd, log_all=True, simple=True) else: # Now patch GROMACS for PLUMED before cmake if plumed_root: if LooseVersion(self.version) >= LooseVersion('5.1'): # Use shared or static patch depending on # setting of self.toolchain.options.get('dynamic') # and adapt cmake flags accordingly as per instructions # from "plumed patch -i" if self.toolchain.options.get('dynamic', False): mode = 'shared' else: mode = 'static' plumed_cmd = plumed_cmd + ' -m %s' % mode run_cmd(plumed_cmd, log_all=True, simple=True) # Select debug or release build if self.toolchain.options.get('debug', None): self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE=Debug") else: self.cfg.update('configopts', "-DCMAKE_BUILD_TYPE=Release") # prefer static libraries, if available if self.toolchain.options.get('dynamic', False): self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=OFF") else: self.cfg.update('configopts', "-DGMX_PREFER_STATIC_LIBS=ON") if plumed_root: self.cfg.update('configopts', "-DBUILD_SHARED_LIBS=OFF") if self.cfg['double_precision']: self.cfg.update('configopts', "-DGMX_DOUBLE=ON") # always specify to use external BLAS/LAPACK self.cfg.update('configopts', "-DGMX_EXTERNAL_BLAS=ON -DGMX_EXTERNAL_LAPACK=ON") # disable GUI tools self.cfg.update('configopts', "-DGMX_X11=OFF") # convince to build for an older architecture than present on the build node by setting GMX_SIMD CMake flag # 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]): major_minor_version = '.'.join(self.version.split('.')[:2]) self.cfg.update( 'configopts', "-DREGRESSIONTEST_PATH='%%(builddir)s/%s-%%(version)s' " % prefix) # enable OpenMP support if desired if self.toolchain.options.get('openmp', None): self.cfg.update('configopts', "-DGMX_OPENMP=ON") else: self.cfg.update('configopts', "-DGMX_OPENMP=OFF") # disable MPI support for initial, serial/SMP build; actual MPI build is done later self.cfg.update('configopts', "-DGMX_MPI=OFF") # explicitly disable GPU support if CUDA is not available, # to avoid that GROMACS find and uses a system-wide CUDA compiler cuda = get_software_root('CUDA') if cuda: self.cfg.update( 'configopts', "-DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=%s" % cuda) else: self.cfg.update('configopts', "-DGMX_GPU=OFF") if get_software_root('imkl'): # using MKL for FFT, so it will also be used for BLAS/LAPACK self.cfg.update( 'configopts', '-DGMX_FFT_LIBRARY=mkl -DMKL_INCLUDE_DIR="$EBROOTMKL/mkl/include" ' ) libs = os.getenv('LAPACK_STATIC_LIBS').split(',') mkl_libs = [ os.path.join(os.getenv('LAPACK_LIB_DIR'), lib) for lib in libs if lib != 'libgfortran.a' ] mkl_libs = ['-Wl,--start-group' ] + mkl_libs + ['-Wl,--end-group'] self.cfg.update('configopts', '-DMKL_LIBRARIES="%s" ' % ';'.join(mkl_libs)) else: shlib_ext = get_shared_lib_ext() for libname in ['BLAS', 'LAPACK']: libdir = os.getenv('%s_LIB_DIR' % libname) if self.toolchain.toolchain_family() == toolchain.CRAYPE: libsci_mpi_mp_lib = glob.glob( os.path.join(libdir, 'libsci_*_mpi_mp.a')) if libsci_mpi_mp_lib: self.cfg.update( 'configopts', '-DGMX_%s_USER=%s' % (libname, libsci_mpi_mp_lib[0])) else: raise EasyBuildError( "Failed to find libsci library to link with for %s", libname) else: # -DGMX_BLAS_USER & -DGMX_LAPACK_USER require full path to library libs = os.getenv('%s_STATIC_LIBS' % libname).split(',') libpaths = [ os.path.join(libdir, lib) for lib in libs if lib != 'libgfortran.a' ] self.cfg.update( 'configopts', '-DGMX_%s_USER="******"' % (libname, ';'.join(libpaths))) # if libgfortran.a is listed, make sure it gets linked in too to avoiding linking issues if 'libgfortran.a' in libs: env.setvar( 'LDFLAGS', "%s -lgfortran -lm" % os.environ.get('LDFLAGS', '')) # no more GSL support in GROMACS 5.x, see http://redmine.gromacs.org/issues/1472 if LooseVersion(self.version) < LooseVersion('5.0'): # enable GSL when it's provided if get_software_root('GSL'): self.cfg.update('configopts', "-DGMX_GSL=ON") else: self.cfg.update('configopts', "-DGMX_GSL=OFF") # include flags for linking to zlib/XZ in $LDFLAGS if they're listed as a dep; # this is important for the tests, to correctly link against libxml2 for dep, link_flag in [('XZ', '-llzma'), ('zlib', '-lz')]: root = get_software_root(dep) if root: libdir = get_software_libdir(dep) ldflags = os.environ.get('LDFLAGS', '') env.setvar( 'LDFLAGS', "%s -L%s %s" % (ldflags, os.path.join(root, libdir), link_flag)) # complete configuration with configure_method of parent self.cfg['separate_build_dir'] = True out = super(EB_GROMACS, self).configure_step() # for recent GROMACS versions, make very sure that a decent BLAS, LAPACK and FFT is found and used if LooseVersion(self.version) >= LooseVersion('4.6.5'): patterns = [ r"Using external FFT library - \S*", r"Looking for dgemm_ - found", r"Looking for cheev_ - found", ] for pattern in patterns: regex = re.compile(pattern, re.M) if not regex.search(out): raise EasyBuildError( "Pattern '%s' not found in GROMACS configuration output.", pattern)
def configure_step(self): """Configure numpy build by composing site.cfg contents.""" # see e.g. https://github.com/numpy/numpy/pull/2809/files self.sitecfg = '\n'.join([ "[DEFAULT]", "library_dirs = %(libs)s", "include_dirs= %(includes)s", "search_static_first=True", ]) if get_software_root("imkl"): if self.toolchain.comp_family() == toolchain.GCC: # see https://software.intel.com/en-us/articles/numpyscipy-with-intel-mkl, # section Building with GNU Compiler chain extrasiteconfig = '\n'.join([ "[mkl]", "lapack_libs = ", "mkl_libs = mkl_rt", ]) else: extrasiteconfig = '\n'.join([ "[mkl]", "lapack_libs = %(lapack)s", "mkl_libs = %(blas)s", ]) else: # [atlas] the only real alternative, even for non-ATLAS BLAS libs (e.g., OpenBLAS, ACML, ...) # using only the [blas] and [lapack] sections results in sub-optimal builds that don't provide _dotblas.so; # it does require a CBLAS interface to be available for the BLAS library being used # e.g. for ACML, the CBLAS module providing a C interface needs to be used extrasiteconfig = '\n'.join([ "[atlas]", "atlas_libs = %(lapack)s", "[lapack]", "lapack_libs = %(lapack)s", # required by scipy, that uses numpy's site.cfg ]) blas = None lapack = None fft = None if get_software_root("imkl"): # with IMKL, no spaces and use '-Wl:' # redefine 'Wl,' to 'Wl:' so that the patch file can do its job def get_libs_for_mkl(varname): """Get list of libraries as required for MKL patch file.""" libs = self.toolchain.variables['LIB%s' % varname].copy() libs.try_remove(['pthread']) tweaks = { 'prefix': '', 'prefix_begin_end': '-Wl:', 'separator': ',', 'separator_begin_end': ',', } libs.try_function_on_element('change', kwargs=tweaks) libs.SEPARATOR = ',' return str( libs ) # str causes list concatenation and adding prefixes & separators blas = get_libs_for_mkl('BLAS_MT') lapack = get_libs_for_mkl('LAPACK_MT') fft = get_libs_for_mkl('FFT') # make sure the patch file is there # we check for a typical characteristic of a patch file that cooperates with the above # not fool-proof, but better than enforcing a particular patch filename patch_found = False patch_wl_regex = re.compile(r"replace\(':',\s*','\)") for patch in self.patches: # patches are either strings (extension) or dicts (easyblock) if isinstance(patch, dict): patch = patch['path'] if patch_wl_regex.search(open(patch, 'r').read()): patch_found = True break if not patch_found: raise EasyBuildError( "Building numpy on top of Intel MKL requires a patch to " "handle -Wl linker flags correctly, which doesn't seem to be there." ) else: # unless Intel MKL is used, $ATLAS should be set to take full control, # and to make sure a fully optimized version is built, including _dotblas.so # which is critical for decent performance of the numpy.dot (matrix dot product) function! env.setvar('ATLAS', '1') lapack = ', '.join([ x for x in self.toolchain.get_variable('LIBLAPACK_MT', typ=list) if x != "pthread" ]) fft = ', '.join(self.toolchain.get_variable('LIBFFT', typ=list)) libs = ':'.join(self.toolchain.get_variable('LDFLAGS', typ=list)) includes = ':'.join(self.toolchain.get_variable('CPPFLAGS', typ=list)) # CBLAS is required for ACML, because it doesn't offer a C interface to BLAS if get_software_root('ACML'): cblasroot = get_software_root('CBLAS') if cblasroot: lapack = ', '.join([lapack, "cblas"]) cblaslib = os.path.join(cblasroot, 'lib') # with numpy as extension, CBLAS might not be included in LDFLAGS because it's not part of a toolchain if not cblaslib in libs: libs = ':'.join([libs, cblaslib]) else: raise EasyBuildError( "CBLAS is required next to ACML to provide a C interface to BLAS, " "but it's not loaded.") if fft: extrasiteconfig += "\n[fftw]\nlibraries = %s" % fft suitesparseroot = get_software_root('SuiteSparse') if suitesparseroot: amddir = os.path.join(suitesparseroot, 'AMD') umfpackdir = os.path.join(suitesparseroot, 'UMFPACK') if not os.path.exists(amddir) or not os.path.exists(umfpackdir): raise EasyBuildError( "Expected SuiteSparse subdirectories are not both there: %s, %s", amddir, umfpackdir) else: extrasiteconfig += '\n'.join([ "[amd]", "library_dirs = %s" % os.path.join(amddir, 'Lib'), "include_dirs = %s" % os.path.join(amddir, 'Include'), "amd_libs = amd", "[umfpack]", "library_dirs = %s" % os.path.join(umfpackdir, 'Lib'), "include_dirs = %s" % os.path.join(umfpackdir, 'Include'), "umfpack_libs = umfpack", ]) self.sitecfg = '\n'.join([self.sitecfg, extrasiteconfig]) self.sitecfg = self.sitecfg % { 'blas': blas, 'lapack': lapack, 'libs': libs, 'includes': includes, } super(EB_numpy, self).configure_step() # check configuration (for debugging purposes) cmd = "python setup.py config" run_cmd(cmd, log_all=True, simple=True)
def configure_step(self): """Run CMake for stage 1 Clang.""" self.llvm_obj_dir_stage1 = os.path.join(self.builddir, 'llvm.obj.1') if self.cfg['bootstrap']: self.llvm_obj_dir_stage2 = os.path.join(self.builddir, 'llvm.obj.2') self.llvm_obj_dir_stage3 = os.path.join(self.builddir, 'llvm.obj.3') if LooseVersion(self.version) >= LooseVersion('3.3'): disable_san_tests = False # all sanitizer tests will fail when there's a limit on the vmem # this is ugly but I haven't found a cleaner way so far (vmemlim, ec) = run_cmd("ulimit -v", regexp=False) if not vmemlim.startswith("unlimited"): disable_san_tests = True self.log.warn( "There is a virtual memory limit set of %s KB. The tests of the " "sanitizers will be disabled as they need unlimited virtual " "memory unless --strict=error is used." % vmemlim.strip()) # the same goes for unlimited stacksize (stacklim, ec) = run_cmd("ulimit -s", regexp=False) if stacklim.startswith("unlimited"): disable_san_tests = True self.log.warn( "The stacksize limit is set to unlimited. This causes the ThreadSanitizer " "to fail. The sanitizers tests will be disabled unless --strict=error is used." ) if (disable_san_tests or self.cfg['skip_sanitizer_tests'] ) and build_option('strict') != run.ERROR: self.log.debug("Disabling the sanitizer tests") self.disable_sanitizer_tests() # Create and enter build directory. mkdir(self.llvm_obj_dir_stage1) os.chdir(self.llvm_obj_dir_stage1) # GCC and Clang are installed in different prefixes and Clang will not # find the GCC installation on its own. # First try with GCCcore, as GCC built on top of GCCcore is just a wrapper for GCCcore and binutils, # instead of a full-fledge compiler gcc_prefix = get_software_root('GCCcore') # If that doesn't work, try with GCC if gcc_prefix is None: gcc_prefix = get_software_root('GCC') # If that doesn't work either, print error and exit if gcc_prefix is None: raise EasyBuildError("Can't find GCC or GCCcore to use") self.cfg.update('configopts', "-DGCC_INSTALL_PREFIX='%s' " % gcc_prefix) self.log.debug("Using %s as GCC_INSTALL_PREFIX", gcc_prefix) self.cfg['configopts'] += "-DCMAKE_BUILD_TYPE=Release " if self.cfg['assertions']: self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=ON " else: self.cfg['configopts'] += "-DLLVM_ENABLE_ASSERTIONS=OFF " self.cfg['configopts'] += '-DLLVM_TARGETS_TO_BUILD="%s" ' % ';'.join( self.cfg['build_targets']) if self.cfg['parallel']: self.make_parallel_opts = "-j %s" % self.cfg['parallel'] self.log.info("Configuring") super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir)
def configure_step(self): """Set CMake options for Blender""" default_config_opts = { 'WITH_BUILDINFO': 'OFF', # disable SSE detection to give EasyBuild full control over optimization compiler flags being used 'WITH_CPU_SSE': 'OFF', # needed unless extra dependencies are added for it to work 'WITH_GAMEENGINE': 'OFF', 'WITH_INSTALL_PORTABLE': 'OFF', # needed unless extra dependencies are added for it to work 'WITH_SYSTEM_GLEW': 'OFF', } for key in default_config_opts: opt = '-D%s=' % key if opt not in self.cfg['configopts']: self.cfg.update('configopts', opt + default_config_opts[key]) # Python paths python_root = get_software_root('Python') if python_root: shlib_ext = get_shared_lib_ext() pyshortver = '.'.join( get_software_version('Python').split('.')[:2]) site_packages = os.path.join(python_root, 'lib', 'python%s' % pyshortver, 'site-packages') # We assume that numpy/requests are included with the Python installation (no longer true for 2019a) numpy_root = find_glob_pattern( os.path.join(site_packages, 'numpy-*-py%s-linux-x86_64.egg' % pyshortver)) requests_root = find_glob_pattern( os.path.join(site_packages, 'requests-*-py%s.egg' % pyshortver)) python_lib = find_glob_pattern( os.path.join(python_root, 'lib', 'libpython%s*.%s' % (pyshortver, shlib_ext))) python_include_dir = find_glob_pattern( os.path.join(python_root, 'include', 'python%s*' % pyshortver)) self.cfg.update('configopts', '-DPYTHON_VERSION=%s' % pyshortver) self.cfg.update('configopts', '-DPYTHON_LIBRARY=%s' % python_lib) self.cfg.update('configopts', '-DPYTHON_INCLUDE_DIR=%s' % python_include_dir) self.cfg.update('configopts', '-DPYTHON_NUMPY_PATH=%s' % numpy_root) self.cfg.update('configopts', '-DPYTHON_REQUESTS_PATH=%s' % requests_root) # OpenEXR openexr_root = get_software_root('OpenEXR') if openexr_root: self.cfg.update( 'configopts', '-DOPENEXR_INCLUDE_DIR=%s' % os.path.join(openexr_root, 'include')) # OpenColorIO if get_software_root('OpenColorIO'): self.cfg.update('configopts', '-DWITH_OPENCOLORIO=ON') # CUDA if get_software_root('CUDA'): self.cfg.update('configopts', '-DWITH_CYCLES_CUDA_BINARIES=ON') super(EB_Blender, self).configure_step()
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)
class EB_imkl(IntelBase): """ Class that can be used to install mkl - tested with 10.2.1.017 -- will fail for all older versions (due to newer silent installer) """ @staticmethod def extra_options(): """Add easyconfig parameters custom to imkl (e.g. interfaces).""" extra_vars = { 'interfaces': [True, "Indicates whether interfaces should be built", CUSTOM], } return IntelBase.extra_options(extra_vars) def __init__(self, *args, **kwargs): super(EB_imkl, self).__init__(*args, **kwargs) # make sure $MKLROOT isn't set, it's known to cause problems with the installation self.cfg.update('unwanted_env_vars', ['MKLROOT']) def install_step(self): """ Actual installation - create silent cfg file - execute command """ silent_cfg_names_map = None silent_cfg_extras = None if LooseVersion(self.version) < LooseVersion('11.1'): # since imkl v11.1, silent.cfg has been slightly changed to be 'more standard' silent_cfg_names_map = { 'activation_name': ACTIVATION_NAME_2012, 'license_file_name': LICENSE_FILE_NAME_2012, } if LooseVersion(self.version) >= LooseVersion('11.1'): silent_cfg_extras = { 'COMPONENTS': 'ALL', } super(EB_imkl, self).install_step(silent_cfg_names_map=silent_cfg_names_map, silent_cfg_extras=silent_cfg_extras) def make_module_req_guess(self): """ A dictionary of possible directories to look for """ if LooseVersion(self.version) >= LooseVersion('10.3'): if self.cfg['m32']: raise EasyBuildError( "32-bit not supported yet for IMKL v%s (>= 10.3)", self.version) else: retdict = { 'PATH': [ 'bin', 'mkl/bin', 'mkl/bin/intel64', 'composerxe-2011/bin' ], 'LD_LIBRARY_PATH': ['lib/intel64', 'mkl/lib/intel64'], 'LIBRARY_PATH': ['lib/intel64', 'mkl/lib/intel64'], 'MANPATH': ['man', 'man/en_US'], 'CPATH': ['mkl/include', 'mkl/include/fftw'], 'FPATH': ['mkl/include', 'mkl/include/fftw'], } if LooseVersion(self.version) >= LooseVersion('11.0'): if LooseVersion(self.version) >= LooseVersion('11.1'): retdict['MIC_LD_LIBRARY_PATH'] = [ 'lib/mic', 'mkl/lib/mic' ] else: retdict['MIC_LD_LIBRARY_PATH'] = [ 'compiler/lib/mic', 'mkl/lib/mic' ] return retdict else: if self.cfg['m32']: return { 'PATH': ['bin', 'bin/ia32', 'tbb/bin/ia32'], 'LD_LIBRARY_PATH': ['lib', 'lib/32'], 'LIBRARY_PATH': ['lib', 'lib/32'], 'MANPATH': ['man', 'share/man', 'man/en_US'], 'CPATH': ['include'], 'FPATH': ['include'] } else: return { 'PATH': ['bin', 'bin/intel64', 'tbb/bin/em64t'], 'LD_LIBRARY_PATH': ['lib', 'lib/em64t'], 'LIBRARY_PATH': ['lib', 'lib/em64t'], 'MANPATH': ['man', 'share/man', 'man/en_US'], 'CPATH': ['include'], 'FPATH': ['include'], } def make_module_extra(self): """Overwritten from Application to add extra txt""" txt = super(EB_imkl, self).make_module_extra() txt += self.module_generator.prepend_paths(self.license_env_var, [self.license_file], allow_abs=True) if self.cfg['m32']: nlspath = os.path.join('idb', '32', 'locale', '%l_%t', '%N') else: nlspath = os.path.join('idb', 'intel64', 'locale', '%l_%t', '%N') txt += self.module_generator.prepend_paths('NLSPATH', nlspath) txt += self.module_generator.set_environment( 'MKLROOT', os.path.join(self.installdir, 'mkl')) return txt def post_install_step(self): """ Install group libraries and interfaces (if desired). """ # reload the dependencies self.load_dependency_modules() if self.cfg['m32']: extra = { 'libmkl.so': 'GROUP (-lmkl_intel -lmkl_intel_thread -lmkl_core)', 'libmkl_em64t.a': 'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)', 'libmkl_solver.a': 'GROUP (libmkl_solver.a)', 'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_core.a)', 'libmkl_lapack.a': 'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)', 'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)' } else: extra = { 'libmkl.so': 'GROUP (-lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core)', 'libmkl_em64t.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)', 'libmkl_solver.a': 'GROUP (libmkl_solver_lp64.a)', 'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_lp64.a)', 'libmkl_lapack.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)', 'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)' } if LooseVersion(self.version) >= LooseVersion('10.3'): libsubdir = os.path.join('mkl', 'lib', 'intel64') else: if self.cfg['m32']: libsubdir = os.path.join('lib', '32') else: libsubdir = os.path.join('lib', 'em64t') for fil, txt in extra.items(): dest = os.path.join(self.installdir, libsubdir, fil) if not os.path.exists(dest): try: f = open(dest, 'w') f.write(txt) f.close() self.log.info("File %s written" % dest) except IOError, err: raise EasyBuildError("Can't write file %s: %s", dest, err) # build the mkl interfaces, if desired if self.cfg['interfaces']: if LooseVersion(self.version) >= LooseVersion('10.3'): intsubdir = os.path.join('mkl', 'interfaces') inttarget = 'libintel64' else: intsubdir = 'interfaces' if self.cfg['m32']: inttarget = 'lib32' else: inttarget = 'libem64t' cmd = "make -f makefile %s" % inttarget # blas95 and lapack95 need more work, ignore for now # blas95 and lapack also need include/.mod to be processed fftw2libs = ['fftw2xc', 'fftw2xf'] fftw3libs = ['fftw3xc', 'fftw3xf'] cdftlibs = ['fftw2x_cdft'] if LooseVersion(self.version) >= LooseVersion('10.3'): cdftlibs.append('fftw3x_cdft') interfacedir = os.path.join(self.installdir, intsubdir) try: os.chdir(interfacedir) self.log.info("Changed to interfaces directory %s" % interfacedir) except OSError, err: raise EasyBuildError("Can't change to interfaces directory %s", interfacedir) compopt = None # determine whether we're using a non-Intel GCC-based toolchain # can't use toolchain.comp_family, because of dummy toolchain used when installing imkl if get_software_root('icc') is None: if get_software_root('GCC'): compopt = 'compiler=gnu' else: raise EasyBuildError( "Not using either Intel compilers nor GCC, " "don't know how to build wrapper libs") else: compopt = 'compiler=intel' for lib in fftw2libs + fftw3libs + cdftlibs: buildopts = [compopt] if lib in fftw3libs: buildopts.append('install_to=$INSTALL_DIR') elif lib in cdftlibs: mpi_spec = None # check whether MPI_FAMILY constant is defined, so mpi_family() can be used if hasattr(self.toolchain, 'MPI_FAMILY' ) and self.toolchain.MPI_FAMILY is not None: mpi_spec_by_fam = { toolchain.MPICH: 'mpich2', # MPICH is MPICH v3.x, which is MPICH2 compatible toolchain.MPICH2: 'mpich2', toolchain.MVAPICH2: 'mpich2', toolchain.OPENMPI: 'openmpi', } mpi_fam = self.toolchain.mpi_family() mpi_spec = mpi_spec_by_fam.get(mpi_fam) self.log.debug( "Determined MPI specification based on MPI toolchain component: %s" % mpi_spec) else: # can't use toolchain.mpi_family, because of dummy toolchain if get_software_root('MPICH2') or get_software_root( 'MVAPICH2'): mpi_spec = 'mpich2' elif get_software_root('OpenMPI'): mpi_spec = 'openmpi' self.log.debug( "Determined MPI specification based on loaded MPI module: %s" % mpi_spec) if mpi_spec is not None: buildopts.append('mpi=%s' % mpi_spec) precflags = [''] if lib.startswith('fftw2x') and not self.cfg['m32']: # build both single and double precision variants precflags = [ 'PRECISION=MKL_DOUBLE', 'PRECISION=MKL_SINGLE' ] intflags = [''] if lib in cdftlibs and not self.cfg['m32']: # build both 32-bit and 64-bit interfaces intflags = ['interface=lp64', 'interface=ilp64'] allopts = [ list(opts) for opts in itertools.product(intflags, precflags) ] for flags, extraopts in itertools.product(['', '-fPIC'], allopts): tup = (lib, flags, buildopts, extraopts) self.log.debug( "Building lib %s with: flags %s, buildopts %s, extraopts %s" % tup) tmpbuild = tempfile.mkdtemp(dir=self.builddir) self.log.debug("Created temporary directory %s" % tmpbuild) # always set INSTALL_DIR, SPEC_OPT, COPTS and CFLAGS # fftw2x(c|f): use $INSTALL_DIR, $CFLAGS and $COPTS # fftw3x(c|f): use $CFLAGS # fftw*cdft: use $INSTALL_DIR and $SPEC_OPT env.setvar('INSTALL_DIR', tmpbuild) env.setvar('SPEC_OPT', flags) env.setvar('COPTS', flags) env.setvar('CFLAGS', flags) try: intdir = os.path.join(interfacedir, lib) os.chdir(intdir) self.log.info("Changed to interface %s directory %s" % (lib, intdir)) except OSError, err: raise EasyBuildError( "Can't change to interface %s directory %s: %s", lib, intdir, err) fullcmd = "%s %s" % (cmd, ' '.join(buildopts + extraopts)) res = run_cmd(fullcmd, log_all=True, simple=True) if not res: raise EasyBuildError( "Building %s (flags: %s, fullcmd: %s) failed", lib, flags, fullcmd) for fn in os.listdir(tmpbuild): src = os.path.join(tmpbuild, fn) if flags == '-fPIC': # add _pic to filename ff = fn.split('.') fn = '.'.join(ff[:-1]) + '_pic.' + ff[-1] dest = os.path.join(self.installdir, libsubdir, fn) try: if os.path.isfile(src): shutil.move(src, dest) self.log.info("Moved %s to %s" % (src, dest)) except OSError, err: raise EasyBuildError("Failed to move %s to %s: %s", src, dest, err) rmtree2(tmpbuild)
def configure_step(self): """Custom configuration procedure for Quantum ESPRESSO.""" if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: self.cfg.update('configopts', '--enable-openmp') if not self.toolchain.options.get('usempi', None): self.cfg.update('configopts', '--disable-parallel') if not self.cfg['with_scalapack']: self.cfg.update('configopts', '--without-scalapack') repls = [] if self.toolchain.comp_family() in [toolchain.INTELCOMP]: # set preprocessor command (-E to stop after preprocessing, -C to preserve comments) cpp = "%s -E -C" % os.getenv('CC') repls.append(('CPP', cpp, False)) env.setvar('CPP', cpp) # also define $FCCPP, but do *not* include -C (comments should not be preserved when preprocessing Fortran) env.setvar('FCCPP', "%s -E" % os.getenv('CC')) super(EB_QuantumESPRESSO, self).configure_step() # compose list of DFLAGS (flag, value, keep_stuff) # for guidelines, see include/defs.h.README in sources dflags = [] comp_fam_dflags = { toolchain.INTELCOMP: '-D__INTEL', toolchain.GCC: '-D__GFORTRAN -D__STD_F95', } dflags.append(comp_fam_dflags[self.toolchain.comp_family()]) if self.toolchain.options.get('openmp', False): libfft = os.getenv('LIBFFT_MT') else: libfft = os.getenv('LIBFFT') if libfft: if "fftw3" in libfft: dflags.append('-D__FFTW3') else: dflags.append('-D__FFTW') env.setvar('FFTW_LIBS', libfft) if get_software_root('ACML'): dflags.append('-D__ACML') if self.toolchain.options.get('usempi', None): dflags.append('-D__MPI -D__PARA') if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: dflags.append(" -D__OPENMP") if self.cfg['with_scalapack']: dflags.append(" -D__SCALAPACK") # always include -w to supress warnings dflags.append('-w') repls.append(('DFLAGS', ' '.join(dflags), False)) # complete C/Fortran compiler and LD flags if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: repls.append(('LDFLAGS', self.toolchain.get_flag('openmp'), True)) repls.append( ('(?:C|F90|F)FLAGS', self.toolchain.get_flag('openmp'), True)) # obtain library settings libs = [] for lib in ['BLAS', 'LAPACK', 'FFT', 'SCALAPACK']: if self.toolchain.options.get('openmp', False): val = os.getenv('LIB%s_MT' % lib) else: val = os.getenv('LIB%s' % lib) repls.append(('%s_LIBS' % lib, val, False)) libs.append(val) libs = ' '.join(libs) repls.append(('BLAS_LIBS_SWITCH', 'external', False)) repls.append(('LAPACK_LIBS_SWITCH', 'external', False)) repls.append(('LD_LIBS', os.getenv('LIBS'), False)) self.log.debug("List of replacements to perform: %s" % repls) if LooseVersion(self.version) >= LooseVersion("6"): make_ext = '.inc' else: make_ext = '.sys' # patch make.sys file fn = os.path.join(self.cfg['start_dir'], 'make' + make_ext) try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): for (k, v, keep) in repls: # need to use [ \t]* instead of \s*, because vars may be undefined as empty, # and we don't want to include newlines if keep: line = re.sub(r"^(%s\s*=[ \t]*)(.*)$" % k, r"\1\2 %s" % v, line) else: line = re.sub(r"^(%s\s*=[ \t]*).*$" % k, r"\1%s" % v, line) # fix preprocessing directives for .f90 files in make.sys if required if self.toolchain.comp_family() in [toolchain.GCC]: line = re.sub( r"\$\(MPIF90\) \$\(F90FLAGS\) -c \$<", "$(CPP) -C $(CPPFLAGS) $< -o $*.F90\n" + "\t$(MPIF90) $(F90FLAGS) -c $*.F90 -o $*.o", line) sys.stdout.write(line) except IOError, err: raise EasyBuildError("Failed to patch %s: %s", fn, err)
def is_double_precision_cuda_build(self): """Check if the current build step involves double precision and CUDA""" cuda = get_software_root('CUDA') return cuda and self.double_prec_pattern in self.cfg['configopts']
def configure_step(self): """ Configure VMD for building. """ # make sure required dependencies are available deps = {} for dep in ['FLTK', 'Mesa', 'Tcl', 'Tk']: deps[dep] = get_software_root(dep) if deps[dep] is None: raise EasyBuildError("Required dependency %s is missing", dep) # optional dependencies for dep in ['ACTC', 'CUDA', 'OptiX', 'Python', 'netCDF']: deps[dep] = get_software_root(dep) # specify Tcl/Tk locations & libraries tclinc = os.path.join(deps['Tcl'], 'include') tcllib = os.path.join(deps['Tcl'], 'lib') env.setvar('TCL_INCLUDE_DIR', tclinc) env.setvar('TCL_LIBRARY_DIR', tcllib) env.setvar('TK_INCLUDE_DIR', os.path.join(deps['Tk'], 'include')) env.setvar('TK_LIBRARY_DIR', os.path.join(deps['Tk'], 'lib')) tclshortver = '.'.join(get_software_version('Tcl').split('.')[:2]) self.cfg.update('buildopts', 'TCLLDFLAGS="-ltcl%s"' % tclshortver) # Netcdf locations, in theory an optional component, however some of the plugins require it. if deps['netCDF']: netcdfinc = os.path.join(deps['netCDF'], 'include') netcdflib = os.path.join(deps['netCDF'], 'lib') netcdfopt = ' '.join([ "NETCDFINC='-I%s'" % netcdfinc, "NETCDFLIB='-L%s'" % netcdflib, ]) else: netcdfopt = '' # Change the following code once we find how to build without netCDF. raise EasyBuildError( "Even though the VMD manual mentions netCDF as an optional component, it is currently required for building the plugins which this VMD EasyBlock always does." ) # Python locations if deps['Python']: pyshortver = '.'.join( get_software_version('Python').split('.')[:2]) pyvermajor = get_software_version('Python').split('.')[0] if pyvermajor == '2': env.setvar( 'PYTHON_INCLUDE_DIR', os.path.join(deps['Python'], 'include/python%s' % pyshortver)) else: env.setvar( 'PYTHON_INCLUDE_DIR', os.path.join(deps['Python'], 'include/python%sm' % pyshortver)) pylibdir = det_pylibdir() python_libdir = os.path.join(deps['Python'], os.path.dirname(pylibdir)) env.setvar('PYTHON_LIBRARY_DIR', python_libdir) # numpy include location, easiest way to determine it is via numpy.get_include() out, ec = run_cmd( "python -c 'import numpy; print( numpy.get_include() )'", simple=False) if ec: raise EasyBuildError( "NumPy support expected when using Python, but failed to determine NumPy include directory: %s", out) else: env.setvar('NUMPY_INCLUDE_DIR', out.strip()) # compiler commands self.cfg.update('buildopts', 'CC="%s"' % os.getenv('CC')) self.cfg.update('buildopts', 'CCPP="%s"' % os.getenv('CXX')) # plugins need to be built first (see http://www.ks.uiuc.edu/Research/vmd/doxygen/compiling.html) change_dir(os.path.join(self.builddir, 'plugins')) cmd = ' '.join([ 'make', self.cfg.get('vmd_arch'), "TCLINC='-I%s'" % tclinc, "TCLLIB='-L%s'" % tcllib, "TCLLDFLAGS='-ltcl%s'" % tclshortver, netcdfopt, self.cfg['buildopts'], ]) run_cmd(cmd, log_all=True, simple=False) # create plugins distribution plugindir = os.path.join(self.vmddir, 'plugins') env.setvar('PLUGINDIR', plugindir) self.log.info("Generating VMD plugins in %s", plugindir) run_cmd("make distrib %s" % self.cfg['buildopts'], log_all=True, simple=False) # explicitely mention whether or not we're building with CUDA/OptiX support if deps['CUDA']: self.log.info("Building with CUDA %s support", get_software_version('CUDA')) if deps['OptiX']: self.log.info("Building with Nvidia OptiX %s support", get_software_version('OptiX')) else: self.log.warn("Not building with Nvidia OptiX support!") else: self.log.warn("Not building with CUDA nor OptiX support!") # see http://www.ks.uiuc.edu/Research/vmd/doxygen/configure.html # LINUXAMD64: Linux 64-bit # LP64: build VMD as 64-bit binary # IMD: enable support for Interactive Molecular Dynamics (e.g. to connect to NAMD for remote simulations) # PTHREADS: enable support for POSIX threads # COLVARS: enable support for collective variables (related to NAMD/LAMMPS) # NOSILENT: verbose build command self.cfg.update('configopts', self.cfg.get('vmd_arch') + " LP64 IMD PTHREADS COLVARS NOSILENT " + self.cfg.get('vmd_extra_opts'), allow_duplicate=False) # add additional configopts based on available dependencies for key in deps: if deps[key]: if key == 'Mesa': self.cfg.update('configopts', "OPENGL MESA", allow_duplicate=False) elif key == 'OptiX': self.cfg.update('configopts', "LIBOPTIX", allow_duplicate=False) elif key == 'Python': self.cfg.update('configopts', "PYTHON NUMPY", allow_duplicate=False) else: self.cfg.update('configopts', key.upper(), allow_duplicate=False) # configure for building with Intel compilers specifically if self.toolchain.comp_family() == toolchain.INTELCOMP: self.cfg.update('configopts', 'ICC', allow_duplicate=False) # specify install location using environment variables env.setvar('VMDINSTALLBINDIR', os.path.join(self.installdir, 'bin')) env.setvar('VMDINSTALLLIBRARYDIR', os.path.join(self.installdir, 'lib')) # configure in vmd-<version> directory change_dir(self.vmddir) run_cmd("%s ./configure %s" % (self.cfg['preconfigopts'], self.cfg['configopts'])) # change to 'src' subdirectory, ready for building change_dir(os.path.join(self.vmddir, 'src'))
def configure_common(self): """Common configuration for all toolchains""" # openmp introduces 2 major differences # -automatic is default: -noautomatic -auto-scalar # some mem-bandwidth optimisation if self.cfg['type'] == 'psmp': self.openmp = self.toolchain.get_flag('openmp') # determine which opt flags to use if self.cfg['typeopt']: optflags = 'OPT' regflags = 'OPT2' else: optflags = 'NOOPT' regflags = 'NOOPT' # make sure a MPI-2 able MPI lib is used mpi2 = False if hasattr(self.toolchain, 'MPI_FAMILY') and self.toolchain.MPI_FAMILY is not None: known_mpi2_fams = [ toolchain.MPICH, toolchain.MPICH2, toolchain.MVAPICH2, toolchain.OPENMPI, toolchain.INTELMPI ] mpi_fam = self.toolchain.mpi_family() if mpi_fam in known_mpi2_fams: mpi2 = True self.log.debug( "Determined MPI2 compatibility based on MPI toolchain component: %s" % mpi_fam) else: self.log.debug( "Cannot determine MPI2 compatibility based on MPI toolchain component: %s" % mpi_fam) else: # can't use toolchain.mpi_family, because of system toolchain mpi2libs = ['impi', 'MVAPICH2', 'OpenMPI', 'MPICH2', 'MPICH'] for mpi2lib in mpi2libs: if get_software_root(mpi2lib): mpi2 = True self.log.debug( "Determined MPI2 compatibility based on loaded MPI module: %s" ) else: self.log.debug( "MPI-2 supporting MPI library %s not loaded.") if not mpi2: raise EasyBuildError( "CP2K needs MPI-2, no known MPI-2 supporting library loaded?") cppflags = os.getenv('CPPFLAGS') ldflags = os.getenv('LDFLAGS') cflags = os.getenv('CFLAGS') fflags = os.getenv('FFLAGS') fflags_lowopt = re.sub('-O[0-9]', '-O1', fflags) options = { 'CC': os.getenv('MPICC'), 'CPP': '', 'FC': '%s %s' % (os.getenv('MPIF90'), self.openmp), 'LD': '%s %s' % (os.getenv('MPIF90'), self.openmp), 'AR': 'ar -r', 'CPPFLAGS': '', 'FPIC': self.fpic, 'DEBUG': self.debug, 'FCFLAGS': '$(FCFLAGS%s)' % optflags, 'FCFLAGS2': '$(FCFLAGS%s)' % regflags, 'CFLAGS': ' %s %s %s $(FPIC) $(DEBUG) %s ' % (cflags, cppflags, ldflags, self.cfg['extracflags']), 'DFLAGS': ' -D__parallel -D__BLACS -D__SCALAPACK -D__FFTSG %s' % self.cfg['extradflags'], 'LIBS': os.getenv('LIBS', ''), 'FCFLAGSNOOPT': '$(DFLAGS) $(CFLAGS) -O0 $(FREE) $(FPIC) $(DEBUG)', 'FCFLAGSOPT': '%s $(FREE) $(SAFE) $(FPIC) $(DEBUG)' % fflags, 'FCFLAGSOPT2': '%s $(FREE) $(SAFE) $(FPIC) $(DEBUG)' % fflags_lowopt, } libint = get_software_root('LibInt') if libint: options['DFLAGS'] += ' -D__LIBINT' libintcompiler = "%s %s" % (os.getenv('CC'), os.getenv('CFLAGS')) # Build libint-wrapper, if required libint_wrapper = '' # required for old versions of GCC if not self.compilerISO_C_BINDING: options['DFLAGS'] += ' -D__HAS_NO_ISO_C_BINDING' # determine path for libint_tools dir libinttools_paths = [ 'libint_tools', 'tools/hfx_tools/libint_tools' ] libinttools_path = None for path in libinttools_paths: path = os.path.join(self.cfg['start_dir'], path) if os.path.isdir(path): libinttools_path = path change_dir(libinttools_path) if not libinttools_path: raise EasyBuildError("No libinttools dir found") # build libint wrapper cmd = "%s -c libint_cpp_wrapper.cpp -I%s/include" % ( libintcompiler, libint) if not run_cmd(cmd, log_all=True, simple=True): raise EasyBuildError("Building the libint wrapper failed") libint_wrapper = '%s/libint_cpp_wrapper.o' % libinttools_path # determine Libint libraries based on major version number libint_maj_ver = get_software_version('Libint').split('.')[0] if libint_maj_ver == '1': libint_libs = "$(LIBINTLIB)/libderiv.a $(LIBINTLIB)/libint.a $(LIBINTLIB)/libr12.a" elif libint_maj_ver == '2': libint_libs = "$(LIBINTLIB)/libint2.a" else: raise EasyBuildError( "Don't know how to handle libint version %s", libint_maj_ver) self.log.info("Using Libint version %s" % (libint_maj_ver)) options['LIBINTLIB'] = '%s/lib' % libint options['LIBS'] += ' %s -lstdc++ %s' % (libint_libs, libint_wrapper) # add Libint include dir to $FCFLAGS options['FCFLAGS'] += ' -I' + os.path.join(libint, 'include') else: # throw a warning, since CP2K without Libint doesn't make much sense self.log.warning( "Libint module not loaded, so building without Libint support") libxc = get_software_root('libxc') if libxc: cur_libxc_version = get_software_version('libxc') if LooseVersion(self.version) >= LooseVersion('6.1'): libxc_min_version = '4.0.3' options['DFLAGS'] += ' -D__LIBXC' else: libxc_min_version = '2.0.1' options['DFLAGS'] += ' -D__LIBXC2' if LooseVersion(cur_libxc_version) < LooseVersion( libxc_min_version): raise EasyBuildError( "This version of CP2K is not compatible with libxc < %s" % libxc_min_version) if LooseVersion(cur_libxc_version) >= LooseVersion('4.0.3'): # cfr. https://www.cp2k.org/howto:compile#k_libxc_optional_wider_choice_of_xc_functionals options['LIBS'] += ' -L%s/lib -lxcf03 -lxc' % libxc elif LooseVersion(cur_libxc_version) >= LooseVersion('2.2'): options['LIBS'] += ' -L%s/lib -lxcf90 -lxc' % libxc else: options['LIBS'] += ' -L%s/lib -lxc' % libxc self.log.info("Using Libxc-%s" % cur_libxc_version) else: self.log.info( "libxc module not loaded, so building without libxc support") return options
def configure_step(self): """Configure Ferret build.""" buildtype = "x86_64-linux" if LooseVersion(self.version) < LooseVersion("7.3"): change_dir('FERRET') deps = ['HDF5', 'netCDF', 'Java'] for name in deps: if not get_software_root(name): raise EasyBuildError("%s module not loaded?", name) if LooseVersion(self.version) >= LooseVersion("7.3"): copy_file('external_functions/ef_utility/site_specific.mk.in', 'external_functions/ef_utility/site_specific.mk') copy_file('site_specific.mk.in', 'site_specific.mk') fns = [ "site_specific.mk", "external_functions/ef_utility/site_specific.mk", ] else: fns = ["site_specific.mk"] regex_subs = [ (r"^BUILDTYPE\s*=.*", "BUILDTYPE = %s" % buildtype), (r"^INSTALL_FER_DIR =.*", "INSTALL_FER_DIR = %s" % self.installdir), ] for name in deps: regex_subs.append((r"^(%s.*DIR\s*)=.*" % name.upper(), r"\1 = %s" % get_software_root(name))) if LooseVersion(self.version) >= LooseVersion("7.3"): regex_subs.extend([ (r"^DIR_PREFIX =.*", "DIR_PREFIX = %s" % self.cfg['start_dir']), (r"^FER_LOCAL_EXTFCNS = $(FER_DIR)", "FER_LOCAL_EXTFCNS = $(INSTALL_FER_DIR)/libs"), ]) for fn in fns: apply_regex_substitutions(fn, regex_subs) comp_vars = { 'CC': 'CC', 'CFLAGS': 'CFLAGS', 'CPPFLAGS': 'CPPFLAGS', 'FC': 'F77', } gfort2ifort = { '-fno-second-underscore': ' ', '-fno-backslash': ' ', '-fdollar-ok': ' ', '-ffast-math': ' ', '-ffixed-line-length-132': '-132', '-fno-automatic': ' ', '-ffpe-trap=overflow': ' ', '-fimplicit-none': '-implicitnone', '-fdefault-real-8': '-r8', '-fdefault-double-8': ' ', '-Wl,-Bstatic -lgfortran -Wl,-Bdynamic': ' ', '-v --verbose -m64': ' ', '-export-dynamic': ' ', '-DG77_SIGNAL': ' ', } fn = 'xgks/CUSTOMIZE.%s' % buildtype regex_subs = [(r"^(FFLAGS\s*=').*-m64 (.*)", r"\1%s \2" % os.getenv('FFLAGS'))] for x, y in comp_vars.items(): regex_subs.append((r"^(%s\s*)=.*" % x, r"\1='%s'" % os.getenv(y))) x11_root = get_software_root('X11') if x11_root: regex_subs.append( (r"^(LD_X11\s*)=.*", r"\1='-L%s/lib -lX11'" % x11_root)) else: regex_subs.append( (r"^(LD_X11\s*)=.*", r"\1='-L/usr/lib64/X11 -lX11'")) if LooseVersion(self.version) >= LooseVersion( "7.3") and self.toolchain.comp_family() == toolchain.INTELCOMP: regex_subs.extend(sorted(gfort2ifort.items())) apply_regex_substitutions(fn, regex_subs) comp_vars = { 'CC': 'CC', 'CXX': 'CXX', 'F77': 'F77', 'FC': 'F77', } if LooseVersion(self.version) >= LooseVersion("7.3"): fns = [ 'platform_specific.mk.%s' % buildtype, 'external_functions/ef_utility/platform_specific.mk.%s' % buildtype, ] else: fns = [ 'fer/platform_specific_flags.mk.%s' % buildtype, 'ppl/platform_specific_flags.mk.%s' % buildtype, 'external_functions/ef_utility/platform_specific_flags.mk.%s' % buildtype, ] regex_subs = [] for x, y in comp_vars.items(): regex_subs.append( (r"^(\s*%s\s*)=.*" % x, r"\1 = %s" % os.getenv(y))) if LooseVersion(self.version) >= LooseVersion("7.3"): regex_subs.extend([ (r"^(\s*LDFLAGS\s*=).*", r"\1 -fPIC %s -lnetcdff -lnetcdf -lhdf5_hl -lhdf5" % os.getenv("LDFLAGS")), (r"^(\s*)CDFLIB", r"\1NONEED"), ]) if self.toolchain.comp_family() == toolchain.INTELCOMP: regex_subs.append( (r"^(\s*LD\s*)=.*", r"\1 = %s -nofor-main" % os.getenv("F77"))) for x in ["CFLAGS", "FFLAGS"]: regex_subs.append((r"^(\s*%s\s*=\s*\$\(CPP_FLAGS\)).*\\" % x, r"\1 %s \\" % os.getenv(x))) if LooseVersion(self.version) >= LooseVersion("7.3"): for x in ["CFLAGS", "FFLAGS"]: regex_subs.append((r"^(\s*%s\s*=).*-m64 (.*)" % x, r"\1%s \2" % os.getenv(x))) regex_subs.extend(sorted(gfort2ifort.items())) regex_subs.append((r"^(\s*MYDEFINES\s*=.*)\\", r"\1-DF90_SYSTEM_ERROR_CALLS \\")) for fn in fns: apply_regex_substitutions(fn, regex_subs) if LooseVersion(self.version) >= LooseVersion("7.3"): comp_vars = { 'CC': 'CC', 'LDFLAGS': 'LDFLAGS', } fn = 'gksm2ps/Makefile' regex_subs = [(r"^(\s*CFLAGS=\")-m64 (.*)", r"\1%s \2" % os.getenv('CFLAGS'))] for x, y in comp_vars.items(): regex_subs.append( (r"^(\s*%s)=.*" % x, r"\1='%s' \\" % os.getenv(y))) apply_regex_substitutions(fn, regex_subs)
def configure_step(self, srcdir=None, builddir=None): """Configure build using cmake""" setup_cmake_env(self.toolchain) if builddir is None and self.cfg.get('separate_build_dir', True): builddir = os.path.join(self.builddir, 'easybuild_obj') # For separate_build_dir we want a clean folder. So remove if it exists # This can happen when multiple iterations are done (e.g. shared, static, ...) if os.path.exists(builddir): self.log.warning( 'Build directory %s already exists (from previous iterations?). Removing...', builddir) remove_dir(builddir) if builddir: mkdir(builddir, parents=True) change_dir(builddir) default_srcdir = self.cfg['start_dir'] else: default_srcdir = '.' if srcdir is None: if self.cfg.get('srcdir', None) is not None: # Note that the join returns srcdir if it is absolute srcdir = os.path.join(default_srcdir, self.cfg['srcdir']) else: srcdir = default_srcdir options = ['-DCMAKE_INSTALL_PREFIX=%s' % self.installdir] if '-DCMAKE_BUILD_TYPE=' in self.cfg['configopts']: if self.cfg.get('build_type') is not None: self.log.warning( 'CMAKE_BUILD_TYPE is set in configopts. Ignoring build_type' ) else: options.append('-DCMAKE_BUILD_TYPE=%s' % self.build_type) # Add -fPIC flag if necessary if self.toolchain.options['pic']: options.append('-DCMAKE_POSITION_INDEPENDENT_CODE=ON') # Set flag for shared libs if requested # Not adding one allows the project to choose a default build_shared_libs = self.cfg.get('build_shared_libs') if build_shared_libs is not None: # Contrary to other options build_shared_libs takes precedence over configopts which may be unexpected. # This is to allow self.lib_ext to be determined correctly. # Usually you want to remove -DBUILD_SHARED_LIBS from configopts and set build_shared_libs to True or False # If you need it in configopts don't set build_shared_libs (or explicitely set it to `None` (Default)) if '-DBUILD_SHARED_LIBS=' in self.cfg['configopts']: print_warning( 'Ignoring BUILD_SHARED_LIBS is set in configopts because build_shared_libs is set' ) self.cfg.update( 'configopts', '-DBUILD_SHARED_LIBS=%s' % ('ON' if build_shared_libs else 'OFF')) env_to_options = { 'CC': 'CMAKE_C_COMPILER', 'CFLAGS': 'CMAKE_C_FLAGS', 'CXX': 'CMAKE_CXX_COMPILER', 'CXXFLAGS': 'CMAKE_CXX_FLAGS', 'F90': 'CMAKE_Fortran_COMPILER', 'FFLAGS': 'CMAKE_Fortran_FLAGS', } for env_name, option in env_to_options.items(): value = os.getenv(env_name) if value is not None: if option.endswith('_COMPILER') and self.cfg.get( 'abs_path_compilers', False): value = which(value) self.log.info( "Using absolute path to compiler command: %s", value) options.append("-D%s='%s'" % (option, value)) if build_option('rpath'): # instruct CMake not to fiddle with RPATH when --rpath is used, since it will undo stuff on install... # https://github.com/LLNL/spack/blob/0f6a5cd38538e8969d11bd2167f11060b1f53b43/lib/spack/spack/build_environment.py#L416 options.append('-DCMAKE_SKIP_RPATH=ON') # show what CMake is doing by default options.append('-DCMAKE_VERBOSE_MAKEFILE=ON') if not self.cfg.get('allow_system_boost', False): # don't pick up on system Boost if Boost is included as dependency # - specify Boost location via -DBOOST_ROOT # - instruct CMake to not search for Boost headers/libraries in other places # - disable search for Boost CMake package configuration file boost_root = get_software_root('Boost') if boost_root: options.extend([ '-DBOOST_ROOT=%s' % boost_root, '-DBoost_NO_SYSTEM_PATHS=ON', '-DBoost_NO_BOOST_CMAKE=ON', ]) options_string = ' '.join(options) if self.cfg.get('configure_cmd') == DEFAULT_CONFIGURE_CMD: command = ' '.join([ self.cfg['preconfigopts'], DEFAULT_CONFIGURE_CMD, options_string, self.cfg['configopts'], srcdir ]) else: command = ' '.join([ self.cfg['preconfigopts'], self.cfg.get('configure_cmd'), self.cfg['configopts'] ]) (out, _) = run_cmd(command, log_all=True, simple=False) return out
def configure_step(self): """Configure build: - set required environment variables (for netCDF, JasPer) - patch compile script and ungrib Makefile for non-default install paths of WRF and JasPer - run configure script and figure how to select desired build option - patch configure.wps file afterwards to fix 'serial compiler' setting """ # netCDF dependency check + setting env vars (NETCDF, NETCDFF) set_netcdf_env_vars(self.log) # WRF dependency check wrf = get_software_root('WRF') if wrf: wrfdir = os.path.join(wrf, det_wrf_subdir(get_software_version('WRF'))) else: raise EasyBuildError("WRF module not loaded?") self.compile_script = 'compile' if LooseVersion(self.version) >= LooseVersion('4.0.3'): # specify install location of WRF via $WRF_DIR (supported since WPS 4.0.3) # see https://github.com/wrf-model/WPS/pull/102 env.setvar('WRF_DIR', wrfdir) else: # patch compile script so that WRF is found regex_subs = [(r"^(\s*set\s*WRF_DIR_PRE\s*=\s*)\${DEV_TOP}(.*)$", r"\1%s\2" % wrfdir)] apply_regex_substitutions(self.compile_script, regex_subs) # libpng dependency check libpng = get_software_root('libpng') zlib = get_software_root('zlib') if libpng: paths = [libpng] if zlib: paths.insert(0, zlib) libpnginc = ' '.join( ['-I%s' % os.path.join(path, 'include') for path in paths]) libpnglib = ' '.join( ['-L%s' % os.path.join(path, 'lib') for path in paths]) else: # define these as empty, assume that libpng will be available via OS (e.g. due to --filter-deps=libpng) libpnglib = "" libpnginc = "" # JasPer dependency check + setting env vars jasper = get_software_root('JasPer') if jasper: env.setvar('JASPERINC', os.path.join(jasper, "include")) jasperlibdir = os.path.join(jasper, "lib") env.setvar('JASPERLIB', jasperlibdir) jasperlib = "-L%s" % jasperlibdir else: raise EasyBuildError("JasPer module not loaded?") # patch ungrib Makefile so that JasPer is found jasperlibs = "%s -ljasper %s -lpng" % (jasperlib, libpnglib) regex_subs = [ (r"^(\s*-L\.\s*-l\$\(LIBTARGET\))(\s*;.*)$", r"\1 %s\2" % jasperlibs), (r"^(\s*\$\(COMPRESSION_LIBS\))(\s*;.*)$", r"\1 %s\2" % jasperlibs), ] apply_regex_substitutions(os.path.join('ungrib', 'src', 'Makefile'), regex_subs) # patch arch/Config.pl script, so that run_cmd_qa receives all output to answer questions patch_perl_script_autoflush(os.path.join("arch", "Config.pl")) # configure # determine build type option to look for self.comp_fam = self.toolchain.comp_family() build_type_option = None if LooseVersion(self.version) >= LooseVersion("3.4"): knownbuildtypes = {'smpar': 'serial', 'dmpar': 'dmpar'} if self.comp_fam == toolchain.INTELCOMP: # @UndefinedVariable build_type_option = " Linux x86_64, Intel compiler" elif self.comp_fam == toolchain.GCC: # @UndefinedVariable if LooseVersion(self.version) >= LooseVersion("3.6"): build_type_option = "Linux x86_64, gfortran" else: build_type_option = "Linux x86_64 g95" else: raise EasyBuildError( "Don't know how to figure out build type to select.") else: knownbuildtypes = {'smpar': 'serial', 'dmpar': 'DM parallel'} if self.comp_fam == toolchain.INTELCOMP: # @UndefinedVariable build_type_option = "PC Linux x86_64, Intel compiler" elif self.comp_fam == toolchain.GCC: # @UndefinedVariable build_type_option = "PC Linux x86_64, gfortran compiler," knownbuildtypes['dmpar'] = knownbuildtypes['dmpar'].upper() else: raise EasyBuildError( "Don't know how to figure out build type to select.") # check and fetch selected build type bt = self.cfg['buildtype'] if bt not in knownbuildtypes.keys(): raise EasyBuildError( "Unknown build type: '%s'. Supported build types: %s", bt, knownbuildtypes.keys()) # fetch option number based on build type option and selected build type build_type_question = r"\s*(?P<nr>[0-9]+).\s*%s\s*\(?%s\)?\s*\n" % ( build_type_option, knownbuildtypes[bt]) cmd = ' '.join( [self.cfg['preconfigopts'], './configure', self.cfg['configopts']]) qa = {} no_qa = [".*compiler is.*"] std_qa = { # named group in match will be used to construct answer r"%s(.*\n)*Enter selection\s*\[[0-9]+-[0-9]+\]\s*:" % build_type_question: "%(nr)s", } run_cmd_qa(cmd, qa, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True) # make sure correct compilers and compiler flags are being used comps = { 'SCC': "%s -I$(JASPERINC) %s" % (os.getenv('CC'), libpnginc), 'SFC': os.getenv('F90'), 'DM_FC': os.getenv('MPIF90'), 'DM_CC': os.getenv('MPICC'), 'FC': os.getenv('MPIF90'), 'CC': os.getenv('MPICC'), } if self.toolchain.options.get('openmp', None): comps.update({ 'LDFLAGS': '%s %s' % (self.toolchain.get_flag('openmp'), os.environ['LDFLAGS']) }) regex_subs = [(r"^(%s\s*=\s*).*$" % key, r"\1 %s" % val) for (key, val) in comps.items()] apply_regex_substitutions('configure.wps', regex_subs)
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'), } # avoid that (system) Intel compilers are always considered self.cfg.update('buildopts', 'AUTOCC=no') # 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): """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): """Configure WIEN2k build by patching siteconfig_lapw script and running it.""" self.cfgscript = "siteconfig_lapw" # patch config file first # toolchain-dependent values comp_answer = None if self.toolchain.comp_family() == toolchain.INTELCOMP: # @UndefinedVariable if LooseVersion(get_software_version("icc")) >= LooseVersion("2011"): if LooseVersion(self.version) < LooseVersion("17"): comp_answer = 'I' # Linux (Intel ifort 12.0 compiler + mkl ) else: comp_answer = 'LI' # Linux (Intel ifort compiler (12.0 or later)+mkl+intelmpi)) else: comp_answer = "K1" # Linux (Intel ifort 11.1 compiler + mkl ) elif self.toolchain.comp_family() == toolchain.GCC: # @UndefinedVariable if LooseVersion(self.version) < LooseVersion("17"): comp_answer = 'V' # Linux (gfortran compiler + gotolib) else: comp_answer = 'LG' # Linux (gfortran compiler + OpenBlas) else: raise EasyBuildError("Failed to determine toolchain-dependent answers.") # libraries liblapack = os.getenv('LIBLAPACK_MT').replace('static', 'dynamic') libscalapack = os.getenv('LIBSCALAPACK_MT').replace('static', 'dynamic') rlibs = "%s %s" % (liblapack, self.toolchain.get_flag('openmp')) rplibs = [libscalapack, liblapack] fftwver = get_software_version('FFTW') if fftwver: suff = '' if LooseVersion(fftwver) >= LooseVersion("3"): suff = '3' rplibs.insert(0, "-lfftw%(suff)s_mpi -lfftw%(suff)s" % {'suff': suff}) else: rplibs.append(os.getenv('LIBFFT')) rplibs = ' '.join(rplibs) vars = { 'FC': '%s' % os.getenv('F90'), 'FOPT': '%s' % os.getenv('FFLAGS'), 'MPF': '%s' % os.getenv('MPIF90'), 'FPOPT': '%s' % os.getenv('FFLAGS'), 'CC': os.getenv('CC'), 'LDFLAGS': '$(FOPT) %s ' % os.getenv('LDFLAGS'), 'R_LIBS': rlibs, # libraries for 'real' (not 'complex') binary 'RP_LIBS': rplibs, # libraries for 'real' parallel binary 'MPIRUN': '', } for line in fileinput.input(self.cfgscript, inplace=1, backup='.orig'): # set config parameters for (key, val) in vars.items(): regexp = re.compile('^([a-z0-9]+):%s:(.*)' % key) res = regexp.search(line) if res: # we need to exclude the lines with 'current', otherwise we break the script if not res.group(1) == "current": if 'OPT' in key: # append instead of replace line = regexp.sub('\\1:%s:%s %s' % (key, res.group(2), val), line) else: line = regexp.sub('\\1:%s:%s' % (key, val), line) # avoid exit code > 0 at end of configuration line = re.sub('(\s+)exit 1', '\\1exit 0', line) sys.stdout.write(line) # set correct compilers env.setvar('bin', os.getcwd()) dc = { 'COMPILERC': os.getenv('CC'), 'COMPILER': os.getenv('F90'), 'COMPILERP': os.getenv('MPIF90'), } if LooseVersion(self.version) < LooseVersion("17"): for (key, val) in dc.items(): write_file(key, val) else: dc['cc'] = dc.pop('COMPILERC') dc['fortran'] = dc.pop('COMPILER') dc['parallel'] = dc.pop('COMPILERP') write_file('WIEN2k_COMPILER', '\n'.join(['%s:%s' % (k, v) for k, v in dc.iteritems()])) # configure with patched configure script self.log.debug('%s part I (configure)' % self.cfgscript) cmd = "./%s" % self.cfgscript qanda = { 'Press RETURN to continue': '', 'Your compiler:': '', 'Hit Enter to continue': '', 'Remote shell (default is ssh) =': '', 'and you need to know details about your installed mpi ..) (y/n)': 'y', 'Q to quit Selection:': 'Q', 'A Compile all programs (suggested) Q Quit Selection:': 'Q', ' Please enter the full path of the perl program: ': '', 'continue or stop (c/s)': 'c', '(like taskset -c). Enter N / your_specific_command:': 'N', } if LooseVersion(self.version) >= LooseVersion("13"): fftw_root = get_software_root('FFTW') if fftw_root: fftw_maj = get_software_version('FFTW').split('.')[0] fftw_spec = 'FFTW%s' % fftw_maj else: raise EasyBuildError("Required FFTW dependency is missing") qanda.update({ ') Selection:': comp_answer, 'Shared Memory Architecture? (y/N):': 'N', 'Set MPI_REMOTE to 0 / 1:': '0', 'You need to KNOW details about your installed MPI and FFTW ) (y/n)': 'y', 'Please specify whether you want to use FFTW3 (default) or FFTW2 (FFTW3 / FFTW2):': fftw_spec, 'Please specify the ROOT-path of your FFTW installation (like /opt/fftw3):': fftw_root, 'is this correct? enter Y (default) or n:': 'Y', }) libxcroot = get_software_root('libxc') libxcquestion = 'LIBXC (that you have installed%s)? (y,N):' % \ (' before' if LooseVersion(self.version) < LooseVersion("17") else '') if libxcroot: qanda.update({ libxcquestion: 'y', 'Do you want to automatically search for LIBXC installations? (Y,n):': 'n', 'Please enter the directory of your LIBXC-installation!:': libxcroot, }) else: qanda.update({libxcquestion: ''}) if LooseVersion(self.version) >= LooseVersion("17"): scalapack_libs = os.getenv('LIBSCALAPACK').split() scalapack = next((lib[2:] for lib in scalapack_libs if 'scalapack' in lib), 'scalapack') blacs = next((lib[2:] for lib in scalapack_libs if 'blacs' in lib), 'openblas') qanda.update({ 'You need to KNOW details about your installed MPI, ELPA, and FFTW ) (y/N)': 'y', 'Do you want to use a present ScaLAPACK installation? (Y,n):': 'y', 'Do you want to use the MKL version of ScaLAPACK? (Y,n):': 'n', # we set it ourselves below 'Do you use Intel MPI? (Y,n):': 'y', 'Is this correct? (Y,n):': 'y', 'Please specify the target architecture of your ScaLAPACK libraries (e.g. intel64)!:': '', 'ScaLAPACK root:': os.getenv('MKLROOT') or os.getenv('EBROOTSCALAPACK'), 'ScaLAPACK library:': scalapack, 'BLACS root:': os.getenv('MKLROOT') or os.getenv('EBROOTOPENBLAS'), 'BLACS library:': blacs, 'Please enter your choice of additional libraries!:': '', 'Do you want to use a present FFTW installation? (Y,n):': 'y', 'Please specify the path of your FFTW installation (like /opt/fftw3/) ' 'or accept present choice (enter):': fftw_root, 'Please specify the target achitecture of your FFTW library (e.g. lib64) ' 'or accept present choice (enter):': '', 'Do you want to automatically search for FFTW installations? (Y,n):': 'n', 'Please specify the ROOT-path of your FFTW installation (like /opt/fftw3/) ' 'or accept present choice (enter):': fftw_root, 'Is this correct? enter Y (default) or n:': 'Y', 'Please specify the name of your FFTW library or accept present choice (enter):': '', 'Please specify your parallel compiler options or accept the recommendations ' '(Enter - default)!:': '', 'Please specify your MPIRUN command or accept the recommendations (Enter - default)!:': '', # the temporary directory is hardcoded into execution scripts and must exist at runtime 'Please enter the full path to your temporary directory:': '/tmp', }) elparoot = get_software_root('ELPA') if elparoot: qanda.update({ 'Do you want to use ELPA? (y,N):': 'y', 'Do you want to automatically search for ELPA installations? (Y,n):': 'n', 'Please specify the ROOT-path of your ELPA installation (like /usr/local/elpa/) ' 'or accept present path (Enter):': elparoot, }) else: qanda.update({'Do you want to use ELPA? (y,N):': 'n'}) else: qanda.update({ 'compiler) Selection:': comp_answer, 'Shared Memory Architecture? (y/n):': 'n', 'If you are using mpi2 set MPI_REMOTE to 0 Set MPI_REMOTE to 0 / 1:': '0', 'Do you have MPI and Scalapack installed and intend to run ' 'finegrained parallel? (This is usefull only for BIG cases ' '(50 atoms and more / unit cell) and you need to know details ' 'about your installed mpi and fftw ) (y/n)': 'y', }) no_qa = [ 'You have the following mkl libraries in %s :' % os.getenv('MKLROOT'), "%s[ \t]*.*" % os.getenv('MPIF90'), "%s[ \t]*.*" % os.getenv('F90'), "%s[ \t]*.*" % os.getenv('CC'), ".*SRC_.*", "Please enter the full path of the perl program:", ] std_qa = { r'S\s+Save and Quit[\s\n]+To change an item select option.[\s\n]+Selection:': 'S', 'Recommended setting for parallel f90 compiler: .* Current selection: Your compiler:': os.getenv('MPIF90'), r'process or you can change single items in "Compiling Options".[\s\n]+Selection:': 'S', r'A\s+Compile all programs (suggested)[\s\n]+Q\s*Quit[\s\n]+Selection:': 'Q', } run_cmd_qa(cmd, qanda, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True) # post-configure patches parallel_options = {} parallel_options_fp = os.path.join(self.cfg['start_dir'], 'parallel_options') if self.cfg['wien_mpirun']: parallel_options.update({'WIEN_MPIRUN': self.cfg['wien_mpirun']}) if self.cfg['taskset'] is None: self.cfg['taskset'] = 'no' parallel_options.update({'TASKSET': self.cfg['taskset']}) for opt in ['use_remote', 'mpi_remote', 'wien_granularity']: parallel_options.update({opt.upper(): int(self.cfg[opt])}) write_file(parallel_options_fp, '\n'.join(['setenv %s "%s"' % tup for tup in parallel_options.items()])) if self.cfg['remote']: if self.cfg['remote'] == 'pbsssh': extratxt = '\n'.join([ '', "set remote = pbsssh", "setenv PBSSSHENV 'LD_LIBRARY_PATH PATH'", '', ]) write_file(parallel_options_fp, extratxt, append=True) else: raise EasyBuildError("Don't know how to handle remote %s", self.cfg['remote']) self.log.debug("Patched file %s: %s", parallel_options_fp, read_file(parallel_options_fp))
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()
class EB_Python(ConfigureMake): """Support for building/installing Python - default configure/build_step/make install works fine To extend Python by adding extra packages there are two ways: - list the packages in the exts_list, this will include the packages in this Python installation - create a seperate easyblock, so the packages can be loaded with module load e.g., you can include numpy and scipy in a default Python installation but also provide newer updated numpy and scipy versions by creating a PythonPackage-derived easyblock for it. """ def prepare_for_extensions(self): """ Set default class and filter for Python packages """ # build and install additional packages with PythonPackage easyblock self.cfg['exts_defaultclass'] = "PythonPackage" self.cfg['exts_filter'] = EXTS_FILTER_PYTHON_PACKAGES # don't pass down any build/install options that may have been specified # 'make' options do not make sense for when building/installing Python libraries (usually via 'python setup.py') msg = "Unsetting '%s' easyconfig parameter before building/installing extensions: %s" for param in ['buildopts', 'installopts']: if self.cfg[param]: self.log.debug(msg, param, self.cfg[param]) self.cfg[param] = '' 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 install_step(self): """Extend make install to make sure that the 'python' command is present.""" super(EB_Python, self).install_step() python_binary_path = os.path.join(self.installdir, 'bin', 'python') if not os.path.isfile(python_binary_path): pyver = '.'.join(self.version.split('.')[:2]) symlink(python_binary_path + pyver, python_binary_path) def sanity_check_step(self): """Custom sanity check for Python.""" pyver = 'python' + '.'.join(self.version.split('.')[:2]) shlib_ext = get_shared_lib_ext() try: fake_mod_data = self.load_fake_module() except EasyBuildError, err: raise EasyBuildError("Loading fake module failed: %s", err) abiflags = '' if LooseVersion(self.version) >= LooseVersion("3"): run_cmd("which python", log_all=True, simple=False) cmd = 'python -c "import sysconfig; print(sysconfig.get_config_var(\'abiflags\'));"' (abiflags, _) = run_cmd(cmd, log_all=True, simple=False) if not abiflags: raise EasyBuildError("Failed to determine abiflags: %s", abiflags) else: abiflags = abiflags.strip() custom_paths = { 'files': [ os.path.join('bin', pyver), os.path.join('lib', 'lib' + pyver + abiflags + '.' + shlib_ext) ], 'dirs': [ os.path.join('include', pyver + abiflags), os.path.join('lib', pyver) ], } # cleanup self.clean_up_fake_module(fake_mod_data) custom_commands = [ "python --version", "python -c 'import _ctypes'", # make sure that foreign function interface (libffi) works "python -c 'import _ssl'", # make sure SSL support is enabled one way or another "python -c 'import readline'", # make sure readline support was built correctly ] if get_software_root('Tk'): # also check whether importing tkinter module works, name is different for Python v2.x and v3.x if LooseVersion(self.version) >= LooseVersion('3'): tkinter = 'tkinter' else: tkinter = 'Tkinter' custom_commands.append("python -c 'import %s'" % tkinter) # check whether _tkinter*.so is found, exact filename doesn't matter tkinter_so = os.path.join(self.installdir, 'lib', pyver, 'lib-dynload', '_tkinter*.' + shlib_ext) tkinter_so_hits = glob.glob(tkinter_so) if len(tkinter_so_hits) == 1: self.log.info("Found exactly one _tkinter*.so: %s", tkinter_so_hits[0]) else: raise EasyBuildError( "Expected to find exactly one _tkinter*.so: %s", tkinter_so_hits) super(EB_Python, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
def configure_step(self): """Custom configuration procedure for Xmipp.""" # Tell xmipp config that there is no Scipion. env.setvar('XMIPP_NOSCIPION', 'True') # Initialize the config file and then patch it with the correct values cmd = ' '.join([ self.cfg['preconfigopts'], os.path.join(self.srcdir, 'xmipp', 'xmipp'), 'config', self.cfg['configopts'], ]) run_cmd(cmd, log_all=True, simple=True) # Parameters to be set in the config file params = { 'CC': os.environ['CC'], 'CXX': os.environ['CXX'], 'LINKERFORPROGRAMS': os.environ['CXX'], 'LIBDIRFLAGS': '', # I don't think Xmipp can actually build without MPI. 'MPI_CC': os.environ.get('MPICC', 'UNKNOWN'), 'MPI_CXX': os.environ.get('MPICXX', 'UNKNOWN'), 'MPI_LINKERFORPROGRAMS': os.environ.get('MPICXX', 'UNKNOWN'), } deps = [ # Name of dependency, name of env var to set, required or not ('HDF5', None, True), ('SQLite', None, True), ('LibTIFF', None, True), ('libjpeg-turbo', None, True), ('Java', 'JAVA_HOME', True), ('MATLAB', 'MATLAB_DIR', False), ] cuda_root = get_software_root('CUDA') if cuda_root: params.update({'CUDA_BIN': os.path.join(cuda_root, 'bin')}) params.update({'CUDA_LIB': os.path.join(cuda_root, 'lib64')}) params.update({'NVCC': os.environ['CUDA_CXX']}) # Their default for NVCC is to use g++-5, fix that nvcc_flags = '--x cu -D_FORCE_INLINES -Xcompiler -fPIC ' nvcc_flags = nvcc_flags + '-Wno-deprecated-gpu-targets -std=c++11' params.update({'NVCC_CXXFLAGS': nvcc_flags}) self.use_cuda = True # Make sure cuFFTAdvisor is available even if unpacked under # a different name if not os.path.isdir('cuFFTAdvisor'): matches = glob.glob(os.path.join(self.srcdir, 'cuFFTAdvisor-*')) if len(matches) == 1: cufft = os.path.basename(matches[0]) symlink(cufft, os.path.join(self.srcdir, 'cuFFTAdvisor'), use_abspath_source=False) else: raise EasyBuildError( "Failed to isolate path to cuFFTAdvisor-*: %s", matches) for dep in ['CUDA', 'MATLAB']: use_dep = bool(get_software_root(dep)) params.update({dep: use_dep}) if get_software_root('OpenCV'): params.update({'OPENCV': True}) if self.use_cuda: params.update({'OPENCVSUPPORTSCUDA': True}) if LooseVersion( get_software_version('OpenCV')) >= LooseVersion('3'): params.update({'OPENCV3': True}) missing_deps = [] for dep, var, required in deps: root = get_software_root(dep) if root: if var: params.update({var: root}) elif required: missing_deps.append(dep) if missing_deps: raise EasyBuildError( "One or more required dependencies not available: %s", ', '.join(missing_deps)) # Here we know that Java exists since it is a required dependency jnipath = os.path.join(get_software_root('Java'), 'include') jnipath = os.pathsep.join([jnipath, os.path.join(jnipath, 'linux')]) params.update({'JNI_CPPPATH': jnipath}) regex_subs = [] # Set the variables in the config file to match the environment from EasyBuild for (key, val) in params.items(): regex_subs.extend([(r'^%s\s*=.*$' % key, r'%s = %s' % (key, val))]) apply_regex_substitutions(self.cfgfile, regex_subs) self.setup_xmipp_env() py_ver = get_software_version('Python') py_maj_ver = LooseVersion(py_ver).version[0] py_min_ver = LooseVersion(py_ver).version[1] pyver = 'python%s.%s' % (py_maj_ver, py_min_ver) pyincpath = os.path.join(get_software_root('Python'), 'include', pyver) # Temp workaround for missing include/pythonx.y in CPATH env.setvar('CPATH', os.pathsep.join([os.environ['CPATH'], pyincpath])) super(EB_Xmipp, self).configure_step()
def install_step(self): """Install by running install command.""" default_cuda_version = self.cfg['default_cuda_version'] if default_cuda_version is None: module_cuda_version_full = get_software_version('CUDA') if module_cuda_version_full is not None: default_cuda_version = '.'.join( module_cuda_version_full.split('.')[:2]) else: error_msg = "A default CUDA version is needed for installation of NVHPC. " error_msg += "It can not be determined automatically and needs to be added manually. " error_msg += "You can edit the easyconfig file, " error_msg += "or use 'eb --try-amend=default_cuda_version=<version>'." raise EasyBuildError(error_msg) # Parse default_compute_capability from different sources (CLI has priority) ec_default_compute_capability = self.cfg['cuda_compute_capabilities'] cfg_default_compute_capability = build_option( 'cuda_compute_capabilities') if cfg_default_compute_capability is not None: default_compute_capability = cfg_default_compute_capability elif ec_default_compute_capability and ec_default_compute_capability is not None: default_compute_capability = ec_default_compute_capability else: error_msg = "A default Compute Capability is needed for installation of NVHPC." error_msg += "Please provide it either in the easyconfig file like 'cuda_compute_capabilities=\"7.0\"'," error_msg += "or use 'eb --cuda-compute-capabilities=7.0' from the command line." raise EasyBuildError(error_msg) # Extract first element of default_compute_capability list, if it is a list if isinstance(default_compute_capability, list): _before_default_compute_capability = default_compute_capability default_compute_capability = _before_default_compute_capability[0] warning_msg = "Replaced list of compute capabilities {} ".format( _before_default_compute_capability) warning_msg += "with first element of list {}".format( default_compute_capability) print_warning(warning_msg) # Remove dot-divider for CC; error out if it is not a string if isinstance(default_compute_capability, str): default_compute_capability = default_compute_capability.replace( '.', '') else: raise EasyBuildError( "Unexpected non-string value encountered for compute capability: %s", default_compute_capability) nvhpc_env_vars = { 'NVHPC_INSTALL_DIR': self.installdir, 'NVHPC_SILENT': 'true', 'NVHPC_DEFAULT_CUDA': str(default_cuda_version), # 10.2, 11.0 'NVHPC_STDPAR_CUDACC': str(default_compute_capability), # 70, 80; single value, no list! } cmd = "%s ./install" % ' '.join( ['%s=%s' % x for x in sorted(nvhpc_env_vars.items())]) run_cmd(cmd, log_all=True, simple=True) # make sure localrc uses GCC in PATH, not always the system GCC, and does not use a system g77 but gfortran install_abs_subdir = os.path.join(self.installdir, self.nvhpc_install_subdir) compilers_subdir = os.path.join(install_abs_subdir, "compilers") makelocalrc_filename = os.path.join(compilers_subdir, "bin", "makelocalrc") for line in fileinput.input(makelocalrc_filename, inplace='1', backup='.orig'): line = re.sub(r"^PATH=/", r"#PATH=/", line) sys.stdout.write(line) cmd = "%s -x %s -g77 /" % (makelocalrc_filename, compilers_subdir) run_cmd(cmd, log_all=True, simple=True) # If an OS libnuma is NOT found, makelocalrc creates symbolic links to libpgnuma.so # If we use the EB libnuma, delete those symbolic links to ensure they are not used if get_software_root("numactl"): for filename in ["libnuma.so", "libnuma.so.1"]: path = os.path.join(compilers_subdir, "lib", filename) if os.path.islink(path): os.remove(path) # install (or update) siterc file to make NVHPC consider $LIBRARY_PATH siterc_path = os.path.join(compilers_subdir, 'bin', 'siterc') write_file(siterc_path, SITERC_LIBRARY_PATH, append=True) self.log.info( "Appended instructions to pick up $LIBRARY_PATH to siterc file at %s: %s", siterc_path, SITERC_LIBRARY_PATH) # The cuda nvvp tar file has broken permissions adjust_permissions(self.installdir, stat.S_IWUSR, add=True, onlydirs=True)
def sanity_check_step(self): """Custom sanity check for GROMACS.""" dirs = [os.path.join('include', 'gromacs')] # in GROMACS v5.1, only 'gmx' binary is there # (only) in GROMACS v5.0, other binaries are symlinks to 'gmx' # bins/libs that never have an _mpi suffix bins = [] libnames = [] # bins/libs that may have an _mpi suffix mpi_bins = [] mpi_libnames = [] if LooseVersion(self.version) < LooseVersion('5.1'): mpi_bins.extend(['mdrun']) if LooseVersion(self.version) >= LooseVersion('5.0'): mpi_bins.append('gmx') mpi_libnames.append('gromacs') else: bins.extend(['editconf', 'g_lie', 'genbox', 'genconf']) libnames.extend(['gmxana']) if LooseVersion(self.version) >= LooseVersion('4.6'): if self.cfg['build_shared_libs']: mpi_libnames.extend(['gmx', 'md']) else: libnames.extend(['gmx', 'md']) else: mpi_libnames.extend(['gmx', 'md']) if LooseVersion(self.version) >= LooseVersion('4.5'): if LooseVersion(self.version) >= LooseVersion('4.6'): if self.cfg['build_shared_libs']: mpi_libnames.append('gmxpreprocess') else: libnames.append('gmxpreprocess') else: mpi_libnames.append('gmxpreprocess') # also check for MPI-specific binaries/libraries if self.toolchain.options.get('usempi', None): if LooseVersion(self.version) < LooseVersion('4.6'): mpisuff = self.cfg.get('mpisuffix', '_mpi') else: mpisuff = '_mpi' mpi_bins.extend([binary + mpisuff for binary in mpi_bins]) mpi_libnames.extend([libname + mpisuff for libname in mpi_libnames]) suffixes = [''] # make sure that configopts is a list: configopts_list = self.cfg['configopts'] if isinstance(configopts_list, str): configopts_list = [configopts_list] lib_files = [] bin_files = [] dsuff = None if not get_software_root('CUDA'): for configopts in configopts_list: # add the _d suffix to the suffix, in case of double precision if self.double_prec_pattern in configopts: dsuff = '_d' if dsuff: suffixes.extend([dsuff]) lib_files.extend([ 'lib%s%s.%s' % (x, suff, self.libext) for x in libnames + mpi_libnames for suff in suffixes ]) bin_files.extend([b + suff for b in bins + mpi_bins for suff in suffixes]) # pkgconfig dir not available for earlier versions, exact version to use here is unclear if LooseVersion(self.version) >= LooseVersion('4.6'): dirs.append(os.path.join(self.lib_subdir, 'pkgconfig')) custom_paths = { 'files': [os.path.join('bin', b) for b in bin_files] + [os.path.join(self.lib_subdir, lib) for lib in lib_files], 'dirs': dirs, } super(EB_GROMACS, self).sanity_check_step(custom_paths=custom_paths)
raise EasyBuildError("Failed to change to build dir: %s", err) nwchem_modules = self.cfg['modules'] # set required NWChem environment variables env.setvar('NWCHEM_TOP', self.cfg['start_dir']) env.setvar('NWCHEM_TARGET', self.cfg['target']) 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([
def sanity_check_step(self): """Custom sanity check paths for Intel MKL.""" mklfiles = None mkldirs = None ver = LooseVersion(self.version) libs = [ "libmkl_core.so", "libmkl_gnu_thread.so", "libmkl_intel_thread.so", "libmkl_sequential.so" ] extralibs = [ "libmkl_blacs_intelmpi_%(suff)s.so", "libmkl_scalapack_%(suff)s.so" ] if self.cfg['interfaces']: compsuff = '_intel' if get_software_root('icc') is None: if get_software_root('GCC'): compsuff = '_gnu' else: raise EasyBuildError( "Not using Intel compilers or GCC, don't know compiler suffix for FFTW libraries." ) precs = ['_double', '_single'] if ver < LooseVersion('11'): # no precision suffix in libfftw2 libs before imkl v11 precs = [''] fftw_vers = [ '2x%s%s' % (x, prec) for x in ['c', 'f'] for prec in precs ] + ['3xc', '3xf'] pics = ['', '_pic'] libs = [ 'libfftw%s%s%s.a' % (fftwver, compsuff, pic) for fftwver in fftw_vers for pic in pics ] fftw_cdft_vers = ['2x_cdft_DOUBLE'] if not self.cfg['m32']: fftw_cdft_vers.append('2x_cdft_SINGLE') if ver >= LooseVersion('10.3'): fftw_cdft_vers.append('3x_cdft') if ver >= LooseVersion('11.0.2'): bits = ['_lp64'] if not self.cfg['m32']: bits.append('_ilp64') else: # no bits suffix in cdft libs before imkl v11.0.2 bits = [''] libs += [ 'libfftw%s%s%s.a' % x for x in itertools.product(fftw_cdft_vers, bits, pics) ] if ver >= LooseVersion('10.3'): if self.cfg['m32']: raise EasyBuildError( "Sanity check for 32-bit not implemented yet for IMKL v%s (>= 10.3)", self.version) else: mkldirs = [ "bin", "mkl/bin", "mkl/bin/intel64", "mkl/lib/intel64", "mkl/include" ] libs += [ lib % { 'suff': suff } for lib in extralibs for suff in ['lp64', 'ilp64'] ] mklfiles = ["mkl/lib/intel64/libmkl.so", "mkl/include/mkl.h"] + \ ["mkl/lib/intel64/%s" % lib for lib in libs] if ver >= LooseVersion('10.3.4') and ver < LooseVersion( '11.1'): mkldirs += ["compiler/lib/intel64"] else: mkldirs += ["lib/intel64"] else: if self.cfg['m32']: mklfiles = ["lib/32/libmkl.so", "include/mkl.h"] + \ ["lib/32/%s" % lib for lib in libs] mkldirs = ["lib/32", "include/32", "interfaces"] else: libs += [ lib % { 'suff': suff } for lib in extralibs for suff in ['lp64', 'ilp64'] ] mklfiles = ["lib/em64t/libmkl.so", "include/mkl.h"] + \ ["lib/em64t/%s" % lib for lib in libs] mkldirs = ["lib/em64t", "include/em64t", "interfaces"] custom_paths = { 'files': mklfiles, 'dirs': mkldirs, } super(EB_imkl, self).sanity_check_step(custom_paths=custom_paths)