From 66557e0b294d3021693812f3470ad1538021f2c0 Mon Sep 17 00:00:00 2001 From: Anthony Shoumikhin Date: Thu, 13 Aug 2026 07:54:32 -0700 Subject: [PATCH] Name the Python extension after what it contains The compiled Python extension in the wheel was called `_portable_lib`. That name is misleading in two ways. "Portable" is the name of a kernel set in this project, the portable kernels, and this file does not contain them: it holds the Python bindings for the runtime. "Lib" says nothing, since every shared object is a library. Someone looking for the portable kernels finds the Python bindings instead, and someone looking for the bindings has no reason to open a file named after kernels. Rename it to `_C`, which is the usual name for a package's compiled C extension and what PyTorch calls the same thing (`torch/_C.cpython-*.so`). The package path already says `pybindings`, as in `executorch.extension.pybindings`, so a name like `_pybindings` would repeat itself while `_C` reads as "this package's C extension". Nothing user facing changes. Applications import the public wrapper: ```python from executorch.extension.pybindings import portable_lib ``` That wrapper re-exports everything from the compiled module and keeps its name, so existing code continues to work. Only the private module behind it is renamed, and it was already documented as experimental and subject to change. Test plan: Built a wheel and confirmed the shipped file is named for the new module: ``` extension/pybindings/_C.cpython-312-x86_64-linux-gnu.so ``` Installed that wheel into a fresh environment and checked both the public wrapper and the private module load, then exported and ran a model through the Python bindings: ``` public wrapper works: True module name : executorch.extension.pybindings._C exported symbols : 22 ``` Also grepped the tree to confirm no build file, test, or comment still names the old module. --- .ci/scripts/wheel/test_base.py | 2 +- .ci/scripts/wheel/test_shared_libraries.py | 10 ++-- CMakeLists.txt | 40 +++++++-------- backends/cuda/runtime/platform/platform.cpp | 4 +- backends/mlx/CMakeLists.txt | 8 +-- extension/pybindings/BUCK | 10 ++-- extension/pybindings/portable_lib.py | 6 +-- extension/pybindings/test/BUCK | 2 +- kernels/quantized/CMakeLists.txt | 28 +++++------ runtime/__init__.py | 2 +- setup.py | 6 +-- shim_et/xplat/executorch/codegen/codegen.bzl | 12 ++--- tools/cmake/executorch-wheel-config.cmake | 52 ++++++++++---------- 13 files changed, 90 insertions(+), 92 deletions(-) diff --git a/.ci/scripts/wheel/test_base.py b/.ci/scripts/wheel/test_base.py index 2b0d3c0dcb4..ec8ff65493b 100644 --- a/.ci/scripts/wheel/test_base.py +++ b/.ci/scripts/wheel/test_base.py @@ -62,7 +62,7 @@ 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 + from executorch.extension.pybindings._C import ( # noqa: F401 _load_for_executorch, ) diff --git a/.ci/scripts/wheel/test_shared_libraries.py b/.ci/scripts/wheel/test_shared_libraries.py index a2f433aef2b..d3f5995eea5 100644 --- a/.ci/scripts/wheel/test_shared_libraries.py +++ b/.ci/scripts/wheel/test_shared_libraries.py @@ -898,7 +898,7 @@ def test_python_extensions_import() -> None: add_library(custom_op_check SHARED custom_op.cpp) # The legacy contract: a custom-op library links the shipped Python extension, # which owns the operator registry it registers into. -target_link_libraries(custom_op_check PRIVATE _portable_lib) +target_link_libraries(custom_op_check PRIVATE _C) # The runtime headers include c10 headers, which belong to torch rather than to # this wheel, so an out-of-tree operator project supplies them the same way it # supplies torch itself. The package config does not and should not ship them. @@ -1149,7 +1149,7 @@ def test_custom_op_compiles(work_dir: Path) -> None: return package_dir = _installed_package_dir() - if not list(package_dir.glob("extension/pybindings/_portable_lib*")): + if not list(package_dir.glob("extension/pybindings/_C*")): print("- the wheel ships no Python extension, skipping the custom op check") return @@ -1530,10 +1530,8 @@ def test_extension_contains_no_component() -> None: return package_dir = _installed_package_dir() - extensions = sorted( - (package_dir / "extension" / "pybindings").glob("_portable_lib.*.so") - ) - assert len(extensions) == 1, f"expected one _portable_lib, found {extensions}" + extensions = sorted((package_dir / "extension" / "pybindings").glob("_C.*.so")) + assert len(extensions) == 1, f"expected one _C, found {extensions}" extension = extensions[0] lib_dir = package_dir / "lib" diff --git a/CMakeLists.txt b/CMakeLists.txt index efa61a5fc06..5b3a80247e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -461,8 +461,8 @@ if(EXECUTORCH_BUILD_PTHREADPOOL) if(APPLE) # Use hidden visibility for pthreadpool on Apple platforms to avoid issues # with pthreadpool symbols from libtorch_cpu taking precedence over the ones - # from the pthreadpool library statically linked in _portable_lib. The - # pthreadpool public APIs are marked as weak by default on some Apple + # from the pthreadpool library statically linked in the Python extension. + # The pthreadpool public APIs are marked as weak by default on some Apple # platforms, so setting to hidden visibility works around this by not # putting the symbol in the indirection table. See # https://github.com/pytorch/executorch/issues/14321 for more details. @@ -1189,19 +1189,19 @@ if(EXECUTORCH_BUILD_PYBIND) list(APPEND _dep_libs aoti_common) endif() - # RPATH for _portable_lib.so. It sits in + # RPATH for the Python extension. It sits in # /executorch/extension/pybindings, so torch is three levels up # and the wheel's own lib/ directory is two. Mach-O spells the loader relative # token differently and takes a list rather than a colon joined string, so # both differ here while the layout reasoning does not. if(APPLE) - set(_portable_lib_origin "@loader_path") - set(_portable_lib_rpath_separator ";") + set(_python_extension_origin "@loader_path") + set(_python_extension_rpath_separator ";") else() - set(_portable_lib_origin "$ORIGIN") - set(_portable_lib_rpath_separator ":") + set(_python_extension_origin "$ORIGIN") + set(_python_extension_rpath_separator ":") endif() - set(_portable_lib_rpath "${_portable_lib_origin}/../../../torch/lib") + set(_python_extension_rpath "${_python_extension_origin}/../../../torch/lib") if(EXECUTORCH_BUILD_EXTENSION_MODULE) # extension_module_static is already bundled into libexecutorch.so; linking @@ -1253,8 +1253,8 @@ if(EXECUTORCH_BUILD_PYBIND) if(EXECUTORCH_BUILD_CUDA) string( APPEND - _portable_lib_rpath - "${_portable_lib_rpath_separator}${_portable_lib_origin}/../../backends/cuda" + _python_extension_rpath + "${_python_extension_rpath_separator}${_python_extension_origin}/../../backends/cuda" ) endif() @@ -1262,8 +1262,8 @@ if(EXECUTORCH_BUILD_PYBIND) list(APPEND _dep_libs qnn_executorch_backend) string( APPEND - _portable_lib_rpath - "${_portable_lib_rpath_separator}${_portable_lib_origin}/../../backends/qualcomm" + _python_extension_rpath + "${_python_extension_rpath_separator}${_python_extension_origin}/../../backends/qualcomm" ) endif() @@ -1326,10 +1326,10 @@ if(EXECUTORCH_BUILD_PYBIND) # portable_lib.py in the same python package. PyTorch requires C++20, so # pybindings must be compiled with C++20. set_target_properties( - portable_lib PROPERTIES OUTPUT_NAME "_portable_lib" CXX_STANDARD 20 + portable_lib PROPERTIES OUTPUT_NAME "_C" CXX_STANDARD 20 ) target_compile_definitions( - portable_lib PUBLIC EXECUTORCH_PYTHON_MODULE_NAME=_portable_lib + portable_lib PUBLIC EXECUTORCH_PYTHON_MODULE_NAME=_C ) target_include_directories(portable_lib PRIVATE ${TORCH_INCLUDE_DIRS}) target_compile_options(portable_lib PUBLIC ${_pybind_compile_options}) @@ -1366,8 +1366,8 @@ if(EXECUTORCH_BUILD_PYBIND) # libtorch_cpu.dylib' else() set_target_properties( - portable_lib PROPERTIES BUILD_RPATH "${_portable_lib_rpath}" - INSTALL_RPATH "${_portable_lib_rpath}" + portable_lib PROPERTIES BUILD_RPATH "${_python_extension_rpath}" + INSTALL_RPATH "${_python_extension_rpath}" ) endif() executorch_target_shared_runtime_path( @@ -1404,10 +1404,10 @@ if(EXECUTORCH_BUILD_PYBIND) LIBRARY DESTINATION executorch/extension/pybindings ) - # Copy MLX metallib next to _portable_lib.so for editable installs. MLX uses - # dladdr() to find the directory containing the library with MLX code, then - # looks for mlx.metallib in that directory. When MLX is statically linked into - # _portable_lib.so, we need the metallib colocated with it. + # Copy the MLX metallib next to the Python extension for editable installs. + # MLX uses dladdr() to find the directory containing the library with MLX + # code, then looks for mlx.metallib in that directory. When MLX is statically + # linked into the Python extension, we need the metallib colocated with it. executorch_target_copy_mlx_metallib(portable_lib) endif() diff --git a/backends/cuda/runtime/platform/platform.cpp b/backends/cuda/runtime/platform/platform.cpp index 903ab3e71e8..ae97c4079dd 100644 --- a/backends/cuda/runtime/platform/platform.cpp +++ b/backends/cuda/runtime/platform/platform.cpp @@ -75,14 +75,14 @@ executorch::runtime::Result load_library( #else // Before loading the delegate .so, we need to ensure symbols from the current - // process (e.g., _portable_lib.so) are globally visible. Python loads modules + // process (e.g. the Python extension) are globally visible. Python loads modules // with RTLD_LOCAL by default, so we re-open the current module with // RTLD_GLOBAL | RTLD_NOLOAD to promote its symbols to global visibility. // This allows the delegate .so to resolve symbols like aoti_torch_dtype_*. static std::once_flag symbols_promoted_flag; std::call_once(symbols_promoted_flag, []() { Dl_info info; - // Get info about a symbol we know exists in _portable_lib.so + // Get info about a symbol we know exists in the Python extension if (dladdr((void*)&load_library, &info) && info.dli_fname) { // Re-open with RTLD_GLOBAL | RTLD_NOLOAD to promote symbols void* handle = diff --git a/backends/mlx/CMakeLists.txt b/backends/mlx/CMakeLists.txt index 9f2ece7155f..eae5297db2c 100644 --- a/backends/mlx/CMakeLists.txt +++ b/backends/mlx/CMakeLists.txt @@ -339,16 +339,16 @@ install( # exist) # # where {binary_dir} is determined at runtime via dladdr() on the library -# containing MLX code. When MLX is statically linked into _portable_lib.so, this -# is the directory containing _portable_lib.so. +# containing MLX code. When MLX is statically linked into _C.so, this is the +# directory containing _C.so. # # For the installed library, we put metallib in lib/ alongside libmlx.a. The # metallib is produced in the mlx_external build tree (MLX_METAL_JIT=ON does not # install it); _mlx_metallib points there. install(FILES ${_mlx_metallib} DESTINATION ${CMAKE_INSTALL_LIBDIR}) -# Cache the metallib path for pybindings to copy it next to _portable_lib.so -# This enables editable installs to work correctly +# Cache the metallib path for pybindings to copy it next to _C.so This enables +# editable installs to work correctly set(MLX_METALLIB_PATH "${_mlx_metallib}" CACHE INTERNAL "Path to mlx.metallib for pybindings" diff --git a/extension/pybindings/BUCK b/extension/pybindings/BUCK index 78100500df3..1c39ea14d28 100644 --- a/extension/pybindings/BUCK +++ b/extension/pybindings/BUCK @@ -34,9 +34,9 @@ fbcode_target(_kind = runtime.genrule, outs = { "aten_lib.pyi": ["aten_lib.pyi"], "core.pyi": ["core.pyi"], - "_portable_lib.pyi": ["_portable_lib.pyi"], + "_C.pyi": ["_C.pyi"], }, - cmd = "cp $(location :pybinding_types)/* $OUT/_portable_lib.pyi && cp $(location :pybinding_types)/* $OUT/aten_lib.pyi && cp $(location :pybinding_types)/* $OUT/core.pyi", + cmd = "cp $(location :pybinding_types)/* $OUT/_C.pyi && cp $(location :pybinding_types)/* $OUT/aten_lib.pyi && cp $(location :pybinding_types)/* $OUT/core.pyi", visibility = ["//executorch/extension/pybindings/..."], ) @@ -50,8 +50,8 @@ fbcode_target(_kind = executorch_pybindings, fbcode_target(_kind = executorch_pybindings, cppdeps = PORTABLE_MODULE_DEPS + MODELS_ATEN_OPS_LEAN_MODE_GENERATED_LIB, # Give this an underscore prefix because it has a pure python wrapper. - python_module_name = "_portable_lib", - types = ["//executorch/extension/pybindings:pybindings_types_gen[_portable_lib.pyi]"], + python_module_name = "_C", + types = ["//executorch/extension/pybindings:pybindings_types_gen[_C.pyi]"], visibility = ["PUBLIC"], ) @@ -67,7 +67,7 @@ fbcode_target(_kind = runtime.python_library, srcs = ["portable_lib.py"], visibility = ["PUBLIC"], deps = [ - ":_portable_lib", + ":_C", "//executorch/exir:_warnings", ], ) diff --git a/extension/pybindings/portable_lib.py b/extension/pybindings/portable_lib.py index 4be4b8956e8..d8813539b45 100644 --- a/extension/pybindings/portable_lib.py +++ b/extension/pybindings/portable_lib.py @@ -72,12 +72,12 @@ e, ) -# Let users import everything from the C++ _portable_lib extension as if this +# Let users import everything from the C++ _C extension as if this # python file defined them. Although we could import these dynamically, it # wouldn't preserve the static type annotations. # # Note that all of these are experimental, and subject to change without notice. -from executorch.extension.pybindings._portable_lib import ( # noqa: F401 +from executorch.extension.pybindings._C import ( # noqa: F401 # Disable "imported but unused" (F401) checks. _create_profile_block, # noqa: F401 _dump_profile_results, # noqa: F401 @@ -101,7 +101,7 @@ Verification, # noqa: F401 ) -# Clean up so that `dir(portable_lib)` is the same as `dir(_portable_lib)` +# Clean up so that `dir(portable_lib)` is the same as `dir(_C)` # (apart from some __dunder__ names). del _torch del _exir_warnings diff --git a/extension/pybindings/test/BUCK b/extension/pybindings/test/BUCK index a18abac2382..55eea4d6063 100644 --- a/extension/pybindings/test/BUCK +++ b/extension/pybindings/test/BUCK @@ -34,7 +34,7 @@ fbcode_target( fbcode_target( _kind = runtime.python_test, - name = "test_pybindings_portable_lib", + name = "test_pybindings_C", srcs = ["test_pybindings.py"], preload_deps = ["//executorch/kernels/quantized:aot_lib"], deps = [ diff --git a/kernels/quantized/CMakeLists.txt b/kernels/quantized/CMakeLists.txt index 578352d9c76..cce5411378c 100644 --- a/kernels/quantized/CMakeLists.txt +++ b/kernels/quantized/CMakeLists.txt @@ -126,20 +126,20 @@ if(NOT CMAKE_GENERATOR STREQUAL "Xcode" ) # pip wheels will need to be able to find the dependent libraries. On - # Linux, the .so has non-absolute dependencies on libs like - # "_portable_lib.so" without paths; as long as we `import torch` first, - # those dependencies will work. But Apple dylibs do not support - # non-absolute dependencies, so we need to tell the loader where to look - # for its libraries. The LC_LOAD_DYLIB entries for the portable_lib - # libraries will look like "@rpath/_portable_lib.cpython-310-darwin.so", - # so we can add an LC_RPATH entry to look in a directory relative to the - # installed location of our _portable_lib.so file. To see these LC_* - # values, run `otool -l libquantized_ops_lib.dylib`. "extension", not - # "extensions": the plural directory does not exist, so the parent's path - # reached nothing and this library could not find the extension it needs. - # torch is three directories up from here, and this library links it - # directly, so the hop has to be recorded or the only route is the - # absolute path from the build machine. + # Linux, the .so has non-absolute dependencies on libs like "_C.so" + # without paths; as long as we `import torch` first, those dependencies + # will work. But Apple dylibs do not support non-absolute dependencies, so + # we need to tell the loader where to look for its libraries. The + # LC_LOAD_DYLIB entries for the portable_lib libraries will look like + # "@rpath/_C.cpython-310-darwin.so", so we can add an LC_RPATH entry to + # look in a directory relative to the installed location of our _C.so + # file. To see these LC_* values, run `otool -l + # libquantized_ops_lib.dylib`. "extension", not "extensions": the plural + # directory does not exist, so the parent's path reached nothing and this + # library could not find the extension it needs. torch is three + # directories up from here, and this library links it directly, so the hop + # has to be recorded or the only route is the absolute path from the build + # machine. if(APPLE) set(RPATH "@loader_path/../../extension/pybindings;@loader_path/../../../torch/lib" diff --git a/runtime/__init__.py b/runtime/__init__.py index 97b99df559b..438e62fa731 100644 --- a/runtime/__init__.py +++ b/runtime/__init__.py @@ -122,7 +122,7 @@ ) except ModuleNotFoundError as e: raise ModuleNotFoundError( - "Prebuilt /extension/pybindings/_portable_lib.so " + "Prebuilt /extension/pybindings/_C.so " "is not found. Please reinstall ExecuTorch from pip." ) from e diff --git a/setup.py b/setup.py index 0abfe2c9007..7b871c4f361 100644 --- a/setup.py +++ b/setup.py @@ -2006,8 +2006,8 @@ def run(self): # noqa C901 # portable kernels, and a selection of backends. This lets users # load and execute .pte files from python. BuiltExtension( - src="_portable_lib.cp*" if _is_windows() else "_portable_lib.*", - modpath="executorch.extension.pybindings._portable_lib", + src="_C.cp*" if _is_windows() else "_C.*", + modpath="executorch.extension.pybindings._C", dependent_cmake_flags=["EXECUTORCH_BUILD_PYBIND"], ), # Install the data_loader pybindings extension which provides the @@ -2017,7 +2017,7 @@ def run(self): # noqa C901 modpath="executorch.extension.pybindings.data_loader", dependent_cmake_flags=["EXECUTORCH_BUILD_PYBIND"], ), - # MLX metallib (Metal GPU kernels) must be colocated with _portable_lib.so + # MLX metallib (Metal GPU kernels) must be colocated with _C.so # because MLX uses dladdr() to find the directory containing the library, # then looks for mlx.metallib in that directory at runtime. # After submodule migration, the path is backends/mlx/mlx/... diff --git a/shim_et/xplat/executorch/codegen/codegen.bzl b/shim_et/xplat/executorch/codegen/codegen.bzl index 318996784a1..ed7c44ad9c8 100644 --- a/shim_et/xplat/executorch/codegen/codegen.bzl +++ b/shim_et/xplat/executorch/codegen/codegen.bzl @@ -528,7 +528,7 @@ def copy_files(genrule_name, target, file_list): default_outs = ["."], ) -def get_portable_lib_deps(): +def get_C_deps(): return [ "//executorch/kernels/portable/cpu:math_constants", "//executorch/kernels/portable/cpu:scalar_utils", @@ -569,7 +569,7 @@ def build_portable_header_lib(name, oplist_header_name, feature = None, **kwargs **kwargs ) -def build_portable_lib( +def build_C( name, et_operator_lib_deps = [], oplist_header_name = None, @@ -651,7 +651,7 @@ def build_portable_lib( name = name, srcs = portable_source_files, exported_preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"], - deps = get_portable_lib_deps() + [":" + portable_header_lib], + deps = get_C_deps() + [":" + portable_header_lib], compiler_flags = compiler_flags, # WARNING: using a deprecated API to avoid being built into a shared # library. In the case of dynamically loading so library we don't want @@ -710,7 +710,7 @@ def build_optimized_lib(name, oplist_header_name, portable_header_lib, feature = # sleef needs to be added as a direct dependency of the operator target when building for Android, # or a linker error may occur. Not sure why this happens; it seems that platform deps of # dependencies are not transitive - deps = get_portable_lib_deps() + get_optimized_lib_deps() + [":" + portable_header_lib] + select({ + deps = get_C_deps() + get_optimized_lib_deps() + [":" + portable_header_lib] + select({ "ovr_config//os:android-arm64": [ "fbsource//third-party/sleef:sleef", ], @@ -1038,8 +1038,8 @@ def executorch_generated_lib( kernel_deps.remove("//executorch/kernels/portable:operators") # Build portable lib. - portable_lib_name = name + "_portable_lib" - build_portable_lib(name = portable_lib_name, portable_header_lib = portable_header_lib, feature = feature, expose_operator_symbols = expose_operator_symbols, platforms = platforms) + portable_lib_name = name + "_C" + build_C(name = portable_lib_name, portable_header_lib = portable_header_lib, feature = feature, expose_operator_symbols = expose_operator_symbols, platforms = platforms) kernel_deps.append(":{}".format(portable_lib_name)) if "//executorch/kernels/optimized:optimized_operators" in kernel_deps: diff --git a/tools/cmake/executorch-wheel-config.cmake b/tools/cmake/executorch-wheel-config.cmake index 998f7578002..eab3bf9b610 100644 --- a/tools/cmake/executorch-wheel-config.cmake +++ b/tools/cmake/executorch-wheel-config.cmake @@ -46,7 +46,7 @@ # Not the Python extension, which carries unresolved interpreter symbols that # only resolve inside an interpreter, so a standalone application linking it # fails with a page of PyUnicode_InternFromString errors. A project building a -# custom operator against the extension asks for the _portable_lib target by +# custom operator against the extension asks for the _C target by # name, which is the long-standing contract for that and also carries the C++20 # requirement PyTorch's headers need. # @@ -632,7 +632,7 @@ _executorch_define_component(backend_openvino executorch_backend_openvino) _executorch_define_component(backend_cuda executorch_backend_cuda) _executorch_define_component(extension_cuda executorch_extension_cuda) -# Find prebuilt _portable_lib..so. This is the legacy contract used +# Find prebuilt _C..so. This is the legacy contract used # to build custom-op extensions against the Python module, and is kept working # independently of the runtime target above. @@ -663,14 +663,14 @@ elseif(_executorch_runtime_library) # Tested on the located library rather than # application on an older CMake is exactly the case this branch exists to keep # working. A C++ application linking only the shared runtime does not need # Python at all, so a missing interpreter must not fail its configure. Skip - # locating the Python extension instead; the legacy _portable_lib target is + # locating the Python extension instead; the legacy _C target is # simply not offered in that case. message( STATUS "Python not usable, skipping the Python extension: ${SYSCONFIG_ERROR}" ) set(EXT_SUFFIX "") - set(_portable_lib_LIBRARY "") + set(_C_LIBRARY "") else() message( FATAL_ERROR @@ -683,38 +683,38 @@ if(EXT_SUFFIX) # package root: the path and the file name are both already known, so a search # only adds the consumer's find-root rules, which reroot an absolute wheel # path into a cross-compile sysroot and report a present extension as missing. - set(_portable_lib_candidate - "${_executorch_package_root}/extension/pybindings/_portable_lib${EXT_SUFFIX}" + set(_C_candidate + "${_executorch_package_root}/extension/pybindings/_C${EXT_SUFFIX}" ) - if(EXISTS "${_portable_lib_candidate}") - set(_portable_lib_LIBRARY "${_portable_lib_candidate}") + if(EXISTS "${_C_candidate}") + set(_C_LIBRARY "${_C_candidate}") else() - set(_portable_lib_LIBRARY "") + set(_C_LIBRARY "") endif() endif() -if(NOT _portable_lib_LIBRARY) +if(NOT _C_LIBRARY) # The interpreter that answered above is whichever python3 is on PATH, which # is not necessarily the one this wheel was built for. A cp310 wheel inspected # by a 3.12 interpreter yields a suffix that names no file here, and the # package then reported itself as not found on a complete install. The shipped # extension carries its own suffix in its name, so take it from the package. - file(GLOB _portable_lib_matches - "${_executorch_package_root}/extension/pybindings/_portable_lib.*" + file(GLOB _C_matches + "${_executorch_package_root}/extension/pybindings/_C.*" ) - foreach(_candidate IN LISTS _portable_lib_matches) + foreach(_candidate IN LISTS _C_matches) if(_candidate MATCHES "\\.(so|pyd|dylib)$") - set(_portable_lib_LIBRARY "${_candidate}") + set(_C_LIBRARY "${_candidate}") break() endif() endforeach() - unset(_portable_lib_matches) + unset(_C_matches) endif() -if(_portable_lib_LIBRARY) +if(_C_LIBRARY) set(EXECUTORCH_FOUND ON) message( - STATUS "ExecuTorch portable library is found at ${_portable_lib_LIBRARY}" + STATUS "ExecuTorch portable library is found at ${_C_LIBRARY}" ) # Only when nothing else is linkable, which is the fused layout: a macOS wheel # ships this extension and no separate runtime library, so the appends above @@ -724,26 +724,26 @@ if(_portable_lib_LIBRARY) # fails with a page of PyUnicode_InternFromString style errors. # # Measured both layouts: split gives the runtime and its components, fused - # gives _portable_lib. Callers who specifically want the extension, such as a + # gives _C. Callers who specifically want the extension, such as a # custom operator project, ask for the target by name rather than relying on # this, and that target carries the C++20 requirement PyTorch's headers need # while the runtime components require C++17. if(NOT EXECUTORCH_LIBRARIES) - list(APPEND EXECUTORCH_LIBRARIES _portable_lib) + list(APPEND EXECUTORCH_LIBRARIES _C) endif() - if(TARGET _portable_lib) + if(TARGET _C) # This file ran already in the same configure, because another subproject # called find_package too. No in-tree target uses this name, so it can only # be the imported one defined below, and re-setting its properties to the # same values is harmless. - message(STATUS "executorch: _portable_lib is already defined, reusing it") + message(STATUS "executorch: _C is already defined, reusing it") else() - add_library(_portable_lib STATIC IMPORTED) + add_library(_C STATIC IMPORTED) endif() # PyTorch requires C++20, so pybindings must be compiled with C++20. set_target_properties( - _portable_lib - PROPERTIES IMPORTED_LOCATION "${_portable_lib_LIBRARY}" + _C + PROPERTIES IMPORTED_LOCATION "${_C_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${EXECUTORCH_INCLUDE_DIRS}" # An interface requirement rather than CXX_STANDARD: an imported # target compiles nothing itself, and CXX_STANDARD does not reach @@ -767,7 +767,7 @@ if(_portable_lib_LIBRARY) # defined on CMake 3.28 or newer while this one has no such requirement. if(_executorch_runtime_library) set_property( - TARGET _portable_lib + TARGET _C APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${_executorch_runtime_library}" ) @@ -782,7 +782,7 @@ if(_portable_lib_LIBRARY) EXECUTORCH_RUNTIME_LIBRARY_DIR "${_executorch_runtime_library}" DIRECTORY ) get_filename_component( - EXECUTORCH_PYTHON_EXTENSION_DIR "${_portable_lib_LIBRARY}" DIRECTORY + EXECUTORCH_PYTHON_EXTENSION_DIR "${_C_LIBRARY}" DIRECTORY ) endif() endif()