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 13cd44a9660..ab4757f0386 100644 --- a/.ci/scripts/wheel/test_shared_libraries.py +++ b/.ci/scripts/wheel/test_shared_libraries.py @@ -899,7 +899,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. @@ -1150,7 +1150,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 @@ -1531,10 +1531,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..cda1004d154 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 - // with RTLD_LOCAL by default, so we re-open the current module with + // 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 0c0bf88c83d..b8246a571b1 100644 --- a/setup.py +++ b/setup.py @@ -1997,8 +1997,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 @@ -2008,7 +2008,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 0fa3c212d8f..d61dd664b44 100644 --- a/tools/cmake/executorch-wheel-config.cmake +++ b/tools/cmake/executorch-wheel-config.cmake @@ -50,9 +50,9 @@ # 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 -# name, which is the long-standing contract for that and also carries the C++20 -# requirement PyTorch's headers need. +# 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. # # EXECUTORCH_BUILD_VERSION -- The full version this package was built from, # including any prerelease suffix and local version label. Compare this when an @@ -647,8 +647,8 @@ _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 -# to build custom-op extensions against the Python module, and is kept working +# 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. # Find python @@ -678,14 +678,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 - # simply not offered in that case. + # 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 @@ -698,39 +698,35 @@ 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.*" - ) - foreach(_candidate IN LISTS _portable_lib_matches) + file(GLOB _C_matches "${_executorch_package_root}/extension/pybindings/_C.*") + 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}" - ) + message(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 # never ran and this is the only thing there is to offer. On a split wheel the @@ -739,26 +735,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 - # 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. + # 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 @@ -782,7 +778,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}" )