Enable GENAI with FetchContent or find_package() for client projects - #1858
Enable GENAI with FetchContent or find_package() for client projects#1858apwojcik wants to merge 39 commits into
FetchContent or find_package() for client projects#1858Conversation
There was a problem hiding this comment.
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-genaitargets and generateonnxruntime-genai-config.cmake+ version file forfind_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. |
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>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| 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) |
There was a problem hiding this comment.
On AIX, is the ort bin dir inside ${ORT_HOME}/bin?
There was a problem hiding this comment.
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)?
| 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 |
There was a problem hiding this comment.
Can we rename _onnxruntime_dll to avoid the dll suffix?
| message(FATAL_ERROR "Auto download ONNX Runtime for this platform is not supported.") | ||
| endif() | ||
| endif() | ||
| set(ORT_BIN_DIR ${ORT_LIB_DIR}) |
There was a problem hiding this comment.
We've mostly had the lib and bin dir be the same in most scenarios. Why do we need the distinction now?
There was a problem hiding this comment.
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.
| /build | ||
| build*/ | ||
| /build_* | ||
| build*/ |
| install(TARGETS onnxruntime-genai | ||
| EXPORT onnxruntime-genaiTargets | ||
| LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
| RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ....
| target_include_directories(onnxruntime-genai INTERFACE | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<INSTALL_INTERFACE:include>) |
There was a problem hiding this comment.
Will this leak all internal headers to consumers?
There was a problem hiding this comment.
No, only the headers marked public and interface.
There was a problem hiding this comment.
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
| if util.is_windows(): | ||
| ort_lib_dir = ortlib_runtimes_dir / "win-x64" |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
| ort_lib_dir = ortlib_runtimes_dir / "win-arm64" | ||
| elif args.android: | ||
| ort_lib_dir = ortlib_runtimes_dir / "android" | ||
| elif util.is_linux(): |
There was a problem hiding this comment.
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.
| elif args.ios: | ||
| ort_lib_dir = ortlib_runtimes_dir / "ios" | ||
| elif not util.is_aix(): | ||
| raise RuntimeError("Unsupported operating system to build examples for") |
There was a problem hiding this comment.
Can this error be cleaner (explicitly mention the build platform)? Any reason to not build here?
There was a problem hiding this comment.
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.
| 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") |
There was a problem hiding this comment.
Any reason for this change?
There was a problem hiding this comment.
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.
|
You will need to sync with the main branch to get this CI fix. |
|
Closing this PR in favor of #2310. Please add any comments or concerns on the new PR. |
The PR changes the onnxruntime-genai CMake files so client projects can use it via FetchContent or find_package() CMake commands.
To accomplish that
project()needs version configured correctly and up to date,onnxruntime-genaitarget needs a properly configuredINTERFACEwhen installing and building,With those changes, it is enough to use
find_package()andtarget_link_libraries()commands in a client project to configure it with the onnxruntime-genai. Please take a look atexamples\c\CMakeLists.txtfor details, it has been updated accordingly.A few changes were required for
--buld_csharpto accommodate changes from this PR. In addition, the ability to build theReleaseNuGet 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.