def install_step(self): """Install python but only keep the bits we need""" super(EB_Tkinter, self).install_step() tmpdir = tempfile.mkdtemp(dir=self.builddir) self.tkinter_so_basename = self.get_tkinter_so_basename(False) if LooseVersion(self.version) >= LooseVersion('3'): tkparts = [ "tkinter", os.path.join("lib-dynload", self.tkinter_so_basename) ] else: tkparts = [ "lib-tk", os.path.join("lib-dynload", self.tkinter_so_basename) ] pylibdir = os.path.join(self.installdir, det_pylibdir()) copy([os.path.join(os.path.dirname(pylibdir), x) for x in tkparts], tmpdir) remove_dir(self.installdir) move_file(os.path.join(tmpdir, tkparts[0]), os.path.join(pylibdir, tkparts[0])) move_file(os.path.join(tmpdir, self.tkinter_so_basename), os.path.join(pylibdir, self.tkinter_so_basename))
def post_install_step(self): super(EB_AOMP, self).post_install_step() # The install script will create a symbolic link as the install # directory, this creates problems for EB as it won't remove the # symlink. To remedy this we remove the link here and rename the actual # install directory created by the AOMP install script if os.path.islink(self.installdir): remove_file(self.installdir) else: err_str = "Expected '{!s}' to be a symbolic link" \ " that needed to be removed, but it wasn't!" raise EasyBuildError(err_str.format(self.installdir)) # Move the actual directory containing the install install_name = '{!s}_{!s}'.format(os.path.basename(self.installdir), self.version) actual_install = os.path.join(os.path.dirname(self.installdir), install_name) if os.path.exists(actual_install) and os.path.isdir(actual_install): move_file(actual_install, self.installdir) else: err_str = "Tried to move '{!s}' to '{!s}', " \ " but it either doesn't exist" \ " or isn't a directory!" raise EasyBuildError( err_str.format(actual_install, self.installdir))
def install_step(self): """Custom install procedure for Nim.""" run_cmd("./koch geninstall") run_cmd("sh install.sh %s" % self.installdir) # install.sh copies stuff into <prefix>/nim, so move it nim_dir = os.path.join(self.installdir, 'nim') for entry in os.listdir(nim_dir): move_file(os.path.join(nim_dir, entry), os.path.join(self.installdir, entry)) # also copy nimble/nimgrep/nimsuggest tools for tool in ['nimble', 'nimgrep', 'nimsuggest']: copy_file(os.path.join('bin', tool), os.path.join(self.installdir, 'bin', tool))
def post_install_step(self): """Create wrappers for the compilers to make sure compilers picks up GCCcore as GCC toolchain""" orig_compiler_tmpl = '%s.orig' def create_wrapper(wrapper_comp): """Create for a particular compiler, with a particular name""" wrapper_f = os.path.join(self.installdir, 'bin', wrapper_comp) write_file( wrapper_f, WRAPPER_TEMPLATE % {'compiler_name': orig_compiler_tmpl % wrapper_comp}) perms = stat.S_IXUSR | stat.S_IRUSR | stat.S_IXGRP | stat.S_IRGRP | stat.S_IXOTH | stat.S_IROTH adjust_permissions(wrapper_f, perms) compilers_to_wrap = [ 'clang', 'clang++', 'clang-%s' % LooseVersion(self.clangversion).version[0], 'clang-cpp', 'flang', ] # Rename original compilers and prepare wrappers to pick up GCCcore as GCC toolchain for the compilers for comp in compilers_to_wrap: actual_compiler = os.path.join(self.installdir, 'bin', comp) if os.path.isfile(actual_compiler): move_file(actual_compiler, orig_compiler_tmpl % actual_compiler) else: err_str = "Tried to move '%s' to '%s', but it does not exist!" raise EasyBuildError(err_str, actual_compiler, '%s.orig' % actual_compiler) if not os.path.exists(actual_compiler): create_wrapper(comp) self.log.info("Wrapper for %s successfully created", comp) else: err_str = "Creating wrapper for '%s' not possible, since original compiler was not renamed!" raise EasyBuildError(err_str, actual_compiler) super(EB_AOCC, self).post_install_step()
def install_step(self): """Install python but only keep the bits we need""" super(EB_Tkinter, self).install_step() tmpdir = tempfile.mkdtemp(dir=self.builddir) pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir())) shlib_ext = get_shared_lib_ext() tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext) tkinter_so_hits = glob.glob(tkinter_so) if len(tkinter_so_hits) != 1: raise EasyBuildError( "Expected to find exactly one _tkinter*.so: %s", tkinter_so_hits) self.tkinter_so_basename = os.path.basename(tkinter_so_hits[0]) if LooseVersion(self.version) >= LooseVersion('3'): tkparts = [ "tkinter", os.path.join("lib-dynload", self.tkinter_so_basename) ] else: tkparts = [ "lib-tk", os.path.join("lib-dynload", self.tkinter_so_basename) ] copy([os.path.join(pylibdir, x) for x in tkparts], tmpdir) remove_dir(self.installdir) move_file(os.path.join(tmpdir, tkparts[0]), os.path.join(pylibdir, tkparts[0])) tkinter_so = os.path.basename(tkparts[1]) move_file(os.path.join(tmpdir, tkinter_so), os.path.join(pylibdir, tkinter_so))
def install_step(self): """Custom install step for netpbm.""" # Preinstallation to a tmp directory. Can't install directly to installdir because the make command fails if the # directory already exists cmd = "make package pkgdir=%s/pkg" % self.builddir (out, _) = run_cmd(cmd, log_all=True, simple=False) # Move things to installdir copy(["%s/pkg/%s" % (self.builddir, x) for x in os.listdir("%s/pkg/" % self.builddir)], self.installdir) # Need to do manually the last bits of the installation configs = [ ("%s/config_template" % self.installdir, "%s/bin/netpbm-config" % self.installdir), ("%s/pkgconfig_template" % self.installdir, "%s/lib/pkgconfig/netpbm.pc" % self.installdir) ] mkdir("%s/lib/pkgconfig" % self.installdir) for template, config_file in configs: move_file(template, config_file) for line in fileinput.input(config_file, inplace=1, backup='.orig'): if re.match(r"^@", line): continue else: line = re.sub(r'@VERSION@', 'Netpbm %s' % self.version, line) line = re.sub(r'@DATADIR@', '%s/lib' % self.installdir, line) line = re.sub(r'@LINKDIR@', '%s/lib' % self.installdir, line) line = re.sub(r'@INCLUDEDIR@', '%s/include' % self.installdir, line) line = re.sub(r'@BINDIR@', '%s/bin' % self.installdir, line) sys.stdout.write(line) adjust_permissions("%s/bin/netpbm-config" % self.installdir, stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) move_file("%s/link/libnetpbm.a" % self.installdir, "%s/lib/libnetpbm.a" % self.installdir) symlink("%s/lib/libnetpbm.so.11" % self.installdir, "%s/lib/libnetpbm.so" % self.installdir) for f in os.listdir("%s/misc/" % self.installdir): move_file("%s/misc/%s" % (self.installdir, f), "%s/lib/%s" % (self.installdir, f)) rmtree2("%s/misc/" % self.installdir) rmtree2("%s/link/" % self.installdir) headers = os.listdir("%s/include/netpbm" % self.installdir) for header in headers: symlink("%s/include/netpbm/%s" % (self.installdir, header), "%s/include/%s" % (self.installdir, header)) return out
def post_install_step(self, *args, **kwargs): """ Post-processing after installation: add symlinks for cc, c++, f77, f95 """ super(EB_GCC, self).post_install_step(*args, **kwargs) # Add symlinks for cc/c++/f77/f95. bindir = os.path.join(self.installdir, 'bin') for key in COMP_CMD_SYMLINKS: src = COMP_CMD_SYMLINKS[key] target = os.path.join(bindir, key) if os.path.exists(target): self.log.info( "'%s' already exists in %s, not replacing it with symlink to '%s'", key, bindir, src) elif os.path.exists(os.path.join(bindir, src)): symlink(src, target, use_abspath_source=False) else: raise EasyBuildError( "Can't link '%s' to non-existing location %s", target, os.path.join(bindir, src)) # Rename include-fixed directory which includes system header files that were processed by fixincludes, # since these may cause problems when upgrading to newer OS version. # (see https://github.com/easybuilders/easybuild-easyconfigs/issues/10666) glob_pattern = os.path.join(self.installdir, 'lib*', 'gcc', '*-linux-gnu', self.version, 'include-fixed') paths = glob.glob(glob_pattern) if paths: # weed out paths that point to the same location, # for example when 'lib64' is a symlink to 'lib' include_fixed_paths = [] for path in paths: if not any( os.path.samefile(path, x) for x in include_fixed_paths): include_fixed_paths.append(path) if len(include_fixed_paths) == 1: include_fixed_path = include_fixed_paths[0] msg = "Found include-fixed subdirectory at %s, " msg += "renaming it to avoid using system header files patched by fixincludes..." self.log.info(msg, include_fixed_path) # limits.h and syslimits.h need to be copied to include/ first, # these are strictly required (by /usr/include/limits.h for example) include_path = os.path.join( os.path.dirname(include_fixed_path), 'include') retained_header_files = ['limits.h', 'syslimits.h'] for fn in retained_header_files: from_path = os.path.join(include_fixed_path, fn) to_path = os.path.join(include_path, fn) if os.path.exists(from_path): if os.path.exists(to_path): raise EasyBuildError( "%s already exists, not overwriting it with %s!", to_path, from_path) else: copy_file(from_path, to_path) self.log.info("%s copied to %s before renaming %s", from_path, to_path, include_fixed_path) else: self.log.warning( "Can't copy non-existing file %s to %s, since it doesn't exist!", from_path, to_path) readme = os.path.join(include_fixed_path, 'README.easybuild') readme_txt = '\n'.join([ "This directory was renamed by EasyBuild to avoid that the header files in it are picked up,", "since they may cause problems when the OS is upgraded to a new (minor) version.", '', "These files were copied to %s first: %s" % (include_path, ', '.join(retained_header_files)), '', "See https://github.com/easybuilders/easybuild-easyconfigs/issues/10666 for more information.", '', ]) write_file(readme, readme_txt) include_fixed_renamed = include_fixed_path + '.renamed-by-easybuild' move_file(include_fixed_path, include_fixed_renamed) self.log.info( "%s renamed to %s to avoid using the header files in it", include_fixed_path, include_fixed_renamed) else: raise EasyBuildError( "Exactly one 'include-fixed' directory expected, found %d: %s", len(include_fixed_paths), include_fixed_paths) else: self.log.info("No include-fixed subdirectory found at %s", glob_pattern)
def configure_step(self): """Set up environment for building/installing CFDEMcoupling.""" # rename top-level directory to CFDEMcoupling-<version> top_dirs = os.listdir(self.builddir) for (pkgname, target_dir) in [('CFDEMcoupling', self.cfdem_project_dir), ('LIGGGHTS', self.liggghts_dir)]: pkg_topdirs = [d for d in top_dirs if d.startswith(pkgname)] if len(pkg_topdirs) == 1: orig_dir = os.path.join(self.builddir, pkg_topdirs[0]) move_file(orig_dir, target_dir) else: error_msg = "Failed to find subdirectory for %s in %s %s (missing sources for %s?)", raise EasyBuildError(error_msg, pkgname, self.builddir, top_dirs, pkgname) env.setvar('CFDEM_VERSION', self.version) env.setvar('CFDEM_PROJECT_DIR', self.cfdem_project_dir) # define $CFDEM_PROJECT_USER_DIR to an empty existing directory project_user_dir = os.path.join(self.builddir, 'project_user_dir') env.setvar('CFDEM_PROJECT_USER_DIR', project_user_dir) mkdir(project_user_dir, parents=True) cfdem_bashrc = os.path.join(self.cfdem_project_dir, 'src', 'lagrangian', 'cfdemParticle', 'etc', 'bashrc') env.setvar('CFDEM_bashrc', cfdem_bashrc) env.setvar('CFDEM_LIGGGHTS_SRC_DIR', os.path.join(self.liggghts_dir, 'src')) env.setvar('CFDEM_LIGGGHTS_MAKEFILE_NAME', 'auto') lpp_dirs = glob.glob(os.path.join(self.builddir, 'LPP-*')) if len(lpp_dirs) == 1: env.setvar('CFDEM_LPP_DIR', lpp_dirs[0]) else: raise EasyBuildError("Failed to isolate LPP-* directory in %s", self.builddir) # build in parallel env.setvar("WM_NCOMPPROCS", str(self.cfg['parallel'])) vtk_root = get_software_root('VTK') if vtk_root: vtk_ver_maj_min = '.'.join( get_software_version('VTK').split('.')[:2]) vtk_inc = os.path.join(vtk_root, 'include', 'vtk-%s' % vtk_ver_maj_min) if os.path.exists(vtk_inc): env.setvar('VTK_INC_USR', '-I%s' % vtk_inc) else: raise EasyBuildError("Expected directory %s does not exist!", vtk_inc) vtk_lib = os.path.join(vtk_root, 'lib') if os.path.exists(vtk_lib): env.setvar('VTK_LIB_USR', '-L%s' % vtk_lib) else: raise EasyBuildError("Expected directory %s does not exist!", vtk_lib) else: raise EasyBuildError("VTK not included as dependency") # can't seem to use defined 'cfdemSysTest' alias, so call cfdemSystemTest.sh script directly... cmd = "source $CFDEM_bashrc && $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/cfdemSystemTest.sh" run_cmd(cmd, log_all=True, simple=True, log_ok=True)
def build_mkl_fftw_interfaces(self, libdir): """Build the Intel MKL FFTW interfaces.""" mkdir(libdir) loosever = LooseVersion(self.version) if loosever >= LooseVersion('10.3'): intsubdir = os.path.join(self.mkl_basedir, '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'] interfacedir = os.path.join(self.installdir, intsubdir) change_dir(interfacedir) self.log.info("Changed to interfaces directory %s", interfacedir) compopt = None # determine whether we're using a non-Intel GCC-based or PGI/NVHPC-based toolchain # can't use toolchain.comp_family, because of system toolchain used when installing imkl if get_software_root('icc') or get_software_root('intel-compilers'): compopt = 'compiler=intel' elif get_software_root('PGI'): compopt = 'compiler=pgi' elif get_software_root('NVHPC'): compopt = 'compiler=nvhpc' # GCC should be the last as the above compilers also have an underlying GCC elif get_software_root('GCC'): compopt = 'compiler=gnu' else: raise EasyBuildError("Not using Intel/GCC/PGI/NVHPC compilers, " "don't know how to build wrapper libs") # patch makefiles for cdft wrappers when PGI or NVHPC is used as compiler if get_software_root('NVHPC'): regex_subs = [ # nvhpc should be considered as a valid compiler ("intel gnu", "intel gnu nvhpc"), # transform 'gnu' case to 'nvhpc' case (r"ifeq \(\$\(compiler\),gnu\)", "ifeq ($(compiler),nvhpc)"), ('=gcc', '=nvc'), ] if get_software_root('PGI'): regex_subs = [ # pgi should be considered as a valid compiler ("intel gnu", "intel gnu pgi"), # transform 'gnu' case to 'pgi' case (r"ifeq \(\$\(compiler\),gnu\)", "ifeq ($(compiler),pgi)"), ('=gcc', '=pgcc'), ] if get_software_root('PGI') or get_software_root('NVHPC'): regex_subs += [ # correct flag to use C99 standard ('-std=c99', '-c99'), # -Wall and -Werror are not valid options for pgcc, no close equivalent ('-Wall', ''), ('-Werror', ''), ] for lib in self.cdftlibs: apply_regex_substitutions( os.path.join(interfacedir, lib, 'makefile'), regex_subs) if get_software_root('NVHPC'): regex_nvc_subs = [ ('pgcc', 'nvc'), ('pgf95', 'nvfortran'), ('pgi', 'nvhpc'), ] for liball in glob.glob(os.path.join(interfacedir, '*', 'makefile')): apply_regex_substitutions(liball, regex_nvc_subs) for lib in fftw2libs + fftw3libs + self.cdftlibs: buildopts = [compopt] if lib in fftw3libs: buildopts.append('install_to=$INSTALL_DIR') elif lib in self.cdftlibs: if self.mpi_spec is not None: buildopts.append('mpi=%s' % self.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 self.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) intdir = os.path.join(interfacedir, lib) change_dir(intdir) self.log.info("Changed to interface %s directory %s", lib, intdir) 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(libdir, fn) if os.path.isfile(src): move_file(src, dest) self.log.info("Moved %s to %s", src, dest) remove_dir(tmpbuild)
def install_step(self): """Custom install step, to add extra symlinks""" install_tbb_lib_path = os.path.join(self.installdir, 'tbb', 'lib') if self.toolchain.is_system_toolchain(): silent_cfg_names_map = None silent_cfg_extras = None if LooseVersion(self.version) < LooseVersion('4.2'): silent_cfg_names_map = { 'activation_name': ACTIVATION_NAME_2012, 'license_file_name': LICENSE_FILE_NAME_2012, } elif LooseVersion(self.version) < LooseVersion('4.4'): silent_cfg_names_map = { 'install_mode_name': INSTALL_MODE_NAME_2015, 'install_mode': INSTALL_MODE_2015, } # In case of TBB 4.4.x and newer we have to specify ARCH_SELECTED in silent.cfg if LooseVersion(self.version) >= LooseVersion('4.4'): silent_cfg_extras = {'ARCH_SELECTED': self.arch.upper()} IntelBase.install_step(self, silent_cfg_names_map=silent_cfg_names_map, silent_cfg_extras=silent_cfg_extras) # determine libdir os.chdir(self.installdir) libpath = os.path.join('tbb', 'libs', 'intel64') if LooseVersion(self.version) < LooseVersion('4.1.0'): libglob = 'tbb/lib/intel64/cc*libc*_kernel*' libs = sorted(glob.glob(libglob), key=LooseVersion) if libs: # take the last one, should be ordered by cc version # we're only interested in the last bit libdir = os.path.basename(libs[-1]) else: raise EasyBuildError("No libs found using %s in %s", libglob, self.installdir) else: libdir = get_tbb_gccprefix(libpath) libpath = os.path.join(libpath, libdir) # applications go looking into tbb/lib so we move what's in there to tbb/libs shutil.move(install_tbb_lib_path, os.path.join(self.installdir, 'tbb', 'libs')) # And add a symlink of the library folder to tbb/lib symlink(os.path.join(self.installdir, libpath), install_tbb_lib_path) else: # no custom install step when building from source (building is done in install directory) cand_lib_paths = glob.glob( os.path.join(self.installdir, 'build', '*_release')) if len(cand_lib_paths) == 1: libpath = os.path.join('build', os.path.basename(cand_lib_paths[0])) else: raise EasyBuildError( "Failed to isolate location of libraries: %s", cand_lib_paths) self.log.debug("libpath: %s" % libpath) # applications usually look into /lib, so we move the folder there and symlink the original one to it # This is also important so that /lib and /lib64 are actually on the same level root_lib_path = os.path.join(self.installdir, 'lib') move_file(libpath, root_lib_path) symlink(os.path.relpath(root_lib_path, os.path.join(libpath)), libpath, use_abspath_source=False) # Install CMake config files if possible if self._has_cmake() and LooseVersion( self.version) >= LooseVersion('2020.0'): cmake_install_dir = os.path.join(root_lib_path, 'cmake', 'TBB') cmd = [ 'cmake', '-DINSTALL_DIR=' + cmake_install_dir, '-DSYSTEM_NAME=Linux', '-P tbb_config_installer.cmake', ] run_cmd(' '.join(cmd), path=os.path.join(self.builddir, 'cmake'))