Skip to content

Commit

Permalink
Add ability to test packaging without rebuilding every time.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
skottmckay committed Aug 5, 2024
1 parent 88c811b commit 538bb5d
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 36 deletions.
23 changes: 0 additions & 23 deletions tools/ci_build/github/apple/assemble_apple_packaging_artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}"

Expand Down
11 changes: 9 additions & 2 deletions tools/ci_build/github/apple/build_and_assemble_apple_pods.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 = [
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion tools/ci_build/github/apple/build_apple_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 8 additions & 5 deletions tools/ci_build/github/apple/c/assemble_c_pod_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
PackageVariant,
copy_repo_relative_to_dir,
gen_file_from_template,
get_podspec_values,
load_json_config,
)

Expand Down Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
copy_repo_relative_to_dir,
filter_files,
gen_file_from_template,
get_podspec_values,
load_json_config,
)

Expand Down Expand Up @@ -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"]),
Expand Down
38 changes: 38 additions & 0 deletions tools/ci_build/github/apple/package_assembly_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions tools/ci_build/github/apple/test_apple_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 538bb5d

Please sign in to comment.