Skip to content
151 changes: 151 additions & 0 deletions cmake/onnxruntime_providers_openvino.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,154 @@ set_target_properties(onnxruntime_providers_openvino PROPERTIES
MAP_IMPORTED_CONFIG_RELEASE RelWithDebInfo
MAP_IMPORTED_CONFIG_DEBUG RelWithDebInfo
)

# ---------------------------------------------------------------------------
# Windows SxS (Side-by-Side) loading support
#
# Embeds private-assembly manifests into OV/TBB DLLs and the provider DLL so
# that Windows loads them from the EP's own directory, avoiding DLL collisions
# when another application in the same process also uses OpenVINO.
# ---------------------------------------------------------------------------
if(WIN32)
# Require mt.exe for manifest embedding
if(NOT CMAKE_MT)
message(FATAL_ERROR
"mt.exe not found — SxS manifest embedding is required on Windows.\n"
"Set -DCMAKE_MT=<path/to/mt.exe> or ensure the Windows SDK is on PATH.")
endif()

# --- Enumerate OV and TBB DLL filenames for the SxS assembly manifest ---
# Glob patterns selecting the OV binaries needed by the EP.
set(_ORT_OV_PATTERNS
"cache.json"
"*openvino.*"
"*openvinod.*"
"*openvino*plugin*"
"*openvino*compiler*"
"*openvino_ir_frontend*"
"*openvino_onnx_frontend*")

function(_ort_glob_ov _out_var _dir)
set(_result "")
foreach(_pat IN LISTS _ORT_OV_PATTERNS)
file(GLOB _tmp "${_dir}/${_pat}")
list(APPEND _result ${_tmp})
endforeach()
set(${_out_var} "${_result}" PARENT_SCOPE)
endfunction()
Comment thread
n1harika marked this conversation as resolved.

if(DEFINED ENV{INTEL_OPENVINO_DIR})
file(TO_CMAKE_PATH "$ENV{INTEL_OPENVINO_DIR}" _ORT_OV_ROOT)
set(_ov_bin "${_ORT_OV_ROOT}/runtime/bin/intel64")
set(_tbb_bin "${_ORT_OV_ROOT}/runtime/3rdparty/tbb/bin")

# TBB: split into non-debug (Release/RelWithDebInfo) and debug subsets
file(GLOB _all_tbb "${_tbb_bin}/tbb*.dll")
set(_tbb_release "")
set(_tbb_debug "")
foreach(_f IN LISTS _all_tbb)
get_filename_component(_lname "${_f}" NAME)
string(TOLOWER "${_lname}" _lname_lower)
if(_lname_lower MATCHES "debug")
list(APPEND _tbb_debug "${_f}")
else()
list(APPEND _tbb_release "${_f}")
endif()
endforeach()

if(EXISTS "${_ov_bin}/Release")
_ort_glob_ov(_ov_release "${_ov_bin}/Release")
set(ORT_OV_INSTALL_FILES_Release ${_ov_release} ${_tbb_release})
endif()
if(EXISTS "${_ov_bin}/Debug")
_ort_glob_ov(_ov_debug "${_ov_bin}/Debug")
set(ORT_OV_INSTALL_FILES_Debug ${_ov_debug} ${_tbb_debug})
endif()
if(EXISTS "${_ov_bin}/RelWithDebInfo")
_ort_glob_ov(_ov_rwdi "${_ov_bin}/RelWithDebInfo")
set(ORT_OV_INSTALL_FILES_RelWithDebInfo ${_ov_rwdi} ${_tbb_release})
elseif(DEFINED ORT_OV_INSTALL_FILES_Release)
set(ORT_OV_INSTALL_FILES_RelWithDebInfo ${ORT_OV_INSTALL_FILES_Release})
endif()
else()
# Python wheel layout — all binaries flat in <site-packages>/openvino/libs/
set(Python3_FIND_VIRTUALENV FIRST)
find_package(Python3 QUIET COMPONENTS Interpreter)
if(Python3_FOUND)
execute_process(
COMMAND "${Python3_EXECUTABLE}" -c
"import openvino, pathlib; print(pathlib.Path(openvino.__file__).parent)"
OUTPUT_VARIABLE _ORT_OV_WHEEL_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _ORT_OV_WHEEL_RESULT)
endif()
if(Python3_FOUND AND _ORT_OV_WHEEL_RESULT EQUAL 0 AND _ORT_OV_WHEEL_DIR)
file(TO_CMAKE_PATH "${_ORT_OV_WHEEL_DIR}" _ORT_OV_ROOT)
set(_libs "${_ORT_OV_ROOT}/libs")
if(EXISTS "${_libs}")
_ort_glob_ov(_ov_wheel "${_libs}")
file(GLOB _tbb_wheel "${_libs}/tbb*.dll")
set(ORT_OV_INSTALL_FILES_wheel ${_ov_wheel} ${_tbb_wheel})
endif()
endif()
endif()

# Collect unique DLL filenames for SxS dep manifest embedding
set(_all_files
${ORT_OV_INSTALL_FILES_Release}
${ORT_OV_INSTALL_FILES_Debug}
${ORT_OV_INSTALL_FILES_RelWithDebInfo}
${ORT_OV_INSTALL_FILES_wheel})
set(ORT_OV_TBB_DLL_NAMES "")
foreach(_f IN LISTS _all_files)
get_filename_component(_ext "${_f}" EXT)
get_filename_component(_name "${_f}" NAME)
if(_ext STREQUAL ".dll")
list(APPEND ORT_OV_TBB_DLL_NAMES "${_name}")
endif()
endforeach()
list(REMOVE_DUPLICATES ORT_OV_TBB_DLL_NAMES)

if(ORT_OV_TBB_DLL_NAMES)
message(STATUS "OpenVINO SxS: DLLs for manifest: ${ORT_OV_TBB_DLL_NAMES}")

# --- Generate assembly manifest ---
set(ORT_SXS_VERSION "${ORT_VERSION}")
set(_file_entries "")
foreach(_dll IN LISTS ORT_OV_TBB_DLL_NAMES)
string(APPEND _file_entries " <file name=\"${_dll}\" />\n")
endforeach()
set(ORT_SXS_ASSEMBLY_FILE_ENTRIES "${_file_entries}")

configure_file(
"${CMAKE_CURRENT_LIST_DIR}/sxs/assembly.manifest.in"
"${CMAKE_BINARY_DIR}/cmake/sxs/openvino_runtime.manifest"
@ONLY)
install(FILES "${CMAKE_BINARY_DIR}/cmake/sxs/openvino_runtime.manifest"
DESTINATION ${CMAKE_INSTALL_BINDIR})

# --- Install OV+TBB binaries alongside the provider DLL ---
if(DEFINED ORT_OV_INSTALL_FILES_wheel)
install(FILES ${ORT_OV_INSTALL_FILES_wheel} DESTINATION ${CMAKE_INSTALL_BINDIR})
else()
foreach(_config IN ITEMS Release Debug RelWithDebInfo)
if(ORT_OV_INSTALL_FILES_${_config})
install(FILES ${ORT_OV_INSTALL_FILES_${_config}}
DESTINATION ${CMAKE_INSTALL_BINDIR}
CONFIGURATIONS ${_config})
endif()
endforeach()
endif()

# --- Embed SxS manifests at install time ---
install(CODE "set(CMAKE_MT \"${CMAKE_MT}\")")
install(CODE "set(SXS_SOURCE_DIR \"${CMAKE_CURRENT_LIST_DIR}/sxs\")")
install(CODE "set(EP_FILE_VERSION \"${ORT_VERSION}.0\")")
install(CODE "set(OV_TBB_DLL_NAMES \"${ORT_OV_TBB_DLL_NAMES}\")")
install(CODE "set(ORT_SXS_BIN_DIR \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}\")")
install(SCRIPT "${CMAKE_CURRENT_LIST_DIR}/sxs/embed_manifests.cmake")
else()
message(WARNING "OpenVINO SxS: No OV/TBB DLLs found — SxS manifest embedding skipped.\n"
"Ensure INTEL_OPENVINO_DIR is set (setupvars.bat) or the openvino wheel is installed.")
endif()
endif()
3 changes: 3 additions & 0 deletions cmake/onnxruntime_unittests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,9 @@ endif()
if (onnxruntime_ENABLE_TRAINING_TORCH_INTEROP)
target_link_libraries(onnxruntime_test_all PRIVATE Python::Python)
endif()
if (WIN32 AND onnxruntime_USE_OPENVINO)
target_link_libraries(onnxruntime_test_all PRIVATE psapi)
endif()
onnxruntime_apply_emscripten_test_link_settings(onnxruntime_test_all)

if (onnxruntime_ENABLE_ATEN)
Expand Down
12 changes: 12 additions & 0 deletions cmake/sxs/assembly.manifest.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
Windows SxS private assembly manifest for the OpenVINO runtime bundled with
onnxruntime_providers_openvino.dll (legacy EP).
Installed as bin/openvino_runtime.manifest alongside the provider DLL.
Version matches the ORT version (MAJOR.MINOR.PATCH.0).
Configured at build time by CMakeLists.txt — do not edit by hand.
-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="openvino_runtime"
version="@ORT_SXS_VERSION@.0" processorArchitecture="amd64" />
@ORT_SXS_ASSEMBLY_FILE_ENTRIES@</assembly>
Comment thread
n1harika marked this conversation as resolved.
Comment thread
n1harika marked this conversation as resolved.
18 changes: 18 additions & 0 deletions cmake/sxs/dep.manifest.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
SxS dependency manifest embedded into each OV/TBB DLL and
onnxruntime_providers_openvino.dll.
Declares a dependency on the openvino_runtime private assembly at the EP version,
matching the version in assembly.manifest.in.
Generated by cmake/sxs/embed_manifests.cmake — do not edit by hand.
-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="${DLL_BASE_NAME}"
version="${EP_FILE_VERSION}" processorArchitecture="amd64" />
Comment thread
n1harika marked this conversation as resolved.
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="openvino_runtime"
version="${EP_FILE_VERSION}" processorArchitecture="amd64" />
Comment thread
n1harika marked this conversation as resolved.
</dependentAssembly>
Comment thread
n1harika marked this conversation as resolved.
</dependency>
</assembly>
117 changes: 117 additions & 0 deletions cmake/sxs/embed_manifests.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Copyright (C) Intel Corporation
# Licensed under the MIT License
#
# Install-time CMake script: embeds SxS manifests into OV+TBB DLLs and
# onnxruntime_providers_openvino.dll.
# Run via install(SCRIPT ...) after OV/TBB binaries are installed.
#
# Variables injected by install(CODE) in onnxruntime_providers_openvino.cmake:
# CMAKE_MT — absolute path to mt.exe
# SXS_SOURCE_DIR — cmake/sxs/ source directory
# EP_FILE_VERSION — EP version in A.B.C.D form (e.g. 1.28.0.0)
# OV_TBB_DLL_NAMES — semicolon-separated list of OV+TBB DLL filenames

cmake_minimum_required(VERSION 3.28)

set(PROVIDER_DLL_NAME "onnxruntime_providers_openvino")

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

# Embed a manifest into a DLL as RT_MANIFEST resource ID 2.
# If the DLL already has a resource ID 2 manifest it is extracted and merged first.
# Temporary files are written next to the DLL and deleted on completion.
function(ort_sxs_embed_manifest DLL_PATH MANIFEST_PATH)
get_filename_component(_dll_dir "${DLL_PATH}" DIRECTORY)
get_filename_component(_dll_name_we "${DLL_PATH}" NAME_WE)
set(_existing "${_dll_dir}/existing_${_dll_name_we}.manifest")

# Try to extract any existing RT_MANIFEST resource ID 2.
execute_process(
COMMAND "${CMAKE_MT}" -nologo
"-inputresource:${DLL_PATH};2"
"-out:${_existing}"
RESULT_VARIABLE _rc
OUTPUT_QUIET ERROR_QUIET)

if(_rc EQUAL 0 AND EXISTS "${_existing}")
# Merge existing + new dep manifest, then re-embed.
execute_process(
COMMAND "${CMAKE_MT}" -nologo
"-manifest" "${_existing}" "${MANIFEST_PATH}"
"-outputresource:${DLL_PATH};2"
RESULT_VARIABLE _rc2)
file(REMOVE "${_existing}")
if(NOT _rc2 EQUAL 0)
message(FATAL_ERROR
"SxS manifest embedding: mt.exe merge failed for '${DLL_PATH}' (exit ${_rc2}).")
endif()
else()
# No existing manifest — embed the new one directly.
execute_process(
COMMAND "${CMAKE_MT}" -nologo
"-manifest" "${MANIFEST_PATH}"
"-outputresource:${DLL_PATH};2"
RESULT_VARIABLE _rc2)
if(NOT _rc2 EQUAL 0)
message(FATAL_ERROR
"SxS manifest embedding: mt.exe embed failed for '${DLL_PATH}' (exit ${_rc2}).")
endif()
endif()
Comment thread
n1harika marked this conversation as resolved.
Outdated
endfunction()

# ---------------------------------------------------------------------------
# Resolve install directory
# ---------------------------------------------------------------------------

if(DEFINED ORT_SXS_BIN_DIR AND NOT ORT_SXS_BIN_DIR STREQUAL "")
set(BIN_DIR "${ORT_SXS_BIN_DIR}")
else()
set(BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin")
endif()
message(STATUS "SxS manifest embedding: processing '${BIN_DIR}'")

# ---------------------------------------------------------------------------
# Step 1: Embed dep manifests into each OV+TBB DLL
# ---------------------------------------------------------------------------

foreach(_name IN LISTS OV_TBB_DLL_NAMES)
set(_dll "${BIN_DIR}/${_name}")
if(NOT EXISTS "${_dll}")
continue() # DLL absent for this config (e.g. debug-only DLL in a Release build)
endif()
get_filename_component(_name_we "${_name}" NAME_WE)
set(DLL_BASE_NAME "${_name_we}")
set(_dep_manifest "${BIN_DIR}/${_name_we}.dep.manifest")
configure_file("${SXS_SOURCE_DIR}/dep.manifest.in" "${_dep_manifest}")
ort_sxs_embed_manifest("${_dll}" "${_dep_manifest}")
file(REMOVE "${_dep_manifest}")
message(STATUS "SxS manifest embedding: embedded dep manifest in ${_name_we}.dll")
endforeach()

# ---------------------------------------------------------------------------
# Step 2: Embed dep manifest into onnxruntime_providers_openvino.dll
# ---------------------------------------------------------------------------

# The provider DLL may be installed to bin/ or lib/ depending on whether it's
# a SHARED or MODULE library. Check both locations.
set(_provider_dll "${BIN_DIR}/${PROVIDER_DLL_NAME}.dll")
if(NOT EXISTS "${_provider_dll}")
# Try the lib/ sibling directory (MODULE libraries install to LIBRARY dest)
get_filename_component(_prefix "${BIN_DIR}" DIRECTORY)
set(_provider_dll "${_prefix}/lib/${PROVIDER_DLL_NAME}.dll")
endif()
if(NOT EXISTS "${_provider_dll}")
message(FATAL_ERROR
"SxS manifest embedding: '${PROVIDER_DLL_NAME}.dll' not found in '${BIN_DIR}' or '${_prefix}/lib'.")
endif()

set(DLL_BASE_NAME "${PROVIDER_DLL_NAME}")
set(_dep_manifest "${BIN_DIR}/${PROVIDER_DLL_NAME}.dep.manifest")
configure_file("${SXS_SOURCE_DIR}/dep.manifest.in" "${_dep_manifest}")
ort_sxs_embed_manifest("${_provider_dll}" "${_dep_manifest}")
file(REMOVE "${_dep_manifest}")
message(STATUS "SxS manifest embedding: embedded dep manifest in ${PROVIDER_DLL_NAME}.dll")

message(STATUS "SxS manifest embedding: done")
Loading
Loading