[Objective-C API] Add script to assemble pod package files. (#7958)

Add a helper script for creating the Objective-C API pod package. It puts the necessary files and generates a podspec in a staging directory.
This commit is contained in:
Edward Chen 2021-06-07 19:16:39 -07:00 committed by GitHub
parent fc331cbd5d
commit 0696e2f0d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 212 additions and 10 deletions

View file

@ -42,15 +42,8 @@ set(OBJC_ROOT "${REPO_ROOT}/objectivec")
# onnxruntime_objc target
# these headers are the public interface
# explicitly list them here so it is easy to see what is included
set(onnxruntime_objc_headers
"${OBJC_ROOT}/include/onnxruntime.h"
"${OBJC_ROOT}/include/ort_coreml_execution_provider.h"
"${OBJC_ROOT}/include/ort_enums.h"
"${OBJC_ROOT}/include/ort_env.h"
"${OBJC_ROOT}/include/ort_session.h"
"${OBJC_ROOT}/include/ort_value.h"
)
file(GLOB onnxruntime_objc_headers CONFIGURE_DEPENDS
"${OBJC_ROOT}/include/*.h")
file(GLOB onnxruntime_objc_srcs CONFIGURE_DEPENDS
"${OBJC_ROOT}/src/*.h"

View file

@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
* Gets whether the CoreML execution provider is available.
*/
BOOL ORTIsCoreMLExecutionProviderAvailable();
BOOL ORTIsCoreMLExecutionProviderAvailable(void);
/**
* Options for configuring the CoreML execution provider.

View file

@ -0,0 +1,157 @@
#!/usr/bin/env python3
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import argparse
import os
import pathlib
import re
import shutil
import sys
_script_dir = pathlib.Path(__file__).parent.resolve(strict=True)
_repo_root = _script_dir.parents[4]
# these variables contain paths or path patterns that are relative to the repo root
# the license file
license_file = "LICENSE"
# include directories for compiling the pod itself
include_dirs = [
"objectivec",
"cmake/external/SafeInt",
]
# pod source files
source_files = [
"objectivec/include/*.h",
"objectivec/src/*.h",
"objectivec/src/*.m",
"objectivec/src/*.mm",
"cmake/external/SafeInt/safeint/SafeInt.hpp",
]
# pod public header files
# note: these are a subset of source_files
public_header_files = [
"objectivec/include/*.h",
]
# pod test source files
test_source_files = [
"objectivec/test/*.h",
"objectivec/test/*.m",
"objectivec/test/*.mm",
]
# pod test resource files
test_resource_files = [
"objectivec/test/testdata/*.ort",
]
def parse_args():
parser = argparse.ArgumentParser(description="""
Assembles the files for the Objective-C pod package in a staging directory.
This directory can be validated (e.g., with `pod lib lint`) and then zipped to create a package for release.
""")
parser.add_argument("--staging-dir", type=pathlib.Path,
default=pathlib.Path("./onnxruntime-mobile-objc-staging"),
help="Staging directory for the Objective-C pod files.")
parser.add_argument("--pod-version", required=True,
help="Objective-C pod version.")
parser.add_argument("--pod-source-http", required=True,
help="Objective-C pod source http value (e.g., the package download URL).")
return parser.parse_args()
_template_variable_pattern = re.compile(r"@(\w+)@") # match "@var@"
def gen_file_from_template(template_file: pathlib.Path, output_file: pathlib.Path,
variable_substitutions: dict[str, str]):
'''
Generates a file from a template file.
The template file may contain template variables that will be substituted
with the provided values in the generated output file.
In the template file, template variable names are delimited by "@"'s,
e.g., "@var@".
:param template_file The template file path.
:param output_file The generated output file path.
:variable_substitutions The mapping from template variable name to value.
'''
with open(template_file, mode="r") as template:
content = template.read()
def replace_template_variable(match):
variable_name = match.group(1)
return variable_substitutions.get(variable_name, match.group(0))
content = _template_variable_pattern.sub(replace_template_variable, content)
with open(output_file, mode="w") as output:
output.write(content)
def copy_to_staging_dir(patterns: list[str], staging_dir: pathlib.Path):
'''
Copies files to a staging directory.
The files are relative to the repo root, and the repo root-relative
intermediate directory structure is maintained.
:param patterns The paths or path patterns relative to the repo root.
:param staging_dir The staging directory.
'''
paths = [path for pattern in patterns for path in _repo_root.glob(pattern)]
for path in paths:
repo_relative_path = path.relative_to(_repo_root)
dst_path = staging_dir / repo_relative_path
os.makedirs(dst_path.parent, exist_ok=True)
shutil.copy(path, dst_path)
def main():
args = parse_args()
staging_dir = args.staging_dir.resolve()
print(f"Assembling files in staging directory: {staging_dir}")
if staging_dir.exists():
print("Warning: staging directory already exists", file=sys.stderr)
# copy the necessary files to the staging directory
copy_to_staging_dir(
[license_file] + source_files + test_source_files + test_resource_files,
staging_dir)
# generate the podspec file from the template
def path_patterns_as_variable_value(patterns: list[str]):
return ", ".join([f'"{pattern}"' for pattern in patterns])
variable_substitutions = {
"VERSION": args.pod_version,
"SOURCE_HTTP": args.pod_source_http,
"LICENSE_FILE": path_patterns_as_variable_value([license_file]),
"INCLUDE_DIR_LIST": path_patterns_as_variable_value(include_dirs),
"PUBLIC_HEADER_FILE_LIST": path_patterns_as_variable_value(public_header_files),
"SOURCE_FILE_LIST": path_patterns_as_variable_value(source_files),
"TEST_SOURCE_FILE_LIST": path_patterns_as_variable_value(test_source_files),
"TEST_RESOURCE_FILE_LIST": path_patterns_as_variable_value(test_resource_files),
}
podspec_template = _script_dir / "onnxruntime-mobile-objc.podspec.template"
podspec = staging_dir / "onnxruntime-mobile-objc.podspec"
gen_file_from_template(podspec_template, podspec, variable_substitutions)
return 0
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,52 @@
Pod::Spec.new do |s|
s.name = 'onnxruntime-mobile-objc'
s.version = '@VERSION@'
s.summary = 'ONNX Runtime Objective-C Pod'
s.description = <<-DESC
Preview pod for the ONNX Runtime Objective-C API.
DESC
s.homepage = 'https://github.com/microsoft/onnxruntime'
s.license = { :type => 'MIT', :file => @LICENSE_FILE@ }
s.author = { "ONNX Runtime" => "onnxruntime@microsoft.com" }
s.source = { :http => "@SOURCE_HTTP@" }
s.ios.deployment_target = '11.0'
s.preserve_paths = [ @LICENSE_FILE@ ]
s.default_subspec = "Core"
s.subspec "Core" do |core|
core.dependency "onnxruntime-mobile-c", "#{s.version}"
core.requires_arc = true
core.compiler_flags = "-std=c++17", "-fobjc-arc-exceptions", "-Wall", "-Wextra", "-Werror"
include_dirs = [
@INCLUDE_DIR_LIST@
].map { |relative_include_dir|
'"${PODS_TARGET_SRCROOT}/' + relative_include_dir + '"'
}
core.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => include_dirs.join(" "),
"EXCLUDED_ARCHS[sdk=iphonesimulator*]": "arm64",
}
core.public_header_files = [
@PUBLIC_HEADER_FILE_LIST@
]
core.source_files = [
@SOURCE_FILE_LIST@
]
core.test_spec "Tests" do |test|
test.source_files = [
@TEST_SOURCE_FILE_LIST@
]
test.resources = [
@TEST_RESOURCE_FILE_LIST@
]
end
end
end