Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions extension/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,24 +116,69 @@ if(TARGET qnn_executorch_backend)
endif()

if(TARGET xnnpack_backend)
executorch_target_link_options_shared_lib(xnnpack_backend)
list(
APPEND
link_libraries
set(_xnnpack_so_link_libs
xnnpack_backend
XNNPACK
pthreadpool
cpuinfo
xnnpack-microkernels-prod
)
if(TARGET kleidiai)
list(APPEND link_libraries kleidiai)
list(APPEND _xnnpack_so_link_libs kleidiai)
endif()

if(EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED)
# Same rationale as EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED below: ship
# xnnpack_backend as its own libxnnpack_executorch_backend.so so the
# consumer can opt out at install time. Link only the backend itself
# (whole-archived so the register_backend static initializer fires) and
# the XNNPACK third-party libs + executorch_core. Kernel registration
# archives stay in libexecutorch_jni.so so loading both shared libraries
# together does not trigger Error::RegistrationAlreadyRegistered (0x16).
add_library(xnnpack_executorch_backend SHARED
${EXECUTORCH_ROOT}/extension/android/jni/jni_noop.cpp
)
executorch_target_link_options_shared_lib(xnnpack_backend)
target_link_options(xnnpack_executorch_backend PRIVATE -fopenmp -static-openmp)
target_link_options_gc_sections(xnnpack_executorch_backend)
target_link_libraries(xnnpack_executorch_backend
PRIVATE ${_xnnpack_so_link_libs} executorch_core log
)
set_target_properties(
xnnpack_executorch_backend PROPERTIES LINK_FLAGS "-Wl,-rpath='$ORIGIN'"
)
# executorch_jni still needs cpuinfo headers / lib for thread count detection.
list(APPEND link_libraries cpuinfo)
else()
executorch_target_link_options_shared_lib(xnnpack_backend)
list(APPEND link_libraries ${_xnnpack_so_link_libs})
endif()
endif()

if(TARGET vulkan_backend)
executorch_target_link_options_shared_lib(vulkan_backend)
list(APPEND link_libraries vulkan_backend)
if(EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED)
# Build vulkan_backend as a standalone shared library that React Native
# Executorch can ship as an opt-in artifact (libvulkan_executorch_backend.so).
# The .so links only vulkan_backend (with --whole-archive so its
# register_backend static initializer fires) plus executorch_core/vulkan_schema.
# Kernel registration libs (optimized_native_cpu_ops_lib, custom_ops, etc.)
# stay in libexecutorch_jni.so to avoid duplicate Kernel registration when
# both .so are loaded together (Error::RegistrationAlreadyRegistered, 0x16).
add_library(vulkan_executorch_backend SHARED
${EXECUTORCH_ROOT}/extension/android/jni/jni_noop.cpp
)
executorch_target_link_options_shared_lib(vulkan_backend)
target_link_options_gc_sections(vulkan_executorch_backend)
target_link_libraries(vulkan_executorch_backend
PRIVATE vulkan_backend vulkan_schema executorch_core log
)
set_target_properties(
vulkan_executorch_backend PROPERTIES LINK_FLAGS "-Wl,-rpath='$ORIGIN'"
)
else()
executorch_target_link_options_shared_lib(vulkan_backend)
list(APPEND link_libraries vulkan_backend)
endif()
endif()

if(EXECUTORCH_BUILD_KERNELS_LLM)
Expand Down
3 changes: 3 additions & 0 deletions extension/android/jni/jni_noop.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Empty translation unit so SHARED libraries that only need to whole-archive
// other static archives (e.g. libvulkan_executorch_backend.so) have at least
// one source file for CMake to invoke the linker on.
6 changes: 5 additions & 1 deletion extension/llm/custom_ops/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ endif()

list(TRANSFORM _custom_ops__srcs PREPEND "${EXECUTORCH_ROOT}/")

if(NOT EXECUTORCH_BUILD_XNNPACK)
if(NOT EXECUTORCH_BUILD_XNNPACK OR EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED)
# custom_ops doesn't actually call into xnnpack_backend (no XNNPACK refs in
# its sources). The transitive PUBLIC link is what was previously dragging
# XNNCompiler/XNNExecutor into libexecutorch_jni.so via the WHOLE_ARCHIVE on
# custom_ops, which defeats EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED. Drop it.
list(APPEND custom_ops_libs extension_threadpool)
else()
list(APPEND custom_ops_libs extension_threadpool xnnpack_backend)
Expand Down
17 changes: 16 additions & 1 deletion scripts/build_android_library.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ build_android_native_library() {
fi

EXECUTORCH_BUILD_VULKAN="${EXECUTORCH_BUILD_VULKAN:-OFF}"
EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED="${EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED:-OFF}"
EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED="${EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED:-OFF}"
XNNPACK_ENABLE_ARM_SME2="${XNNPACK_ENABLE_ARM_SME2:-ON}"

cmake . -DCMAKE_INSTALL_PREFIX="${CMAKE_OUT}" \
Expand All @@ -52,6 +54,8 @@ build_android_native_library() {
-DEXECUTORCH_BUILD_QNN="${EXECUTORCH_BUILD_QNN}" \
-DQNN_SDK_ROOT="${QNN_SDK_ROOT}" \
-DEXECUTORCH_BUILD_VULKAN="${EXECUTORCH_BUILD_VULKAN}" \
-DEXECUTORCH_BUILD_VULKAN_BACKEND_SHARED="${EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED}" \
-DEXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED="${EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED}" \
-DXNNPACK_ENABLE_ARM_SME2="${XNNPACK_ENABLE_ARM_SME2}" \
-DFLATCC_ALLOW_WERROR=OFF \
-DSUPPORT_REGEX_LOOKAHEAD=ON \
Expand All @@ -68,7 +72,18 @@ build_android_native_library() {
# Copy artifacts to ABI specific directory
local SO_STAGE_DIR="cmake-out-android-so/${ANDROID_ABI}"
mkdir -p ${SO_STAGE_DIR}
cp "${CMAKE_OUT}"/extension/android/*.so "${SO_STAGE_DIR}/libexecutorch.so"
cp "${CMAKE_OUT}"/extension/android/libexecutorch_jni.so "${SO_STAGE_DIR}/libexecutorch.so"

# Copy standalone Vulkan backend shared library if built. Used by React
# Native Executorch as an opt-in artifact when the app enables Vulkan.
if [ -f "${CMAKE_OUT}"/extension/android/libvulkan_executorch_backend.so ]; then
cp "${CMAKE_OUT}"/extension/android/libvulkan_executorch_backend.so "${SO_STAGE_DIR}/"
fi

# Same for XNNPACK as a standalone shared library.
if [ -f "${CMAKE_OUT}"/extension/android/libxnnpack_executorch_backend.so ]; then
cp "${CMAKE_OUT}"/extension/android/libxnnpack_executorch_backend.so "${SO_STAGE_DIR}/"
fi

# Copy QNN related so library
if [ -n "$QNN_SDK_ROOT" ] && [ "$ANDROID_ABI" == "arm64-v8a" ]; then
Expand Down
Loading