diff --git a/.pipelines/nuget-publishing.yml b/.pipelines/nuget-publishing.yml
index 22ec44677..1888d1234 100644
--- a/.pipelines/nuget-publishing.yml
+++ b/.pipelines/nuget-publishing.yml
@@ -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
@@ -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 }}
@@ -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 }}
diff --git a/.pipelines/stages/capi-packaging-stage.yml b/.pipelines/stages/capi-packaging-stage.yml
index add22efa9..a4aa477c9 100644
--- a/.pipelines/stages/capi-packaging-stage.yml
+++ b/.pipelines/stages/capi-packaging-stage.yml
@@ -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
@@ -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:
diff --git a/.pipelines/stages/jobs/android-java-api-aar.yml b/.pipelines/stages/jobs/android-java-api-aar.yml
index fface352e..f9b145308 100644
--- a/.pipelines/stages/jobs/android-java-api-aar.yml
+++ b/.pipelines/stages/jobs/android-java-api-aar.yml
@@ -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)
diff --git a/.pipelines/stages/jobs/nuget-packaging-job.yml b/.pipelines/stages/jobs/nuget-packaging-job.yml
index efa71e52b..1be6a9cd2 100644
--- a/.pipelines/stages/jobs/nuget-packaging-job.yml
+++ b/.pipelines/stages/jobs/nuget-packaging-job.yml
@@ -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
@@ -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
@@ -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'
@@ -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) {
@@ -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'
diff --git a/.pipelines/stages/jobs/steps/capi-appleframework-step.yml b/.pipelines/stages/jobs/steps/capi-appleframework-step.yml
index d3bef23c0..1970812ed 100644
--- a/.pipelines/stages/jobs/steps/capi-appleframework-step.yml
+++ b/.pipelines/stages/jobs/steps/capi-appleframework-step.yml
@@ -22,12 +22,12 @@ 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)'
@@ -35,5 +35,5 @@ steps:
- 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'
diff --git a/.pipelines/stages/jobs/steps/utils/set-cmake-build-type.yml b/.pipelines/stages/jobs/steps/utils/set-cmake-build-type.yml
new file mode 100644
index 000000000..077fd2337
--- /dev/null
+++ b/.pipelines/stages/jobs/steps/utils/set-cmake-build-type.yml
@@ -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"
\ No newline at end of file
diff --git a/.pipelines/stages/nuget-packaging-stage.yml b/.pipelines/stages/nuget-packaging-stage.yml
index 9122b2459..9d869f382 100644
--- a/.pipelines/stages/nuget-packaging-stage.yml
+++ b/.pipelines/stages/nuget-packaging-stage.yml
@@ -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
@@ -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
@@ -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 }}
diff --git a/nuget/Microsoft.ML.OnnxRuntimeGenAI.Managed.nuspec b/nuget/Microsoft.ML.OnnxRuntimeGenAI.Managed.nuspec
index f4d06bc0a..1bd50e0fc 100644
--- a/nuget/Microsoft.ML.OnnxRuntimeGenAI.Managed.nuspec
+++ b/nuget/Microsoft.ML.OnnxRuntimeGenAI.Managed.nuspec
@@ -15,6 +15,9 @@
+
+
+
@@ -27,6 +30,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/nuget/targets/net8.0-android/Microsoft.ML.OnnxRuntimeGenAI.targets b/nuget/targets/net8.0-android/Microsoft.ML.OnnxRuntimeGenAI.targets
new file mode 100644
index 000000000..a5b44939c
--- /dev/null
+++ b/nuget/targets/net8.0-android/Microsoft.ML.OnnxRuntimeGenAI.targets
@@ -0,0 +1,8 @@
+
+
+
+
+ %(Filename)%(Extension)
+
+
+
\ No newline at end of file
diff --git a/nuget/targets/net8.0-ios/Microsoft.ML.OnnxRuntimeGenAI.targets b/nuget/targets/net8.0-ios/Microsoft.ML.OnnxRuntimeGenAI.targets
new file mode 100644
index 000000000..d90112963
--- /dev/null
+++ b/nuget/targets/net8.0-ios/Microsoft.ML.OnnxRuntimeGenAI.targets
@@ -0,0 +1,13 @@
+
+
+
+
+ Static
+ True
+ True
+ True
+ -lc++
+ CoreML
+
+
+
\ No newline at end of file
diff --git a/nuget/targets/net8.0-maccatalyst/README.md b/nuget/targets/net8.0-maccatalyst/README.md
new file mode 100644
index 000000000..ef91f0f7c
--- /dev/null
+++ b/nuget/targets/net8.0-maccatalyst/README.md
@@ -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)
diff --git a/nuget/targets/net8.0-maccatalyst/_._ b/nuget/targets/net8.0-maccatalyst/_._
new file mode 100644
index 000000000..e69de29bb
diff --git a/nuget/targets/Microsoft.ML.OnnxRuntimeGenAI.props b/nuget/targets/netstandard/Microsoft.ML.OnnxRuntimeGenAI.props
similarity index 100%
rename from nuget/targets/Microsoft.ML.OnnxRuntimeGenAI.props
rename to nuget/targets/netstandard/Microsoft.ML.OnnxRuntimeGenAI.props
diff --git a/nuget/targets/Microsoft.ML.OnnxRuntimeGenAI.targets b/nuget/targets/netstandard/Microsoft.ML.OnnxRuntimeGenAI.targets
similarity index 100%
rename from nuget/targets/Microsoft.ML.OnnxRuntimeGenAI.targets
rename to nuget/targets/netstandard/Microsoft.ML.OnnxRuntimeGenAI.targets
diff --git a/src/csharp/Microsoft.ML.OnnxRuntimeGenAI.csproj b/src/csharp/Microsoft.ML.OnnxRuntimeGenAI.csproj
index a17d999a0..ee53c83fb 100644
--- a/src/csharp/Microsoft.ML.OnnxRuntimeGenAI.csproj
+++ b/src/csharp/Microsoft.ML.OnnxRuntimeGenAI.csproj
@@ -1,6 +1,16 @@
- net8.0;netstandard2.0
+ false
+ net8.0;netstandard2.0;
+
+
+
+
+ net8.0-android;net8.0-ios;net8.0-maccatalyst
+
+
+
+ $(BaseTargets);$(MobileTargets)
AnyCPU
default
true
@@ -22,6 +32,16 @@
true
true
true
+
+
+ true
+ true
+ true
@@ -68,6 +88,22 @@
+
+ $(OrtConstants);__MOBILE__
+
+
+
+ $(OrtConstants);__ANDROID__
+
+
+
+ $(OrtConstants);__IOS__
+
+
+
+ $(DefineConstants);$(OrtConstants)
+
+
diff --git a/src/csharp/NativeMethods.cs b/src/csharp/NativeMethods.cs
index 431b8e8cc..20b368c82 100644
--- a/src/csharp/NativeMethods.cs
+++ b/src/csharp/NativeMethods.cs
@@ -10,7 +10,15 @@ internal static class NativeMethods
{
internal class NativeLib
{
+#if __ANDROID__
+ // define the library name required for android
+ internal const string DllName = "libonnxruntime-genai.so";
+#elif __IOS__
+ // define the library name required for iOS
+ internal const string DllName = "__Internal";
+#else
internal const string DllName = "onnxruntime-genai";
+#endif
}
// The returned pointer is owned by the OgaResult object and will be freed when the OgaResult
@@ -73,7 +81,7 @@ internal class NativeLib
[DllImport(NativeLib.DllName, CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr /* OgaResult* */ OgaGeneratorParamsSetModelInput(IntPtr /* OgaGeneratorParams* */ generatorParams,
- byte[] /* const char* */ name,
+ byte[] /* const char* */ name,
IntPtr /* const OgaTensor* */ tensor);
[DllImport(NativeLib.DllName, CallingConvention = CallingConvention.Winapi)]
diff --git a/tools/ci_build/github/android/build_aar_package.py b/tools/ci_build/github/android/build_aar_package.py
index 2151acabb..8b3b339ac 100644
--- a/tools/ci_build/github/android/build_aar_package.py
+++ b/tools/ci_build/github/android/build_aar_package.py
@@ -72,7 +72,7 @@ def _parse_build_settings(args):
if build_settings["android_min_sdk_version"] > build_settings["android_target_sdk_version"]:
raise ValueError(
- f"android_min_sdk_version {build_settings['android_min_sdk_version']} cannot be larger than "
+ f"android_min_sdk_version {build_settings['android_min_sdk_version']} cannot be larger than "
f"android_target_sdk_version {build_settings['android_target_sdk_version']}"
)
@@ -95,9 +95,10 @@ def _build_aar(args):
build_config = args.config
aar_dir = intermediates_dir / "aar" / build_config
jnilibs_dir = intermediates_dir / "jnilibs" / build_config
- base_build_command = ([sys.executable, str(BUILD_PY),
- f"--config={build_config}", f"--ort_home={str(args.ort_home)}"] +
- build_settings["build_params"])
+ base_build_command = [sys.executable, str(BUILD_PY), f"--config={build_config}"]
+ if args.ort_home:
+ base_build_command += [f"--ort_home={str(args.ort_home)}"]
+ base_build_command += build_settings["build_params"]
header_files_path = None
@@ -181,7 +182,7 @@ def parse_args():
help="Configuration to build.",
)
- parser.add_argument("--ort_home", type=Path, default=REPO_ROOT / "ort",
+ parser.add_argument("--ort_home", type=Path, default=None,
help="Path to an unzipped onnxruntime AAR.")
parser.add_argument(
diff --git a/tools/nuget/generate_nuspec_for_native_nuget.py b/tools/nuget/generate_nuspec_for_native_nuget.py
index ba464add6..00b7dfd08 100644
--- a/tools/nuget/generate_nuspec_for_native_nuget.py
+++ b/tools/nuget/generate_nuspec_for_native_nuget.py
@@ -97,7 +97,7 @@ def generate_release_notes(line_list):
def generate_dependencies(xml_text, package_version, ort_package_name, ort_package_version):
xml_text.append("")
- target_frameworks = ["NETSTANDARD" , "NETCOREAPP", "NETFRAMEWORK"]
+ target_frameworks = ["NETSTANDARD" , "NETCOREAPP", "NETFRAMEWORK", "net8.0-android31.0", "net8.0-ios15.4", "net8.0-maccatalyst14.0"]
for framework in target_frameworks:
xml_text.append(f'')
xml_text.append(f'')
@@ -122,23 +122,37 @@ def add_native_artifact_if_exists(xml_lines, runtime, artifact):
f''
)
- runtimes = ["win-x64", "win-arm64", "linux-x64", "osx-x64", "osx-arm64"]
+ runtimes = ["win-x64", "win-arm64", "linux-x64", "osx-x64", "osx-arm64", "ios", "android"]
for runtime in runtimes:
if runtime.startswith("win"):
add_native_artifact_if_exists(lines, runtime, "onnxruntime-genai.lib")
add_native_artifact_if_exists(lines, runtime, "onnxruntime-genai.dll")
add_native_artifact_if_exists(lines, runtime, "d3d12core.dll")
- if runtime.startswith("linux"):
+ elif runtime.startswith("linux"):
add_native_artifact_if_exists(lines, runtime, "libonnxruntime-genai.so")
- if runtime.startswith("osx"):
+ elif runtime.startswith("osx"):
add_native_artifact_if_exists(lines, runtime, "libonnxruntime-genai.dylib")
+ elif runtime.startswith("ios"):
+ add_native_artifact_if_exists(lines, runtime, "onnxruntime-genai.xcframework.zip")
+ elif runtime.startswith("android"):
+ add_native_artifact_if_exists(lines, runtime, "onnxruntime-genai.aar")
# targets
for dotnet in ["netstandard2.0", "net8.0", "native"]:
- lines.append(f'')
- lines.append(f'')
- # include
+ lines.append(f'')
+ lines.append(f'')
+
+ # mobile targets
+ lines.append(f'')
+ lines.append(f'')
+
+ lines.append(f'')
+ lines.append(f'')
+ lines.append(f'')
+ lines.append(f'')
+
+ # include
lines.append(f'')
lines.append('')