Updates to apple packaging (#21611)
### Description <!-- Describe your changes. --> Add ability to test packaging without rebuilding every time. Add ability to comment out some platforms/architectures without the scripts to assemble the c/obj-c packages breaking. Update a couple of commands to preserve symlinks. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Make debugging packaging issues faster. Creates correct package for mac-catalyst and doesn't require setting symlinks via bash script.
This commit is contained in:
Родитель
134f47743e
Коммит
bcc01ac123
|
@ -23,29 +23,6 @@ ORT_POD_VERSION=${4:?${USAGE_TEXT}}
|
|||
POD_ARCHIVE_BASENAME="pod-archive-${POD_NAME}-${ORT_POD_VERSION}.zip"
|
||||
PODSPEC_BASENAME="${POD_NAME}.podspec"
|
||||
|
||||
|
||||
# Macos requires a different structure for the framework
|
||||
# This will create the necessary symlinks for the macos framework before packaging
|
||||
# Adding the symlinks here rather than in the build script ensures that symlinks are not lost
|
||||
for MACOS_DIR in "${BINARIES_STAGING_DIR}/${POD_NAME}/onnxruntime.xcframework/macos"*; do
|
||||
if [ -d "${MACOS_DIR}" ]; then
|
||||
echo "Creating symlinks for ${MACOS_DIR}"
|
||||
pushd "${MACOS_DIR}/onnxruntime.framework"
|
||||
|
||||
rm -rf Headers Resources onnxruntime
|
||||
rm -rf Versions/Current
|
||||
|
||||
ln -sfn A Versions/Current
|
||||
ln -sfn Versions/Current/Headers Headers
|
||||
ln -sfn Versions/Current/Resources Resources
|
||||
ln -sfn Versions/Current/onnxruntime onnxruntime
|
||||
|
||||
popd
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo "Contents of ${BINARIES_STAGING_DIR}/${POD_NAME}:"
|
||||
ls -lR "${BINARIES_STAGING_DIR}/${POD_NAME}"
|
||||
|
||||
|
|
|
@ -57,6 +57,11 @@ def parse_args():
|
|||
)
|
||||
|
||||
parser.add_argument("--test", action="store_true", help="Run tests on the framework and pod package files.")
|
||||
parser.add_argument(
|
||||
"--skip-build",
|
||||
action="store_true",
|
||||
help="Use build from previous run. Useful to debug test issues or packaging changes.",
|
||||
)
|
||||
|
||||
build_framework_group = parser.add_argument_group(
|
||||
title="iOS framework build arguments",
|
||||
|
@ -114,7 +119,8 @@ def main():
|
|||
|
||||
build_apple_framework_args += ["--build_dir", str(build_dir), args.build_settings_file]
|
||||
|
||||
run(build_apple_framework_args)
|
||||
if not args.skip_build:
|
||||
run(build_apple_framework_args)
|
||||
|
||||
if args.test:
|
||||
test_apple_packages_args = [
|
||||
|
@ -171,7 +177,8 @@ def main():
|
|||
def move_dir(src, dst):
|
||||
if dst.is_dir():
|
||||
shutil.rmtree(dst)
|
||||
shutil.move(src, dst)
|
||||
shutil.copytree(src, dst, symlinks=True)
|
||||
shutil.rmtree(src)
|
||||
|
||||
move_dir(c_pod_staging_dir, staging_dir / c_pod_name)
|
||||
move_dir(objc_pod_staging_dir, staging_dir / objc_pod_name)
|
||||
|
|
|
@ -200,7 +200,7 @@ def _build_package(args):
|
|||
xcframework_dir = os.path.join(build_dir, "framework_out")
|
||||
pathlib.Path(xcframework_dir).mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy(os.path.join(REPO_DIR, "LICENSE"), xcframework_dir)
|
||||
shutil.copytree(public_headers_path, os.path.join(xcframework_dir, "Headers"), dirs_exist_ok=True)
|
||||
shutil.copytree(public_headers_path, os.path.join(xcframework_dir, "Headers"), dirs_exist_ok=True, symlinks=True)
|
||||
_merge_framework_info_files(framework_info_files_to_merge, os.path.join(build_dir, "xcframework_info.json"))
|
||||
|
||||
# remove existing xcframework if any
|
||||
|
|
|
@ -16,6 +16,7 @@ from package_assembly_utils import ( # noqa: E402
|
|||
PackageVariant,
|
||||
copy_repo_relative_to_dir,
|
||||
gen_file_from_template,
|
||||
get_podspec_values,
|
||||
load_json_config,
|
||||
)
|
||||
|
||||
|
@ -66,23 +67,25 @@ def assemble_c_pod_package(
|
|||
print("Warning: staging directory already exists", file=sys.stderr)
|
||||
|
||||
# copy the necessary files to the staging directory
|
||||
shutil.copytree(framework_dir, staging_dir / framework_dir.name, dirs_exist_ok=True)
|
||||
shutil.copytree(public_headers_dir, staging_dir / public_headers_dir.name, dirs_exist_ok=True)
|
||||
shutil.copytree(framework_dir, staging_dir / framework_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)
|
||||
copy_repo_relative_to_dir(["LICENSE"], staging_dir)
|
||||
|
||||
(ios_deployment_target, macos_deployment_target, weak_framework) = get_podspec_values(framework_info)
|
||||
|
||||
# generate the podspec file from the template
|
||||
variable_substitutions = {
|
||||
"DESCRIPTION": pod_config["description"],
|
||||
# By default, we build both "iphoneos" and "iphonesimulator" architectures, and the deployment target should be the same between these two.
|
||||
"IOS_DEPLOYMENT_TARGET": framework_info["iphonesimulator"]["APPLE_DEPLOYMENT_TARGET"],
|
||||
"MACOSX_DEPLOYMENT_TARGET": framework_info.get("macosx", {}).get("APPLE_DEPLOYMENT_TARGET", ""),
|
||||
"IOS_DEPLOYMENT_TARGET": ios_deployment_target,
|
||||
"MACOSX_DEPLOYMENT_TARGET": macos_deployment_target,
|
||||
"LICENSE_FILE": "LICENSE",
|
||||
"NAME": pod_name,
|
||||
"ORT_C_FRAMEWORK": framework_dir.name,
|
||||
"ORT_C_HEADERS_DIR": public_headers_dir.name,
|
||||
"SUMMARY": pod_config["summary"],
|
||||
"VERSION": pod_version,
|
||||
"WEAK_FRAMEWORK": framework_info["iphonesimulator"]["WEAK_FRAMEWORK"],
|
||||
"WEAK_FRAMEWORK": weak_framework,
|
||||
}
|
||||
|
||||
podspec_template = _script_dir / "c.podspec.template"
|
||||
|
|
|
@ -17,6 +17,7 @@ from package_assembly_utils import ( # noqa: E402
|
|||
copy_repo_relative_to_dir,
|
||||
filter_files,
|
||||
gen_file_from_template,
|
||||
get_podspec_values,
|
||||
load_json_config,
|
||||
)
|
||||
|
||||
|
@ -147,12 +148,14 @@ def assemble_objc_pod_package(
|
|||
def path_patterns_as_variable_value(patterns: list[str]):
|
||||
return ", ".join([f'"{pattern}"' for pattern in patterns])
|
||||
|
||||
(ios_deployment_target, macos_deployment_target, _) = get_podspec_values(framework_info)
|
||||
|
||||
variable_substitutions = {
|
||||
"C_POD_NAME": c_pod_config["name"],
|
||||
"DESCRIPTION": pod_config["description"],
|
||||
"INCLUDE_DIR_LIST": path_patterns_as_variable_value(include_dirs),
|
||||
"IOS_DEPLOYMENT_TARGET": framework_info["iphonesimulator"]["APPLE_DEPLOYMENT_TARGET"],
|
||||
"MACOSX_DEPLOYMENT_TARGET": framework_info.get("macosx", {}).get("APPLE_DEPLOYMENT_TARGET", ""),
|
||||
"IOS_DEPLOYMENT_TARGET": ios_deployment_target,
|
||||
"MACOSX_DEPLOYMENT_TARGET": macos_deployment_target,
|
||||
"LICENSE_FILE": license_file,
|
||||
"NAME": pod_name,
|
||||
"PUBLIC_HEADER_FILE_LIST": path_patterns_as_variable_value(pod_files["public_header_files"]),
|
||||
|
|
|
@ -118,6 +118,44 @@ def load_json_config(json_config_file: pathlib.Path):
|
|||
return json.load(config)
|
||||
|
||||
|
||||
def get_podspec_values(framework_info):
|
||||
"""
|
||||
Get the podspec deployement targets and weak framework info from the dictionary that load_json_config returned.
|
||||
Looks for iphonesimulator, iphoneos and macos settings.
|
||||
Handles missing platforms and checks consistency.
|
||||
Returns empty string for deployment target if that platofrm is not enabled.
|
||||
|
||||
:return (ios_deployment_target, macos_deployment_target, weak_framework)
|
||||
"""
|
||||
ios_deployment_target = ""
|
||||
macos_deployment_target = ""
|
||||
weak_framework = "" # should be the same for all platforms
|
||||
# get info, allowing for a subset of platforms to be specified
|
||||
for framework in ("iphonesimulator", "iphoneos", "macosx"):
|
||||
if framework not in framework_info:
|
||||
continue
|
||||
|
||||
target = framework_info[framework]["APPLE_DEPLOYMENT_TARGET"]
|
||||
weak = framework_info[framework]["WEAK_FRAMEWORK"]
|
||||
|
||||
if not weak_framework:
|
||||
weak_framework = weak
|
||||
else:
|
||||
# should be consistent
|
||||
assert weak == weak_framework
|
||||
|
||||
if framework == "macosx":
|
||||
macos_deployment_target = target
|
||||
else:
|
||||
if not ios_deployment_target:
|
||||
ios_deployment_target = target
|
||||
else:
|
||||
# should be consistent
|
||||
assert ios_deployment_target == target
|
||||
|
||||
return (ios_deployment_target, macos_deployment_target, weak_framework)
|
||||
|
||||
|
||||
def get_ort_version():
|
||||
"""
|
||||
Gets the ONNX Runtime version string from the repo.
|
||||
|
|
|
@ -89,8 +89,9 @@ def _test_apple_packages(args):
|
|||
|
||||
# create a zip file contains the framework
|
||||
zip_file_path = local_pods_dir / f"{pod_name}.zip"
|
||||
# shutil.make_archive require target file as full path without extension
|
||||
shutil.make_archive(zip_file_path.with_suffix(""), "zip", root_dir=local_pods_dir)
|
||||
|
||||
# shutil.make_archive doesn't preserve symlinks. we know this is running on macOS so use zip
|
||||
subprocess.run(["zip", "-r", "-y", str(zip_file_path), "."], cwd=local_pods_dir, check=True)
|
||||
|
||||
# update the podspec to point to the local framework zip file
|
||||
with open(podspec) as file:
|
||||
|
|
|
@ -111,7 +111,7 @@ stages:
|
|||
cp -R $(Build.BinariesDirectory)/ios_framework/framework_out/onnxruntime.xcframework \
|
||||
$(Build.BinariesDirectory)/artifacts_staging/onnxruntime-ios-xcframework-$(OnnxRuntimeVersion)
|
||||
pushd $(Build.BinariesDirectory)/artifacts_staging
|
||||
zip -vr $(Build.BinariesDirectory)/artifacts/onnxruntime_xcframework.zip \
|
||||
zip -vry $(Build.BinariesDirectory)/artifacts/onnxruntime_xcframework.zip \
|
||||
onnxruntime-ios-xcframework-$(OnnxRuntimeVersion)
|
||||
popd
|
||||
displayName: "Build Apple xcframework"
|
||||
|
|
Загрузка…
Ссылка в новой задаче