Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions cmake/external/onnxruntime_external_deps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,10 @@ endforeach()

message("Loading Dependencies ...")

if(ENABLE_PYTHON)
FetchContent_Declare(
pybind11_project
URL ${DEP_URL_pybind11}
URL_HASH SHA1=${DEP_SHA1_pybind11}
FIND_PACKAGE_ARGS 2.6 NAMES pybind11
)
onnxruntime_fetchcontent_makeavailable(pybind11_project)

if(TARGET pybind11::module)
set(pybind11_lib pybind11::module)
else()
set(pybind11_dep pybind11::pybind11)
endif()
endif()
# The Python bindings are built with nanobind, which is discovered and wired up
# inside src/python/CMakeLists.txt (after find_package(Python ...) is called).
# nanobind is provided via pip (see test/python/requirements.txt) and located
# using `python -m nanobind --cmake_dir`, so no FetchContent entry is needed here.

FetchContent_Declare(
googletest
Expand Down
53 changes: 51 additions & 2 deletions src/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,43 @@ file(GLOB python_srcs CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
)
find_package(Python COMPONENTS Interpreter Development)
pybind11_add_module(python ${python_srcs})

# The Python bindings are built with nanobind. In addition to producing the
# extension module, nanobind lets us emit a typed `.pyi` stub so that editors
# such as VS Code (Pylance) can resolve the generated classes and methods for
# go-to-definition, find-references, and autocompletion.
find_package(Python 3.9 COMPONENTS Interpreter Development.Module REQUIRED)

# Locate the pip-installed nanobind (declared in test/python/requirements.txt).
execute_process(
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE nanobind_ROOT
RESULT_VARIABLE _nanobind_result)
if(NOT _nanobind_result EQUAL 0)
message(FATAL_ERROR
"nanobind was not found for '${Python_EXECUTABLE}'. Install the Python build "
"requirements first, e.g. `pip install -r test/python/requirements.txt` "
"(or `pip install nanobind`).")
endif()
find_package(nanobind CONFIG REQUIRED)

nanobind_add_module(python NB_STATIC ${python_srcs})
target_include_directories(python PRIVATE ${ORT_HEADER_DIR})
target_link_directories(python PRIVATE ${ORT_LIB_DIR})
target_link_libraries(python PRIVATE onnxruntime-genai)

# This project compiles with warnings-as-errors (`/WX`), but nanobind's bundled
# runtime sources (and generated binding glue) are third-party code that isn't
# held to that policy. Relax warnings-as-errors for the binding target and the
# nanobind runtime library so their warnings don't fail the build.
if(MSVC)
target_compile_options(python PRIVATE /WX-)
if(TARGET nanobind-static)
target_compile_options(nanobind-static PRIVATE /WX-)
endif()
endif()

if(NOT (CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
target_link_libraries(python PRIVATE ${ONNXRUNTIME_LIB})
endif()
Expand Down Expand Up @@ -54,6 +85,21 @@ if(BUILD_WHEEL)
${WHEEL_TARGET_NAME}
COMMENT "Copying files to wheel directory: ${WHEEL_TARGET_NAME}"
)

# Generate a typed stub (onnxruntime_genai.pyi) plus a py.typed marker next to
# the compiled extension so IDEs can resolve the nanobind-generated API. The
# stub is produced for the extension submodule and imported via the package so
# that its __init__ runs `add_onnxruntime_dependency` first, ensuring the
# matching onnxruntime shared library is on the DLL search path.
nanobind_add_stub(
onnxruntime_genai_stub
MODULE onnxruntime_genai.onnxruntime_genai
OUTPUT "${WHEEL_TARGET_NAME}/onnxruntime_genai.pyi"
MARKER_FILE "${WHEEL_TARGET_NAME}/py.typed"
PYTHON_PATH "${WHEEL_FILES_DIR}"
DEPENDS python
)

set(auditwheel_exclude_list
"libcublas.so.11"
"libcublas.so.12"
Expand Down Expand Up @@ -105,4 +151,7 @@ if(BUILD_WHEEL)
EXCLUDE_FROM_ALL
)
endif()

# Ensure the typed stub is generated before the wheel is packaged.
add_dependencies(PyPackageBuild onnxruntime_genai_stub)
endif()
Loading
Loading