swig: fix older builds on newer platforms by updating config files (#16854)

* swig: revise 'autotools' automated 'config.*' update mechanism to support 'config.sub' and adapt 'swig' accordingly
This commit is contained in:
Joseph Ciurej 2020-06-22 08:44:29 -07:00 committed by GitHub
parent 4e9a98997a
commit 42f2c168d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 58 deletions

View File

@ -57,8 +57,9 @@ class AutotoolsPackage(PackageBase):
#: This attribute is used in UI queries that need to know the build #: This attribute is used in UI queries that need to know the build
#: system base class #: system base class
build_system_class = 'AutotoolsPackage' build_system_class = 'AutotoolsPackage'
#: Whether or not to update ``config.guess`` on old architectures #: Whether or not to update ``config.guess`` and ``config.sub`` on old
patch_config_guess = True #: architectures
patch_config_files = True
#: Whether or not to update ``libtool`` #: Whether or not to update ``libtool``
#: (currently only for Arm/Clang/Fujitsu compilers) #: (currently only for Arm/Clang/Fujitsu compilers)
patch_libtool = True patch_libtool = True
@ -87,72 +88,92 @@ def archive_files(self):
return [os.path.join(self.build_directory, 'config.log')] return [os.path.join(self.build_directory, 'config.log')]
@run_after('autoreconf') @run_after('autoreconf')
def _do_patch_config_guess(self): def _do_patch_config_files(self):
"""Some packages ship with an older config.guess and need to have """Some packages ship with older config.guess/config.sub files and
this updated when installed on a newer architecture. In particular, need to have these updated when installed on a newer architecture.
config.guess fails for PPC64LE for version prior to a 2013-06-10 In particular, config.guess fails for PPC64LE for version prior
build date (automake 1.13.4) and for ARM (aarch64).""" to a 2013-06-10 build date (automake 1.13.4) and for ARM (aarch64)."""
if not self.patch_config_guess or ( if not self.patch_config_files or (
not self.spec.satisfies('target=ppc64le:') and not self.spec.satisfies('target=ppc64le:') and
not self.spec.satisfies('target=aarch64:') not self.spec.satisfies('target=aarch64:')
): ):
return return
my_config_guess = None
config_guess = None # TODO: Expand this to select the 'config.sub'-compatible architecture
if os.path.exists('config.guess'): # for each platform (e.g. 'config.sub' doesn't accept 'power9le', but
# First search the top-level source directory # does accept 'ppc64le').
my_config_guess = 'config.guess' if self.spec.satisfies('target=ppc64le:'):
config_arch = 'ppc64le'
elif self.spec.satisfies('target=aarch64:'):
config_arch = 'aarch64'
else: else:
# Then search in all sub directories. config_arch = 'local'
my_config_files = {'guess': None, 'sub': None}
config_files = {'guess': None, 'sub': None}
config_args = {'guess': [], 'sub': [config_arch]}
for config_name in config_files.keys():
config_file = 'config.{0}'.format(config_name)
if os.path.exists(config_file):
# First search the top-level source directory
my_config_files[config_name] = config_file
else:
# Then search in all sub directories recursively.
# We would like to use AC_CONFIG_AUX_DIR, but not all packages # We would like to use AC_CONFIG_AUX_DIR, but not all packages
# ship with their configure.in or configure.ac. # ship with their configure.in or configure.ac.
d = '.' config_path = next((os.path.join(r, f)
dirs = [os.path.join(d, o) for o in os.listdir(d) for r, ds, fs in os.walk('.') for f in fs
if os.path.isdir(os.path.join(d, o))] if f == config_file), None)
for dirname in dirs: my_config_files[config_name] = config_path
path = os.path.join(dirname, 'config.guess')
if os.path.exists(path):
my_config_guess = path
if my_config_guess is not None: if my_config_files[config_name] is not None:
try: try:
check_call([my_config_guess], stdout=PIPE, stderr=PIPE) config_path = my_config_files[config_name]
# The package's config.guess already runs OK, so just use it check_call([config_path] + config_args[config_name],
return stdout=PIPE, stderr=PIPE)
# The package's config file already runs OK, so just use it
continue
except Exception as e: except Exception as e:
tty.debug(e) tty.debug(e)
else: else:
return continue
# Look for a spack-installed automake package # Look for a spack-installed automake package
if 'automake' in self.spec: if 'automake' in self.spec:
automake_path = os.path.join(self.spec['automake'].prefix, 'share', automake_dir = 'automake-' + str(self.spec['automake'].version)
'automake-' + automake_path = os.path.join(self.spec['automake'].prefix,
str(self.spec['automake'].version)) 'share', automake_dir)
path = os.path.join(automake_path, 'config.guess') path = os.path.join(automake_path, config_file)
if os.path.exists(path): if os.path.exists(path):
config_guess = path config_files[config_name] = path
# Look for the system's config.guess # Look for the system's config.guess
if config_guess is None and os.path.exists('/usr/share'): if (config_files[config_name] is None and
os.path.exists('/usr/share')):
automake_dir = [s for s in os.listdir('/usr/share') if automake_dir = [s for s in os.listdir('/usr/share') if
"automake" in s] "automake" in s]
if automake_dir: if automake_dir:
automake_path = os.path.join('/usr/share', automake_dir[0]) automake_path = os.path.join('/usr/share', automake_dir[0])
path = os.path.join(automake_path, 'config.guess') path = os.path.join(automake_path, config_file)
if os.path.exists(path): if os.path.exists(path):
config_guess = path config_files[config_name] = path
if config_guess is not None: if config_files[config_name] is not None:
try: try:
check_call([config_guess], stdout=PIPE, stderr=PIPE) config_path = config_files[config_name]
mod = os.stat(my_config_guess).st_mode & 0o777 | stat.S_IWUSR my_config_path = my_config_files[config_name]
os.chmod(my_config_guess, mod)
shutil.copyfile(config_guess, my_config_guess) check_call([config_path] + config_args[config_name],
return stdout=PIPE, stderr=PIPE)
m = os.stat(my_config_path).st_mode & 0o777 | stat.S_IWUSR
os.chmod(my_config_path, m)
shutil.copyfile(config_path, my_config_path)
continue
except Exception as e: except Exception as e:
tty.debug(e) tty.debug(e)
raise RuntimeError('Failed to find suitable config.guess') raise RuntimeError('Failed to find suitable ' + config_file)
@run_before('configure') @run_before('configure')
def _set_autotools_environment_variables(self): def _set_autotools_environment_variables(self):

View File

@ -43,6 +43,9 @@ class Swig(AutotoolsPackage, SourceforgePackage):
depends_on('autoconf', type='build', when=_version) depends_on('autoconf', type='build', when=_version)
depends_on('automake', type='build', when=_version) depends_on('automake', type='build', when=_version)
depends_on('libtool', type='build', when=_version) depends_on('libtool', type='build', when=_version)
# Need newer 'automake' to support newer platforms
for _target in ['ppc64le', 'aarch64']:
depends_on('automake@1.15:', type='build', when='target={0}:'.format(_target))
depends_on('pkgconfig', type='build') depends_on('pkgconfig', type='build')
build_directory = 'spack-build' build_directory = 'spack-build'