Skip to content

Build and install shared library for consumers and backends#18560

Open
tomeuv wants to merge 4 commits intopytorch:mainfrom
tomeuv:FHS-upstream
Open

Build and install shared library for consumers and backends#18560
tomeuv wants to merge 4 commits intopytorch:mainfrom
tomeuv:FHS-upstream

Conversation

@tomeuv
Copy link
Copy Markdown

@tomeuv tomeuv commented Mar 29, 2026

Summary

These are the changes that I needed so that both my Mesa backend (tentatively named Torx), and my test suite can link to Executorch. This should be also what Linux distributions such as Debian and Fedora would need to package Executorch.

There are some fixes as well for recent toolchains, whichi will be needed as well by distributions.

I also install the headers for runtime/backend/, which weren't installed before, to make out-of-tree backends to build cleanly.

Test plan

Build with:

$ CMAKE_ARGS="-DEXECUTORCH_BUILD_SHARED=ON \
       -DEXECUTORCH_BUILD_EXTENSION_LLM=OFF \
       -DEXECUTORCH_BUILD_EXTENSION_LLM_RUNNER=OFF" \
       pip install --break-system-packages --no-build-isolation .

Then run:

$ cmake --install pip-out/temp.linux-$(uname -m)-cpython-3*/cmake-out

And check that the headers and shared library (libexecutorch.so.1.3.0) were installed.

cc @kimishpatel @YifanShenSZ @cymbalrush @metascroy

Copilot AI review requested due to automatic review settings March 29, 2026 12:51
@pytorch-bot
Copy link
Copy Markdown

pytorch-bot Bot commented Mar 29, 2026

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/18560

Note: Links to docs will display an error until the docs builds have been completed.

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

❌ 3 New Failures, 2 Cancelled Jobs, 2 Unrelated Failures

As of commit 444a4c3 with merge base e6efe18 (image):

NEW FAILURES - The following jobs have failed:

CANCELLED JOBS - The following jobs were cancelled. Please retry:

BROKEN TRUNK - The following jobs failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla
Copy link
Copy Markdown

meta-cla Bot commented Mar 29, 2026

Hi @tomeuv!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@github-actions
Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds packaging-oriented build/install capabilities so external consumers (including out-of-tree backends) can link against ExecuTorch more easily, with a consolidated shared library option and a few toolchain compatibility fixes.

Changes:

  • Introduce EXECUTORCH_BUILD_SHARED and build/install a consolidated libexecutorch shared library plus a executorch.pc pkg-config file.
  • Install additional runtime backend headers for downstream/backend builds.
  • Toolchain fixes: disable flatcc Werror and add missing <cstdint> includes in CoreML inmemoryfs headers.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/cmake/preset/default.cmake Adds EXECUTORCH_BUILD_SHARED build option.
tools/cmake/executorch.pc.in New pkg-config template for installed shared library consumers.
third-party/CMakeLists.txt Passes/forces FLATCC_ALLOW_WERROR=OFF and fixes arg expansion for ExternalProject.
backends/apple/coreml/runtime/inmemoryfs/memory_buffer.hpp Adds missing <cstdint> include for fixed-width integer types.
backends/apple/coreml/runtime/inmemoryfs/inmemory_filesystem.hpp Adds missing <cstdint> include for fixed-width integer types.
CMakeLists.txt Sets project version, installs backend headers, and adds consolidated shared library build/install + pkg-config install.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CMakeLists.txt Outdated
Comment thread tools/cmake/executorch.pc.in Outdated
Comment thread CMakeLists.txt Outdated
@meta-cla
Copy link
Copy Markdown

meta-cla Bot commented Mar 29, 2026

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 29, 2026
@nil-is-all nil-is-all added the module: coreml Issues related to Apple's Core ML delegation and code under backends/apple/coreml/ label Mar 30, 2026
@kirklandsign
Copy link
Copy Markdown
Contributor

Hi @tomeuv could you please follow up with the comments from copilot?

@tomeuv
Copy link
Copy Markdown
Author

tomeuv commented Apr 14, 2026

Hi @tomeuv could you please follow up with the comments from copilot?

Sorry, it took me some time to be able to get back to it. I addressed those and also fixed an issue found by the linter.

Copilot AI review requested due to automatic review settings April 19, 2026 14:09
@tomeuv
Copy link
Copy Markdown
Author

tomeuv commented Apr 19, 2026

Had to install two more shared libraries so Executorch-using applications can run the CPU operations not delegated to my backend.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/cmake/executorch.pc.in Outdated
Comment thread kernels/portable/CMakeLists.txt Outdated
Comment thread kernels/portable/CMakeLists.txt Outdated
Comment thread kernels/quantized/CMakeLists.txt Outdated
Comment thread kernels/quantized/CMakeLists.txt Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/cmake/executorch.pc.in
Comment thread CMakeLists.txt Outdated
Comment thread CMakeLists.txt Outdated
Comment thread tools/cmake/preset/default.cmake
Comment thread kernels/portable/CMakeLists.txt Outdated
Comment thread kernels/portable/CMakeLists.txt Outdated
Comment thread kernels/portable/CMakeLists.txt Outdated
Comment thread third-party/CMakeLists.txt
Copilot AI review requested due to automatic review settings April 19, 2026 16:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/cmake/Utils.cmake
Comment thread tools/cmake/Utils.cmake
Comment thread CMakeLists.txt Outdated
Copilot AI review requested due to automatic review settings April 19, 2026 16:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CMakeLists.txt Outdated
Copilot AI review requested due to automatic review settings April 19, 2026 17:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

tomeuv and others added 4 commits April 22, 2026 18:24
Add missing #include <cstdint> in CoreML inmemoryfs headers for
compilers that don't implicitly include it, disable -Werror in the
flatcc ExternalProject_Add and add_subdirectory builds, and fix a
missing dollar sign in the flatcc ExternalProject_Add invocation.

Co-authored-by: Claude <noreply@anthropic.com>
…ORCH_BUILD_SHARED=ON)

When EXECUTORCH_BUILD_SHARED=ON is passed, all static libraries are built
with PIC and a new executorch_shared target bundles executorch_core plus
commonly-used extensions (data_loader, flat_tensor, named_data_map,
module, tensor) into a single libexecutorch.so via whole-archive linking.

We add a helper to Utils.cmake to avoid duplicating the definitions of
other libraries that we will export in later commits.

A pkg-config file is also generated and installed for consumer
discovery.

When EXECUTORCH_BUILD_SHARED is OFF (the default), behavior is unchanged.

Co-authored-by: Claude <noreply@anthropic.com>
Create libexecutorch_portable_ops.so under EXECUTORCH_BUILD_SHARED.

Allows applications to run operations on the CPU that their backend of
choice doesn't support natively.

Co-authored-by: Claude <noreply@anthropic.com>
Create libexecutorch_quantized_ops.so under EXECUTORCH_BUILD_SHARED.

Allows applications to run (de)quantization on the CPU when their
backend of choice doesn't support natively.

Co-authored-by: Claude <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


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.
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.
Comment thread CMakeLists.txt
set_target_properties(
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.
Comment thread CMakeLists.txt
Comment on lines +1168 to +1172
# 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(
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.
@kirklandsign
Copy link
Copy Markdown
Contributor

@claude review

@claude
Copy link
Copy Markdown

claude Bot commented Apr 23, 2026

Claude finished @kirklandsign's task in 2m 12s —— View job


Review of PR #18560: Build and install shared library for consumers and backends

  • Gather diff and read changed files
  • Review CMakeLists.txt changes
  • Review tools/cmake/Utils.cmake
  • Review tools/cmake/executorch.pc.in
  • Review kernel CMakeLists.txt changes
  • Review third-party and header fixes
  • Post review summary

Overall this is a useful contribution for distro packaging and out-of-tree backends. The toolchain fixes and <cstdint> includes are straightforward and correct. There are a few issues that should be addressed before merging:

Issues

1. Target ordering: executorch_shared used before it's created (High)

kernels/portable/CMakeLists.txt:111 and kernels/quantized/CMakeLists.txt:163 both pass executorch_shared as a dependency to executorch_add_shared_library(), which calls target_link_libraries(... PRIVATE ${ARGN}). However, executorch_shared isn't created until CMakeLists.txt:1171, which is after both add_subdirectory(kernels/portable) (line 595) and add_subdirectory(kernels/quantized) (line 1154).

CMake will treat executorch_shared as a plain library name (-lexecutorch_shared) rather than a target reference. Since the consolidated library's output name is executorch (not executorch_shared), this link will fail at runtime or link time.

Options to fix:

  • Create executorch_shared earlier (right after executorch/executorch_core are defined), then add the extension/kernel WHOLE_ARCHIVE dependencies to it later using target_link_libraries calls in the top-level CMakeLists.
  • Or use $<TARGET_NAME_IF_EXISTS:executorch_shared> in the kernel subdirectories (though this changes semantics).
  • Or move the executorch_portable_ops/executorch_quantized_ops shared library creation into the top-level CMakeLists after executorch_shared is defined.

Fix this →

2. Export name collision: executorch exported twice (High)

At CMakeLists.txt:1175, EXPORT_NAME executorch is set on executorch_shared. But the static executorch target is already exported under that name at line 660:

install(
  TARGETS executorch executorch_core
  EXPORT ExecuTorchTargets
  ...
)

This will cause CMake export-set generation to fail with duplicate target names. The shared library should either:

  • Use a distinct export name (e.g., keep executorch_shared), or
  • Conditionally skip exporting the static executorch target when EXECUTORCH_BUILD_SHARED=ON.

Fix this →

3. executorch_add_shared_library also exports to ExecuTorchTargets (Medium)

tools/cmake/Utils.cmake:236 installs every shared library created by executorch_add_shared_library() into the ExecuTorchTargets export set. Combined with the EXPORT_NAME executorch on executorch_shared, this means the export set will have both the static executorch and the shared executorch (via export name). Even the kernel shared libs (executorch_portable_ops, executorch_quantized_ops) get added to ExecuTorchTargets — consider whether that's intentional for consumers who might only want the main library.

4. Cflags include path in pkg-config may be incorrect (Medium)

In tools/cmake/executorch.pc.in:9:

Cflags: ... -I${includedir}/executorch/runtime/core/portable_type/c10 ...

Headers are typically included as <c10/macros/Macros.h>, which requires the include path to be .../portable_type (the parent of c10/), not .../portable_type/c10. With the current path, consumers would need to include as <macros/Macros.h> instead. Verify the intended include pattern and adjust accordingly.

Fix this →

Minor / Nits

5. Bug fix in third-party/CMakeLists.txt:104 — The change from {_executorch_external_project_additional_args} to ${_executorch_external_project_additional_args} (adding the missing $) is a genuine bug fix. This was silently being treated as a literal string. Worth noting in the commit message as a pre-existing bug fix since it affects all builds, not just shared library builds.

6. FLATCC_ALLOW_WERROR uses FORCE — At third-party/CMakeLists.txt:121, the cache variable is set with FORCE, which overrides any user-supplied value. The ExternalProject version at line 94 does not force. This inconsistency means users cannot opt back into Werror for the add_subdirectory path. Consider whether FORCE is truly needed or if a simple non-forced cache set would suffice.

7. The executorch_add_shared_library helper doesn't use WHOLE_ARCHIVE — In tools/cmake/Utils.cmake:226, dependencies are linked with plain PRIVATE linkage. But the callers in kernels/portable/CMakeLists.txt:111 and kernels/quantized/CMakeLists.txt:163 pass static library targets (portable_ops_lib, portable_kernels, etc.) that contain operator registrations via static initializers. Without WHOLE_ARCHIVE, the linker may discard these registration symbols, causing operators to silently not be available at runtime. The top-level executorch_shared handles this correctly (uses WHOLE_ARCHIVE explicitly), but the kernel shared libraries don't.

Fix this →

8. Missing Libs.private in pkg-config — The .pc file doesn't declare Libs.private, so consumers doing static linking (or transitive dependency resolution) won't pick up dependencies like dl, pthread, etc. that ExecuTorch may need. For a shared-library-only package this is less critical, but worth considering for completeness.

Looks Good

  • The <cstdint> includes in the CoreML headers are correct and necessary for newer toolchains (GCC 13+).
  • The CMAKE_POSITION_INDEPENDENT_CODE global set when EXECUTORCH_BUILD_SHARED=ON is the right approach.
  • Version parsing from version.txt and passing to project(VERSION ...) is clean.
  • The VERSION/SOVERSION properties on the shared library follow standard conventions.
  • Installing runtime/backend/ headers enables out-of-tree backend development.

@GregoryComer GregoryComer requested review from GregoryComer and JacobSzwejbka and removed request for cccclai April 23, 2026 23:26
@GregoryComer
Copy link
Copy Markdown
Member

Thanks for putting this up. I'm taking a deeper look, but overall the direction looks good. I'm checking some of the specific CMake changes, but I should be able to get back to you within a day or two.

Copy link
Copy Markdown
Member

@GregoryComer GregoryComer left a comment

Choose a reason for hiding this comment

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

@tomeuv Overall, looks sound to me. I played around with a few build configurations locally, and the WHOLE_ARCHIVE logic seems to work properly. Though it is a bit fragile on our side.

The only issue I see is the export naming conflict between the static and shared executorch. Both are exported as "executorch", which causes a failure when trying to use via find_package. Could we either export it as executorch-shared, or alternatively, only export the shared or static version based on EXECUTORCH_BUILD_SHARED?

If we can resolve that, as well as rebase and lint, I think we should be ready to land it. Thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: coreml Issues related to Apple's Core ML delegation and code under backends/apple/coreml/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants