Skip to content

Commit

Permalink
Added iOS & Android support in NuGet package (#923)
Browse files Browse the repository at this point in the history
  • Loading branch information
skyline75489 authored Oct 10, 2024
1 parent b3dfed6 commit 0f59a90
Show file tree
Hide file tree
Showing 18 changed files with 215 additions and 37 deletions.
7 changes: 7 additions & 0 deletions .pipelines/nuget-publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ parameters:
type: boolean
default: true

- name: enable_android
displayName: 'Whether Android AAR package is built.'
type: boolean
default: true

- name: enable_apple_framework
displayName: 'Whether Apple framework for iOS & MacCatalyst is built.'
type: boolean
Expand Down Expand Up @@ -94,6 +99,7 @@ stages:
enable_win_dml: ${{ parameters.enable_win_dml }}
enable_win_arm64: ${{ parameters.enable_win_arm64 }}
enable_macos_cpu: ${{ parameters.enable_macos_cpu }}
enable_android: ${{ parameters.enable_android }}
enable_apple_framework: ${{ parameters.enable_apple_framework }}
ort_version: ${{ parameters.ort_version }}
ort_cuda_version: ${{ parameters.ort_cuda_version }}
Expand All @@ -110,6 +116,7 @@ stages:
enable_win_dml: ${{ parameters.enable_win_dml }}
enable_win_arm64: ${{ parameters.enable_win_arm64 }}
enable_macos_cpu: ${{ parameters.enable_macos_cpu }}
enable_android: ${{ parameters.enable_android }}
enable_apple_framework: ${{ parameters.enable_apple_framework }}
ort_version: ${{ parameters.ort_version }}
ort_cuda_version: ${{ parameters.ort_cuda_version }}
Expand Down
8 changes: 8 additions & 0 deletions .pipelines/stages/capi-packaging-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ parameters:
type: boolean
- name: enable_macos_cpu
type: boolean
- name: enable_android
type: boolean
- name: enable_apple_framework
type: boolean
- name: ort_version
Expand Down Expand Up @@ -114,6 +116,12 @@ stages:
os: 'osx'
build_config: ${{ parameters.build_config }}

- ${{ if eq(parameters.enable_android, true) }}:
- template: jobs/android-java-api-aar.yml
parameters:
ort_version: ${{ parameters.ort_version }}
build_config: ${{ parameters.build_config }}

- ${{ if eq(parameters.enable_apple_framework, true) }}:
- template: jobs/capi-packaging-job.yml
parameters:
Expand Down
7 changes: 5 additions & 2 deletions .pipelines/stages/jobs/android-java-api-aar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ jobs:

- template: steps/utils/use-android-ndk.yml
- template: steps/utils/set-genai-version.yml
- template: steps/utils/set-cmake-build-type.yml
parameters:
build_config: ${{parameters.build_config}}

- task: CmdLine@2
displayName: Build Android AAR Packages
inputs:
script: |
set -e -x
BUILD_DIR=$(Build.BinariesDirectory)
BUILD_CONFIG=${{parameters.build_config}}
BUILD_CONFIG=$(cmake_build_type)
GENAI_VERSION=$(genai_version)
PACKAGE_NAME=${{parameters.package_name}}
ARTIFACTS_DIR=$(Build.ArtifactStagingDirectory)
Expand Down
63 changes: 49 additions & 14 deletions .pipelines/stages/jobs/nuget-packaging-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ parameters:
type: boolean
default: false

- name: enable_android
displayName: 'Whether Android AAR package is built.'
type: boolean
default: false

- name: enable_apple_framework
displayName: 'Whether Apple framework for iOS & MacCatalyst is built.'
type: boolean
Expand Down Expand Up @@ -153,6 +158,20 @@ jobs:
ArtifactName: onnxruntime-genai-osx-cpu-arm64-capi
TargetPath: '$(Build.BinariesDirectory)/artifact-downloads'

- ${{ if eq(parameters.enable_apple_framework, true) }}:
- template: steps/utils/flex-download-pipeline-artifact.yml
parameters:
StepName: 'Download iOS XCFramework Artifacts'
ArtifactName: onnxruntime-genai-ios-xcframework
TargetPath: '$(Build.BinariesDirectory)/artifact-downloads'

- ${{ if eq(parameters.enable_android, true) }}:
- template: steps/utils/flex-download-pipeline-artifact.yml
parameters:
StepName: 'Download Android AAR Artifacts'
ArtifactName: drop-android
TargetPath: '$(Build.BinariesDirectory)/artifact-downloads'

- checkout: self
path: onnxruntime-genai
clean: true
Expand All @@ -162,7 +181,7 @@ jobs:

- powershell: |
dotnet --info
dotnet build Microsoft.ML.OnnxRuntimeGenAI.csproj -p:Configuration="$(buildConfig)" --verbosity normal
dotnet build Microsoft.ML.OnnxRuntimeGenAI.csproj -p:Configuration="$(buildConfig)" -p:IncludeMobileTargets=true --verbosity normal
displayName: 'Build CSharp'
workingDirectory: '$(Build.Repository.LocalPath)\src\csharp'
Expand All @@ -181,10 +200,12 @@ jobs:
- powershell: |
$artifacts_dir = '$(Build.BinariesDirectory)/artifact-downloads'
Write-Host "List downloaded artifacts"
$artifacts = Get-ChildItem -Path $artifacts_dir/* -Include *.zip,*.tar.gz
$artifacts = Get-ChildItem -Path $artifacts_dir/* -Include *.zip,*.tar.gz,*.aar
Write-Host $artifacts
$outputDir = '$(Build.Repository.LocalPath)/$(buildDir)'
Write-Host "List extracted artifacts"
Get-ChildItem -Path $nativeBuildOutputDir -Recurse
mkdir -Force $outputDir
foreach ($file in $artifacts) {
Expand All @@ -195,28 +216,42 @@ jobs:
$rid = $Matches.1
}
else {
Write-Host "Invalid artifact name" $file
return
$rid_match = $a -match "onnxruntime-genai-(android|ios)-$(genai_version)(.+?)?(\.zip|\.aar)"
if ($rid_match) {
$rid = $Matches.1
}
else {
Write-Host "Invalid artifact name" $file
return
}
}
mkdir -Force $outputDir/$rid
if ($a -like "*.zip") {
Expand-Archive -Path $file -DestinationPath $outputDir/$rid
mkdir -Force $outputDir/$rid
mkdir -Force $outputDir/$rid/$(buildConfig)
if ($rid -like "ios") {
Move-Item $file $outputDir/$rid/$(buildConfig)/onnxruntime-genai.xcframework.zip
}
elseif ($a -like "*.aar") {
Move-Item $file $outputDir/$rid/$(buildConfig)/onnxruntime-genai.aar
}
elseif ($a -like "*.tar.gz") {
tar -xf $file -C $outputDir/$rid
else {
if ($a -like "*.zip") {
Expand-Archive -Path $file -DestinationPath $outputDir/$rid
}
elseif ($a -like "*.tar.gz") {
tar -xf $file -C $outputDir/$rid
}
}
mkdir -Force $outputDir/$rid/$(buildConfig)
$b = $file.Basename
$b = $b -split '.tar'
$b = $b[0]
Move-Item $outputDir/$rid/$b/lib/* $outputDir/$rid/$(buildConfig) -Force
if (Test-Path $outputDir/$rid/$b/lib/) {
Move-Item $outputDir/$rid/$b/lib/* $outputDir/$rid/$(buildConfig) -Force
}
Get-ChildItem -Path $outputDir/$rid -Recurse
}
Write-Host "List extracted artifacts"
Get-ChildItem -Path $nativeBuildOutputDir -Recurse
displayName: 'Extract Artifacts & Prepare Native Libraries'
workingDirectory: '$(Build.BinariesDirectory)/artifact-downloads'
Expand Down
10 changes: 5 additions & 5 deletions .pipelines/stages/jobs/steps/capi-appleframework-step.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ steps:
tools/ci_build/github/apple/default_full_ios_framework_build_settings.json
mkdir $(Build.BinariesDirectory)/artifacts
mkdir -p $(Build.BinariesDirectory)/artifacts_staging/onnxruntime-genai-ios-xcframework-$(genai_version)
mkdir -p $(Build.BinariesDirectory)/artifacts_staging/onnxruntime-genai.xcframework
cp -R $(Build.BinariesDirectory)/apple_framework/framework_out/onnxruntime-genai.xcframework \
$(Build.BinariesDirectory)/artifacts_staging/onnxruntime-genai-ios-xcframework-$(genai_version)
$(Build.BinariesDirectory)/artifacts_staging/
pushd $(Build.BinariesDirectory)/artifacts_staging
zip -vr $(Build.BinariesDirectory)/artifacts/onnxruntime_genai_ios_xcframework.zip \
onnxruntime-genai-ios-xcframework-$(genai_version)
zip -vr $(Build.BinariesDirectory)/artifacts/onnxruntime-genai-ios-$(genai_version).zip \
onnxruntime-genai.xcframework
popd
displayName: 'Build Apple XCFramework'
workingDirectory: '$(Build.Repository.LocalPath)'

- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: ONNXRuntime GenAI XCFramework'
inputs:
ArtifactName: capi-onnxruntime-genai-ios-xcframework
ArtifactName: onnxruntime-genai-ios-xcframework
PathtoPublish: '$(Build.BinariesDirectory)/artifacts'
23 changes: 23 additions & 0 deletions .pipelines/stages/jobs/steps/utils/set-cmake-build-type.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
parameters:
- name: build_config
type: string
steps:
- task: PowerShell@2
displayName: 'Set CMake Build Type'
inputs:
workingDirectory: $(Build.SourcesDirectory)
targetType: inline
script: |
$chosen_build_config = "${{ parameters.build_config }}"
$cmake_build_type = $chosen_build_config;
if ($chosen_build_config -eq "release") {
$cmake_build_type = "Release"
}
elseif ($chosen_build_config -eq "relwithdebinfo") {
$cmake_build_type = "RelWithDebInfo"
}
elseif ($chosen_build_config -eq "debug") {
$cmake_build_type = "Debug"
}
Write-Host "Current build type: $cmake_build_type"
Write-Host "##vso[task.setvariable variable=cmake_build_type]$cmake_build_type"
10 changes: 8 additions & 2 deletions .pipelines/stages/nuget-packaging-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ parameters:
type: boolean
default: true

- name: enable_android
displayName: 'Whether Android AAR package is built.'
type: boolean
default: true

- name: enable_apple_framework
displayName: 'Whether Apple framework for iOS & MacCatalyst is built.'
type: boolean
default: false
default: true

- name: ort_version
type: string
Expand All @@ -62,6 +67,7 @@ stages:
enable_win_cpu: ${{ parameters.enable_win_cpu }}
enable_win_arm64: ${{ parameters.enable_win_arm64 }}
enable_macos_cpu: ${{ parameters.enable_macos_cpu }}
enable_android: ${{ parameters.enable_android }}
enable_apple_framework: ${{ parameters.enable_apple_framework }}
- ${{ if or(eq(parameters.enable_linux_cuda, true), eq(parameters.enable_win_cuda, true)) }}:
- template: jobs/nuget-packaging-job.yml
Expand All @@ -74,7 +80,7 @@ stages:
- ${{ if eq(parameters.enable_win_dml, true) }}:
- template: jobs/nuget-packaging-job.yml
parameters:
ep: 'directml'
ep: 'directml'
ort_version: ${{ parameters.ort_dml_version }}
build_config: ${{ parameters.build_config }}
enable_win_dml: ${{ parameters.enable_win_dml }}
Expand Down
13 changes: 13 additions & 0 deletions nuget/Microsoft.ML.OnnxRuntimeGenAI.Managed.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<dependencies>
<group targetFramework="net8.0" />
<group targetFramework="netstandard2.0" />
<group targetFramework="net8.0-android31.0" />
<group targetFramework="net8.0-ios15.4" />
<group targetFramework="net8.0-maccatalyst14.0" />
</dependencies>
</metadata>
<files>
Expand All @@ -27,6 +30,16 @@
<file src="..\src\csharp\bin\$configuration$\net8.0\Microsoft.ML.OnnxRuntimeGenAI.dll" target="lib\net8.0" />
<file src="..\src\csharp\bin\$configuration$\net8.0\Microsoft.ML.OnnxRuntimeGenAI.pdb" target="lib\net8.0" />

<file src="..\src\csharp\bin\$configuration$\net8.0-android\Microsoft.ML.OnnxRuntimeGenAI.dll" target="lib\net8.0-android31.0" />
<file src="..\src\csharp\bin\$configuration$\net8.0-android\Microsoft.ML.OnnxRuntimeGenAI.pdb" target="lib\net8.0-android31.0" />
<file src="..\src\csharp\bin\$configuration$\net8.0-android\Microsoft.ML.OnnxRuntimeGenAI.xml" target="lib\net8.0-android31.0" />

<file src="..\src\csharp\bin\$configuration$\net8.0-ios\Microsoft.ML.OnnxRuntimeGenAI.dll" target="lib\net8.0-ios15.4" />
<file src="..\src\csharp\bin\$configuration$\net8.0-ios\Microsoft.ML.OnnxRuntimeGenAI.pdb" target="lib\net8.0-ios15.4" />

<file src="..\src\csharp\bin\$configuration$\net8.0-maccatalyst\Microsoft.ML.OnnxRuntimeGenAI.dll" target="lib\net8.0-maccatalyst14.0" />
<file src="..\src\csharp\bin\$configuration$\net8.0-maccatalyst\Microsoft.ML.OnnxRuntimeGenAI.pdb" target="lib\net8.0-maccatalyst14.0" />

<!-- Targets -->
<file src="targets\Microsoft.ML.OnnxRuntimeGenAI.Managed.targets" target="build\netstandard2.0" />
<file src="targets\Microsoft.ML.OnnxRuntimeGenAI.Managed.targets" target="build\net8.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition=" '$(AndroidApplication)'=='true' ">
<AndroidLibrary Bind="false" Include="$(MSBuildThisFileDirectory)..\..\runtimes\android\native\*">
<Link>%(Filename)%(Extension)</Link>
</AndroidLibrary>
</ItemGroup>
</Project>
13 changes: 13 additions & 0 deletions nuget/targets/net8.0-ios/Microsoft.ML.OnnxRuntimeGenAI.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?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-genai.xcframework">
<Kind>Static</Kind>
<IsCxx>True</IsCxx>
<SmartLink>True</SmartLink>
<ForceLoad>True</ForceLoad>
<LinkerFlags>-lc++</LinkerFlags>
<WeakFrameworks>CoreML</WeakFrameworks>
</NativeReference>
</ItemGroup>
</Project>
3 changes: 3 additions & 0 deletions nuget/targets/net8.0-maccatalyst/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Notes for maccatalyst .NET targets:

We only add a blank file for the target framework folder here and thus will be including blank TFM under build/ and buildTransitive/ in the Nuget package. The reason is for Mac Catalyst platform, it directly will resolve the xcframework from the runtimes/native/ios folder based on this [RuntimeidentifierGraph](https://github.com/dotnet/sdk/blob/main/src/Layout/redist/PortableRuntimeIdentifierGraph.json#L300-L304)
Empty file.
38 changes: 37 additions & 1 deletion src/csharp/Microsoft.ML.OnnxRuntimeGenAI.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<Project Sdk="MSBuild.Sdk.Extras/3.0.22">
<PropertyGroup>
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
<IncludeMobileTargets>false</IncludeMobileTargets>
<BaseTargets>net8.0;netstandard2.0;</BaseTargets>
<MobileTargets></MobileTargets>
</PropertyGroup>

<PropertyGroup Condition="'$(IncludeMobileTargets)' == 'true'">
<MobileTargets>net8.0-android;net8.0-ios;net8.0-maccatalyst</MobileTargets>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>$(BaseTargets);$(MobileTargets)</TargetFrameworks>
<Platforms>AnyCPU</Platforms>
<LangVersion>default</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand All @@ -22,6 +32,16 @@
<IsLinuxBuild Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinuxBuild>
<IsWindowsBuild Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindowsBuild>
<IsMacOSBuild Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsMacOSBuild>

<!-- $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) gives better results than
$(TargetPlatformIdentifier). See https://github.com/dotnet/msbuild/issues/7359
Note there are slight differences in casing (e.g. macos vs macOS), so if we ever
change to use $(TargetPlatformIdentifier) we need to adjust for that.
-->
<IsAndroidTarget Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">true</IsAndroidTarget>
<IsIOSTarget Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' OR
$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">true</IsIOSTarget>
<IsMacTarget Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'macos'">true</IsMacTarget>
</PropertyGroup>


Expand Down Expand Up @@ -68,6 +88,22 @@
</WriteLinesToFile>
</Target>

<PropertyGroup Condition="'$(IsIOSTarget)'=='true' OR '$(IsAndroidTarget)'=='true'">
<OrtConstants>$(OrtConstants);__MOBILE__</OrtConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(IsAndroidTarget)'=='true'">
<OrtConstants>$(OrtConstants);__ANDROID__</OrtConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(IsIOSTarget)'=='true'">
<OrtConstants>$(OrtConstants);__IOS__</OrtConstants>
</PropertyGroup>

<PropertyGroup>
<DefineConstants>$(DefineConstants);$(OrtConstants)</DefineConstants>
</PropertyGroup>

<ItemGroup>
<None Include="$(NativeBuildOutputDir)\onnxruntime-genai.lib" Condition="Exists('$(NativeBuildOutputDir)\onnxruntime-genai.lib')" PackagePath="" Pack="false" CopyToOutputDirectory="Never" Visible="false" />
<None Include="$(NativeBuildOutputDir)\onnxruntime-genai.dll" Condition="Exists('$(NativeBuildOutputDir)\onnxruntime-genai.dll')" PackagePath="" Pack="false" CopyToOutputDirectory="PreserveNewest" Visible="false" />
Expand Down
Loading

0 comments on commit 0f59a90

Please sign in to comment.