mirror of
https://github.com/python/cpython.git
synced 2025-11-24 12:20:42 +00:00
[3.14] gh-99948: Support ctypes.util.find_library in emscripten environment (GH-138519) (#139022)
Co-authored-by: Gyeongjae Choi <def6488@gmail.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
This commit is contained in:
parent
c1154943b1
commit
9741cfc73a
3 changed files with 88 additions and 0 deletions
|
|
@ -173,6 +173,25 @@ elif sys.platform == "android":
|
|||
fname = f"{directory}/lib{name}.so"
|
||||
return fname if os.path.isfile(fname) else None
|
||||
|
||||
elif sys.platform == "emscripten":
|
||||
def _is_wasm(filename):
|
||||
# Return True if the given file is an WASM module
|
||||
wasm_header = b"\x00asm"
|
||||
with open(filename, 'br') as thefile:
|
||||
return thefile.read(4) == wasm_header
|
||||
|
||||
def find_library(name):
|
||||
candidates = [f"lib{name}.so", f"lib{name}.wasm"]
|
||||
paths = os.environ.get("LD_LIBRARY_PATH", "")
|
||||
for libdir in paths.split(":"):
|
||||
for name in candidates:
|
||||
libfile = os.path.join(libdir, name)
|
||||
|
||||
if os.path.isfile(libfile) and _is_wasm(libfile):
|
||||
return libfile
|
||||
|
||||
return None
|
||||
|
||||
elif os.name == "posix":
|
||||
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
|
||||
import re, tempfile
|
||||
|
|
|
|||
|
|
@ -153,5 +153,73 @@ class FindLibraryAndroid(unittest.TestCase):
|
|||
self.assertIsNone(find_library(name))
|
||||
|
||||
|
||||
@unittest.skipUnless(test.support.is_emscripten,
|
||||
'Test only valid for Emscripten')
|
||||
class FindLibraryEmscripten(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
import tempfile
|
||||
|
||||
# A very simple wasm module
|
||||
# In WAT format: (module)
|
||||
cls.wasm_module = b'\x00asm\x01\x00\x00\x00\x00\x08\x04name\x02\x01\x00'
|
||||
|
||||
cls.non_wasm_content = b'This is not a WASM file'
|
||||
|
||||
cls.temp_dir = tempfile.mkdtemp()
|
||||
cls.libdummy_so_path = os.path.join(cls.temp_dir, 'libdummy.so')
|
||||
with open(cls.libdummy_so_path, 'wb') as f:
|
||||
f.write(cls.wasm_module)
|
||||
|
||||
cls.libother_wasm_path = os.path.join(cls.temp_dir, 'libother.wasm')
|
||||
with open(cls.libother_wasm_path, 'wb') as f:
|
||||
f.write(cls.wasm_module)
|
||||
|
||||
cls.libnowasm_so_path = os.path.join(cls.temp_dir, 'libnowasm.so')
|
||||
with open(cls.libnowasm_so_path, 'wb') as f:
|
||||
f.write(cls.non_wasm_content)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
import shutil
|
||||
shutil.rmtree(cls.temp_dir)
|
||||
|
||||
def test_find_wasm_file_with_so_extension(self):
|
||||
with os_helper.EnvironmentVarGuard() as env:
|
||||
env.set('LD_LIBRARY_PATH', self.temp_dir)
|
||||
result = find_library('dummy')
|
||||
self.assertEqual(result, self.libdummy_so_path)
|
||||
def test_find_wasm_file_with_wasm_extension(self):
|
||||
with os_helper.EnvironmentVarGuard() as env:
|
||||
env.set('LD_LIBRARY_PATH', self.temp_dir)
|
||||
result = find_library('other')
|
||||
self.assertEqual(result, self.libother_wasm_path)
|
||||
|
||||
def test_ignore_non_wasm_file(self):
|
||||
with os_helper.EnvironmentVarGuard() as env:
|
||||
env.set('LD_LIBRARY_PATH', self.temp_dir)
|
||||
result = find_library('nowasm')
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_find_nothing_without_ld_library_path(self):
|
||||
with os_helper.EnvironmentVarGuard() as env:
|
||||
if 'LD_LIBRARY_PATH' in env:
|
||||
del env['LD_LIBRARY_PATH']
|
||||
result = find_library('dummy')
|
||||
self.assertIsNone(result)
|
||||
result = find_library('other')
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_find_nothing_with_wrong_ld_library_path(self):
|
||||
import tempfile
|
||||
with tempfile.TemporaryDirectory() as empty_dir:
|
||||
with os_helper.EnvironmentVarGuard() as env:
|
||||
env.set('LD_LIBRARY_PATH', empty_dir)
|
||||
result = find_library('dummy')
|
||||
self.assertIsNone(result)
|
||||
result = find_library('other')
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
:func:`ctypes.util.find_library` now works in Emscripten build.
|
||||
Loading…
Add table
Add a link
Reference in a new issue