diff --git a/js/README.md b/js/README.md index b7e4366971d02..1662de6d4ac78 100644 --- a/js/README.md +++ b/js/README.md @@ -344,13 +344,13 @@ From ORT v1.13 onwards the 'full' ONNX Runtime package is used. It supports both Full build: ```sh - python tools/ci_build/github/apple/build_ios_framework.py tools/ci_build/github/apple/default_full_apple_framework_build_settings.json --config Release + python tools/ci_build/github/apple/build_apple_framework.py tools/ci_build/github/apple/default_full_apple_framework_build_settings.json --config Release ``` Reduced size build: ```sh - python tools/ci_build/github/apple/build_ios_framework.py tools/ci_build/github/apple/default_mobile_ios_framework_build_settings.json --config MinSizeRel --include_ops_by_config --enable_reduced_operator_type_support + python tools/ci_build/github/apple/build_apple_framework.py tools/ci_build/github/apple/default_mobile_ios_framework_build_settings.json --config MinSizeRel --include_ops_by_config --enable_reduced_operator_type_support ``` The build creates `Headers`, `LICENSE`, and `onnxruntime.xcframework` in `build/iOS_framework/framework_out` directory. From `framework_out` directory, create an archive file named `onnxruntime-c.zip` for a full build or `onnxruntime-mobile-c.zip` for a reduced size build and copy to `/js/react_native/local_pods` directory. diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 2b7f7182f6179..f05d3a8389a10 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -1261,7 +1261,9 @@ def generate_build_tree( if args.build_apple_framework or args.ios: if not args.cmake_generator == "Xcode": - raise BuildError("MacOS/iOS build requires use of the Xcode CMake generator ('--cmake_generator Xcode').") + raise BuildError( + "iOS/MacOS framework build requires use of the Xcode CMake generator ('--cmake_generator Xcode')." + ) needed_args = [ args.apple_sysroot, @@ -1281,14 +1283,14 @@ def generate_build_tree( "-DCMAKE_OSX_SYSROOT=" + args.apple_sysroot, "-DCMAKE_OSX_DEPLOYMENT_TARGET=" + args.apple_deploy_target, # we do not need protoc binary for ios cross build - "-Dprotobuf_BUILD_PROTOC_BINARIES=OFF" + "-Dprotobuf_BUILD_PROTOC_BINARIES=OFF", ] if args.ios: cmake_args += [ - "-DCMAKE_SYSTEM_NAME=iOS" , - "-DCMAKE_TOOLCHAIN_FILE=" - + (args.ios_toolchain_file if args.ios_toolchain_file else "../cmake/onnxruntime_ios.toolchain.cmake"), - ] + "-DCMAKE_SYSTEM_NAME=iOS", + "-DCMAKE_TOOLCHAIN_FILE=" + + (args.ios_toolchain_file if args.ios_toolchain_file else "../cmake/onnxruntime_ios.toolchain.cmake"), + ] if args.build_wasm: emsdk_dir = os.path.join(cmake_dir, "external", "emsdk") @@ -1750,7 +1752,7 @@ def run_ios_tests(args, source_dir, config, cwd): ) if args.build_apple_framework: - package_test_py = os.path.join(source_dir, "tools", "ci_build", "github", "apple", "test_ios_packages.py") + package_test_py = os.path.join(source_dir, "tools", "ci_build", "github", "apple", "test_apple_packages.py") framework_info_file = os.path.join(cwd, "framework_info.json") dynamic_framework_dir = os.path.join(cwd, config + "-" + args.apple_sysroot) static_framework_dir = os.path.join(cwd, config + "-" + args.apple_sysroot, "static_framework") diff --git a/tools/ci_build/github/apple/build_and_assemble_ios_pods.py b/tools/ci_build/github/apple/build_and_assemble_apple_pods.py similarity index 84% rename from tools/ci_build/github/apple/build_and_assemble_ios_pods.py rename to tools/ci_build/github/apple/build_and_assemble_apple_pods.py index 4bdd7f7870663..006dc4c33ffce 100755 --- a/tools/ci_build/github/apple/build_and_assemble_ios_pods.py +++ b/tools/ci_build/github/apple/build_and_assemble_apple_pods.py @@ -60,20 +60,20 @@ def parse_args(): build_framework_group = parser.add_argument_group( title="iOS framework build arguments", - description="See the corresponding arguments in build_ios_framework.py for details.", + description="See the corresponding arguments in build_apple_framework.py for details.", ) build_framework_group.add_argument("--include-ops-by-config") build_framework_group.add_argument( - "--build-settings-file", required=True, help="The positional argument of build_ios_framework.py." + "--build-settings-file", required=True, help="The positional argument of build_apple_framework.py." ) build_framework_group.add_argument( "-b", - "--build-ios-framework-arg", + "--build-apple-framework-arg", action="append", - dest="build_ios_framework_extra_args", + dest="build_apple_framework_extra_args", default=[], - help="Pass an argument through to build_ios_framework.py. This may be specified multiple times.", + help="Pass an argument through to build_apple_framework.py. This may be specified multiple times.", ) args = parser.parse_args() @@ -101,27 +101,27 @@ def main(): # build framework package_variant = PackageVariant[args.variant] - framework_info_file = build_dir / "framework_info.json" + framework_info_file = build_dir / "xcframework_info.json" - log.info("Building iOS framework.") + log.info("Building Apple framework.") - build_ios_framework_args = [ + build_apple_framework_args = [ sys.executable, - str(SCRIPT_DIR / "build_ios_framework.py"), - *args.build_ios_framework_extra_args, + str(SCRIPT_DIR / "build_apple_framework.py"), + *args.build_apple_framework_extra_args, ] if args.include_ops_by_config is not None: - build_ios_framework_args += ["--include_ops_by_config", args.include_ops_by_config] + build_apple_framework_args += ["--include_ops_by_config", args.include_ops_by_config] - build_ios_framework_args += ["--build_dir", str(build_dir), args.build_settings_file] + build_apple_framework_args += ["--build_dir", str(build_dir), args.build_settings_file] - run(build_ios_framework_args) + run(build_apple_framework_args) if args.test: - test_ios_packages_args = [ + test_apple_packages_args = [ sys.executable, - str(SCRIPT_DIR / "test_ios_packages.py"), + str(SCRIPT_DIR / "test_apple_packages.py"), "--fail_if_cocoapods_missing", "--framework_info_file", str(framework_info_file), @@ -131,7 +131,7 @@ def main(): package_variant.name, ] - run(test_ios_packages_args) + run(test_apple_packages_args) # assemble pods and then move them to their target locations (staging_dir/) staging_dir.mkdir(parents=True, exist_ok=True) diff --git a/tools/ci_build/github/apple/build_ios_framework.py b/tools/ci_build/github/apple/build_apple_framework.py similarity index 93% rename from tools/ci_build/github/apple/build_ios_framework.py rename to tools/ci_build/github/apple/build_apple_framework.py index 8a9b56b2dd4f2..e0d8627dbdc3a 100644 --- a/tools/ci_build/github/apple/build_ios_framework.py +++ b/tools/ci_build/github/apple/build_apple_framework.py @@ -101,18 +101,21 @@ def _build_for_apple_sysroot( return framework_dir -def _merge_framework_into_files(files, output_file): + +def _merge_framework_info_files(files, output_file): merged_data = defaultdict(dict) for file in files: - with open(file, 'r') as f: + with open(file, "r") as f: data = json.load(f) for platform, values in data.items(): - merged_data[platform].update(values) + assert platform not in merged_data, f"Duplicate platform value: {platform}" + merged_data[platform] = dict(values) - with open(output_file, 'w') as f: + with open(output_file, "w") as f: json.dump(merged_data, f, indent=2) + def _build_package(args): build_settings = _parse_build_settings(args) build_dir = os.path.abspath(args.build_dir) @@ -122,12 +125,16 @@ def _build_package(args): build_config = args.config # build framework for individual sysroot - base_build_command = [] framework_dirs = [] framework_info_files_to_merge = [] public_headers_path = "" for sysroot in build_settings["build_osx_archs"]: - base_build_command = [sys.executable, BUILD_PY] + build_settings["build_params"]["base"] + build_settings["build_params"][sysroot] + ["--config=" + build_config] + base_build_command = ( + [sys.executable, BUILD_PY] + + build_settings["build_params"]["base"] + + build_settings["build_params"][sysroot] + + ["--config=" + build_config] + ) if args.include_ops_by_config is not None: base_build_command += ["--include_ops_by_config=" + str(args.include_ops_by_config.resolve())] @@ -157,7 +164,7 @@ def _build_package(args): pathlib.Path(xcframework_dir).mkdir(parents=True, exist_ok=True) shutil.copy(os.path.join(REPO_DIR, "LICENSE"), xcframework_dir) shutil.copytree(public_headers_path, os.path.join(xcframework_dir, "Headers"), dirs_exist_ok=True) - _merge_framework_into_files(framework_info_files_to_merge, os.path.join(build_dir, "framework_info.json")) + _merge_framework_info_files(framework_info_files_to_merge, os.path.join(build_dir, "xcframework_info.json")) # remove existing xcframework if any xcframework_path = os.path.join(xcframework_dir, "onnxruntime.xcframework") diff --git a/tools/ci_build/github/apple/c/assemble_c_pod_package.py b/tools/ci_build/github/apple/c/assemble_c_pod_package.py index 38ef6038ba8f0..42075aaa5f424 100644 --- a/tools/ci_build/github/apple/c/assemble_c_pod_package.py +++ b/tools/ci_build/github/apple/c/assemble_c_pod_package.py @@ -77,9 +77,9 @@ def assemble_c_pod_package( # generate the podspec file from the template variable_substitutions = { "DESCRIPTION": pod_config["description"], - # By default, we build both "iphoneos" and "iphonesimulator" architectures, and the deployment target should be the same between these two. + # By default, we build both "iphoneos" and "iphonesimulator" architectures, and the deployment target should be the same between these two. "IOS_DEPLOYMENT_TARGET": framework_info["iphoneos"]["APPLE_DEPLOYMENT_TARGET"], - "MACOSX_DEPLOYMENT_TARGET": framework_info.get("macosx", {}).get("APPLE_DEPLOYMENT_TARGET", None), + "MACOSX_DEPLOYMENT_TARGET": framework_info.get("macosx", {}).get("APPLE_DEPLOYMENT_TARGET", ""), "LICENSE_FILE": "LICENSE", "NAME": pod_name, "ORT_C_FRAMEWORK": framework_dir.name, diff --git a/tools/ci_build/github/apple/default_full_apple_framework_build_settings.json b/tools/ci_build/github/apple/default_full_apple_framework_build_settings.json index 86b4efdc63750..50f8d00e6683d 100644 --- a/tools/ci_build/github/apple/default_full_apple_framework_build_settings.json +++ b/tools/ci_build/github/apple/default_full_apple_framework_build_settings.json @@ -8,7 +8,6 @@ "x86_64" ], "macosx": [ - "arm64", "x86_64" ] }, diff --git a/tools/ci_build/github/apple/test_ios_packages.py b/tools/ci_build/github/apple/test_apple_packages.py similarity index 99% rename from tools/ci_build/github/apple/test_ios_packages.py rename to tools/ci_build/github/apple/test_apple_packages.py index ced215c3f88d5..1f067d21f2d84 100644 --- a/tools/ci_build/github/apple/test_ios_packages.py +++ b/tools/ci_build/github/apple/test_apple_packages.py @@ -19,7 +19,7 @@ REPO_DIR = SCRIPT_PATH.parents[4] -def _test_ios_packages(args): +def _test_apple_packages(args): # check if CocoaPods is installed if shutil.which("pod") is None: if args.fail_if_cocoapods_missing: @@ -162,6 +162,7 @@ def _test_ios_packages(args): cwd=target_proj_path, ) + def parse_args(): parser = argparse.ArgumentParser( os.path.basename(__file__), description="Test iOS framework using CocoaPods package." @@ -210,7 +211,7 @@ def parse_args(): def main(): args = parse_args() - _test_ios_packages(args) + _test_apple_packages(args) if __name__ == "__main__": diff --git a/tools/ci_build/github/apple/use_ios_pods_with_custom_build.md b/tools/ci_build/github/apple/use_ios_pods_with_custom_build.md index c01f0796db0fb..c8da2eff57c33 100644 --- a/tools/ci_build/github/apple/use_ios_pods_with_custom_build.md +++ b/tools/ci_build/github/apple/use_ios_pods_with_custom_build.md @@ -2,9 +2,9 @@ If you require a custom build of ONNX Runtime, you can create CocoaPods pods with your custom build locally and use them from a Podfile. -**Prerequisite** - The custom build must be able to be done with [build_ios_framework.py](./build_ios_framework.py). +**Prerequisite** - The custom build must be able to be done with [build_apple_framework.py](./build_apple_framework.py). -To do a custom build and create the pods, run [build_and_assemble_ios_pods.py](./build_and_assemble_ios_pods.py). +To do a custom build and create the pods, run [build_and_assemble_apple_pods.py](./build_and_assemble_apple_pods.py). Use the `--help` argument to see more information. ## Example usage @@ -15,7 +15,7 @@ Our custom build will use a custom reduced operator kernel config file: `/path/t Run the script: ```bash -python3 tools/ci_build/github/apple/build_and_assemble_ios_pods.py \ +python3 tools/ci_build/github/apple/build_and_assemble_apple_pods.py \ --staging-dir /path/to/staging/dir \ --include-ops-by-config /path/to/custom.config \ --build-settings-file tools/ci_build/github/apple/default_mobile_ios_framework_build_settings.json diff --git a/tools/ci_build/github/azure-pipelines/post-merge-jobs.yml b/tools/ci_build/github/azure-pipelines/post-merge-jobs.yml index 2a94499c7a268..8cf01182bcc13 100644 --- a/tools/ci_build/github/azure-pipelines/post-merge-jobs.yml +++ b/tools/ci_build/github/azure-pipelines/post-merge-jobs.yml @@ -284,14 +284,14 @@ stages: displayName: "Install Python requirements" - script: | - python tools/ci_build/github/apple/build_ios_framework.py \ + python tools/ci_build/github/apple/build_apple_framework.py \ --build_dir "$(Build.BinariesDirectory)/ios_framework" \ --build_dynamic_framework \ tools/ci_build/github/apple/default_mobile_ios_framework_build_settings.json displayName: "Build iOS dynamic framework" - script: | - python tools/ci_build/github/apple/test_ios_packages.py \ - --framework_info_file "$(Build.BinariesDirectory)/ios_framework/framework_info.json" \ + python tools/ci_build/github/apple/test_apple_packages.py \ + --framework_info_file "$(Build.BinariesDirectory)/ios_framework/xcframework_info.json" \ --c_framework_dir "$(Build.BinariesDirectory)/ios_framework/framework_out" displayName: "Test pod with iOS dynamic framework" diff --git a/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml b/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml index 50fc907efb2eb..45ad2936a4a47 100644 --- a/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml +++ b/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml @@ -117,32 +117,32 @@ stages: - script: | set -e -x - python3 tools/ci_build/github/apple/build_ios_framework.py \ - --build_dir "$(Build.BinariesDirectory)/ios_framework" \ + python3 tools/ci_build/github/apple/build_apple_framework.py \ + --build_dir "$(Build.BinariesDirectory)/apple_framework" \ --path_to_protoc_exe $(Build.BinariesDirectory)/protobuf_install/bin/protoc \ tools/ci_build/github/apple/default_full_apple_framework_build_settings.json mkdir $(Build.BinariesDirectory)/artifacts - mkdir -p $(Build.BinariesDirectory)/artifacts_staging/onnxruntime-ios-xcframework-$(OnnxRuntimeVersion) - cp -R $(Build.BinariesDirectory)/ios_framework/framework_out/onnxruntime.xcframework \ - $(Build.BinariesDirectory)/artifacts_staging/onnxruntime-ios-xcframework-$(OnnxRuntimeVersion) + mkdir -p $(Build.BinariesDirectory)/artifacts_staging/onnxruntime-apple-xcframework-$(OnnxRuntimeVersion) + cp -R $(Build.BinariesDirectory)/apple_framework/framework_out/onnxruntime.xcframework \ + $(Build.BinariesDirectory)/artifacts_staging/onnxruntime-apple-xcframework-$(OnnxRuntimeVersion) pushd $(Build.BinariesDirectory)/artifacts_staging zip -vr $(Build.BinariesDirectory)/artifacts/onnxruntime_xcframework.zip \ - onnxruntime-ios-xcframework-$(OnnxRuntimeVersion) + onnxruntime-apple-xcframework-$(OnnxRuntimeVersion) popd - displayName: "Build iOS xcframework" + displayName: "Build Apple xcframework" - script: | - python3 tools/ci_build/github/apple/test_ios_packages.py \ + python3 tools/ci_build/github/apple/test_apple_packages.py \ --fail_if_cocoapods_missing \ - --framework_info_file "$(Build.BinariesDirectory)/ios_framework/framework_info.json" \ - --c_framework_dir "$(Build.BinariesDirectory)/ios_framework/framework_out" \ + --framework_info_file "$(Build.BinariesDirectory)/apple_framework/xcframework_info.json" \ + --c_framework_dir "$(Build.BinariesDirectory)/apple_framework/framework_out" \ --variant Full - displayName: "Test iOS framework" + displayName: "Test Apple framework" - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.BinariesDirectory)/artifacts' - artifactName: 'onnxruntime-ios-full-xcframework' + artifactName: 'onnxruntime-apple-full-xcframework' - template: component-governance-component-detection-steps.yml parameters: diff --git a/tools/ci_build/github/azure-pipelines/templates/react-native-ci.yml b/tools/ci_build/github/azure-pipelines/templates/react-native-ci.yml index 33f956f931f18..47cd72f412c67 100644 --- a/tools/ci_build/github/azure-pipelines/templates/react-native-ci.yml +++ b/tools/ci_build/github/azure-pipelines/templates/react-native-ci.yml @@ -126,7 +126,7 @@ stages: BuildStep: - script: | set -e -x - python $(Build.SourcesDirectory)/tools/ci_build/github/apple/build_and_assemble_ios_pods.py \ + python $(Build.SourcesDirectory)/tools/ci_build/github/apple/build_and_assemble_apple_pods.py \ --build-dir "$(Build.BinariesDirectory)/ios_framework_full" \ --staging-dir "$(Build.BinariesDirectory)/staging" \ --variant Full \ @@ -134,7 +134,7 @@ stages: -b="--path_to_protoc_exe" -b "$(Build.BinariesDirectory)/installed/bin/protoc" # Mobile build: - # python $(Build.SourcesDirectory)/tools/ci_build/github/apple/build_and_assemble_ios_pods.py \ + # python $(Build.SourcesDirectory)/tools/ci_build/github/apple/build_and_assemble_apple_pods.py \ # --build_dir $(Build.BinariesDirectory)/ios_framework_mobile \ # --staging-dir "$(Build.BinariesDirectory)/staging" \ # --include_ops_by_config $(Build.SourcesDirectory)/tools/ci_build/github/android/mobile_package.required_operators.config \ diff --git a/tools/ci_build/github/azure-pipelines/templates/stages/mac-ios-packaging-build-stage.yml b/tools/ci_build/github/azure-pipelines/templates/stages/mac-ios-packaging-build-stage.yml index 6ab829e108700..d3f7465d74591 100644 --- a/tools/ci_build/github/azure-pipelines/templates/stages/mac-ios-packaging-build-stage.yml +++ b/tools/ci_build/github/azure-pipelines/templates/stages/mac-ios-packaging-build-stage.yml @@ -38,7 +38,7 @@ stages: cPodName: onnxruntime-training-c objcPodName: onnxruntime-training-objc - timeoutInMinutes: 240 + timeoutInMinutes: 180 steps: - script: | @@ -84,7 +84,7 @@ stages: # create and test mobile pods - script: | - python tools/ci_build/github/apple/build_and_assemble_ios_pods.py \ + python tools/ci_build/github/apple/build_and_assemble_apple_pods.py \ --build-dir "$(Build.BinariesDirectory)/apple_framework" \ --staging-dir "$(Build.BinariesDirectory)/staging" \ --pod-version "$(ortPodVersion)" \ @@ -96,9 +96,9 @@ stages: displayName: "Build macOS/iOS framework and assemble pod package files" - script: | - python tools/ci_build/github/apple/test_ios_packages.py \ + python tools/ci_build/github/apple/test_apple_packages.py \ --fail_if_cocoapods_missing \ - --framework_info_file "$(Build.BinariesDirectory)/apple_framework/framework_info.json" \ + --framework_info_file "$(Build.BinariesDirectory)/apple_framework/xcframework_info.json" \ --c_framework_dir "$(Build.BinariesDirectory)/apple_framework/framework_out" \ --variant ${{ parameters.packageVariant }} \ --test_project_stage_dir "$(Build.BinariesDirectory)/app_center_test" \