Skip to content

Commit

Permalink
Update macosx framework packaging to follow apple guidelines (micros…
Browse files Browse the repository at this point in the history
…oft#776)

* Update macosx framework packaging to follow apple guidelines

* Test path fix

* Update tools/ci_build/extract_nuget_files.ps1

---------
  • Loading branch information
vraspar authored Aug 13, 2024
1 parent be29e28 commit 8b5354f
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .pipelines/ios_packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:
pushd ${POD_STAGING_DIR}
# assemble the files in the artifacts staging directory
zip -r ${ARTIFACTS_STAGING_DIR}/${POD_ARCHIVE_BASENAME} * --exclude ${PODSPEC_BASENAME}
zip -vry ${ARTIFACTS_STAGING_DIR}/${POD_ARCHIVE_BASENAME} * --exclude ${PODSPEC_BASENAME}
cp ${PODSPEC_BASENAME} ${ARTIFACTS_STAGING_DIR}/${PODSPEC_BASENAME}
popd
Expand Down
4 changes: 2 additions & 2 deletions .pipelines/templates/build-package-for-ios-cocoapods.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,13 @@ jobs:
POD_STAGING_DIR="$(Build.BinariesDirectory)/pod_staging"
ARTIFACTS_STAGING_DIR="$(Build.ArtifactStagingDirectory)"
POD_NAME="onnxruntime-extensions-c"
POD_ARCHIVE_BASENAME="pod-archive-${POD_NAME}-${ORT_EXTENSIONS_POD_VERSION}.zip"
POD_ARCHIVE_BASENAME="onnxruntime_extensions.xcframework.${ORT_EXTENSIONS_POD_VERSION}.zip"
PODSPEC_BASENAME="${POD_NAME}.podspec"
pushd ${POD_STAGING_DIR}
# assemble the files in the artifacts staging directory
zip -r ${ARTIFACTS_STAGING_DIR}/${POD_ARCHIVE_BASENAME} * --exclude ${PODSPEC_BASENAME}
zip -vry ${ARTIFACTS_STAGING_DIR}/${POD_ARCHIVE_BASENAME} * --exclude ${PODSPEC_BASENAME}
cp ${PODSPEC_BASENAME} ${ARTIFACTS_STAGING_DIR}/${PODSPEC_BASENAME}
popd
Expand Down
2 changes: 1 addition & 1 deletion nuget/DummyNativeNuget.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<file src="targets\net6.0-android\Microsoft.ML.OnnxRuntime.Extensions.Dummy.targets" target="build\net6.0-android31.0" />
<file src="targets\net6.0-android\Microsoft.ML.OnnxRuntime.Extensions.Dummy.targets" target="buildTransitive\net6.0-android31.0" />
<!-- iOS via Xamarin/MAUI. -->
<file src="..\nuget-artifacts\onnxruntime_extensions.xcframework\**" target="runtimes\ios\native\onnxruntime_extensions.xcframework" />
<file src="..\nuget-artifacts\onnxruntime_extensions.xcframework.zip" target="runtimes\ios\native\" />
<file src="targets\xamarinios10\Microsoft.ML.OnnxRuntime.Extensions.Dummy.targets" target="build\xamarinios10" />
<file src="targets\xamarinios10\Microsoft.ML.OnnxRuntime.Extensions.Dummy.targets" target="buildTransitive\xamarinios10" />
<file src="targets\net6.0-ios\Microsoft.ML.OnnxRuntime.Extensions.Dummy.targets" target="build\net6.0-ios15.4" />
Expand Down
2 changes: 1 addition & 1 deletion nuget/NativeNuget.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<file src="targets\net6.0-android\Microsoft.ML.OnnxRuntime.Extensions.targets" target="build\net6.0-android31.0" />
<file src="targets\net6.0-android\Microsoft.ML.OnnxRuntime.Extensions.targets" target="buildTransitive\net6.0-android31.0" />
<!-- iOS via Xamarin/MAUI. -->
<file src="..\nuget-artifacts\onnxruntime_extensions.xcframework\**" target="runtimes\ios\native\onnxruntime_extensions.xcframework" />
<file src="..\nuget-artifacts\onnxruntime_extensions.xcframework.zip" target="runtimes\ios\native\" />
<file src="targets\xamarinios10\Microsoft.ML.OnnxRuntime.Extensions.targets" target="build\xamarinios10" />
<file src="targets\xamarinios10\Microsoft.ML.OnnxRuntime.Extensions.targets" target="buildTransitive\xamarinios10" />
<file src="targets\net6.0-ios\Microsoft.ML.OnnxRuntime.Extensions.targets" target="build\net6.0-ios15.4" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="('$(OutputType)'!='Library' OR '$(IsAppExtension)'=='True')">
<NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\ios\native\onnxruntime_extensions.xcframework">
<NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\ios\native\onnxruntime_extensions.xcframework.zip">
<Kind>Static</Kind>
<IsCxx>True</IsCxx>
<SmartLink>True</SmartLink>
Expand Down
9 changes: 3 additions & 6 deletions tools/android/build_aar.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ def build_for_abi(
str(_repo_dir / "tools" / "build.py"),
f"--build_dir={build_dir}",
f"--config={config}",
"--update",
"--build",
"--parallel",
"--test",
# Android options
"--android",
f"--android_abi={abi}",
Expand All @@ -53,7 +50,7 @@ def do_build_by_mode(
api_level: int,
sdk_path: Path,
ndk_path: Path,
build_py_args: list[str]
build_py_args: list[str],
):
output_dir = output_dir.resolve()

Expand All @@ -77,12 +74,12 @@ def do_build_by_mode(

jnilib_names = ["libortextensions.so", "libonnxruntime_extensions4j_jni.so"]
for jnilib_name in jnilib_names:
shutil.copyfile(build_dir / config / "java" / "android" / abi / jnilib_name, jnilibs_dir / jnilib_name)
shutil.copyfile(build_dir / config / "lib" / jnilib_name, jnilibs_dir / jnilib_name)

# depending on the build settings these libraries may not be build
optional_jnilib_names = ["libcrypto.so", "libssl.so", "libcurl.so"]
for jnilib_name in optional_jnilib_names:
src = build_dir / config / "java" / "android" / abi / jnilib_name
src = build_dir / config / "lib" / jnilib_name
if src.exists():
shutil.copyfile(src, jnilibs_dir / jnilib_name)

Expand Down
17 changes: 16 additions & 1 deletion tools/ci_build/extract_nuget_files.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ New-Item -Path $nuget_sources_dir -ItemType directory

## .zip files
# unzip directly
Get-ChildItem $artifact_download_dir -Filter *.zip |
Get-ChildItem $artifact_download_dir -Include *.zip -Exclude onnxruntime_extensions.xcframework.*.zip |
Foreach-Object {
$cmd = "7z.exe x $($_.FullName) -y -o$nuget_sources_dir"
Write-Output $cmd
Expand All @@ -44,6 +44,21 @@ Foreach-Object {
Invoke-Expression -Command $cmd
}

# process iOS xcframework
$xcframeworks = Get-ChildItem $Env:BUILD_BINARIESDIRECTORY\nuget-artifacts -Filter onnxruntime_extensions.xcframework.*.zip
if ($xcframeworks.Count -eq 1) {
$xcframework = $xcframeworks[0]
# remove version info from filename and use required filename format
$target_file = "$nuget_sources_dir\onnxruntime_extensions.xcframework.zip"
New-Item -Path $target_dir -ItemType directory

Write-Output "Copy-Item $($xcframework.FullName) $target_file"
Copy-Item $xcframework.FullName $target_file
}
elseif ($xcframeworks.Count -ne 1) {
Write-Error "Expected at most one onnxruntime_extensions.xcframework.*.zip file but got: [$xcframeworks]"
}

# copy android AAR.

# target file structure:
Expand Down
13 changes: 9 additions & 4 deletions tools/ios/assemble_pod_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

import argparse
import json
from pathlib import Path
import re
import shutil
import sys
from pathlib import Path
from typing import Dict

_script_dir = Path(__file__).resolve().parent
Expand Down Expand Up @@ -60,7 +60,12 @@ def replace_template_variable(match):


def assemble_pod_package(
staging_dir: Path, xcframework_dir: Path, public_headers_dir: Path, xcframework_info_file: Path, pod_version: str, catalyst_enabled: bool,
staging_dir: Path,
xcframework_dir: Path,
public_headers_dir: Path,
xcframework_info_file: Path,
pod_version: str,
catalyst_enabled: bool,
):
staging_dir = staging_dir.resolve()
xcframework_dir = xcframework_dir.resolve(strict=True)
Expand All @@ -74,8 +79,8 @@ def assemble_pod_package(

# copy files to staging dir
shutil.copyfile(_repo_dir / "LICENSE", staging_dir / "LICENSE")
shutil.copytree(xcframework_dir, staging_dir / xcframework_dir.name, dirs_exist_ok=True)
shutil.copytree(public_headers_dir, staging_dir / public_headers_dir.name, dirs_exist_ok=True)
shutil.copytree(xcframework_dir, staging_dir / xcframework_dir.name, dirs_exist_ok=True, symlinks=True)
shutil.copytree(public_headers_dir, staging_dir / public_headers_dir.name, dirs_exist_ok=True, symlinks=True)

# generate podspec
pod_name = "onnxruntime-extensions-c"
Expand Down
75 changes: 58 additions & 17 deletions tools/ios/build_xcframework.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@

import argparse
import json
import os
from pathlib import Path
import shutil
import sys
from pathlib import Path

_repo_dir = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(_repo_dir / "tools"))
Expand Down Expand Up @@ -98,7 +97,7 @@ def build_framework_for_platform_and_arch(

cmake_defines = []

if platform != "macosx" and platform != "maccatalyst": #ios simulator or iphoneos platform
if platform != "macosx" and platform != "maccatalyst": # ios simulator or iphoneos platform
cmake_defines += [
# required by OpenCV CMake toolchain file
# https://github.com/opencv/opencv/blob/4223495e6cd67011f86b8ecd9be1fa105018f3b1/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake#L64-L66
Expand Down Expand Up @@ -213,19 +212,61 @@ def platform_arch_framework_build_dir(platform, arch):
platform_fat_framework_dir.mkdir()

# copy over files from arch-specific framework to fat framework
for framework_file_relative_path in [Path("Headers"), Path("Info.plist")]:
src = first_arch_framework_dir / framework_file_relative_path
dst = platform_fat_framework_dir / framework_file_relative_path
if src.is_dir():
shutil.copytree(src, dst)
else:
shutil.copy(src, dst)

# combine arch-specific framework libraries
arch_libs = [str(framework_dir / "onnxruntime_extensions") for framework_dir in arch_framework_dirs]
run(
*([_lipo, "-create", "-output", str(platform_fat_framework_dir / "onnxruntime_extensions")] + arch_libs)
)
# macos requires different framework structure:
# https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html
if platform == "macosx" or platform == "maccatalyst":
# Set up directory strcture
dest_headers_dir = platform_fat_framework_dir / "Versions/A/Headers"
dest_resources_dir = platform_fat_framework_dir / "Versions/A/Resources"

# Copy headers and Info.plist
shutil.copytree(first_arch_framework_dir / Path("Headers"), dest_headers_dir)
Path(dest_resources_dir).mkdir(parents=True, exist_ok=True)
shutil.copy(first_arch_framework_dir / Path("Info.plist"), dest_resources_dir / "Info.plist")

# combine arch-specific framework libraries
arch_libs = [str(framework_dir / "onnxruntime_extensions") for framework_dir in arch_framework_dirs]
run(
*(
[
_lipo,
"-create",
"-output",
str(platform_fat_framework_dir / "Versions/A/onnxruntime_extensions"),
]
+ arch_libs
)
)

# create Symbolic links
Path(platform_fat_framework_dir / "Versions/Current").symlink_to("A", target_is_directory=True)
Path(platform_fat_framework_dir / "Headers").symlink_to(
"Versions/Current/Headers", target_is_directory=True
)
Path(platform_fat_framework_dir / "Resources").symlink_to(
"Versions/Current/Resources", target_is_directory=True
)
Path(platform_fat_framework_dir / "onnxruntime_extensions").symlink_to(
"Versions/Current/onnxruntime_extensions"
)

else:
for framework_file_relative_path in [Path("Headers"), Path("Info.plist")]:
src = first_arch_framework_dir / framework_file_relative_path
dst = platform_fat_framework_dir / framework_file_relative_path
if src.is_dir():
shutil.copytree(src, dst)
else:
shutil.copy(src, dst)

# combine arch-specific framework libraries
arch_libs = [str(framework_dir / "onnxruntime_extensions") for framework_dir in arch_framework_dirs]
run(
*(
[_lipo, "-create", "-output", str(platform_fat_framework_dir / "onnxruntime_extensions")]
+ arch_libs
)
)

platform_fat_framework_dirs.append(platform_fat_framework_dir)

Expand All @@ -241,7 +282,7 @@ def platform_arch_framework_build_dir(platform, arch):
# copy public headers
output_headers_dir = output_dir / "Headers"
_rmtree_if_existing(output_headers_dir)
shutil.copytree(headers_dir, output_headers_dir)
shutil.copytree(headers_dir, output_headers_dir, symlinks=True)

# merge framework_info.json per platform into xcframework_info.json in output_dir
_merge_framework_info_files(framework_info_files_to_merge, Path(output_dir, "xcframework_info.json"))
Expand Down

0 comments on commit 8b5354f

Please sign in to comment.