Separate onnxruntime_providers compilation from its archive - #32162
Separate onnxruntime_providers compilation from its archive#32162Ryan VanderMeulen (rvandermeulen) wants to merge 1 commit into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
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_objobject 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-codedonnxruntime_providerstarget. - 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.
There was a problem hiding this comment.
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_LANGUAGEis only meaningful for linkable targets (e.g., STATIC/SHARED libraries, executables). For anOBJECT_LIBRARYit is effectively ignored, so this property assignment is misleading. Prefer removing it here and (if needed) applyingLINKER_LANGUAGE CXXonly to the actual archive target (onnxruntime_providers).
set_target_properties(onnxruntime_providers_obj PROPERTIES LINKER_LANGUAGE CXX)
|
Seems I'm at an impasse with the reviewbots. I'll wait for Edward Chen (@edgchen1)'s review for now 😄 |
| 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. |
There was a problem hiding this comment.
is it possible to avoid the duplication of the public usage requirements? e.g., would querying a property like INTERFACE_INCLUDE_DIRECTORIES work?
There was a problem hiding this comment.
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.
a18c317 to
a69cc9d
Compare
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.
a69cc9d to
7b93e65
Compare
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
onnxruntime_unittests.cmakeworkaround keys off the providers target's actualTYPEinstead of re-testing that condition.The change
onnxruntime_providers_objalways holds the provider objects. Theonnxruntime_providersstatic archive is materialized only where something needs an archive file, and is skipped on MSVC shared-library builds: withonnxruntime_ENABLE_LTOthe objects carry whole-program IR, which pushes that archive past the 4 GiB limitlib.exeenforces on the COFF archive format (LNK1248). Nolib.exeoption 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 inonnxruntime_providers_cpu.cmakealone.Two constraints shaped the result:
onnxruntime_providers_objin any form. Even aPRIVATElink is recorded as$<LINK_ONLY:>, andinstall(EXPORT)then rejectsonnxruntime_providersfor requiring a target that is not in any export set. The objects arrive throughTARGET_OBJECTS, and the archive restates the only public usage requirement it had (MPI_CXX_INCLUDE_DIRS, underENABLE_TRAINING+USE_NCCL).onnxruntime_INTERNAL_LIBRARIESis consumed both as a link list and as a list of archive files: the Apple static-framework prelink inonnxruntime.cmake, andbundle_static_library()inonnxruntime_webassembly.cmake, which collects only dependencies whoseTYPEisSTATIC_LIBRARYand 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 intoonnxruntime_unittest_utils, and the objects reaching the shared library. MSVC, Apple, Emscripten and the training build rely on CI.