@@ -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+
11091152def 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 ()
0 commit comments