def configure_step(self): """Custom configuration procedure for RPMs: rebuild RPMs for relocation if required.""" # make sure that rpm is available if not check_os_dependency('rpm'): self.log.error("Command 'rpm' is required but not available.") # determine whether RPMs need to be rebuilt to make relocation work cmd = "rpm --version" (out, _) = run_cmd(cmd, log_all=True, simple=False) rpmver_re = re.compile("^RPM\s+version\s+(?P<version>[0-9.]+).*") res = rpmver_re.match(out) self.log.debug("RPM version found: %s" % res.group()) if res: ver = res.groupdict()['version'] # rebuilding is required on SL6, which implies rpm v4.8 (works fine without rebuilding on SL5) if LooseVersion(ver) >= LooseVersion('4.8.0'): self.rebuild_rpm = True self.log.debug("Enabling rebuild of RPMs to make relocation work...") else: self.log.error("Checking RPM version failed, so just carrying on with the default behavior...") if self.rebuild_rpm: self.rebuild_rpms()
def configure_step(self): """Custom configuration step for OpenMPI.""" def config_opt_unused(key, enable_opt=False): """Helper function to check whether a configure option is already specified in 'configopts'.""" if enable_opt: regex = re.compile('--(disable|enable)-%s' % key) else: regex = re.compile('--(with|without)-%s' % key) return not bool(regex.search(self.cfg['configopts'])) config_opt_names = [ # suppress failure modes in relation to mpirun path 'mpirun-prefix-by-default', # build shared libraries 'shared', ] for key in config_opt_names: if config_opt_unused(key, enable_opt=True): self.cfg.update('configopts', '--enable-%s' % key) # handle dependencies for dep in ['CUDA', 'hwloc', 'libevent', 'libfabric', 'PMIx', 'UCX']: if config_opt_unused(dep.lower()): dep_root = get_software_root(dep) if dep_root: if dep == 'libfabric': opt_name = 'ofi' else: opt_name = dep.lower() self.cfg.update('configopts', '--with-%s=%s' % (opt_name, dep_root)) # check whether VERBS support should be enabled if config_opt_unused('verbs'): # for OpenMPI v4.x, the openib BTL should be disabled when UCX is used; # this is required to avoid "error initializing an OpenFabrics device" warnings, # see also https://www.open-mpi.org/faq/?category=all#ofa-device-error if LooseVersion(self.version) >= LooseVersion( '4.0.0') and '--with-ucx=' in self.cfg['configopts']: self.cfg.update('configopts', '--without-verbs') else: # auto-detect based on available OS packages verbs = False for osdep in [ 'libibverbs-dev', 'libibverbs-devel', 'rdma-core-devel' ]: if check_os_dependency(osdep): verbs = True break if verbs: self.cfg.update('configopts', '--with-verbs') else: self.cfg.update('configopts', '--without-verbs') super(EB_OpenMPI, self).configure_step()
def validate_os_deps(self): """ validate presence of OS dependencies osdependencies should be a single list """ not_found = [] for dep in self['osdependencies']: # make sure we have a tuple if isinstance(dep, basestring): dep = (dep, ) elif not isinstance(dep, tuple): self.log.error( "Non-tuple value type for OS dependency specification: %s (type %s)" % (dep, type(dep))) if not any([check_os_dependency(cand_dep) for cand_dep in dep]): not_found.append(dep) if not_found: self.log.error("One or more OS dependencies were not found: %s" % not_found) else: self.log.info("OS dependencies ok: %s" % self['osdependencies']) return True
def rebuild_rpm(rpm_path, targetdir): """Rebuild the RPM on the specified location, to make it relocatable.""" # make sure that rpmrebuild command is available if not check_os_dependency('rpmrebuild'): raise EasyBuildError( "Command 'rpmrebuild' is required but not available.") rpmmacros = os.path.join(expanduser('~'), '.rpmmacros') if os.path.exists(rpmmacros): raise EasyBuildError( "rpmmacros file %s found which will override any other settings, so exiting.", rpmmacros) rpmrebuild_tmpdir = os.path.join(tempfile.gettempdir(), "rpmrebuild") env.setvar("RPMREBUILD_TMPDIR", rpmrebuild_tmpdir) try: if not os.path.exists(rpmrebuild_tmpdir): os.makedirs(rpmrebuild_tmpdir) _log.debug("Created RPMREBUILD_TMPDIR dir %s" % rpmrebuild_tmpdir) if not os.path.exists(targetdir): os.makedirs(targetdir) _log.debug("Created target directory for rebuilt RPMs %s" % targetdir) except OSError, err: raise EasyBuildError( "Failed to create directories for rebuilding RPM: %s", err)
def test_check_os_dependency(self): """Test check_os_dependency.""" # mock get_os_name in systemtools module to get control over command used to check OS dep st.get_os_name = lambda: 'centos' # add fake 'rpm' command that fails when $LD_LIBRARY_PATH is set rpm = os.path.join(self.test_prefix, 'rpm') rpm_txt = '\n'.join([ "#!/bin/bash", "if [[ -z $LD_LIBRARY_PATH ]]; then", ' echo "OK: $@ (LD_LIBRARY_PATH: $LD_LIBRARY_PATH)"', " exit 0", "else", ' echo "LD_LIBRARY_PATH set ($LD_LIBRARY_PATH), fail!"', " exit 1", "fi", ]) write_file(rpm, rpm_txt) adjust_permissions(rpm, stat.S_IXUSR, add=True) # also create fake 'locate' command, which is used as fallback locate = os.path.join(self.test_prefix, 'locate') write_file(locate, 'exit 1') adjust_permissions(locate, stat.S_IXUSR, add=True) os.environ['PATH'] = self.test_prefix + ':' + os.getenv('PATH') self.assertTrue(os.path.samefile(which('rpm'), rpm)) # redefine $HOME to put .bash_profile startup script to control $LD_LIBRARY_PATH value # we can't directly control the $LD_LIBRARY_PATH via os.environ, doesn't work... os.environ['HOME'] = self.test_prefix bash_profile = os.path.join(self.test_prefix, '.bash_profile') write_file(bash_profile, 'unset LD_LIBRARY_PATH') # mocked rpm always exits with exit code 0 (unless $LD_LIBRARY_PATH is set) self.assertTrue(check_os_dependency('foo')) # still works fine if $LD_LIBRARY_PATH is set write_file(bash_profile, 'export LD_LIBRARY_PATH=%s' % self.test_prefix) self.assertTrue(check_os_dependency('bar'))
def configure_step(self): """Custom configuration step for OpenMPI.""" def config_opt_unused(key, enable_opt=False): """Helper function to check whether a configure option is already specified in 'configopts'.""" if enable_opt: regex = re.compile('--(disable|enable)-%s' % key) else: regex = re.compile('--(with|without)-%s' % key) return not bool(regex.search(self.cfg['configopts'])) config_opt_names = [ # suppress failure modes in relation to mpirun path 'mpirun-prefix-by-default', # build shared libraries 'shared', ] for key in config_opt_names: if config_opt_unused(key, enable_opt=True): self.cfg.update('configopts', '--enable-%s' % key) # check whether VERBS support should be enabled if config_opt_unused('verbs'): # auto-detect based on available OS packages verbs = False for osdep in [ 'libibverbs-dev', 'libibverbs-devel', 'rdma-core-devel' ]: if check_os_dependency(osdep): verbs = True break if verbs: self.cfg.update('configopts', '--with-verbs') else: self.cfg.update('configopts', '--without-verbs') # handle dependencies for dep in ['CUDA', 'hwloc', 'libevent', 'PMIx', 'UCX']: if config_opt_unused(dep.lower()): dep_root = get_software_root(dep) if dep_root: self.cfg.update('configopts', '--with-%s=%s' % (dep.lower(), dep_root)) super(EB_OpenMPI, self).configure_step()
def validate_os_deps(self): """ validate presence of OS dependencies osdependencies should be a single list """ not_found = [] for dep in self['osdependencies']: # make sure we have a tuple if isinstance(dep, basestring): dep = (dep,) elif not isinstance(dep, tuple): self.log.error("Non-tuple value type for OS dependency specification: %s (type %s)" % (dep, type(dep))) if not any([check_os_dependency(cand_dep) for cand_dep in dep]): not_found.append(dep) if not_found: self.log.error("One or more OS dependencies were not found: %s" % not_found) else: self.log.info("OS dependencies ok: %s" % self['osdependencies']) return True
def rebuild_rpm(rpm_path, targetdir): """Rebuild the RPM on the specified location, to make it relocatable.""" # make sure that rpmrebuild command is available if not check_os_dependency('rpmrebuild'): _log.error("Command 'rpmrebuild' is required but not available.") rpmmacros = os.path.join(expanduser('~'), '.rpmmacros') if os.path.exists(rpmmacros): _log.error("rpmmacros file %s found which will override any other settings, so exiting." % rpmmacros) rpmrebuild_tmpdir = os.path.join(tempfile.gettempdir(), "rpmrebuild") env.setvar("RPMREBUILD_TMPDIR", rpmrebuild_tmpdir) try: if not os.path.exists(rpmrebuild_tmpdir): os.makedirs(rpmrebuild_tmpdir) _log.debug("Created RPMREBUILD_TMPDIR dir %s" % rpmrebuild_tmpdir) if not os.path.exists(targetdir): os.makedirs(targetdir) _log.debug("Created target directory for rebuilt RPMs %s" % targetdir) except OSError, err: _log.error("Failed to create directories for rebuilding RPM: %s" % err)
def configure_step(self): """ Configure for GCC build: - prepare extra source dirs (GMP, MPFR, MPC, ...) - create obj dir to build in (GCC doesn't like to be built in source dir) - add configure and make options, according to .eb spec file - decide whether or not to do a staged build (which is required to enable PPL/CLooG support) - set platform_lib based on config.guess output """ sysroot = build_option('sysroot') if sysroot: # based on changes made to GCC in Gentoo Prefix # https://gitweb.gentoo.org/repo/gentoo.git/tree/profiles/features/prefix/standalone/profile.bashrc # add --with-sysroot configure option, to instruct GCC to consider # value set for EasyBuild's --sysroot configuration option as the root filesystem of the operating system # (see https://gcc.gnu.org/install/configure.html) self.cfg.update('configopts', '--with-sysroot=%s' % sysroot) # avoid that --sysroot is passed to linker by patching value for SYSROOT_SPEC in gcc/gcc.c apply_regex_substitutions(os.path.join('gcc', 'gcc.c'), [('--sysroot=%R', '')]) # prefix dynamic linkers with sysroot # this patches lines like: # #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" # for PowerPC (rs6000) we have to set DYNAMIC_LINKER_PREFIX to sysroot gcc_config_headers = glob.glob( os.path.join('gcc', 'config', '*', '*linux*.h')) regex_subs = [ ('(_DYNAMIC_LINKER.*[":])/lib', r'\1%s/lib' % sysroot), ('(DYNAMIC_LINKER_PREFIX\\s+)""', r'\1"%s"' % sysroot), ] for gcc_config_header in gcc_config_headers: apply_regex_substitutions(gcc_config_header, regex_subs) # self.configopts will be reused in a 3-staged build, # configopts is only used in first configure self.configopts = self.cfg['configopts'] # I) prepare extra source dirs, e.g. for GMP, MPFR, MPC (if required), so GCC can build them stage1_info = self.prep_extra_src_dirs("stage1") configopts = stage1_info['configopts'] # II) update config options # enable specified language support if self.cfg['languages']: self.configopts += " --enable-languages=%s" % ','.join( self.cfg['languages']) if self.cfg['withnvptx']: if self.iter_idx == 0: self.configopts += " --without-cuda-driver" self.configopts += " --enable-offload-targets=nvptx-none" else: # register installed GCC as compiler to use nvptx path = "%s/bin:%s" % (self.installdir, os.getenv('PATH')) env.setvar('PATH', path) ld_lib_path = "%(dir)s/lib64:%(dir)s/lib:%(val)s" % { 'dir': self.installdir, 'val': os.getenv('LD_LIBRARY_PATH') } env.setvar('LD_LIBRARY_PATH', ld_lib_path) extra_source = {1: "nvptx-tools", 2: "newlib"}[self.iter_idx] extra_source_dirs = glob.glob( os.path.join(self.builddir, '%s-*' % extra_source)) if len(extra_source_dirs) != 1: raise EasyBuildError("Failed to isolate %s source dir" % extra_source) if self.iter_idx == 1: # compile nvptx-tools change_dir(extra_source_dirs[0]) else: # self.iter_idx == 2 # compile nvptx target compiler symlink(os.path.join(extra_source_dirs[0], 'newlib'), 'newlib') self.create_dir("build-nvptx-gcc") self.cfg.update('configopts', self.configopts) self.cfg.update( 'configopts', "--with-build-time-tools=%s/nvptx-none/bin" % self.installdir) self.cfg.update('configopts', "--target=nvptx-none") host_type = self.determine_build_and_host_type()[1] self.cfg.update( 'configopts', "--enable-as-accelerator-for=%s" % host_type) self.cfg.update('configopts', "--disable-sjlj-exceptions") self.cfg.update('configopts', "--enable-newlib-io-long-long") self.cfg['configure_cmd_prefix'] = '../' return super(EB_GCC, self).configure_step() # enable building of libiberty, if desired if self.cfg['withlibiberty']: self.configopts += " --enable-install-libiberty" # enable link-time-optimization (LTO) support, if desired if self.cfg['withlto']: self.configopts += " --enable-lto" else: self.configopts += " --disable-lto" # configure for a release build self.configopts += " --enable-checking=release " # enable multilib: allow both 32 and 64 bit if self.cfg['multilib']: glibc_32bit = [ "glibc.i686", # Fedora, RedHat-based "glibc.ppc", # "" on Power "libc6-dev-i386", # Debian-based "gcc-c++-32bit", # OpenSuSE, SLES ] if not any([check_os_dependency(dep) for dep in glibc_32bit]): raise EasyBuildError( "Using multilib requires 32-bit glibc (install one of %s, depending on your OS)", ', '.join(glibc_32bit)) self.configopts += " --enable-multilib --with-multilib-list=m32,m64" else: self.configopts += " --disable-multilib" # build both static and dynamic libraries (???) self.configopts += " --enable-shared=yes --enable-static=yes " # use POSIX threads self.configopts += " --enable-threads=posix " # enable plugin support self.configopts += " --enable-plugins " # use GOLD as default linker if self.cfg['use_gold_linker']: self.configopts += " --enable-gold=default --enable-ld --with-plugin-ld=ld.gold" else: self.configopts += " --enable-gold --enable-ld=default" # enable bootstrap build for self-containment (unless for staged build) if not self.stagedbuild: configopts += " --enable-bootstrap" else: configopts += " --disable-bootstrap" if self.stagedbuild: # # STAGE 1: configure GCC build that will be used to build PPL/CLooG # self.log.info( "Starting with stage 1 of 3-staged build to enable CLooG and/or PPL, ISL support..." ) self.stage1installdir = os.path.join(self.builddir, 'GCC_stage1_eb') configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % { 'p': self.stage1installdir } else: # unstaged build, so just run standard configure/make/make install # set prefixes self.log.info("Performing regular GCC build...") configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % { 'p': self.installdir } # prioritize lib over lib{64,32,x32} for all architectures by overriding default MULTILIB_OSDIRNAMES config # only do this when multilib is not enabled if self.cfg['prefer_lib_subdir'] and not self.cfg['multilib']: cfgfile = 'gcc/config/i386/t-linux64' multilib_osdirnames = "MULTILIB_OSDIRNAMES = m64=../lib:../lib64 m32=../lib:../lib32 mx32=../lib:../libx32" self.log.info("Patching MULTILIB_OSDIRNAMES in %s with '%s'", cfgfile, multilib_osdirnames) write_file(cfgfile, multilib_osdirnames, append=True) elif self.cfg['multilib']: self.log.info( "Not patching MULTILIB_OSDIRNAMES since use of --enable-multilib is enabled" ) # III) create obj dir to build in, and change to it # GCC doesn't like to be built in the source dir if self.stagedbuild: objdir = self.create_dir("stage1_obj") self.stage1prefix = objdir else: objdir = self.create_dir("obj") # IV) actual configure, but not on default path cmd = "../configure %s %s" % (self.configopts, configopts) self.run_configure_cmd(cmd) self.disable_lto_mpfr_old_gcc(objdir)
def configure_step(self): """Custom configuration step for OpenMPI.""" def config_opt_used(key, enable_opt=False): """Helper function to check whether a configure option is already specified in 'configopts'.""" if enable_opt: regex = '--(disable|enable)-%s' % key else: regex = '--(with|without)-%s' % key return bool(re.search(regex, self.cfg['configopts'])) config_opt_names = [ # suppress failure modes in relation to mpirun path 'mpirun-prefix-by-default', # build shared libraries 'shared', ] for key in config_opt_names: if not config_opt_used(key, enable_opt=True): self.cfg.update('configopts', '--enable-%s' % key) # List of EasyBuild dependencies for which OMPI has known options known_dependencies = ('CUDA', 'hwloc', 'libevent', 'libfabric', 'PMIx', 'UCX') # Value to use for `--with-<dep>=<value>` if the dependency is not specified in the easyconfig # No entry is interpreted as no option added at all # This is to make builds reproducible even when the system libraries are changed and avoids failures # due to e.g. finding only PMIx but not libevent on the system unused_dep_value = dict() # Known options since version 3.0 (no earlier ones checked) if LooseVersion(self.version) >= LooseVersion('3.0'): # Default to disable the option with "no" unused_dep_value = {dep: 'no' for dep in known_dependencies} # For these the default is to use an internal copy and not using any is not supported for dep in ('hwloc', 'libevent', 'PMIx'): unused_dep_value[dep] = 'internal' # handle dependencies for dep in known_dependencies: opt_name = dep.lower() # If the option is already used, don't add it if config_opt_used(opt_name): continue # libfabric option renamed in OpenMPI 3.1.0 to ofi if dep == 'libfabric' and LooseVersion( self.version) >= LooseVersion('3.1'): opt_name = 'ofi' # Check new option name. They are synonyms since 3.1.0 for backward compatibility if config_opt_used(opt_name): continue dep_root = get_software_root(dep) # If the dependency is loaded, specify its path, else use the "unused" value, if any if dep_root: opt_value = dep_root else: opt_value = unused_dep_value.get(dep) if opt_value is not None: self.cfg.update('configopts', '--with-%s=%s' % (opt_name, opt_value)) if bool(get_software_root('PMIx')) != bool( get_software_root('libevent')): raise EasyBuildError( 'You must either use both PMIx and libevent as dependencies or none of them. ' 'This is to enforce the same libevent is used for OpenMPI as for PMIx or ' 'the behavior may be unpredictable.') # check whether VERBS support should be enabled if not config_opt_used('verbs'): # for OpenMPI v4.x, the openib BTL should be disabled when UCX is used; # this is required to avoid "error initializing an OpenFabrics device" warnings, # see also https://www.open-mpi.org/faq/?category=all#ofa-device-error is_ucx_enabled = ('--with-ucx' in self.cfg['configopts'] and '--with-ucx=no' not in self.cfg['configopts']) if LooseVersion( self.version) >= LooseVersion('4.0.0') and is_ucx_enabled: verbs = False else: # auto-detect based on available OS packages os_packages = EASYCONFIG_CONSTANTS['OS_PKG_IBVERBS_DEV'][0] verbs = any( check_os_dependency(osdep) for osdep in os_packages) if verbs: self.cfg.update('configopts', '--with-verbs') else: self.cfg.update('configopts', '--without-verbs') super(EB_OpenMPI, self).configure_step()
def configure_step(self): """ Configure for GCC build: - prepare extra source dirs (GMP, MPFR, MPC, ...) - create obj dir to build in (GCC doesn't like to be built in source dir) - add configure and make options, according to .eb spec file - decide whether or not to do a staged build (which is required to enable PPL/CLooG support) - set platform_lib based on config.guess output """ # self.configopts will be reused in a 3-staged build, # configopts is only used in first configure self.configopts = self.cfg['configopts'] # I) prepare extra source dirs, e.g. for GMP, MPFR, MPC (if required), so GCC can build them stage1_info = self.prep_extra_src_dirs("stage1") configopts = stage1_info['configopts'] # II) update config options # enable specified language support if self.cfg['languages']: self.configopts += " --enable-languages=%s" % ','.join(self.cfg['languages']) # enable building of libiberty, if desired if self.cfg['withlibiberty']: self.configopts += " --enable-install-libiberty" # enable link-time-optimization (LTO) support, if desired if self.cfg['withlto']: self.configopts += " --enable-lto" else: self.configopts += " --disable-lto" # configure for a release build self.configopts += " --enable-checking=release " # enable multilib: allow both 32 and 64 bit if self.cfg['multilib']: glibc_32bit = [ "glibc.i686", # Fedora, RedHat-based "glibc.ppc", # "" on Power "libc6-dev-i386", # Debian-based "gcc-c++-32bit", # OpenSuSE, SLES ] if not any([check_os_dependency(dep) for dep in glibc_32bit]): raise EasyBuildError("Using multilib requires 32-bit glibc (install one of %s, depending on your OS)", ', '.join(glibc_32bit)) self.configopts += " --enable-multilib --with-multilib-list=m32,m64" else: self.configopts += " --disable-multilib" # build both static and dynamic libraries (???) self.configopts += " --enable-shared=yes --enable-static=yes " # use POSIX threads self.configopts += " --enable-threads=posix " # enable plugin support self.configopts += " --enable-plugins " # use GOLD as default linker if self.cfg['use_gold_linker']: self.configopts += " --enable-gold=default --enable-ld --with-plugin-ld=ld.gold" else: self.configopts += " --enable-gold --enable-ld=default" # enable bootstrap build for self-containment (unless for staged build) if not self.stagedbuild: configopts += " --enable-bootstrap" else: configopts += " --disable-bootstrap" if self.stagedbuild: # # STAGE 1: configure GCC build that will be used to build PPL/CLooG # self.log.info("Starting with stage 1 of 3-staged build to enable CLooG and/or PPL, ISL support...") self.stage1installdir = os.path.join(self.builddir, 'GCC_stage1_eb') configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % {'p': self.stage1installdir} else: # unstaged build, so just run standard configure/make/make install # set prefixes self.log.info("Performing regular GCC build...") configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % {'p': self.installdir} # prioritize lib over lib{64,32,x32} for all architectures by overriding default MULTILIB_OSDIRNAMES config # only do this when multilib is not enabled if self.cfg['prefer_lib_subdir'] and not self.cfg['multilib']: cfgfile = 'gcc/config/i386/t-linux64' multilib_osdirnames = "MULTILIB_OSDIRNAMES = m64=../lib:../lib64 m32=../lib:../lib32 mx32=../lib:../libx32" self.log.info("Patching MULTILIB_OSDIRNAMES in %s with '%s'", cfgfile, multilib_osdirnames) write_file(cfgfile, multilib_osdirnames, append=True) elif self.cfg['multilib']: self.log.info("Not patching MULTILIB_OSDIRNAMES since use of --enable-multilib is enabled") # III) create obj dir to build in, and change to it # GCC doesn't like to be built in the source dir if self.stagedbuild: objdir = self.create_dir("stage1_obj") self.stage1prefix = objdir else: objdir = self.create_dir("obj") # IV) actual configure, but not on default path cmd = "../configure %s %s" % (self.configopts, configopts) # instead of relying on uname, we run the same command GCC uses to # determine the platform out, ec = run_cmd("../config.guess", simple=False) if ec == 0: self.platform_lib = out.rstrip() self.run_configure_cmd(cmd) self.disable_lto_mpfr_old_gcc(objdir)
def configure_step(self): """ Configure for GCC build: - prepare extra source dirs (GMP, MPFR, MPC, ...) - create obj dir to build in (GCC doesn't like to be built in source dir) - add configure and make options, according to .eb spec file - decide whether or not to do a staged build (which is required to enable PPL/CLooG support) - set platform_lib based on config.guess output """ # self.configopts will be reused in a 3-staged build, # configopts is only used in first configure self.configopts = self.cfg['configopts'] # I) prepare extra source dirs, e.g. for GMP, MPFR, MPC (if required), so GCC can build them stage1_info = self.prep_extra_src_dirs("stage1") configopts = stage1_info['configopts'] # II) update config options # enable specified language support if self.cfg['languages']: self.configopts += " --enable-languages=%s" % ','.join( self.cfg['languages']) # enable building of libiberty, if desired if self.cfg['withlibiberty']: self.configopts += " --enable-install-libiberty" # enable link-time-optimization (LTO) support, if desired if self.cfg['withlto']: self.configopts += " --enable-lto" else: self.configopts += " --disable-lto" # configure for a release build self.configopts += " --enable-checking=release " # enable multilib: allow both 32 and 64 bit if self.cfg['multilib']: glibc_32bit = [ "glibc.i686", # Fedora, RedHat-based "glibc.ppc", # "" on Power "libc6-dev-i386", # Debian-based "gcc-c++-32bit", # OpenSuSE, SLES ] if not any([check_os_dependency(dep) for dep in glibc_32bit]): raise EasyBuildError( "Using multilib requires 32-bit glibc (install one of %s, depending on your OS)", ', '.join(glibc_32bit)) self.configopts += " --enable-multilib --with-multilib-list=m32,m64" else: self.configopts += " --disable-multilib" # build both static and dynamic libraries (???) self.configopts += " --enable-shared=yes --enable-static=yes " # use POSIX threads self.configopts += " --enable-threads=posix " # enable plugin support self.configopts += " --enable-plugins " # use GOLD as default linker if self.cfg['use_gold_linker']: self.configopts += " --enable-gold=default --enable-ld --with-plugin-ld=ld.gold" else: self.configopts += " --enable-gold --enable-ld=default" # enable bootstrap build for self-containment (unless for staged build) if not self.stagedbuild: configopts += " --enable-bootstrap" else: configopts += " --disable-bootstrap" if self.stagedbuild: # # STAGE 1: configure GCC build that will be used to build PPL/CLooG # self.log.info( "Starting with stage 1 of 3-staged build to enable CLooG and/or PPL, ISL support..." ) self.stage1installdir = os.path.join(self.builddir, 'GCC_stage1_eb') configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % { 'p': self.stage1installdir } else: # unstaged build, so just run standard configure/make/make install # set prefixes self.log.info("Performing regular GCC build...") configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % { 'p': self.installdir } # prioritize lib over lib{64,32,x32} for all architectures by overriding default MULTILIB_OSDIRNAMES config # only do this when multilib is not enabled if self.cfg['prefer_lib_subdir'] and not self.cfg['multilib']: cfgfile = 'gcc/config/i386/t-linux64' multilib_osdirnames = "MULTILIB_OSDIRNAMES = m64=../lib:../lib64 m32=../lib:../lib32 mx32=../lib:../libx32" self.log.info("Patching MULTILIB_OSDIRNAMES in %s with '%s'", cfgfile, multilib_osdirnames) write_file(cfgfile, multilib_osdirnames, append=True) elif self.cfg['multilib']: self.log.info( "Not patching MULTILIB_OSDIRNAMES since use of --enable-multilib is enabled" ) # III) create obj dir to build in, and change to it # GCC doesn't like to be built in the source dir if self.stagedbuild: objdir = self.create_dir("stage1_obj") self.stage1prefix = objdir else: objdir = self.create_dir("obj") # IV) actual configure, but not on default path cmd = "../configure %s %s" % (self.configopts, configopts) # instead of relying on uname, we run the same command GCC uses to # determine the platform out, ec = run_cmd("../config.guess", simple=False) if ec == 0: self.platform_lib = out.rstrip() self.run_configure_cmd(cmd) self.disable_lto_mpfr_old_gcc(objdir)
def configure_step(self): """ Configure for GCC build: - prepare extra source dirs (GMP, MPFR, MPC, ...) - create obj dir to build in (GCC doesn't like to be built in source dir) - add configure and make options, according to .eb spec file - decide whether or not to do a staged build (which is required to enable PPL/CLooG support) - set platform_lib based on config.guess output """ sysroot = build_option('sysroot') if sysroot: # based on changes made to GCC in Gentoo Prefix # https://gitweb.gentoo.org/repo/gentoo.git/tree/profiles/features/prefix/standalone/profile.bashrc # add --with-sysroot configure option, to instruct GCC to consider # value set for EasyBuild's --sysroot configuration option as the root filesystem of the operating system # (see https://gcc.gnu.org/install/configure.html) self.cfg.update('configopts', '--with-sysroot=%s' % sysroot) # avoid that --sysroot is passed to linker by patching value for SYSROOT_SPEC in gcc/gcc.c apply_regex_substitutions(os.path.join('gcc', 'gcc.c'), [('--sysroot=%R', '')]) # prefix dynamic linkers with sysroot # this patches lines like: # #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" gcc_config_headers = glob.glob( os.path.join('gcc', 'config', '*', '*linux*.h')) regex_subs = [('(_DYNAMIC_LINKER.*[":])/lib', r'\1%s/lib' % sysroot)] apply_regex_substitutions(gcc_config_headers, regex_subs) # self.configopts will be reused in a 3-staged build, # configopts is only used in first configure self.configopts = self.cfg['configopts'] # I) prepare extra source dirs, e.g. for GMP, MPFR, MPC (if required), so GCC can build them stage1_info = self.prep_extra_src_dirs("stage1") configopts = stage1_info['configopts'] # II) update config options # enable specified language support if self.cfg['languages']: self.configopts += " --enable-languages=%s" % ','.join( self.cfg['languages']) # enable building of libiberty, if desired if self.cfg['withlibiberty']: self.configopts += " --enable-install-libiberty" # enable link-time-optimization (LTO) support, if desired if self.cfg['withlto']: self.configopts += " --enable-lto" else: self.configopts += " --disable-lto" # configure for a release build self.configopts += " --enable-checking=release " # enable multilib: allow both 32 and 64 bit if self.cfg['multilib']: glibc_32bit = [ "glibc.i686", # Fedora, RedHat-based "glibc.ppc", # "" on Power "libc6-dev-i386", # Debian-based "gcc-c++-32bit", # OpenSuSE, SLES ] if not any([check_os_dependency(dep) for dep in glibc_32bit]): raise EasyBuildError( "Using multilib requires 32-bit glibc (install one of %s, depending on your OS)", ', '.join(glibc_32bit)) self.configopts += " --enable-multilib --with-multilib-list=m32,m64" else: self.configopts += " --disable-multilib" # build both static and dynamic libraries (???) self.configopts += " --enable-shared=yes --enable-static=yes " # use POSIX threads self.configopts += " --enable-threads=posix " # enable plugin support self.configopts += " --enable-plugins " # use GOLD as default linker if self.cfg['use_gold_linker']: self.configopts += " --enable-gold=default --enable-ld --with-plugin-ld=ld.gold" else: self.configopts += " --enable-gold --enable-ld=default" # enable bootstrap build for self-containment (unless for staged build) if not self.stagedbuild: configopts += " --enable-bootstrap" else: configopts += " --disable-bootstrap" if self.stagedbuild: # # STAGE 1: configure GCC build that will be used to build PPL/CLooG # self.log.info( "Starting with stage 1 of 3-staged build to enable CLooG and/or PPL, ISL support..." ) self.stage1installdir = os.path.join(self.builddir, 'GCC_stage1_eb') configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % { 'p': self.stage1installdir } else: # unstaged build, so just run standard configure/make/make install # set prefixes self.log.info("Performing regular GCC build...") configopts += " --prefix=%(p)s --with-local-prefix=%(p)s" % { 'p': self.installdir } # prioritize lib over lib{64,32,x32} for all architectures by overriding default MULTILIB_OSDIRNAMES config # only do this when multilib is not enabled if self.cfg['prefer_lib_subdir'] and not self.cfg['multilib']: cfgfile = 'gcc/config/i386/t-linux64' multilib_osdirnames = "MULTILIB_OSDIRNAMES = m64=../lib:../lib64 m32=../lib:../lib32 mx32=../lib:../libx32" self.log.info("Patching MULTILIB_OSDIRNAMES in %s with '%s'", cfgfile, multilib_osdirnames) write_file(cfgfile, multilib_osdirnames, append=True) elif self.cfg['multilib']: self.log.info( "Not patching MULTILIB_OSDIRNAMES since use of --enable-multilib is enabled" ) # III) create obj dir to build in, and change to it # GCC doesn't like to be built in the source dir if self.stagedbuild: objdir = self.create_dir("stage1_obj") self.stage1prefix = objdir else: objdir = self.create_dir("obj") # note: this also triggers the use of an updated config.guess script # (unless both the 'build_type' and 'host_type' easyconfig parameters are specified) build_type, host_type = self.determine_build_and_host_type() if build_type: configopts += ' --build=' + build_type if host_type: configopts += ' --host=' + host_type # IV) actual configure, but not on default path cmd = "../configure %s %s" % (self.configopts, configopts) self.run_configure_cmd(cmd) self.disable_lto_mpfr_old_gcc(objdir)