GH-128469: warn when libpython was loaded from outside the build directory (#128645)

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
Filipe Laíns 🇵🇸 2025-01-29 22:35:55 +00:00 committed by GitHub
parent a1a4e9f39a
commit 29b3ce8355
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 0 deletions

View file

@ -1,7 +1,13 @@
import copy import copy
import ntpath import ntpath
import os
import pathlib import pathlib
import posixpath import posixpath
import shutil
import subprocess
import sys
import sysconfig
import tempfile
import unittest import unittest
from test.support import verbose from test.support import verbose
@ -864,6 +870,37 @@ class MockGetPathTests(unittest.TestCase):
actual = getpath(ns, expected) actual = getpath(ns, expected)
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
class RealGetPathTests(unittest.TestCase):
@unittest.skipUnless(
sysconfig.is_python_build(),
'Test only available when running from the buildir',
)
@unittest.skipUnless(
any(sys.platform.startswith(p) for p in ('linux', 'freebsd', 'centos')),
'Test only support on Linux-like OS-es (support LD_LIBRARY_PATH)',
)
@unittest.skipUnless(
sysconfig.get_config_var('LDLIBRARY') != sysconfig.get_config_var('LIBRARY'),
'Test only available when using a dynamic libpython',
)
def test_builddir_wrong_library_warning(self):
library_name = sysconfig.get_config_var('INSTSONAME')
with tempfile.TemporaryDirectory() as tmpdir:
shutil.copy2(
os.path.join(sysconfig.get_config_var('srcdir'), library_name),
os.path.join(tmpdir, library_name)
)
env = os.environ.copy()
env['LD_LIBRARY_PATH'] = tmpdir
process = subprocess.run(
[sys.executable, '-c', ''],
env=env, check=True, capture_output=True, text=True,
)
error_msg = 'The runtime library has been loaded from outside the build directory'
self.assertTrue(process.stderr.startswith(error_msg), process.stderr)
# ****************************************************************************** # ******************************************************************************
DEFAULT_NAMESPACE = dict( DEFAULT_NAMESPACE = dict(

View file

@ -785,6 +785,19 @@ if os_name != 'nt' and build_prefix:
base_exec_prefix = config.get('base_exec_prefix') or EXEC_PREFIX or base_prefix base_exec_prefix = config.get('base_exec_prefix') or EXEC_PREFIX or base_prefix
# ******************************************************************************
# MISC. RUNTIME WARNINGS
# ******************************************************************************
# When running Python from the build directory, if libpython is dynamically
# linked, the wrong library might be loaded.
if build_prefix and library and not dirname(abspath(library)).startswith(build_prefix):
msg = f'The runtime library has been loaded from outside the build directory ({library})!'
if os_name == 'posix':
msg += ' Consider setting LD_LIBRARY_PATH=. to force it to be loaded from the build directory.'
warn(msg)
# ****************************************************************************** # ******************************************************************************
# SET pythonpath FROM _PTH FILE # SET pythonpath FROM _PTH FILE
# ****************************************************************************** # ******************************************************************************