diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 99504911a3dbe0..2aec2bd166ea84 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -173,6 +173,28 @@ def find_library(name): 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): + if not _is_wasm(libfile): + continue + + return libfile + + return None + elif os.name == "posix": # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump import re, tempfile diff --git a/Lib/test/test_ctypes/test_find.py b/Lib/test/test_ctypes/test_find.py index 3bd41a0e435d91..ca7f233784b1d9 100644 --- a/Lib/test/test_ctypes/test_find.py +++ b/Lib/test/test_ctypes/test_find.py @@ -153,5 +153,37 @@ def test_find(self): self.assertIsNone(find_library(name)) +@unittest.skipUnless(test.support.is_emscripten, + 'Test only valid for Emscripten') +class FindLibraryEmscripten(unittest.TestCase): + def test_find_on_libpath(self): + import tempfile + + # A very simple wasm module + # In WAT format: (module) + wasm_module = b'\x00asm\x01\x00\x00\x00\x00\x08\x04name\x02\x01\x00' + + with tempfile.TemporaryDirectory() as d: + libname = 'dummy' + dstname = os.path.join(d, 'lib%s.so' % libname) + with open(dstname, 'wb') as f: + f.write(wasm_module) + + # now check that the .so can't be found (since not in + # LD_LIBRARY_PATH) + self.assertIsNone(find_library(libname)) + # now add the location to LD_LIBRARY_PATH + with os_helper.EnvironmentVarGuard() as env: + KEY = 'LD_LIBRARY_PATH' + if KEY not in env: + v = d + else: + v = '%s:%s' % (env[KEY], d) + env.set(KEY, v) + # now check that the .so can be found (since in + # LD_LIBRARY_PATH) + self.assertEqual(find_library(libname), dstname) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2025-09-05-05-53-43.gh-issue-99948.KMSlG6.rst b/Misc/NEWS.d/next/Library/2025-09-05-05-53-43.gh-issue-99948.KMSlG6.rst new file mode 100644 index 00000000000000..46e6dfad1cd5d8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-05-05-53-43.gh-issue-99948.KMSlG6.rst @@ -0,0 +1 @@ +:func:`ctypes.util.find_library` now works in Emscripten build.

AltStyle によって変換されたページ (->オリジナル) /