@@ -226,10 +226,10 @@ index a977141..540cd3a 100644
226226
227227 if (winml_is_inbox)
228228diff --git a/cmake/onnxruntime_python.cmake b/cmake/onnxruntime_python.cmake
229- index 5dfd004..51043a3 100644
229+ index 5dfd004..5f96c8e 100644
230230--- a/cmake/onnxruntime_python.cmake
231231+++ b/cmake/onnxruntime_python.cmake
232- @@ -216,10 +216,50 @@ endif()
232+ @@ -216,16 +216,69 @@ endif()
233233 if(onnxruntime_WEBGPU_LINKED_INTO_HOST)
234234 list(APPEND onnxruntime_pybind11_state_static_providers PRIVATE onnxruntime_providers_webgpu)
235235 endif()
@@ -243,9 +243,12 @@ index 5dfd004..51043a3 100644
243243+ if(onnxruntime_BUILD_INTERNAL_SHARED_LIB)
244244+ target_link_libraries(onnxruntime_pybind11_state PRIVATE onnxruntime_internal)
245245+ endif()
246+ + set(onnxruntime_pybind11_state_providers_target ${onnxruntime_providers_target})
246247+ if(WIN32 AND onnxruntime_BUILD_INTERNAL_SHARED_LIB)
247- + # onnxruntime_internal.dll exports what the objects of the Python bindings take from its static libraries. The
248- + # protobuf classes of onnx stay in the Python bindings, as they would need their data imported.
248+ + # The CPU provider is an object library with MSVC; its objects are in onnxruntime_internal.dll.
249+ + set(onnxruntime_pybind11_state_providers_target)
250+ + # onnxruntime_internal.dll exports what the objects of the Python bindings take from its libraries. The protobuf
251+ + # classes of onnx stay in the Python bindings, as they would need their data imported.
249252+ target_compile_definitions(onnxruntime_pybind11_state PRIVATE ORT_IMPORT_INTERNAL_DATA)
250253+ get_filename_component(_onnxruntime_linker_dir "${CMAKE_LINKER}" DIRECTORY)
251254+ find_program(onnxruntime_DUMPBIN dumpbin HINTS "${_onnxruntime_linker_dir}" REQUIRED)
@@ -261,16 +264,26 @@ index 5dfd004..51043a3 100644
261264+ else()
262265+ list(APPEND _onnxruntime_internal_def_libraries $<TARGET_FILE:${_lib}>)
263266+ endif()
267+ + elseif(_type STREQUAL "OBJECT_LIBRARY")
268+ + list(APPEND _onnxruntime_internal_def_libraries $<TARGET_OBJECTS:${_lib}>)
264269+ endif()
265270+ endif()
266271+ endforeach()
267272+ list(REMOVE_DUPLICATES _onnxruntime_internal_def_libraries)
273+ + # The object files exceed the length of a command line.
274+ + set(_onnxruntime_internal_def_inputs ${CMAKE_CURRENT_BINARY_DIR}/onnxruntime_internal_def_inputs)
275+ + file(GENERATE OUTPUT ${_onnxruntime_internal_def_inputs}/objects.txt
276+ + CONTENT "$<JOIN:$<TARGET_OBJECTS:onnxruntime_pybind11_state>,\n>\n")
277+ + file(GENERATE OUTPUT ${_onnxruntime_internal_def_inputs}/libraries.txt
278+ + CONTENT "$<JOIN:${_onnxruntime_internal_def_libraries},\n>\n")
279+ + file(GENERATE OUTPUT ${_onnxruntime_internal_def_inputs}/excluded_libraries.txt
280+ + CONTENT "$<JOIN:${_onnxruntime_internal_def_excluded_libraries},\n>\n")
268281+ add_custom_command(OUTPUT ${INTERNAL_DEF_FILE}
269282+ COMMAND ${Python_EXECUTABLE} "${REPO_ROOT}/tools/ci_build/gen_internal_def.py"
270283+ --dumpbin "${onnxruntime_DUMPBIN}" --public_def "${SYMBOL_FILE}" --output "${INTERNAL_DEF_FILE}"
271- + --objects "$<TARGET_OBJECTS:onnxruntime_pybind11_state> "
272- + --libraries ${_onnxruntime_internal_def_libraries}
273- + --excluded_libraries ${_onnxruntime_internal_def_excluded_libraries}
284+ + --objects "@${_onnxruntime_internal_def_inputs}/objects.txt "
285+ + --libraries "@${_onnxruntime_internal_def_inputs}/libraries.txt"
286+ + --excluded_libraries "@${_onnxruntime_internal_def_inputs}/excluded_libraries.txt"
274287+ DEPENDS "$<TARGET_OBJECTS:onnxruntime_pybind11_state>" ${_onnxruntime_internal_def_libraries}
275288+ ${_onnxruntime_internal_def_excluded_libraries} "${SYMBOL_FILE}" "${REPO_ROOT}/tools/ci_build/gen_internal_def.py"
276289+ COMMENT "Generating the exports of onnxruntime_internal for onnxruntime_pybind11_state"
@@ -281,7 +294,14 @@ index 5dfd004..51043a3 100644
281294 target_link_libraries(onnxruntime_pybind11_state PRIVATE
282295 onnxruntime_session
283296 ${onnxruntime_libs}
284- @@ -854,10 +894,14 @@ add_custom_command(
297+ ${onnxruntime_pybind11_state_static_providers}
298+ onnxruntime_optimizer
299+ - ${onnxruntime_providers_target}
300+ + ${onnxruntime_pybind11_state_providers_target}
301+ onnxruntime_util
302+ onnxruntime_lora
303+ onnxruntime_framework
304+ @@ -854,10 +907,14 @@ add_custom_command(
285305 )
286306
287307 if (onnxruntime_BUILD_SHARED_LIB)
@@ -395,10 +415,10 @@ index 15965a1..5209d65 100755
395415 for c in args.config:
396416diff --git a/tools/ci_build/gen_internal_def.py b/tools/ci_build/gen_internal_def.py
397417new file mode 100644
398- index 0000000..b0f2377
418+ index 0000000..9253dea
399419--- /dev/null
400420+++ b/tools/ci_build/gen_internal_def.py
401- @@ -0,0 +1,97 @@
421+ @@ -0,0 +1,102 @@
402422+ #!/usr/bin/env python3
403423+ # Copyright (c) Microsoft Corporation. All rights reserved.
404424+ # Licensed under the MIT License.
@@ -420,7 +440,8 @@ index 0000000..b0f2377
420440+
421441+
422442+ def parse_arguments():
423- + parser = argparse.ArgumentParser()
443+ + parser = argparse.ArgumentParser(fromfile_prefix_chars="@")
444+ + parser.convert_arg_line_to_args = lambda line: [line.strip()] if line.strip() else []
424445+ parser.add_argument("--dumpbin", required=True)
425446+ parser.add_argument("--public_def", required=True, help="module-definition file of the public API")
426447+ parser.add_argument("--output", required=True)
@@ -430,14 +451,21 @@ index 0000000..b0f2377
430451+ return parser.parse_args()
431452+
432453+
433- + def external_symbols(dumpbin, path):
434- + """Yields (name, defined, is_function) for the external symbols of an object file or static library."""
435- + out = subprocess.run([dumpbin, "/nologo", "/SYMBOLS", path], capture_output=True, text=True, errors="replace", check=True)
436- + for line in out.stdout.splitlines():
437- + m = SYMBOL_RE.match(line)
438- + if m:
439- + section, function, name = m.groups()
440- + yield name, section != "UNDEF", function is not None
454+ + def external_symbols(dumpbin, paths):
455+ + """Yields (name, defined, is_function) for the external symbols of object files or static libraries."""
456+ + for i in range(0, len(paths), 64):
457+ + out = subprocess.run(
458+ + [dumpbin, "/nologo", "/SYMBOLS", *paths[i : i + 64]],
459+ + capture_output=True,
460+ + text=True,
461+ + errors="replace",
462+ + check=True,
463+ + )
464+ + for line in out.stdout.splitlines():
465+ + m = SYMBOL_RE.match(line)
466+ + if m:
467+ + section, function, name = m.groups()
468+ + yield name, section != "UNDEF", function is not None
441469+
442470+
443471+ args = parse_arguments()
@@ -450,26 +478,23 @@ index 0000000..b0f2377
450478+ public.append(fields[0])
451479+
452480+ defined = {}
453- + for library in args.libraries:
454- + for name, is_defined, is_function in external_symbols(args.dumpbin, library):
455- + if is_defined:
456- + defined.setdefault(name, is_function)
457- + for library in args.excluded_libraries:
458- + for name, is_defined, _ in external_symbols(args.dumpbin, library):
459- + if is_defined:
460- + defined.pop(name, None)
481+ + for name, is_defined, is_function in external_symbols(args.dumpbin, args.libraries):
482+ + if is_defined:
483+ + defined.setdefault(name, is_function)
484+ + for name, is_defined, _ in external_symbols(args.dumpbin, args.excluded_libraries):
485+ + if is_defined:
486+ + defined.pop(name, None)
461487+
462488+ referenced = set()
463489+ imported = set()
464490+ defined_in_objects = set()
465- + for obj in args.objects:
466- + for name, is_defined, _ in external_symbols(args.dumpbin, obj):
467- + if is_defined:
468- + defined_in_objects.add(name)
469- + elif name.startswith("__imp_"):
470- + imported.add(name[len("__imp_") :])
471- + else:
472- + referenced.add(name)
491+ + for name, is_defined, _ in external_symbols(args.dumpbin, args.objects):
492+ + if is_defined:
493+ + defined_in_objects.add(name)
494+ + elif name.startswith("__imp_"):
495+ + imported.add(name[len("__imp_") :])
496+ + else:
497+ + referenced.add(name)
473498+
474499+ functions = []
475500+ data = []
0 commit comments