Add iOS packaging pipeline. (#327)
This commit is contained in:
Родитель
81e7799c69
Коммит
9baed694a3
|
@ -442,7 +442,6 @@ jobs:
|
|||
|
||||
#############
|
||||
# iOS
|
||||
# Only cmake==3.25.0 works OpenCV compiling now.
|
||||
#############
|
||||
- job: IosPackage
|
||||
pool:
|
||||
|
@ -456,23 +455,27 @@ jobs:
|
|||
architecture: 'x64'
|
||||
displayName: "Use Python 3.9"
|
||||
|
||||
# iOS xcframework build doesn't work with CMake 3.25.1, pin to 3.25.0
|
||||
- script: |
|
||||
python -m pip install cmake==3.25.0
|
||||
displayName: "Install CMake 3.25.0"
|
||||
|
||||
- template: ../.pipelines/templates/set-package-version-variable-step.yml
|
||||
parameters:
|
||||
PackageVersionVariableName: ORT_EXTENSIONS_POD_VERSION
|
||||
|
||||
- script: |
|
||||
python ./tools/ios/build_xcframework.py \
|
||||
--output-dir $(Build.BinariesDirectory)/xcframework_out \
|
||||
--platform-arch iphonesimulator x86_64 \
|
||||
--config Release
|
||||
displayName: Build xcframework
|
||||
displayName: Build xcframework for iphonesimulator x86_64
|
||||
|
||||
- script: |
|
||||
set -e -x
|
||||
POD_VERSION=$(cat ./version.txt)-dev
|
||||
python ./tools/ios/assemble_pod_package.py \
|
||||
--staging-dir $(Build.BinariesDirectory)/pod_staging \
|
||||
--xcframework-dir $(Build.BinariesDirectory)/xcframework_out/onnxruntime_extensions.xcframework \
|
||||
--public-headers-dir $(Build.BinariesDirectory)/xcframework_out/Headers \
|
||||
--framework-info-file $(Build.BinariesDirectory)/xcframework_out/framework_info.json \
|
||||
--pod-version ${POD_VERSION}
|
||||
--xcframework-output-dir $(Build.BinariesDirectory)/xcframework_out \
|
||||
--pod-version ${ORT_EXTENSIONS_POD_VERSION}
|
||||
displayName: Assemble pod
|
||||
|
||||
- script: |
|
||||
|
@ -481,7 +484,10 @@ jobs:
|
|||
displayName: Install pods for OrtExtensionsUsage
|
||||
workingDirectory: $(Build.SourcesDirectory)/test/ios/OrtExtensionsUsage
|
||||
|
||||
- template: templates/xcode-build-and-test-step.yml
|
||||
- template: ../.pipelines/templates/with-ios-simulator-steps.yml
|
||||
parameters:
|
||||
steps:
|
||||
- template: ../.pipelines/templates/xcode-build-and-test-step.yml
|
||||
parameters:
|
||||
xcWorkspacePath: '$(Build.SourcesDirectory)/test/ios/OrtExtensionsUsage/OrtExtensionsUsage.xcworkspace'
|
||||
scheme: 'OrtExtensionsUsage'
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
# packaging pipeline for iOS CocoaPods package
|
||||
|
||||
parameters:
|
||||
- name: IsReleaseBuild
|
||||
displayName: "Is this is a release build?"
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
- job: IosPackaging
|
||||
displayName: "iOS Packaging"
|
||||
|
||||
pool:
|
||||
vmImage: "macOS-12"
|
||||
|
||||
timeoutInMinutes: 120
|
||||
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "3.9"
|
||||
addToPath: true
|
||||
architecture: "x64"
|
||||
|
||||
# iOS xcframework build doesn't work with CMake 3.25.1, pin to 3.25.0
|
||||
- script: |
|
||||
python -m pip install cmake==3.25.0
|
||||
displayName: "Install CMake 3.25.0"
|
||||
|
||||
- template: templates/set-package-version-variable-step.yml
|
||||
parameters:
|
||||
IsReleaseBuild: ${{ parameters.IsReleaseBuild }}
|
||||
PackageVersionVariableName: ORT_EXTENSIONS_POD_VERSION
|
||||
|
||||
- script: |
|
||||
python ./tools/gen_selectedops.py ./tools/ios/package_ops.config
|
||||
displayName: "Generate selected ops CMake file"
|
||||
|
||||
- script: |
|
||||
python ./tools/ios/build_xcframework.py \
|
||||
--output-dir $(Build.BinariesDirectory)/xcframework_out \
|
||||
--config Release \
|
||||
--cmake-extra-defines OCOS_ENABLE_SELECTED_OPLIST=ON
|
||||
displayName: "Build xcframework"
|
||||
|
||||
- script: |
|
||||
python ./tools/ios/assemble_pod_package.py \
|
||||
--staging-dir $(Build.BinariesDirectory)/pod_staging \
|
||||
--xcframework-output-dir $(Build.BinariesDirectory)/xcframework_out \
|
||||
--pod-version ${ORT_EXTENSIONS_POD_VERSION}
|
||||
displayName: "Assemble pod"
|
||||
|
||||
- script: |
|
||||
pod lib lint
|
||||
displayName: "Lint pod"
|
||||
workingDirectory: $(Build.BinariesDirectory)/pod_staging
|
||||
|
||||
- script: |
|
||||
ORT_EXTENSIONS_LOCAL_POD_PATH=$(Build.BinariesDirectory)/pod_staging \
|
||||
pod install
|
||||
displayName: "Install pods for OrtExtensionsUsage"
|
||||
workingDirectory: $(Build.SourcesDirectory)/test/ios/OrtExtensionsUsage
|
||||
|
||||
- template: templates/with-ios-simulator-steps.yml
|
||||
parameters:
|
||||
steps:
|
||||
- template: templates/xcode-build-and-test-step.yml
|
||||
parameters:
|
||||
xcWorkspacePath: '$(Build.SourcesDirectory)/test/ios/OrtExtensionsUsage/OrtExtensionsUsage.xcworkspace'
|
||||
scheme: 'OrtExtensionsUsage'
|
||||
|
||||
- task: InstallAppleCertificate@2
|
||||
inputs:
|
||||
certSecureFile: '$(ios_signing_certificate_name)'
|
||||
certPwd: '$(ios_signing_certificate_password)'
|
||||
keychain: 'temp'
|
||||
displayName: "Install ORT Mobile Test Signing Certificate"
|
||||
|
||||
- task: InstallAppleProvisioningProfile@1
|
||||
inputs:
|
||||
provProfileSecureFile: '$(ios_provision_profile_name)'
|
||||
removeProfile: true
|
||||
displayName: "Install ORT Mobile Test Provisioning Profile"
|
||||
|
||||
- task: Xcode@5
|
||||
inputs:
|
||||
actions: 'build-for-testing'
|
||||
configuration: 'Debug'
|
||||
xcWorkspacePath: '$(Build.SourcesDirectory)/test/ios/OrtExtensionsUsage/OrtExtensionsUsage.xcworkspace'
|
||||
sdk: 'iphoneos'
|
||||
scheme: 'OrtExtensionsUsage'
|
||||
signingOption: 'manual'
|
||||
signingIdentity: '$(APPLE_CERTIFICATE_SIGNING_IDENTITY)'
|
||||
provisioningProfileName: 'iOS Team Provisioning Profile'
|
||||
args: '-derivedDataPath $(Build.BinariesDirectory)/appcenter_test_derived_data'
|
||||
displayName: "Build appcenter test"
|
||||
|
||||
- script: |
|
||||
appcenter test run xcuitest \
|
||||
--app "AI-Frameworks/ORT-Ext-Mobile-iOS-Testapp" \
|
||||
--devices "AI-Frameworks/apple-test-device-set" \
|
||||
--test-series "master" \
|
||||
--locale "en_US" \
|
||||
--build-dir $(Build.BinariesDirectory)/appcenter_test_derived_data/Build/Products/Debug-iphoneos \
|
||||
--token $(app_center_api_token)
|
||||
displayName: "Run appcenter test"
|
||||
|
||||
- script: |
|
||||
set -e -x
|
||||
|
||||
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"
|
||||
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}
|
||||
cp ${PODSPEC_BASENAME} ${ARTIFACTS_STAGING_DIR}/${PODSPEC_BASENAME}
|
||||
|
||||
popd
|
||||
displayName: "Assemble artifacts"
|
||||
|
||||
- publish: "$(Build.ArtifactStagingDirectory)"
|
||||
artifact: ios_packaging_artifacts
|
||||
displayName: "Publish artifacts"
|
|
@ -0,0 +1,28 @@
|
|||
parameters:
|
||||
- name: IsReleaseBuild
|
||||
displayName: |
|
||||
If true, the version is a release version. Otherwise, the version has a development suffix.
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: PackageVersionVariableName
|
||||
displayName: |
|
||||
The name of the variable that will contain the version value.
|
||||
type: string
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
set -e -x
|
||||
|
||||
VERSION_FILE="$(Build.SourcesDirectory)/version.txt"
|
||||
BASE_VERSION="$(cat "${VERSION_FILE}")"
|
||||
|
||||
if [[ "${{ parameters.IsReleaseBuild }}" == "true" ]]; then
|
||||
VERSION="${BASE_VERSION}"
|
||||
else
|
||||
SHORT_COMMIT_HASH="$(git rev-parse --short HEAD)"
|
||||
VERSION="${BASE_VERSION}-dev+$(Build.BuildId).${SHORT_COMMIT_HASH}"
|
||||
fi
|
||||
|
||||
echo "##vso[task.setvariable variable=${{ parameters.PackageVersionVariableName }}]${VERSION}"
|
||||
displayName: "Set \"${{ parameters.PackageVersionVariableName }}\" variable to package version"
|
|
@ -0,0 +1,23 @@
|
|||
parameters:
|
||||
- name: steps
|
||||
type: stepList
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
set -e -x
|
||||
|
||||
ORT_EXTENSIONS_BUILD_SIMULATOR_ID=$(xcrun simctl create iPhoneSimulatorForPipeline com.apple.CoreSimulator.SimDeviceType.iPhone-8)
|
||||
|
||||
echo "##vso[task.setvariable variable=ORT_EXTENSIONS_BUILD_SIMULATOR_ID]${ORT_EXTENSIONS_BUILD_SIMULATOR_ID}"
|
||||
displayName: "Create iPhone simulator"
|
||||
|
||||
- ${{ parameters.steps }}
|
||||
|
||||
- bash: |
|
||||
set -e -x
|
||||
|
||||
if [[ -n "${ORT_EXTENSIONS_BUILD_SIMULATOR_ID-}" ]]; then
|
||||
xcrun simctl delete ${ORT_EXTENSIONS_BUILD_SIMULATOR_ID}
|
||||
fi
|
||||
displayName: "Delete iPhone simulator"
|
||||
condition: always()
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
# builds an iOS xcframework
|
||||
# see tools/ios/build_xcframework.py for details
|
||||
|
||||
# Get directory this script is in
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
python ${DIR}/tools/ios/build_xcframework.py "$@"
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2E95FB6B2948166D00AA2CA7 /* OrtExtensionsUsageUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E95FB6A2948166D00AA2CA7 /* OrtExtensionsUsageUITests.swift */; };
|
||||
2ECE95DE293A742700039409 /* OrtExtensionsUsageApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ECE95DD293A742700039409 /* OrtExtensionsUsageApp.swift */; };
|
||||
2ECE95E0293A742700039409 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ECE95DF293A742700039409 /* ContentView.swift */; };
|
||||
2ECE95E2293A742800039409 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2ECE95E1293A742800039409 /* Assets.xcassets */; };
|
||||
|
@ -18,6 +19,13 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
2E95FB6E2948166D00AA2CA7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2ECE95D2293A742700039409 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2ECE95D9293A742700039409;
|
||||
remoteInfo = OrtExtensionsUsage;
|
||||
};
|
||||
2ECE95EB293A742800039409 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2ECE95D2293A742700039409 /* Project object */;
|
||||
|
@ -28,6 +36,8 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2E95FB682948166D00AA2CA7 /* OrtExtensionsUsageUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OrtExtensionsUsageUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2E95FB6A2948166D00AA2CA7 /* OrtExtensionsUsageUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrtExtensionsUsageUITests.swift; sourceTree = "<group>"; };
|
||||
2ECE95DA293A742700039409 /* OrtExtensionsUsage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OrtExtensionsUsage.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2ECE95DD293A742700039409 /* OrtExtensionsUsageApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrtExtensionsUsageApp.swift; sourceTree = "<group>"; };
|
||||
2ECE95DF293A742700039409 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
|
@ -43,6 +53,13 @@
|
|||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
2E95FB652948166D00AA2CA7 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2ECE95D7293A742700039409 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -60,11 +77,20 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2E95FB692948166D00AA2CA7 /* OrtExtensionsUsageUITests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2E95FB6A2948166D00AA2CA7 /* OrtExtensionsUsageUITests.swift */,
|
||||
);
|
||||
path = OrtExtensionsUsageUITests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2ECE95D1293A742700039409 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2ECE95DC293A742700039409 /* OrtExtensionsUsage */,
|
||||
2ECE95ED293A742800039409 /* OrtExtensionsUsageTests */,
|
||||
2E95FB692948166D00AA2CA7 /* OrtExtensionsUsageUITests */,
|
||||
2ECE95DB293A742700039409 /* Products */,
|
||||
614CBC9BE6DEBAEABF4B9145 /* Pods */,
|
||||
);
|
||||
|
@ -75,6 +101,7 @@
|
|||
children = (
|
||||
2ECE95DA293A742700039409 /* OrtExtensionsUsage.app */,
|
||||
2ECE95EA293A742800039409 /* OrtExtensionsUsageTests.xctest */,
|
||||
2E95FB682948166D00AA2CA7 /* OrtExtensionsUsageUITests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -121,6 +148,24 @@
|
|||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
2E95FB672948166D00AA2CA7 /* OrtExtensionsUsageUITests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2E95FB722948166D00AA2CA7 /* Build configuration list for PBXNativeTarget "OrtExtensionsUsageUITests" */;
|
||||
buildPhases = (
|
||||
2E95FB642948166D00AA2CA7 /* Sources */,
|
||||
2E95FB652948166D00AA2CA7 /* Frameworks */,
|
||||
2E95FB662948166D00AA2CA7 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
2E95FB6F2948166D00AA2CA7 /* PBXTargetDependency */,
|
||||
);
|
||||
name = OrtExtensionsUsageUITests;
|
||||
productName = OrtExtensionsUsageUITests;
|
||||
productReference = 2E95FB682948166D00AA2CA7 /* OrtExtensionsUsageUITests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.ui-testing";
|
||||
};
|
||||
2ECE95D9293A742700039409 /* OrtExtensionsUsage */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2ECE95FE293A742900039409 /* Build configuration list for PBXNativeTarget "OrtExtensionsUsage" */;
|
||||
|
@ -166,6 +211,10 @@
|
|||
LastSwiftUpdateCheck = 1410;
|
||||
LastUpgradeCheck = 1410;
|
||||
TargetAttributes = {
|
||||
2E95FB672948166D00AA2CA7 = {
|
||||
CreatedOnToolsVersion = 14.1;
|
||||
TestTargetID = 2ECE95D9293A742700039409;
|
||||
};
|
||||
2ECE95D9293A742700039409 = {
|
||||
CreatedOnToolsVersion = 14.1;
|
||||
LastSwiftMigration = 1410;
|
||||
|
@ -191,11 +240,19 @@
|
|||
targets = (
|
||||
2ECE95D9293A742700039409 /* OrtExtensionsUsage */,
|
||||
2ECE95E9293A742800039409 /* OrtExtensionsUsageTests */,
|
||||
2E95FB672948166D00AA2CA7 /* OrtExtensionsUsageUITests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
2E95FB662948166D00AA2CA7 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2ECE95D8293A742700039409 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -217,6 +274,14 @@
|
|||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
2E95FB642948166D00AA2CA7 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2E95FB6B2948166D00AA2CA7 /* OrtExtensionsUsageUITests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2ECE95D6293A742700039409 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -238,6 +303,11 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
2E95FB6F2948166D00AA2CA7 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2ECE95D9293A742700039409 /* OrtExtensionsUsage */;
|
||||
targetProxy = 2E95FB6E2948166D00AA2CA7 /* PBXContainerItemProxy */;
|
||||
};
|
||||
2ECE95EC293A742800039409 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2ECE95D9293A742700039409 /* OrtExtensionsUsage */;
|
||||
|
@ -246,6 +316,48 @@
|
|||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
2E95FB702948166D00AA2CA7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.onnxruntime-extensions.OrtExtensionsUsageUITests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = OrtExtensionsUsage;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2E95FB712948166D00AA2CA7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.onnxruntime-extensions.OrtExtensionsUsageUITests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = OrtExtensionsUsage;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2ECE95FC293A742900039409 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -370,7 +482,6 @@
|
|||
COMPRESS_PNG_FILES = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"OrtExtensionsUsage/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = UBF8T346G9;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
|
@ -405,7 +516,6 @@
|
|||
COMPRESS_PNG_FILES = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"OrtExtensionsUsage/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = UBF8T346G9;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
|
@ -436,7 +546,6 @@
|
|||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = UBF8T346G9;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
|
||||
MARKETING_VERSION = 1.0;
|
||||
|
@ -456,7 +565,6 @@
|
|||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = UBF8T346G9;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
|
||||
MARKETING_VERSION = 1.0;
|
||||
|
@ -472,6 +580,15 @@
|
|||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2E95FB722948166D00AA2CA7 /* Build configuration list for PBXNativeTarget "OrtExtensionsUsageUITests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2E95FB702948166D00AA2CA7 /* Debug */,
|
||||
2E95FB712948166D00AA2CA7 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
2ECE95D5293A742700039409 /* Build configuration list for PBXProject "OrtExtensionsUsage" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
|
@ -19,6 +19,7 @@ struct ContentView: View {
|
|||
.imageScale(.large)
|
||||
.foregroundColor(.accentColor)
|
||||
Text("Decode image result: \(runOrtDecodeAndCheckImage())")
|
||||
.accessibilityIdentifier("decodeImageResult")
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import XCTest
|
||||
|
||||
final class OrtExtensionsUsageUITests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
|
||||
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||
continueAfterFailure = false
|
||||
|
||||
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testDecodeImageResultOk() throws {
|
||||
// UI tests must launch the application that they test.
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
let element = app.staticTexts.element(matching: XCUIElement.ElementType.staticText, identifier: "decodeImageResult")
|
||||
XCTAssertEqual(element.label, "Decode image result: Ok")
|
||||
}
|
||||
|
||||
}
|
|
@ -21,3 +21,11 @@ target 'OrtExtensionsUsage' do
|
|||
# Pods for testing
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,81 +1,136 @@
|
|||
import os
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
OPMAP_TO_CMAKE_FLAGS = {
|
||||
'BlingFireSentenceBreaker': 'OCOS_ENABLE_BLINGFIRE',
|
||||
'GPT2Tokenizer': 'OCOS_ENABLE_GPT2_TOKENIZER',
|
||||
'WordpieceTokenizer': 'OCOS_ENABLE_WORDPIECE_TOKENIZER',
|
||||
'StringConcat': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringECMARegexReplace': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringECMARegexSplitWithOffsets': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringEqual': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringToHashBucket': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringToHashBucketFast': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringJoin': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringLength': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringLower': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringRegexReplace': 'OCOS_ENABLE_RE2_REGEX',
|
||||
'StringRegexSplitWithOffsets': 'OCOS_ENABLE_RE2_REGEX',
|
||||
'StringSplit': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringToVector': 'OCOS_ENABLE_TF_STRING',
|
||||
'StringUpper': 'OCOS_ENABLE_TF_STRING',
|
||||
'SegmentExtraction': 'OCOS_ENABLE_MATH',
|
||||
'StringMapping': 'OCOS_ENABLE_TF_STRING',
|
||||
'VectorToString': 'OCOS_ENABLE_TF_STRING',
|
||||
'MaskedFill': 'OCOS_ENABLE_TF_STRING',
|
||||
'BertTokenizer': 'OCOS_ENABLE_BERT_TOKENIZER',
|
||||
'BasicTokenizer': 'OCOS_ENABLE_BERT_TOKENIZER',
|
||||
'BertTokenizerDecoder': 'OCOS_ENABLE_BERT_TOKENIZER',
|
||||
'SentencepieceTokenizer': 'OCOS_ENABLE_SPM_TOKENIZER',
|
||||
'ImageDecode': 'OCOS_ENABLE_VISION',
|
||||
'ImageEncode': 'OCOS_ENABLE_VISION',
|
||||
'GaussianBlur': 'OCOS_ENABLE_CV2'
|
||||
CMAKE_FLAG_TO_OPS = {
|
||||
"OCOS_ENABLE_BERT_TOKENIZER": [
|
||||
"BasicTokenizer",
|
||||
"BertTokenizer",
|
||||
"BertTokenizerDecoder",
|
||||
],
|
||||
"OCOS_ENABLE_BLINGFIRE": [
|
||||
"BlingFireSentenceBreaker",
|
||||
],
|
||||
"OCOS_ENABLE_CV2": [
|
||||
"GaussianBlur",
|
||||
],
|
||||
"OCOS_ENABLE_GPT2_TOKENIZER": [
|
||||
"GPT2Tokenizer",
|
||||
],
|
||||
"OCOS_ENABLE_MATH": [
|
||||
"SegmentExtraction",
|
||||
],
|
||||
"OCOS_ENABLE_RE2_REGEX": [
|
||||
"StringRegexReplace",
|
||||
"StringRegexSplitWithOffsets",
|
||||
],
|
||||
"OCOS_ENABLE_SPM_TOKENIZER": [
|
||||
"SentencepieceTokenizer",
|
||||
],
|
||||
"OCOS_ENABLE_TF_STRING": [
|
||||
"MaskedFill",
|
||||
"StringConcat",
|
||||
"StringECMARegexReplace",
|
||||
"StringECMARegexSplitWithOffsets",
|
||||
"StringEqual",
|
||||
"StringJoin",
|
||||
"StringLength",
|
||||
"StringLower",
|
||||
"StringMapping",
|
||||
"StringSplit",
|
||||
"StringToHashBucket",
|
||||
"StringToHashBucketFast",
|
||||
"StringToVector",
|
||||
"StringUpper",
|
||||
"VectorToString",
|
||||
],
|
||||
"OCOS_ENABLE_VISION": [
|
||||
"DecodeImage",
|
||||
"EncodeImage",
|
||||
],
|
||||
"OCOS_ENABLE_WORDPIECE_TOKENIZER": [
|
||||
"WordpieceTokenizer",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def gen_cmake_oplist(opconfig_file, oplist_cmake_file='_selectedoplist.cmake'):
|
||||
def _gen_op_to_cmake_flag():
|
||||
op_to_cmake_flag = dict()
|
||||
for cmake_flag, op_list in CMAKE_FLAG_TO_OPS.items():
|
||||
for op in op_list:
|
||||
assert op not in op_to_cmake_flag, f"Duplicate op in CMAKE_FLAG_TO_OPS: {op}"
|
||||
op_to_cmake_flag[op] = cmake_flag
|
||||
return op_to_cmake_flag
|
||||
|
||||
|
||||
OP_TO_CMAKE_FLAG = _gen_op_to_cmake_flag()
|
||||
|
||||
SCRIPT_DIR = pathlib.Path(__file__).parent.resolve()
|
||||
GENERATED_CMAKE_CONFIG_FILE = SCRIPT_DIR.parent / "cmake" / "_selectedoplist.cmake"
|
||||
|
||||
|
||||
def gen_cmake_oplist(opconfig_file):
|
||||
print(
|
||||
"[onnxruntime-extensions] Generating CMake config file '{}' from op config file '{}'".format(
|
||||
GENERATED_CMAKE_CONFIG_FILE, args.selected_op_config_file
|
||||
)
|
||||
)
|
||||
|
||||
ext_domain = "ai.onnx.contrib" # default_opset_domain()
|
||||
new_ext_domain = "com.microsoft.extensions"
|
||||
ext_domain_cnt = 0
|
||||
cmake_options = set()
|
||||
with open(oplist_cmake_file, 'w') as f:
|
||||
with open(GENERATED_CMAKE_CONFIG_FILE, "w") as f:
|
||||
print("# Auto-Generated File, please do not edit!!!", file=f)
|
||||
with open(opconfig_file, 'r') as opfile:
|
||||
with open(opconfig_file, "r") as opfile:
|
||||
for _ln in opfile:
|
||||
if _ln.startswith(ext_domain) or _ln.startswith(new_ext_domain):
|
||||
ext_domain_cnt += 1
|
||||
items = _ln.strip().split(';')
|
||||
items = _ln.strip().split(";")
|
||||
if len(items) < 3:
|
||||
raise RuntimeError("The malformed operator config file.")
|
||||
for _op in items[2].split(','):
|
||||
for _op in items[2].split(","):
|
||||
if not _op:
|
||||
continue # is None or ""
|
||||
if _op not in OPMAP_TO_CMAKE_FLAGS:
|
||||
raise RuntimeError("Cannot find the custom operator({})\'s build flags, please update "
|
||||
"the OPMAP_TO_CMAKE_FLAGS dictionary.".format(_op))
|
||||
if OPMAP_TO_CMAKE_FLAGS[_op] not in cmake_options:
|
||||
cmake_options.add(OPMAP_TO_CMAKE_FLAGS[_op])
|
||||
print("set({} ON CACHE INTERNAL \"\")".format(OPMAP_TO_CMAKE_FLAGS[_op]), file=f)
|
||||
if _op not in OP_TO_CMAKE_FLAG:
|
||||
raise RuntimeError(
|
||||
"Cannot find the custom operator({})'s build flags, please update "
|
||||
"the CMAKE_FLAG_TO_OPS dictionary.".format(_op)
|
||||
)
|
||||
if OP_TO_CMAKE_FLAG[_op] not in cmake_options:
|
||||
cmake_options.add(OP_TO_CMAKE_FLAG[_op])
|
||||
print('set({} ON CACHE INTERNAL "")'.format(OP_TO_CMAKE_FLAG[_op]), file=f)
|
||||
print("# End of Building the Operator CMake variables", file=f)
|
||||
|
||||
if ext_domain_cnt == 0:
|
||||
print('[onnxruntime-extensions] warning: lines starting with extension domains of ai.onnx.contrib or '
|
||||
'com.microsoft.extensions in operators config file is 0')
|
||||
print(
|
||||
"[onnxruntime-extensions] warning: lines starting with extension domains of ai.onnx.contrib or "
|
||||
"com.microsoft.extensions in operators config file is 0",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
print('[onnxruntime-extensions] The cmake tool file has been generated successfully.')
|
||||
print("[onnxruntime-extensions] The cmake tool file has been generated successfully.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# command: python gen_selectedops.py <path-to-operators-config-file>
|
||||
# will generate the _selectedoplist.cmake file in ${PROJECT_SOURCE_DIR}/cmake/ folder
|
||||
print('[onnxruntime-extensions] gen_selectedops.py arguments: ', sys.argv)
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate the cmake/_selectedoplist.cmake file from the selected op config file.",
|
||||
)
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
print('[onnxruntime-extensions] Generating _selectedoplist.cmake file to folder: ${PROJECT_SOURCE_DIR}/cmake/')
|
||||
current_dir = os.path.dirname(__file__)
|
||||
target_cmake_path = os.path.abspath(os.path.join(current_dir, '../cmake/_selectedoplist.cmake'))
|
||||
print('[onnxruntime-extensions] Target cmake file path: ', target_cmake_path)
|
||||
parser.add_argument(
|
||||
"selected_op_config_file",
|
||||
type=pathlib.Path,
|
||||
help="Path to selected op config file.",
|
||||
)
|
||||
|
||||
gen_cmake_oplist(sys.argv[1], target_cmake_path)
|
||||
else:
|
||||
print('[onnxruntime-extensions] gen_selectedops.py arguments error!')
|
||||
args = parser.parse_args()
|
||||
args.selected_op_config_file = args.selected_op_config_file.resolve(strict=True)
|
||||
|
||||
return args
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
gen_cmake_oplist(args.selected_op_config_file)
|
||||
|
|
|
@ -113,32 +113,53 @@ def parse_args():
|
|||
required=True,
|
||||
help="Path to the pod output staging directory.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--xcframework-dir",
|
||||
type=Path,
|
||||
required=True,
|
||||
help="Path to the onnxruntime_extensions xcframework to include in the pod.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--public-headers-dir",
|
||||
type=Path,
|
||||
required=True,
|
||||
help="Path to the public header directory to include in the pod.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--framework-info-file",
|
||||
type=Path,
|
||||
required=True,
|
||||
help="Path to the framework_info.json file containing additional values for the podspec. "
|
||||
"This file should be generated by CMake in the build directory.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--pod-version",
|
||||
required=True,
|
||||
help="The pod's version.",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
input_paths_group = parser.add_argument_group(description="Input path arguments.")
|
||||
|
||||
input_paths_group.add_argument(
|
||||
"--xcframework-output-dir",
|
||||
type=Path,
|
||||
help=f"Path to the output directory produced by {_script_dir / 'build_xcframework.py'}. "
|
||||
"Specify either this argument or the other input path arguments.",
|
||||
)
|
||||
input_paths_group.add_argument(
|
||||
"--xcframework-dir",
|
||||
type=Path,
|
||||
help="Path to the onnxruntime_extensions xcframework to include in the pod.",
|
||||
)
|
||||
input_paths_group.add_argument(
|
||||
"--public-headers-dir",
|
||||
type=Path,
|
||||
help="Path to the public header directory to include in the pod.",
|
||||
)
|
||||
input_paths_group.add_argument(
|
||||
"--framework-info-file",
|
||||
type=Path,
|
||||
help="Path to the framework_info.json file containing additional values for the podspec. "
|
||||
"This file should be generated by CMake in the build directory.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert bool(args.xcframework_output_dir is not None) ^ bool(
|
||||
args.xcframework_dir is not None
|
||||
and args.public_headers_dir is not None
|
||||
and args.framework_info_file is not None
|
||||
), "Specify either --xcframework-output-dir OR all of --xcframework-dir, --public-headers-dir, and "
|
||||
"--framework-info-file."
|
||||
|
||||
if args.xcframework_output_dir is not None:
|
||||
args.xcframework_dir = args.xcframework_output_dir / "onnxruntime_extensions.xcframework"
|
||||
args.public_headers_dir = args.xcframework_output_dir / "Headers"
|
||||
args.framework_info_file = args.xcframework_output_dir / "framework_info.json"
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -35,7 +35,7 @@ def _get_opencv_toolchain_file(platform: str, opencv_dir: Path):
|
|||
def _run(cmd_args: List[str], **kwargs):
|
||||
import shlex
|
||||
|
||||
print(f"Running command:\n {shlex.join(cmd_args)}")
|
||||
print(f"Running command:\n {shlex.join(cmd_args)}", flush=True)
|
||||
subprocess.run(cmd_args, check=True, **kwargs)
|
||||
|
||||
|
||||
|
@ -47,16 +47,26 @@ def _rmtree_if_existing(dir: Path):
|
|||
|
||||
|
||||
def build_framework_for_platform_and_arch(
|
||||
build_dir: Path, platform: str, arch: str, config: str, opencv_dir: Path, ios_deployment_target: str
|
||||
build_dir: Path,
|
||||
platform: str,
|
||||
arch: str,
|
||||
config: str,
|
||||
opencv_dir: Path,
|
||||
ios_deployment_target: str,
|
||||
cmake_extra_defines: List[str],
|
||||
) -> Path:
|
||||
build_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# generate build files
|
||||
generate_args = [
|
||||
generate_args = (
|
||||
[
|
||||
_cmake,
|
||||
"-G=Xcode",
|
||||
f"-S={_repo_dir}",
|
||||
f"-B={build_dir}",
|
||||
]
|
||||
+ [f"-D{cmake_extra_define}" for cmake_extra_define in cmake_extra_defines]
|
||||
+ [
|
||||
"-DCMAKE_SYSTEM_NAME=iOS",
|
||||
f"-DCMAKE_OSX_DEPLOYMENT_TARGET={ios_deployment_target}",
|
||||
f"-DCMAKE_OSX_SYSROOT={platform}",
|
||||
|
@ -72,6 +82,7 @@ def build_framework_for_platform_and_arch(
|
|||
# https://github.com/opencv/opencv/blob/4223495e6cd67011f86b8ecd9be1fa105018f3b1/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake#L96-L101
|
||||
f"-DIPHONEOS_DEPLOYMENT_TARGET={ios_deployment_target}",
|
||||
]
|
||||
)
|
||||
_run(generate_args)
|
||||
|
||||
# build
|
||||
|
@ -86,6 +97,7 @@ def build_xcframework(
|
|||
config: str,
|
||||
opencv_dir: Path,
|
||||
ios_deployment_target: str,
|
||||
cmake_extra_defines: List[str],
|
||||
):
|
||||
output_dir = output_dir.resolve()
|
||||
intermediate_build_dir = output_dir / "intermediates"
|
||||
|
@ -110,6 +122,7 @@ def build_xcframework(
|
|||
config,
|
||||
opencv_dir,
|
||||
ios_deployment_target,
|
||||
cmake_extra_defines,
|
||||
)
|
||||
|
||||
arch_framework_dirs.append(arch_framework_dir)
|
||||
|
@ -186,6 +199,14 @@ def parse_args():
|
|||
help="Specify a platform/arch pair to build. Repeat to specify multiple pairs. "
|
||||
"If no pairs are specified, all supported pairs will be built.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cmake-extra-defines",
|
||||
action="append",
|
||||
nargs="+",
|
||||
default=[],
|
||||
help="Extra definition(s) to pass to CMake (with the CMake -D option) during build system generation. "
|
||||
"E.g., `--cmake-extra-defines OPTION1=ON OPTION2=OFF --cmake-extra-defines OPTION3=ON`.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
@ -212,6 +233,9 @@ def parse_args():
|
|||
|
||||
args.platform_archs = platform_archs_from_args(args.platform_archs)
|
||||
|
||||
# convert from List[List[str]] to List[str]
|
||||
args.cmake_extra_defines = [element for inner_list in args.cmake_extra_defines for element in inner_list]
|
||||
|
||||
return args
|
||||
|
||||
|
||||
|
@ -224,6 +248,7 @@ def main():
|
|||
config=args.config,
|
||||
opencv_dir=_repo_dir / "cmake/externals/opencv",
|
||||
ios_deployment_target=args.ios_deployment_target,
|
||||
cmake_extra_defines=args.cmake_extra_defines,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
com.microsoft.extensions;1;DecodeImage,EncodeImage
|
Загрузка…
Ссылка в новой задаче