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
51 changes: 50 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
# Copyright 2024-2026 Arm Limited and/or its affiliates.
Expand Down Expand Up @@ -46,7 +46,6 @@
#

cmake_minimum_required(VERSION 3.24)
project(executorch)

set(EXECUTORCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR})

Expand Down Expand Up @@ -87,6 +86,10 @@
)
endif()

project(executorch
VERSION "${ET_VERSION_MAJOR}.${ET_VERSION_MINOR}.${ET_VERSION_PATCH}"
)

message(
STATUS
"ExecuTorch version: ${ET_VERSION_MAJOR}.${ET_VERSION_MINOR}.${ET_VERSION_PATCH}"
Expand Down Expand Up @@ -160,6 +163,10 @@
load_build_preset()
include(${PROJECT_SOURCE_DIR}/tools/cmake/preset/default.cmake)

if(EXECUTORCH_BUILD_SHARED)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()

# Enable ccache if available
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
Expand Down Expand Up @@ -1158,6 +1165,48 @@
list(APPEND _executorch_backends vgf_backend)
endif()

# Consolidated shared library: bundles executorch_core plus commonly used
# extensions into a single libexecutorch.so.
if(EXECUTORCH_BUILD_SHARED)
executorch_add_shared_library(executorch_shared)
set_target_properties(
Comment on lines +1168 to +1172
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

executorch_shared is created after the portable/quantized kernel subdirectories are added, but those subdirectories attempt to link against executorch_shared when EXECUTORCH_BUILD_SHARED is enabled. Because the target doesn’t exist yet at that point, those links won’t bind to the intended target.

Consider creating executorch_shared earlier (right after executorch / executorch_core are defined) and then adding the extension/kernel WHOLE_ARCHIVE dependencies later, so subdirectories can safely reference the target.

Copilot uses AI. Check for mistakes.
executorch_shared
PROPERTIES OUTPUT_NAME executorch
EXPORT_NAME executorch
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting EXPORT_NAME executorch on executorch_shared will collide with the already-exported executorch target (installed earlier via install(TARGETS executorch executorch_core EXPORT ExecuTorchTargets ...)). CMake export/install generation requires unique exported target names within an export set; this will break the ExecuTorchTargets export.

To fix: don’t reuse the executorch export name unless you also stop exporting/rename the existing executorch target when EXECUTORCH_BUILD_SHARED is ON. Alternative: export the shared library under a distinct target name (keep OUTPUT_NAME executorch for the file name), and optionally add a separate alias/imported target in the package config for consumer convenience.

Suggested change
EXPORT_NAME executorch

Copilot uses AI. Check for mistakes.
)
target_include_directories(
executorch_shared PUBLIC ${_common_include_directories}
)
target_compile_definitions(
executorch_shared PUBLIC C10_USING_CUSTOM_GENERATED_MACROS
)
# Link executorch without WHOLE_ARCHIVE because its INTERFACE link options
# (from executorch_target_link_options_shared_lib) already force
# whole-archive. Link executorch_core explicitly since executorch only has a
# PRIVATE dep on it (symbols wouldn't propagate otherwise).
target_link_libraries(
executorch_shared PRIVATE executorch
$<LINK_LIBRARY:WHOLE_ARCHIVE,executorch_core>
)
foreach(_ext_target
extension_data_loader extension_flat_tensor extension_named_data_map
extension_module_static extension_tensor
)
if(TARGET ${_ext_target})
target_link_libraries(
executorch_shared PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,${_ext_target}>
)
endif()
endforeach()
configure_file(
tools/cmake/executorch.pc.in ${CMAKE_CURRENT_BINARY_DIR}/executorch.pc
@ONLY
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/executorch.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endif()

# Top-level interface targets.

# A target containing all configured backends.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include <cstdint>
#include <memory>
#include <stdio.h>
#include <string>
Expand Down
6 changes: 6 additions & 0 deletions kernels/portable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ install(
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/executorch/kernels/portable/
)

if(EXECUTORCH_BUILD_SHARED)
executorch_add_shared_library(
executorch_portable_ops portable_ops_lib portable_kernels executorch_shared
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

executorch_add_shared_library(... executorch_shared) is evaluated while executorch_shared has not been created yet (it’s defined later in the top-level CMakeLists). In this situation CMake treats executorch_shared as a plain library name (e.g. -lexecutorch_shared) rather than a target, which will fail because the consolidated library’s output name is executorch.

Create executorch_shared before adding the kernels subdirectories (so it exists when this line runs), or avoid linking to executorch_shared here (e.g., link to the correct target or add the dependency from the top-level after the target exists).

Suggested change
executorch_portable_ops portable_ops_lib portable_kernels executorch_shared
executorch_portable_ops portable_ops_lib portable_kernels

Copilot uses AI. Check for mistakes.
)
endif()

# Build the portable custom ops AOT library for registering custom ops into
# PyTorch. Requires find_package(Torch), which must be called at root scope
# before this subdirectory is processed. Not targeting ARM_BAREMETAL as aot_lib
Expand Down
7 changes: 7 additions & 0 deletions kernels/quantized/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,10 @@ install(
PUBLIC_HEADER
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/executorch/kernels/quantized/
)

if(EXECUTORCH_BUILD_SHARED)
executorch_add_shared_library(
executorch_quantized_ops quantized_ops_lib quantized_kernels
executorch_shared
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as in portable kernels: this links against executorch_shared before that target is created (it’s defined later in the root CMakeLists). CMake will treat it as a raw library name and try to link -lexecutorch_shared, which won’t exist (the consolidated library is output as libexecutorch).

Fix by ensuring executorch_shared is created before processing this subdirectory, or by restructuring so this dependency is added after executorch_shared exists / using the correct target name.

Suggested change
executorch_shared
$<TARGET_NAME_IF_EXISTS:executorch_shared>

Copilot uses AI. Check for mistakes.
)
endif()
4 changes: 3 additions & 1 deletion third-party/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ ExternalProject_Add(
-DFLATCC_TEST=OFF
-DFLATCC_REFLECTION=OFF
-DFLATCC_DEBUG_CLANG_SANITIZE=OFF
-DFLATCC_ALLOW_WERROR=OFF
-DFLATCC_INSTALL=ON
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
Expand All @@ -100,7 +101,7 @@ ExternalProject_Add(
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
${_flatcc_extra_cmake_args}
BUILD_BYPRODUCTS <INSTALL_DIR>/bin/flatcc
{_executorch_external_project_additional_args}
${_executorch_external_project_additional_args}
)
file(REMOVE_RECURSE ${PROJECT_SOURCE_DIR}/third-party/flatcc/lib)
ExternalProject_Get_Property(flatcc_ep INSTALL_DIR)
Expand All @@ -117,6 +118,7 @@ set(FLATCC_TEST OFF CACHE BOOL "")
set(FLATCC_REFLECTION OFF CACHE BOOL "")
set(FLATCC_DEBUG_CLANG_SANITIZE OFF CACHE BOOL "")
set(FLATCC_INSTALL OFF CACHE BOOL "")
set(FLATCC_ALLOW_WERROR OFF CACHE BOOL "" FORCE)
Comment thread
tomeuv marked this conversation as resolved.
add_subdirectory(flatcc)
# Unfortunately flatcc writes libs directly in to the source tree [1]. So to
# ensure the target lib is created last, force flatcc_cli to build first.
Expand Down
28 changes: 28 additions & 0 deletions tools/cmake/Utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,31 @@ function(executorch_target_copy_mlx_metallib target)
endif()
endif()
endfunction()

# Create and install a shared library composed from dependency libraries. The
# target links the provided dependencies and carries VERSION/SOVERSION.
function(executorch_add_shared_library target_name)
set(_empty_source_name "${target_name}_empty.cpp")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_empty_source_name}"
"// intentionally empty"
)
add_library(
${target_name} SHARED "${CMAKE_CURRENT_BINARY_DIR}/${_empty_source_name}"
)
Comment thread
tomeuv marked this conversation as resolved.
if(ARGN)
target_link_libraries(${target_name} PRIVATE ${ARGN})
endif()
set_target_properties(
${target_name}
PROPERTIES VERSION "${PROJECT_VERSION}"
SOVERSION "${PROJECT_VERSION_MAJOR}"
LINKER_LANGUAGE CXX
)
install(
TARGETS ${target_name}
EXPORT ExecuTorchTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
Comment thread
tomeuv marked this conversation as resolved.
endfunction()
10 changes: 10 additions & 0 deletions tools/cmake/executorch.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@

Name: ExecuTorch
Description: On-device AI framework for PyTorch models
Version: @PROJECT_VERSION@
Cflags: -I${includedir} -I${includedir}/executorch/runtime/core/portable_type -I${includedir}/executorch/runtime/core/portable_type/c10 -DC10_USING_CUSTOM_GENERATED_MACROS
Libs: -L${libdir} -lexecutorch
Comment thread
tomeuv marked this conversation as resolved.
4 changes: 4 additions & 0 deletions tools/cmake/preset/default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ define_overridable_option(
EXECUTORCH_BUILD_CPUINFO "Build cpuinfo library." BOOL
${_default_executorch_build_cpuinfo}
)
define_overridable_option(
EXECUTORCH_BUILD_SHARED "Build a consolidated ExecuTorch shared library" BOOL
OFF
)
Comment thread
tomeuv marked this conversation as resolved.

# Threadpool size options. At most one can be specified. Note that the default
# is managed in threadpool.cpp to allow the user to specify an alternate mode
Expand Down
Loading