diff --git a/.ci/scripts/wheel/test_base.py b/.ci/scripts/wheel/test_base.py index f8a7309a6c2..278e46fe75a 100644 --- a/.ci/scripts/wheel/test_base.py +++ b/.ci/scripts/wheel/test_base.py @@ -41,6 +41,18 @@ class ModelTest: def run_tests(model_tests: List[ModelTest]) -> None: + # Test that we can import the portable_lib module - verifies RPATH is correct + print("Testing portable_lib import...") + try: + from executorch.extension.pybindings._portable_lib import ( # noqa: F401 + _load_for_executorch, + ) + + print("✓ Successfully imported _load_for_executorch from portable_lib") + except ImportError as e: + print(f"✗ Failed to import portable_lib: {e}") + raise + # Why are we doing this envvar shenanigans? Since we build the testers, which # uses buck, we cannot run as root. This is a sneaky of getting around that # test. diff --git a/CMakeLists.txt b/CMakeLists.txt index fc427d517a9..e419a45a879 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -869,6 +869,21 @@ if(EXECUTORCH_BUILD_PYBIND) target_compile_options(portable_lib PUBLIC ${_pybind_compile_options}) target_link_libraries(portable_lib PRIVATE ${_dep_libs}) + # Set RPATH to find PyTorch libraries relative to the installation location + # This goes from executorch/extension/pybindings up to site-packages, then to + # torch/lib + if(APPLE) + set_target_properties( + portable_lib PROPERTIES BUILD_RPATH "@loader_path/../../../torch/lib" + INSTALL_RPATH "@loader_path/../../../torch/lib" + ) + else() + set_target_properties( + portable_lib PROPERTIES BUILD_RPATH "$ORIGIN/../../../torch/lib" + INSTALL_RPATH "$ORIGIN/../../../torch/lib" + ) + endif() + install( TARGETS portable_lib EXPORT ExecuTorchTargets