From 9479ba525b55dbbb4bf2bf4e18ce74c70ecf3171 Mon Sep 17 00:00:00 2001 From: moyo1997 <54333118+moyo1997@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:49:00 -0800 Subject: [PATCH] Build onnxruntime.dll as arm64x (#18633) Build onnxruntime.dll as arm64x Added a .cmake file to generate a link repro of the onnxruntime.dll during arm64 build. This provides us a directory containing all the arm64 objs, def file and libs to link to when it is time to building arm64x onnxruntime.dll during the arm64ec build by passing the /machine:arm64x flag to the linker along with the arm64 artifacts. If other dlls wanted to be built as x, setting the ARM64X_TARGETS variable in the toplevel cmakelists.txt to include these other targets is all that will be needed. Added build_arm64x.bat as a wrapper for the multiple (rm64, then arm64ec) cmake calls needed to build as arm64x. AB#22533 --- .gitignore | 1 + build_arm64x.bat | 12 ++++++++++++ cmake/CMakeLists.txt | 5 +++++ cmake/arm64x.cmake | 33 +++++++++++++++++++++++++++++++++ tools/ci_build/build.py | 10 ++++++++++ 5 files changed, 61 insertions(+) create mode 100644 build_arm64x.bat create mode 100644 cmake/arm64x.cmake diff --git a/.gitignore b/.gitignore index 6937f338b8a6..4d0a1205b7c1 100644 --- a/.gitignore +++ b/.gitignore @@ -195,3 +195,4 @@ Package.pins Package.resolved .build/ .swiftpm/ +repros/ diff --git a/build_arm64x.bat b/build_arm64x.bat new file mode 100644 index 000000000000..fbcdd373086a --- /dev/null +++ b/build_arm64x.bat @@ -0,0 +1,12 @@ +:: Copyright (c) Microsoft Corporation. All rights reserved. +:: Licensed under the MIT License. + +@echo off + +setlocal +set PATH=C:\Program Files\Git\usr\bin;%PATH% +set LINK_REPRO_NAME=/mylink.rsp + +rem Requires a Python install to be available in your PATH +python "%~dp0\tools\ci_build\build.py" --arm64 --buildasx --build_dir "%~dp0\build\arm64-x" %* +python "%~dp0\tools\ci_build\build.py" --arm64ec --buildasx --build_dir "%~dp0\build\arm64ec-x" %* diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index e82219a0aff6..2331562d4a3b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1776,3 +1776,8 @@ if(TARGET onnxruntime) "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") endif() + +if(DEFINED BUILD_AS_ARM64X) + set(ARM64X_TARGETS onnxruntime) + include("${CMAKE_SOURCE_DIR}/arm64x.cmake") +endif() diff --git a/cmake/arm64x.cmake b/cmake/arm64x.cmake new file mode 100644 index 000000000000..be476e09625b --- /dev/null +++ b/cmake/arm64x.cmake @@ -0,0 +1,33 @@ +set(arm64ReproDir "${CMAKE_SOURCE_DIR}/repros") + +if("${BUILD_AS_ARM64X}" STREQUAL "ARM64") + foreach (n ${ARM64X_TARGETS}) + add_custom_target(mkdirs_${n} ALL COMMAND cmd /c (if exist \"${arm64ReproDir}/${n}_temp/\" rmdir /s /q \"${arm64ReproDir}/${n}_temp\") && mkdir \"${arm64ReproDir}/${n}_temp\" ) + add_dependencies(${n} mkdirs_${n}) + target_link_options(${n} PRIVATE "/LINKREPRO:${arm64ReproDir}/${n}_temp") + add_custom_target(${n}_checkRepro ALL COMMAND cmd /c if exist \"${n}_temp/*.obj\" if exist \"${n}\" rmdir /s /q \"${n}\" 2>nul && if not exist \"${n}\" ren \"${n}_temp\" \"${n}\" DEPENDS ${n} + WORKING_DIRECTORY ${arm64ReproDir}) + endforeach() + + +elseif("${BUILD_AS_ARM64X}" STREQUAL "ARM64EC") + foreach (n ${ARM64X_TARGETS}) + set(ARM64_LIBS) + set(ARM64_OBJS) + set(ARM64_DEF) + + file(GLOB ARM64_OBJS "${arm64ReproDir}/${n}/*.obj") + file(GLOB ARM64_DEF "${arm64ReproDir}/${n}/*.def") + file(GLOB ARM64_LIBS "${arm64ReproDir}/${n}/*.LIB") + + if(NOT "${ARM64_DEF}" STREQUAL "") + set(ARM64_DEF "/defArm64Native:${ARM64_DEF}") + endif() + target_sources(${n} PRIVATE ${ARM64_OBJS}) + target_link_options(${n} PRIVATE /machine:arm64x "${ARM64_DEF}") + + if(NOT "${ARM64_LIBS}" STREQUAL "") + target_link_libraries(${n} PUBLIC ${ARM64_LIBS}) + endif() + endforeach() +endif() diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index c75af7a4bb71..c115a7ce4c2b 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -346,6 +346,11 @@ def convert_arg_line_to_args(self, arg_line): help="[cross-compiling] Create ARM64EC makefiles. Requires --update and no existing cache " "CMake setup. Delete CMakeCache.txt if needed", ) + parser.add_argument( + "--buildasx", + action="store_true", + help="[cross-compiling] Create ARM64X Binary.", + ) parser.add_argument("--msvc_toolset", help="MSVC toolset to use. e.g. 14.11") parser.add_argument("--windows_sdk_version", help="Windows SDK version to use. e.g. 10.0.19041.0") parser.add_argument("--android", action="store_true", help="Build for Android") @@ -2517,8 +2522,12 @@ def main(): cmake_extra_args = ["-A", "ARM"] elif args.arm64: cmake_extra_args = ["-A", "ARM64"] + if args.buildasx: + cmake_extra_args += ["-D", "BUILD_AS_ARM64X=ARM64"] elif args.arm64ec: cmake_extra_args = ["-A", "ARM64EC"] + if args.buildasx: + cmake_extra_args += ["-D", "BUILD_AS_ARM64X=ARM64EC"] cmake_extra_args += ["-G", args.cmake_generator] # Cannot test on host build machine for cross-compiled # builds (Override any user-defined behaviour for test if any) @@ -2553,6 +2562,7 @@ def main(): cmake_extra_args = ["-A", target_arch, "-T", toolset, "-G", args.cmake_generator] if args.enable_wcos: cmake_extra_defines.append("CMAKE_USER_MAKE_RULES_OVERRIDE=wcos_rules_override.cmake") + elif args.cmake_generator is not None: cmake_extra_args += ["-G", args.cmake_generator]