auditwheel-emscripten 0.1.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  from pathlib import Path
2
2
 
3
3
  import typer
4
- from rich.pretty import pprint
5
4
 
6
5
  from .. import function_type, get_exports, get_imports, repair, show
6
+ from ..show import locate_dependency
7
7
  from ..wheel_utils import unpack_if_wheel
8
8
 
9
9
  app = typer.Typer()
@@ -14,18 +14,55 @@ def main():
14
14
  """Auditwheel-like tool for emscripten wheels and shared libraries."""
15
15
 
16
16
 
17
+ def print_dylib(
18
+ library: str,
19
+ deps: list[str],
20
+ runtime_paths: list[str],
21
+ libraries: list[str],
22
+ show_runtime_paths: bool = False,
23
+ ):
24
+ """
25
+ Print shared library dependencies and runtime paths.
26
+ The output looks similar to the output of `ldd`
27
+ """
28
+ print(f"{library}:")
29
+
30
+ for dep in deps:
31
+ line = f"\t{dep:>10}"
32
+ deppath = locate_dependency(library, dep, libraries, runtime_paths)
33
+ if deppath:
34
+ line += f" => {deppath}"
35
+ print(line)
36
+
37
+ if show_runtime_paths and runtime_paths:
38
+ print("\n\tRuntime search paths:")
39
+ for path in runtime_paths:
40
+ print(f"\t {path}")
41
+
42
+ print()
43
+
44
+
17
45
  @app.command("show")
18
46
  def _show(
19
47
  wheel_or_so_file: Path = typer.Argument(
20
48
  ..., help="Path to wheel or a shared library file."
21
- )
49
+ ),
50
+ show_runtime_paths: bool = typer.Option(
51
+ False,
52
+ "-r",
53
+ "--with-runtime-paths",
54
+ help="Show runtime paths.",
55
+ ),
22
56
  ):
23
57
  """
24
58
  Show shared library dependencies of a wheel or a shared library file.
25
59
  """
26
60
  try:
27
- dependencies = show(wheel_or_so_file)
28
- pprint(dependencies)
61
+ libraries = show(wheel_or_so_file)
62
+ for lib, (deps, runtime_paths) in libraries.items():
63
+ print_dylib(
64
+ lib, deps, runtime_paths, list(libraries.keys()), show_runtime_paths
65
+ )
29
66
  except Exception as e:
30
67
  raise e
31
68
 
@@ -41,6 +78,12 @@ def _repair(
41
78
  None,
42
79
  help="Directory to output repaired wheel or shared library. (default: overwrite the input file)",
43
80
  ),
81
+ show_runtime_paths: bool = typer.Option(
82
+ False,
83
+ "-r",
84
+ "--with-runtime-paths",
85
+ help="Show runtime paths.",
86
+ ),
44
87
  ):
45
88
  """
46
89
  Repair a wheel file: copy shared libraries to the wheel directory.
@@ -52,8 +95,11 @@ def _repair(
52
95
  output_dir,
53
96
  modify_rpath=True,
54
97
  )
55
- dependencies = show(repaired_wheel)
56
- pprint(dependencies)
98
+ libraries = show(repaired_wheel)
99
+ for lib, (deps, runtime_paths) in libraries.items():
100
+ print_dylib(
101
+ lib, deps, runtime_paths, list(libraries.keys()), show_runtime_paths
102
+ )
57
103
  except RuntimeError as e:
58
104
  raise e
59
105
 
@@ -9,19 +9,22 @@ from .show import show
9
9
  from .wheel_utils import WHEEL_INFO_RE, is_emscripten_wheel, pack, unpack
10
10
 
11
11
 
12
- def resolve_sharedlib(wheel_file: str | Path, libdir: str | Path) -> dict[str, Path]:
12
+ def resolve_sharedlib(wheel_file: str | Path, libdir: str | Path | list[str | Path]) -> dict[str, Path]:
13
13
  """
14
14
  Resolve the full path of shared libraries inside the wheel file
15
15
  """
16
+ libdirs = []
17
+ libdir = libdir if isinstance(libdir, list) else [libdir]
16
18
 
17
- libdirs = libdir_candidates(libdir)
19
+ for d in libdir:
20
+ libdirs.extend(libdir_candidates(d))
18
21
 
19
22
  dependencies = show(wheel_file)
20
23
  dep_queue = deque([lib, deps] for lib, deps in dependencies.items())
21
24
 
22
25
  dependencies_resolved: dict[str, Path] = {}
23
26
  while dep_queue:
24
- lib, deps = dep_queue.popleft()
27
+ lib, (deps, _) = dep_queue.popleft()
25
28
  for dep in deps:
26
29
  if dep in dependencies_resolved:
27
30
  continue
@@ -1,5 +1,6 @@
1
1
  import tempfile
2
2
  from pathlib import Path
3
+ import os.path
3
4
 
4
5
  from .lib_utils import get_all_shared_libs_in_dir, sharedlib_regex
5
6
  from .module import parse_dylink_section
@@ -7,26 +8,31 @@ from .wheel_utils import is_emscripten_wheel, unpack
7
8
  from .wasm_utils import is_wasm_module
8
9
 
9
10
 
10
- def show_dylib(dylib_file: Path) -> list[str]:
11
+ def show_dylib(dylib_file: Path) -> tuple[list[str], list[str]]:
11
12
  if not is_wasm_module(dylib_file):
12
13
  raise RuntimeError(f"{dylib_file} is not a WASM file")
13
14
 
14
15
  dylink = parse_dylink_section(dylib_file)
15
- return dylink.needed
16
+ return dylink.needed, dylink.runtime_paths
16
17
 
17
18
 
18
- def show_wheel_unpacked(wheel_extract_dir: str | Path) -> dict[str, list[str]]:
19
+ def show_wheel_unpacked(
20
+ wheel_extract_dir: str | Path,
21
+ ) -> dict[str, tuple[list[str], list[str]]]:
19
22
  dependencies = {}
20
23
 
21
24
  shared_libs = get_all_shared_libs_in_dir(wheel_extract_dir)
22
25
  for shared_lib in shared_libs:
23
- deps = show_dylib(shared_lib)
24
- dependencies[shared_lib.relative_to(wheel_extract_dir).as_posix()] = deps
26
+ deps, runtime_paths = show_dylib(shared_lib)
27
+ dependencies[shared_lib.relative_to(wheel_extract_dir).as_posix()] = (
28
+ deps,
29
+ runtime_paths,
30
+ )
25
31
 
26
32
  return dependencies
27
33
 
28
34
 
29
- def show_wheel(wheel_file: Path) -> dict[str, list[str]]:
35
+ def show_wheel(wheel_file: Path) -> dict[str, tuple[list[str], list[str]]]:
30
36
  if not is_emscripten_wheel(wheel_file.name):
31
37
  raise RuntimeError(f"{wheel_file} is not an emscripten wheel")
32
38
 
@@ -37,7 +43,7 @@ def show_wheel(wheel_file: Path) -> dict[str, list[str]]:
37
43
  return show_wheel_unpacked(extract_dir)
38
44
 
39
45
 
40
- def show(wheel_or_so_file: str | Path) -> dict[str, list[str]]:
46
+ def show(wheel_or_so_file: str | Path) -> dict[str, tuple[list[str], list[str]]]:
41
47
  file = Path(wheel_or_so_file)
42
48
  if not file.exists():
43
49
  raise RuntimeError(f"no such file: {file}")
@@ -53,3 +59,21 @@ def show(wheel_or_so_file: str | Path) -> dict[str, list[str]]:
53
59
  }
54
60
  else:
55
61
  raise RuntimeError(f"unknown file type: {file}")
62
+
63
+
64
+ def locate_dependency(
65
+ base: str, dep: str, libraries: list[str], runtime_paths: list[str]
66
+ ) -> str | None:
67
+ """
68
+ Check if the dependencies exists in the wheel using runtime paths.
69
+ If the dependency exists, return the path to the dependency.
70
+ Otherwise, return None.
71
+ """
72
+ for path in runtime_paths:
73
+ relpath = path.replace("$ORIGIN", "..")
74
+ # Always use unix-style separators
75
+ candidate = os.path.normpath(str(Path(base) / relpath / dep)).replace("\\", "/")
76
+ if candidate in libraries:
77
+ return candidate
78
+
79
+ return None
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: auditwheel_emscripten
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: auditwheel-like tool for Pyodide
5
- Project-URL: Home, https://github.com/ryanking13/auditwheel-emscripten
5
+ Project-URL: Home, https://github.com/pyodide/auditwheel-emscripten
6
6
  Author-email: Gyeongjae Choi <def6488@gmail.com>
7
7
  License: Mozilla Public License Version 2.0
8
8
  ==================================
@@ -391,7 +391,7 @@ Description-Content-Type: text/markdown
391
391
  # auditwheel-emscripten
392
392
 
393
393
  [![PyPI Latest Release](https://img.shields.io/pypi/v/auditwheel-emscripten.svg)](https://pypi.org/project/auditwheel-emscripten/)
394
- ![Test Status](https://github.com/ryanking13/auditwheel-emscripten/actions/workflows/test.yml/badge.svg)
394
+ ![Test Status](https://github.com/pyodide/auditwheel-emscripten/actions/workflows/test.yml/badge.svg)
395
395
 
396
396
  auditwheel-like tool for wheels targeting Emscripten platform
397
397
 
@@ -429,26 +429,29 @@ Python-in-the-browser using Emscripten.
429
429
  ```
430
430
 
431
431
  ```sh
432
- # wget https://cdn.jsdelivr.net/pyodide/v0.21.3/full/Shapely-1.8.2-cp310-cp310-emscripten_3_1_14_wasm32.whl
433
- $ pyodide auditwheel show Shapely-1.8.2-cp310-cp310-emscripten_3_1_14_wasm32.whl
434
-
435
- The following external shared libraries are required:
436
- {
437
- │ 'shapely/speedups/_speedups.cpython-310-wasm32-emscripten.so': ['libgeos_c.so'],
438
- │ 'shapely/vectorized/_vectorized.cpython-310-wasm32-emscripten.so': ['libgeos_c.so']
439
- }
432
+ $ pyodide auditwheel show shapely-2.0.7-cp313-cp313-pyodide_2025_0_wasm32.whl
433
+ shapely/speedups/_speedups.cpython-310-wasm32-emscripten.so:
434
+ libgeos_c.so
435
+
436
+ shapely/vectorized/_vectorized.cpython-310-wasm32-emscripten.so:
437
+ libgeos_c.so
440
438
  ```
441
439
 
442
440
  ```sh
443
- $ pyodide auditwheel repair --libdir <directory which contains libgeos_c.so> Shapely-1.8.2-cp310-cp310-emscripten_3_1_14_wasm32.whl
444
-
445
- Repaired wheel has following external shared libraries:
446
- {
447
- │ 'Shapely.libs/libgeos.so.3.10.3': [],
448
- │ 'Shapely.libs/libgeos_c.so': ['libgeos.so.3.10.3'],
449
- │ 'shapely/speedups/_speedups.cpython-310-wasm32-emscripten.so': ['libgeos_c.so'],
450
- │ 'shapely/vectorized/_vectorized.cpython-310-wasm32-emscripten.so': ['libgeos_c.so']
451
- }
441
+ $ pyodide auditwheel repair --libdir <directory which contains libgeos_c.so> shapely-2.0.7-cp313-cp313-pyodide_2025_0_wasm32.whl
442
+ shapely/lib.cpython-313-wasm32-emscripten.so:
443
+ libgeos_c.so => shapely.libs/libgeos_c.so
444
+
445
+ shapely/_geometry_helpers.cpython-313-wasm32-emscripten.so:
446
+ libgeos_c.so => shapely.libs/libgeos_c.so
447
+
448
+ shapely/_geos.cpython-313-wasm32-emscripten.so:
449
+ libgeos_c.so => shapely.libs/libgeos_c.so
450
+
451
+ shapely.libs/libgeos.so:
452
+
453
+ shapely.libs/libgeos_c.so:
454
+ libgeos.so => shapely.libs/libgeos.so
452
455
  ```
453
456
 
454
457
 
@@ -5,18 +5,18 @@ auditwheel_emscripten/imports.py,sha256=YI8KItf1qujmycSLb7c7igpCBXNqJAJVUIH3H8HY
5
5
  auditwheel_emscripten/lib_utils.py,sha256=4qodvz1go0tgHZA803Q3vcIR-QQbOdqSR0p2wo7wjrA,682
6
6
  auditwheel_emscripten/module.py,sha256=wwLAzlhGKgGojNvUdommO7FGfME49rWVRZOPRp77qjU,6619
7
7
  auditwheel_emscripten/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- auditwheel_emscripten/repair.py,sha256=CvTj2SobzAfQjKbXPqvPe7lWRPD9DTHEfJFpHuQD7KY,3755
9
- auditwheel_emscripten/show.py,sha256=TTulud3juo1QPo7avIa0K_nOR7iYBAVIMpUdXKaLLVI,1714
8
+ auditwheel_emscripten/repair.py,sha256=ucqS6igx5U-wGcTcpqeQa3Gi9sZ2EyykWSrhCNl4yoI,3884
9
+ auditwheel_emscripten/show.py,sha256=i_2bOE-IP3fghGN4Sc5qAm4rIQ7NbvPucpv3G2klE4Y,2483
10
10
  auditwheel_emscripten/wasm_utils.py,sha256=-IuAWiPPOkWmPpaW4u3tyxttpP0ZTWeKk0VMh1dj384,220
11
11
  auditwheel_emscripten/wheel_utils.py,sha256=_uh8MiKYpjtBcpOE5bG2vEfh9eXlZhz-nMMVo6-Fvl8,2995
12
12
  auditwheel_emscripten/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- auditwheel_emscripten/cli/main.py,sha256=rhJoQCu8uL_CPevF3vIrZ6c3IsDILTgxW8JNfc5lADY,4043
13
+ auditwheel_emscripten/cli/main.py,sha256=9_yxawwpf_5A8ED3mWtZZHezMklDrp-iWE4UCs_hvsA,5334
14
14
  auditwheel_emscripten/emscripten_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  auditwheel_emscripten/emscripten_tools/diagnostics.py,sha256=fG8kS7BByJKwC3JJrfJc0TB1EDV4W--LQwcf4fnN0GI,7072
16
16
  auditwheel_emscripten/emscripten_tools/utils.py,sha256=sAcW8WaxfN0lNA64y9d0_CsdfYecV_YUcN6nrDrMmMs,3316
17
17
  auditwheel_emscripten/emscripten_tools/webassembly.py,sha256=ppyx_lzgtve2hCDn8jQn1Wto_2pGv-Kk-CcOhqUB8NQ,17408
18
- auditwheel_emscripten-0.1.0.dist-info/METADATA,sha256=6ofoErOVppyKzcdUEdCT_7rftjfEVFSvTjfmY-62o-M,27093
19
- auditwheel_emscripten-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
- auditwheel_emscripten-0.1.0.dist-info/entry_points.txt,sha256=Jok5wALksOWKJv8BRV2Riozxts_stW2n-ud9uHTNCB8,62
21
- auditwheel_emscripten-0.1.0.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
22
- auditwheel_emscripten-0.1.0.dist-info/RECORD,,
18
+ auditwheel_emscripten-0.2.1.dist-info/METADATA,sha256=KKKQoL_DrnVUEE2yP3StzHSv9BZi9mBLc-b2nDUzggk,26972
19
+ auditwheel_emscripten-0.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
20
+ auditwheel_emscripten-0.2.1.dist-info/entry_points.txt,sha256=Jok5wALksOWKJv8BRV2Riozxts_stW2n-ud9uHTNCB8,62
21
+ auditwheel_emscripten-0.2.1.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
22
+ auditwheel_emscripten-0.2.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any