123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- From ffe5a060a1b24bedc2aac5d60d6b3b7e40f55adc Mon Sep 17 00:00:00 2001
- From: Vincent Fazio <5265893+vfazio@users.noreply.github.com>
- Date: Wed, 28 Feb 2024 13:55:04 -0600
- Subject: [PATCH] gh-115382: Fix cross compiles when host and target use same
- SOABI
- Previously, when a build was configured to use a host interpreter via
- --with-build-python, the PYTHON_FOR_BUILD config value included a path
- in PYTHONPATH that pointed to the target's built external modules.
- For "normal" foreign architecture cross compiles, when loading compiled
- external libraries, the target libraries were processed first due to
- their precedence in sys.path. These libraries were then ruled out due to
- a mismatch in the SOABI so the import mechanism continued searching
- until it found the host's native modules.
- However, if the host interpreter and the target python were on the same
- version + SOABI combination, the host interpreter would attempt to load
- the target's external modules due to their precedence in sys.path.
- Despite the "match", the target build may have been linked against a
- different libc or may include unsupported instructions so loading or
- executing the target's external modules can lead to crashes.
- Now, the path to the target's external modules is no longer defined in
- PYTHONPATH to prevent accidentally loading these foreign modules.
- One caveat is that during certain build stages, the target's sysconfig
- module requires higher precedence than the host's version in order to
- accurately query the target build's configuration.
- This worked previously due to the target's sysconfig data module having
- precedence over the host's (see above). In order to keep this desired
- behavior, a new environment variable, _PYTHON_SYSCONFIGDATA_PATH, has
- been defined so sysconfig can search this directory for the target's
- sysconfig data.
- Signed-off-by: Vincent Fazio <vfazio@gmail.com>
- Upstream-issue: https://github.com/python/cpython/issues/115382
- Upstream: https://github.com/python/cpython/pull/116294
- ---
- Lib/sysconfig.py | 15 ++++++++++++++-
- Lib/test/libregrtest/main.py | 1 +
- Lib/test/pythoninfo.py | 1 +
- Tools/scripts/run_tests.py | 1 +
- configure | 2 +-
- configure.ac | 2 +-
- 6 files changed, 19 insertions(+), 3 deletions(-)
- diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
- index ebe37118274..ba424236e11 100644
- --- a/Lib/sysconfig.py
- +++ b/Lib/sysconfig.py
- @@ -528,7 +528,20 @@ def _init_posix(vars):
- """Initialize the module as appropriate for POSIX systems."""
- # _sysconfigdata is generated at build time, see _generate_posix_vars()
- name = _get_sysconfigdata_name()
- - _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
- +
- + # For cross builds, the path to the target's sysconfigdata must be specified
- + # so it can be imported. It cannot be in PYTHONPATH, as foreign modules in
- + # sys.path can cause crashes when loaded by the host interpreter.
- + # Rely on truthiness as a valueless env variable is still an empty string.
- + # See OS X note in _generate_posix_vars re _sysconfigdata.
- + if (path := os.environ.get('_PYTHON_SYSCONFIGDATA_PATH')):
- + from importlib.machinery import FileFinder, SourceFileLoader, SOURCE_SUFFIXES
- + from importlib.util import module_from_spec
- + spec = FileFinder(path, (SourceFileLoader, SOURCE_SUFFIXES)).find_spec(name)
- + _temp = module_from_spec(spec)
- + spec.loader.exec_module(_temp)
- + else:
- + _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
- build_time_vars = _temp.build_time_vars
- vars.update(build_time_vars)
-
- diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
- index a9725fa9673..121e2e73938 100644
- --- a/Lib/test/libregrtest/main.py
- +++ b/Lib/test/libregrtest/main.py
- @@ -519,6 +519,7 @@ def _add_cross_compile_opts(self, regrtest_opts):
- '_PYTHON_PROJECT_BASE',
- '_PYTHON_HOST_PLATFORM',
- '_PYTHON_SYSCONFIGDATA_NAME',
- + "_PYTHON_SYSCONFIGDATA_PATH",
- 'PYTHONPATH'
- }
- old_environ = os.environ
- diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py
- index 74ebb5e5b8a..fa7fbca34e1 100644
- --- a/Lib/test/pythoninfo.py
- +++ b/Lib/test/pythoninfo.py
- @@ -326,6 +326,7 @@ def format_groups(groups):
- "_PYTHON_HOST_PLATFORM",
- "_PYTHON_PROJECT_BASE",
- "_PYTHON_SYSCONFIGDATA_NAME",
- + "_PYTHON_SYSCONFIGDATA_PATH",
- "__PYVENV_LAUNCHER__",
-
- # Sanitizer options
- diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
- index 445a34ae3e8..4077a834245 100644
- --- a/Tools/scripts/run_tests.py
- +++ b/Tools/scripts/run_tests.py
- @@ -42,6 +42,7 @@ def main(regrtest_args):
- '_PYTHON_PROJECT_BASE',
- '_PYTHON_HOST_PLATFORM',
- '_PYTHON_SYSCONFIGDATA_NAME',
- + "_PYTHON_SYSCONFIGDATA_PATH",
- 'PYTHONPATH'
- }
- environ = {
- diff --git a/configure b/configure
- index cb3db60f9c2..5fc0cffa977 100755
- --- a/configure
- +++ b/configure
- @@ -3262,7 +3262,7 @@ fi
- fi
- ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python
- PYTHON_FOR_FREEZE="$with_build_python"
- - PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python
- + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5
- $as_echo "$with_build_python" >&6; }
-
- diff --git a/configure.ac b/configure.ac
- index 852cbaa6e4c..5ca316a948b 100644
- --- a/configure.ac
- +++ b/configure.ac
- @@ -162,7 +162,7 @@ AC_ARG_WITH(
- dnl Build Python interpreter is used for regeneration and freezing.
- ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python
- PYTHON_FOR_FREEZE="$with_build_python"
- - PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python
- + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python
- AC_MSG_RESULT([$with_build_python])
- ], [
- AS_VAR_IF([cross_compiling], [yes],
- --
- 2.44.0
|