Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Lib/ctypes/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions Lib/test/test_ctypes/test_find.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:func:`ctypes.util.find_library` now works in Emscripten build.
Loading