Skip to content

Enable GENAI with FetchContent or find_package() for client projects - #1858

Closed
apwojcik wants to merge 39 commits into
microsoft:mainfrom
apwojcik:fetch_content
Closed

Enable GENAI with FetchContent or find_package() for client projects#1858
apwojcik wants to merge 39 commits into
microsoft:mainfrom
apwojcik:fetch_content

Conversation

@apwojcik

@apwojcik apwojcik commented Nov 9, 2025

Copy link
Copy Markdown

The PR changes the onnxruntime-genai CMake files so client projects can use it via FetchContent or find_package() CMake commands.

To accomplish that

  • the project() needs version configured correctly and up to date,
  • the onnxruntime-genai target needs a properly configured INTERFACE when installing and building,
  • correctly place binaries and files needed for development in the designated directories,
  • export required information and generate config package scripts (CMakeConfigPackageHelpers),

With those changes, it is enough to use find_package() and target_link_libraries() commands in a client project to configure it with the onnxruntime-genai. Please take a look at examples\c\CMakeLists.txt for details, it has been updated accordingly.

A few changes were required for --buld_csharp to accommodate changes from this PR. In addition, the ability to build the Release NuGet package for C# has been added.

A minor optimization for MultiConfig generators is that build.py generates a single build directory rather than one per build type.

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.

Updates the CMake/build tooling so onnxruntime-genai can be consumed cleanly by downstream projects via FetchContent or find_package() by exporting/installing targets and generating a CMake package config.

Changes:

  • Add version parsing and set the top-level project(... VERSION ...) to keep package metadata consistent.
  • Export/install onnxruntime-genai targets and generate onnxruntime-genai-config.cmake + version file for find_package().
  • Update examples/build scripts and language bindings packaging to use exported targets and correct runtime binary locations.

Reviewed changes

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

Show a summary per file
File Description
src/python/CMakeLists.txt Include additional embedded libs when assembling the Python wheel.
src/java/CMakeLists.txt Copy embedded dependencies in one step and adjust ORT native lib search dir for tests on Windows.
src/csharp/Microsoft.ML.OnnxRuntimeGenAI.sln Add a Release solution configuration.
requirements.txt Introduce Python dependency list.
examples/c/CMakeLists.txt Switch C examples to find_package() + imported targets and set C++ standard requirements.
cmake/version.cmake New shared version parsing from VERSION_INFO.
cmake/package.cmake Install/export targets and generate CMake package config/version files.
cmake/ortlib.cmake Add ORT_BIN_DIR and improve ORT discovery via find_package() when ORT_HOME is set.
cmake/onnxruntime-genai-config.cmake.in New package config template for find_package(onnxruntime-genai).
cmake/global_variables.cmake Remove duplicated version parsing and update ORT library existence check.
build.py Improve multi-config build dir handling, add MSBuild extra properties, and use CMAKE_PREFIX_PATH for examples.
benchmark/c/CMakeLists.txt Simplify benchmark link/include usage to rely on the genai target.
CMakeLists.txt Set project version, add install dirs, provide install/build interface includes, and set shared lib versioning.
.gitignore Ignore local Python venv and normalize Java CMakeCache ignore entry.

Comment thread cmake/package.cmake Outdated
Comment thread examples/c/CMakeLists.txt Outdated
Comment thread examples/c/CMakeLists.txt Outdated
Comment thread cmake/version.cmake Outdated
Comment thread cmake/ortlib.cmake Outdated
Comment thread cmake/global_variables.cmake
Comment thread build.py Outdated
Comment thread build.py Outdated
Comment thread src/csharp/Microsoft.ML.OnnxRuntimeGenAI.sln Outdated
apwojcik and others added 4 commits April 10, 2026 21:29
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment thread requirements.txt Outdated
Comment thread tools/python/util/platform_helpers.py Fixed
baijumeswani
baijumeswani previously approved these changes May 4, 2026
Comment thread cmake/ortlib.cmake
set(ORT_BIN_DIR ${ORT_LIB_DIR})
elseif (CMAKE_SYSTEM_NAME MATCHES "AIX")
set(ORT_HEADER_DIR ${ORT_HOME}/include/onnxruntime)
set(ORT_BIN_DIR ${ORT_HOME}/bin)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

On AIX, is the ort bin dir inside ${ORT_HOME}/bin?

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I am not sure. I don't have access to AIX systems. If there's no bin directory, I will change it to LIB. I must have made that change because CI was failing for AIX (if any)?

Comment thread cmake/ortlib.cmake Outdated
find_file(_onnxruntime_lib onnxruntime.lib REQUIRED
HINTS "${ORT_HOME}" PATH_SUFFIXES lib)
else()
find_file(_onnxruntime_dll ${CMAKE_SHARED_LIBRARY_PREFIX}onnxruntime${CMAKE_SHARED_LIBRARY_SUFFIX} REQUIRED

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we rename _onnxruntime_dll to avoid the dll suffix?

Comment thread cmake/ortlib.cmake
message(FATAL_ERROR "Auto download ONNX Runtime for this platform is not supported.")
endif()
endif()
set(ORT_BIN_DIR ${ORT_LIB_DIR})

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We've mostly had the lib and bin dir be the same in most scenarios. Why do we need the distinction now?

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It is required for ONNX Runtime installed with the cmake --install ... command. On Windows, the command puts .dlls/.exe in the bin directory. That is expected for this type of installation.

Comment thread .gitignore
/build
build*/
/build_*
build*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

duplicate?

Comment thread cmake/package.cmake
install(TARGETS onnxruntime-genai
EXPORT onnxruntime-genaiTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would this put the binary in bin instead of lib? Is that intentional? It breaks existing expectation and will have consequences on our packaging pipelines as well.

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The command will put the .so files in the lib directory. On Windows, it will put .dll/.exe files in the bin directory, which is expected behavior with cmake --install ....

Comment thread CMakeLists.txt
Comment on lines +174 to +175
target_include_directories(onnxruntime-genai INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<INSTALL_INTERFACE:include>)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will this leak all internal headers to consumers?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

No, only the headers marked public and interface.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Those are all the files installed on Windows with the cmake --install ... command. I anonymized the actual installation path with .... The command installs similar files on other operating systems, except that the .so files are located in the lib directory rather than bin.

❯ cmake --install .\build\Release\ --prefix C:\...\onnxruntime-genai\Release --config Release
-- Installing: C:/.../onnxruntime-genai/Release/lib/onnxruntime-genai.lib
-- Installing: C:/.../onnxruntime-genai/Release/bin/onnxruntime-genai.dll
-- Installing: C:/.../onnxruntime-genai/Release/include/ort_genai_c.h
-- Installing: C:/.../onnxruntime-genai/Release/include/ort_genai.h
-- Installing: C:/.../onnxruntime-genai/Release/lib/cmake/onnxruntime-genai/onnxruntime-genai-targets.cmake
-- Installing: C:/.../onnxruntime-genai/Release/lib/cmake/onnxruntime-genai/onnxruntime-genai-targets-release.cmake
-- Installing: C:/.../onnxruntime-genai/Release/./README.md
-- Installing: C:/.../onnxruntime-genai/Release/./ThirdPartyNotices.txt
-- Installing: C:/.../onnxruntime-genai/Release/./SECURITY.md
-- Installing: C:/.../onnxruntime-genai/Release/./LICENSE
-- Installing: C:/.../onnxruntime-genai/Release/lib/cmake/onnxruntime-genai/onnxruntime-genai-config.cmake
-- Installing: C:/.../onnxruntime-genai/Release/lib/cmake/onnxruntime-genai/onnxruntime-genai-config-version.cmake

Comment thread build.py Outdated
Comment on lines +802 to +803
if util.is_windows():
ort_lib_dir = ortlib_runtimes_dir / "win-x64"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Implicit assumption that is_windows() is always win-x64? Haven't looked at is_windows(), does it only return true if it is win-x64?

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The change is needed for CI to pass when building examples, and the ONNX Runtime is extracted from a .nuget package. There's no Windows 32bit variant anymore. In the .nuget package, there are only win-x64 and win-arm64 subdirectories.

But you're right, the if will consume both win-x64 and win-arm64 and hardcode the path for win-x64. I will make win-arm64 the first to be checked.

Comment thread build.py Outdated
ort_lib_dir = ortlib_runtimes_dir / "win-arm64"
elif args.android:
ort_lib_dir = ortlib_runtimes_dir / "android"
elif util.is_linux():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same here.

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The change is to make CI pass with the ONNX Runtime extracted from the .nuget package. When used with find_package(), CMake will automatically configure all directories for building examples.

Comment thread build.py Outdated
elif args.ios:
ort_lib_dir = ortlib_runtimes_dir / "ios"
elif not util.is_aix():
raise RuntimeError("Unsupported operating system to build examples for")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can this error be cleaner (explicitly mention the build platform)? Any reason to not build here?

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This part is only when ONNX Runtime has been extracted from the .nuget package. There are no ONNXRuntime libraries for AIX in the .nuget package. The script is not blocking on building AIX here. It only blocks on unknown operating systems. The find_package() branch above will build examples for any operating system.

Comment thread cmake/ortlib.cmake
set(ORT_BINARY_PLATFORM "x64")
if (APPLE)
if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Any reason for this change?

@apwojcik apwojcik May 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The variable CMAKE_OSX_ARCHITECTURE returns an empty string on macOS Tahoe and CMake 4+. CMAKE_SYSTEM_PROCESSOR always returns the requested value for any macOS, OSX, or iOS target and CMake version.

@kunal-vaishnavi

Copy link
Copy Markdown
Contributor

You will need to sync with the main branch to get this CI fix.

@baijumeswani
baijumeswani dismissed their stale review May 12, 2026 16:38

Accidentally approved

@apwojcik
apwojcik requested a review from a team as a code owner May 15, 2026 09:12
@kunal-vaishnavi

Copy link
Copy Markdown
Contributor

Closing this PR in favor of #2310. Please add any comments or concerns on the new PR.

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.

5 participants