Skip to content

Separate onnxruntime_providers compilation from its archive - #32162

Open
Ryan VanderMeulen (rvandermeulen) wants to merge 1 commit into
microsoft:mainfrom
rvandermeulen:providers-object-library
Open

Separate onnxruntime_providers compilation from its archive#32162
Ryan VanderMeulen (rvandermeulen) wants to merge 1 commit into
microsoft:mainfrom
rvandermeulen:providers-object-library

Conversation

@rvandermeulen

@rvandermeulen Ryan VanderMeulen (rvandermeulen) commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Supersedes #30511, which GitHub closed automatically when I force-pushed a commit that had lost its parent (pushed from a shallow clone), and which it will not let me reopen. The review discussion there is still readable; both of Edward Chen (@edgchen1)'s comments on it are addressed here.

What changed in response to that review

  • Compilation and packaging are now separate targets rather than one target changing type by configuration, so consumers no longer have to repeat the condition that chose it.
  • The onnxruntime_unittests.cmake workaround keys off the providers target's actual TYPE instead of re-testing that condition.

The change

onnxruntime_providers_obj always holds the provider objects. The onnxruntime_providers static archive is materialized only where something needs an archive file, and is skipped on MSVC shared-library builds: with onnxruntime_ENABLE_LTO the objects carry whole-program IR, which pushes that archive past the 4 GiB limit lib.exe enforces on the COFF archive format (LNK1248). No lib.exe option raises that limit, and a shared-library build only needs the objects for the final link.

Consumers link ${onnxruntime_providers_target}, so the choice lives in onnxruntime_providers_cpu.cmake alone.

Two constraints shaped the result:

  • The archive cannot link onnxruntime_providers_obj in any form. Even a PRIVATE link is recorded as $<LINK_ONLY:>, and install(EXPORT) then rejects onnxruntime_providers for requiring a target that is not in any export set. The objects arrive through TARGET_OBJECTS, and the archive restates the only public usage requirement it had (MPI_CXX_INCLUDE_DIRS, under ENABLE_TRAINING+USE_NCCL).
  • Consumers go through a variable rather than being repointed at the object library, because onnxruntime_INTERNAL_LIBRARIES is consumed both as a link list and as a list of archive files: the Apple static-framework prelink in onnxruntime.cmake, and bundle_static_library() in onnxruntime_webassembly.cmake, which collects only dependencies whose TYPE is STATIC_LIBRARY and would otherwise drop the providers silently. That is also why the condition stays keyed on MSVC.

Verification

Locally on Linux: the archive path and the static/install(EXPORT) path configure and provider objects compile; forcing the object-library branch yields no archive, no provider objects absorbed into onnxruntime_unittest_utils, and the objects reaching the shared library. MSVC, Apple, Emscripten and the training build rely on CI.

Copilot AI balanced review requested due to automatic review settings August 19, 2026 00:21
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR changes how the onnxruntime_providers library is built/consumed by introducing an object-library based path (primarily for MSVC shared builds) and updating downstream link dependencies to use a single indirection target variable.

Changes:

  • Introduce onnxruntime_providers_obj object library and set ${onnxruntime_providers_target} to either the object library or a materialized static archive depending on configuration.
  • Update multiple CMake link lists to use ${onnxruntime_providers_target} instead of the hard-coded onnxruntime_providers target.
  • Adjust unit test utility linking to avoid copying object-library objects into an intermediate static archive.

Reviewed changes

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

Show a summary per file
File Description
cmake/onnxruntime_providers_cpu.cmake Splits providers into object library + conditional archive with ${onnxruntime_providers_target} indirection.
cmake/onnxruntime_unittests.cmake Switches tests to ${onnxruntime_providers_target} and adds special handling when it’s an object library.
cmake/onnxruntime.cmake Updates internal library aggregation to use ${onnxruntime_providers_target}.
cmake/onnxruntime_webassembly.cmake Uses ${onnxruntime_providers_target} when bundling/linking for WebAssembly.
cmake/onnxruntime_training.cmake Updates training runner deps/linking to ${onnxruntime_providers_target}.
cmake/onnxruntime_python.cmake Updates pybind module linking to ${onnxruntime_providers_target}.
cmake/onnxruntime_providers_webgpu.cmake Updates WebGPU provider linking to ${onnxruntime_providers_target}.
cmake/onnxruntime_providers_pch.cmake Renames PCH target to onnxruntime_providers_obj.
cmake/CMakeLists.txt Includes providers PCH config only if onnxruntime_providers_obj exists.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmake/onnxruntime_unittests.cmake
Comment thread cmake/onnxruntime_providers_cpu.cmake
Comment thread cmake/onnxruntime_training.cmake

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 2 comments.

Suppressed comments (1)

cmake/onnxruntime_providers_cpu.cmake:210

  • LINKER_LANGUAGE is only meaningful for linkable targets (e.g., STATIC/SHARED libraries, executables). For an OBJECT_LIBRARY it is effectively ignored, so this property assignment is misleading. Prefer removing it here and (if needed) applying LINKER_LANGUAGE CXX only to the actual archive target (onnxruntime_providers).
set_target_properties(onnxruntime_providers_obj PROPERTIES LINKER_LANGUAGE CXX)

Comment thread cmake/onnxruntime.cmake
Comment thread cmake/onnxruntime_unittests.cmake
@rvandermeulen

Copy link
Copy Markdown
Contributor Author

Seems I'm at an impasse with the reviewbots. I'll wait for Edward Chen (@edgchen1)'s review for now 😄

Comment thread cmake/onnxruntime_providers_cpu.cmake Outdated
onnxruntime_add_static_library(onnxruntime_providers $<TARGET_OBJECTS:onnxruntime_providers_obj>)
# The archive must not link onnxruntime_providers_obj: install(EXPORT) rejects an exported target
# that references one outside the export set, and even a PRIVATE link records it as $<LINK_ONLY:>.
# The objects arrive through TARGET_OBJECTS, so only public usage requirements are restated here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is it possible to avoid the duplication of the public usage requirements? e.g., would querying a property like INTERFACE_INCLUDE_DIRECTORIES work?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good idea, and it is in the latest push, though the property has to be copied rather than referenced. $<TARGET_PROPERTY:onnxruntime_providers_obj,INTERFACE_INCLUDE_DIRECTORIES> on the archive fails the same way linking the object library does, because the generator expression still counts as requiring a target outside the export set:

install(EXPORT "propTargets" ...) includes target "providers" which
requires target "providers_obj" that is not in any export set.

Reading the properties at configure time and copying the values works, and the exported target ends up carrying them. The archive now does that for INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_COMPILE_DEFINITIONS, so the MPI include is no longer restated by hand and any future public requirement on the object library is picked up automatically. That also covers the property-drift point raised in the other thread.

onnxruntime_providers_obj now always holds the provider objects, and the
onnxruntime_providers static archive is materialized only where something
needs an archive file. Consumers link ${onnxruntime_providers_target}, so
the choice lives in onnxruntime_providers_cpu.cmake alone rather than being
a condition each consumer has to repeat.

The archive is skipped on MSVC shared-library builds. With
onnxruntime_ENABLE_LTO the objects carry whole-program IR, which pushes it
past the 4 GiB limit lib.exe enforces on the COFF archive format (LNK1248),
and no lib.exe option raises that limit.

The archive deliberately does not reference onnxruntime_providers_obj: the
objects arrive through TARGET_OBJECTS, and install(EXPORT) rejects an
exported target that requires one outside the export set. That covers a
PRIVATE link, recorded as $<LINK_ONLY:>, and a $<TARGET_PROPERTY:>
reference alike, so the object library's public usage requirements are
copied across by value instead.

The archive also gets a generated placeholder source. Xcode does not create
an archive for a target built only from object files, which left
libonnxruntime_providers.a missing and failed every iOS job; the
add_library() documentation recommends giving any target that references
$<TARGET_OBJECTS:objlib> at least one real source file.

In onnxruntime_unittests.cmake the workaround for absorbing objects into
onnxruntime_unittest_utils now keys off the providers target's actual type
instead of re-testing the configuration that chose it.
The providers precompiled-header include was guarded on the
onnxruntime_providers target existing. That guard now tests
onnxruntime_providers_obj: the PCH itself only applies under MSVC, which is
precisely where the archive is skipped, so leaving the guard on the archive
would have silently dropped the PCH there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants