Fix clingo bootstrapping on rhel + ppc64le

The system Python interpreter on rhel is patched to have
slightly different names for some architectures. This
makes it incompatible with manylinux generated extensions
for ppc64le.

To fix this issue when bootstrapping Spack we generate
on-the-fly symbolic links to the name expected by the
current interpreter if it differs from the default.

Links:
  https://github.com/pypa/manylinux/issues/687
  https://src.fedoraproject.org/fork/churchyard/rpms/python3/blame/00274-fix-arch-names.patch?identifier=test_email-mktime
This commit is contained in:
Massimiliano Culpo 2021-09-02 16:43:43 +02:00 committed by Todd Gamblin
parent 4033cc0250
commit fd0884c273

View file

@ -5,8 +5,11 @@
from __future__ import print_function from __future__ import print_function
import contextlib import contextlib
import fnmatch
import json import json
import os import os
import os.path
import re
import sys import sys
try: try:
@ -81,6 +84,7 @@ def _try_import_from_store(module, abstract_spec_str):
sys.path.extend(module_paths) sys.path.extend(module_paths)
try: try:
_fix_ext_suffix(candidate_spec)
if _python_import(module): if _python_import(module):
msg = ('[BOOTSTRAP MODULE {0}] The installed spec "{1}/{2}" ' msg = ('[BOOTSTRAP MODULE {0}] The installed spec "{1}/{2}" '
'provides the "{0}" Python module').format( 'provides the "{0}" Python module').format(
@ -101,6 +105,55 @@ def _try_import_from_store(module, abstract_spec_str):
return False return False
def _fix_ext_suffix(candidate_spec):
"""Fix the external suffixes of Python extensions on the fly for
platforms that may need it
Args:
candidate_spec (Spec): installed spec with a Python module
to be checked.
"""
# Here we map target families to the patterns expected
# by pristine CPython. Only architectures with known issues
# are included. Known issues:
#
# [RHEL + ppc64le]: https://github.com/spack/spack/issues/25734
#
_suffix_to_be_checked = {
'ppc64le': {
'glob': '*.cpython-*-powerpc64le-linux-gnu.so',
're': r'.cpython-[\w]*-powerpc64le-linux-gnu.so'
}
}
# If the current architecture is not problematic return
generic_target = archspec.cpu.host().family
if str(generic_target) not in _suffix_to_be_checked:
return
# If there's no EXT_SUFFIX (Python < 3.5) or the suffix matches
# the expectations, return since the package is surely good
ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
if ext_suffix is None:
return
expected = _suffix_to_be_checked[str(generic_target)]
if fnmatch.fnmatch(ext_suffix, expected['glob']):
return
# If we are here it means the current interpreter expects different names
# than pristine CPython. So:
# 1. Find what we have
# 2. Compute what we want
# 3. Create symbolic links if they're not there already
extensions_on_disk = fs.find(candidate_spec.prefix, expected['glob'])
link_names = [re.sub(expected['re'], ext_suffix, s) for s in extensions_on_disk]
for file_name, link_name in zip(extensions_on_disk, link_names):
if os.path.exists(link_name):
continue
os.symlink(file_name, link_name)
@_bootstrapper(type='buildcache') @_bootstrapper(type='buildcache')
class _BuildcacheBootstrapper(object): class _BuildcacheBootstrapper(object):
"""Install the software needed during bootstrapping from a buildcache.""" """Install the software needed during bootstrapping from a buildcache."""