Skip to content

GH-127429: fix sysconfig data generation on cross-builds #127430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 2, 2024
2 changes: 1 addition & 1 deletion .github/workflows/jit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:

# The `find` line is required as a result of https://github.com/actions/runner-images/issues/9966.
# This is a bug in the macOS runner image where the pre-installed Python is installed in the same
# directory as the Homebrew Python, which causes the build to fail for macos-13. This line removes
# directory as the Homebrew Python, which causes the build to fail for macos-13. This line removes
# the symlink to the pre-installed Python so that the Homebrew Python is used instead.
- name: Native macOS
if: runner.os == 'macOS'
Expand Down
49 changes: 36 additions & 13 deletions Lib/sysconfig/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,22 @@ def get_default_scheme():

def get_makefile_filename():
"""Return the path of the Makefile."""

# GH-127429: When cross-compiling, use the Makefile from the target, instead of the host Python.
if cross_base := os.environ.get('_PYTHON_PROJECT_BASE'):
return os.path.join(cross_base, 'Makefile')

if _PYTHON_BUILD:
return os.path.join(_PROJECT_BASE, "Makefile")

if hasattr(sys, 'abiflags'):
config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}'
else:
config_dir_name = 'config'

if hasattr(sys.implementation, '_multiarch'):
config_dir_name += f'-{sys.implementation._multiarch}'

return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile')


Expand Down Expand Up @@ -464,27 +472,44 @@ def get_path(name, scheme=get_default_scheme(), vars=None, expand=True):
def _init_config_vars():
global _CONFIG_VARS
_CONFIG_VARS = {}

prefix = _PREFIX
exec_prefix = _EXEC_PREFIX
base_prefix = _BASE_PREFIX
base_exec_prefix = _BASE_EXEC_PREFIX

try:
abiflags = sys.abiflags
except AttributeError:
abiflags = ''

if os.name == 'posix':
_init_posix(_CONFIG_VARS)
# If we are cross-compiling, load the prefixes from the Makefile instead.
if '_PYTHON_PROJECT_BASE' in os.environ:
prefix = _CONFIG_VARS['prefix']
exec_prefix = _CONFIG_VARS['exec_prefix']
base_prefix = _CONFIG_VARS['prefix']
base_exec_prefix = _CONFIG_VARS['exec_prefix']
abiflags = _CONFIG_VARS['ABIFLAGS']

# Normalized versions of prefix and exec_prefix are handy to have;
# in fact, these are the standard versions used most places in the
# Distutils.
_CONFIG_VARS['prefix'] = _PREFIX
_CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
_CONFIG_VARS['prefix'] = prefix
_CONFIG_VARS['exec_prefix'] = exec_prefix
_CONFIG_VARS['py_version'] = _PY_VERSION
_CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
_CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT
_CONFIG_VARS['installed_base'] = _BASE_PREFIX
_CONFIG_VARS['base'] = _PREFIX
_CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX
_CONFIG_VARS['platbase'] = _EXEC_PREFIX
_CONFIG_VARS['installed_base'] = base_prefix
_CONFIG_VARS['base'] = prefix
_CONFIG_VARS['installed_platbase'] = base_exec_prefix
_CONFIG_VARS['platbase'] = exec_prefix
_CONFIG_VARS['projectbase'] = _PROJECT_BASE
_CONFIG_VARS['platlibdir'] = sys.platlibdir
_CONFIG_VARS['implementation'] = _get_implementation()
_CONFIG_VARS['implementation_lower'] = _get_implementation().lower()
try:
_CONFIG_VARS['abiflags'] = sys.abiflags
except AttributeError:
# sys.abiflags may not be defined on all platforms.
_CONFIG_VARS['abiflags'] = ''
_CONFIG_VARS['abiflags'] = abiflags
try:
_CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '')
except AttributeError:
Expand All @@ -493,8 +518,6 @@ def _init_config_vars():
if os.name == 'nt':
_init_non_posix(_CONFIG_VARS)
_CONFIG_VARS['VPATH'] = sys._vpath
if os.name == 'posix':
_init_posix(_CONFIG_VARS)
if _HAS_USER_BASE:
# Setting 'userbase' is done below the call to the
# init function to enable using 'get_config_var' in
Expand Down
7 changes: 6 additions & 1 deletion Lib/sysconfig/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
_PYTHON_BUILD,
_get_sysconfigdata_name,
get_config_h_filename,
get_config_var,
get_config_vars,
get_default_scheme,
get_makefile_filename,
Expand Down Expand Up @@ -161,7 +162,7 @@ def _print_config_dict(d, stream):

def _get_pybuilddir():
pybuilddir = f'build/lib.{get_platform()}-{get_python_version()}'
if hasattr(sys, "gettotalrefcount"):
if get_config_var('Py_DEBUG') == '1':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_config_var('Py_DEBUG') is an int rather than str.

pybuilddir += '-pydebug'
return pybuilddir

Expand Down Expand Up @@ -229,11 +230,15 @@ def _generate_posix_vars():
f.write('build_time_vars = ')
_print_config_dict(vars, stream=f)

print(f'Written {destfile}')

# Write a JSON file with the output of sysconfig.get_config_vars
jsonfile = os.path.join(pybuilddir, _get_json_data_name())
with open(jsonfile, 'w') as f:
json.dump(get_config_vars(), f, indent=2)

print(f'Written {jsonfile}')

# Create file used for sys.path fixup -- see Modules/getpath.c
with open('pybuilddir.txt', 'w', encoding='utf8') as f:
f.write(pybuilddir)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed bug where, on cross-builds, the :mod:`sysconfig` POSIX data was being
generated with the host Python's ``Makefile``. The data is now generated from
current build's ``Makefile``.
6 changes: 2 additions & 4 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1609,8 +1609,8 @@ if test "$cross_compiling" = yes; then
RUNSHARED=
fi

# HOSTRUNNER - Program to run CPython for the host platform
AC_MSG_CHECKING([HOSTRUNNER])
AC_ARG_VAR([HOSTRUNNER], [Program to run CPython for the host platform])
if test -z "$HOSTRUNNER"
then
AS_CASE([$ac_sys_system],
Expand Down
Loading