Skip to content

Commit f1d7443

Browse files
committed
Update
[ghstack-poisoned]
2 parents bea599c + 6fc6c9c commit f1d7443

2 files changed

Lines changed: 49 additions & 3 deletions

File tree

.ci/scripts/wheel/test_cpp_sdk.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,11 +1106,55 @@ def test_documented_example_compiles(work_dir: Path) -> None:
11061106
print("\u2713 the C++ example in the documentation compiles and links")
11071107

11081108

1109+
def test_python_extension_links_shared_runtime() -> None:
1110+
"""The Python extension must depend on the shipped runtime library.
1111+
1112+
Checking that one library defines the registry does not prove the extension uses it.
1113+
An extension that kept its own copy, or linked nothing, would satisfy that count and
1114+
still give a process two registries. Its dependency list settles it.
1115+
"""
1116+
if shutil.which("readelf") is None:
1117+
print("- readelf is not available, skipping the extension dependency check")
1118+
return
1119+
1120+
package_dir = _installed_package_dir()
1121+
extensions = sorted(
1122+
(package_dir / "extension" / "pybindings").glob("_portable_lib*.so")
1123+
)
1124+
if not extensions:
1125+
print("- no Python extension in this wheel, skipping the dependency check")
1126+
return
1127+
1128+
for extension in extensions:
1129+
result = subprocess.run(
1130+
["readelf", "-d", str(extension)],
1131+
capture_output=True,
1132+
text=True,
1133+
check=False,
1134+
)
1135+
assert result.returncode == 0, (
1136+
f"readelf could not read {extension.name}, so the dependency check cannot "
1137+
"be trusted"
1138+
)
1139+
needed = re.findall(r"Shared library: \[([^\]]+)\]", result.stdout)
1140+
runtime = [name for name in needed if name.startswith("libexecutorch.so")]
1141+
assert runtime, (
1142+
f"{extension.relative_to(package_dir)} does not depend on the shipped "
1143+
f"runtime, so it cannot be using the same registry as a C++ application; "
1144+
f"it needs {needed}"
1145+
)
1146+
print(
1147+
f"\u2713 {extension.relative_to(package_dir)} resolves the registry through "
1148+
f"{runtime[0]}"
1149+
)
1150+
1151+
11091152
def run_tests(work_dir: Path) -> None:
11101153
test_shipped_libraries_load()
11111154
test_shipped_libraries_resolve_without_build_tree()
11121155
test_single_backend_registry()
11131156
test_python_extensions_import()
1157+
test_python_extension_links_shared_runtime()
11141158
test_wheel_platform_tag()
11151159
test_custom_op_compiles(work_dir)
11161160
test_no_absolute_runtime_paths()

setup.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,13 @@ def get_build_type(is_debug=None) -> str:
322322
# need for it.
323323
_UNSUPPORTED_WHEEL_HEADERS = frozenset(
324324
{
325-
"bundled_module.h",
326-
# These two include a third-party header the wheel does not ship, so they
327-
# cannot compile from an installed package no matter what is linked.
325+
# These two include a third-party header the wheel does not ship, so they cannot
326+
# compile from an installed package no matter what is linked.
328327
"cpuinfo_utils.h",
329328
"threadpool.h",
329+
# These three compile, but declare entry points whose definitions are not in any
330+
# shipped library, so a consumer that includes them fails at link time.
331+
"bundled_module.h",
330332
"file_descriptor_data_loader.h",
331333
"serialize.h",
332334
}

0 commit comments

Comments
 (0)