Restructure MacOS framework package to fix malformed Framework errors (#21536)

### Description

Refactor framework directory structure for MacOS packages

### 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. -->
Apple started enforcing specific [framework
structure](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html)
for MacOS packages. We need to change how we package for MacOS to follow
the guidelines

Fixes following issue: [Malformed
Framework](https://github.com/microsoft/onnxruntime-swift-package-manager/issues/19
)
This commit is contained in:
vraspar 2024-08-04 12:47:16 -07:00 committed by GitHub
parent 2653226ed0
commit 88c811b638
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 72 additions and 12 deletions

View file

@ -23,10 +23,36 @@ 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}"
pushd "${BINARIES_STAGING_DIR}/${POD_NAME}"
# assemble the files in the artifacts staging directory
zip -r "${ARTIFACTS_STAGING_DIR}/${POD_ARCHIVE_BASENAME}" ./* --exclude "${PODSPEC_BASENAME}"
zip -r -y "${ARTIFACTS_STAGING_DIR}/${POD_ARCHIVE_BASENAME}" ./* --exclude "${PODSPEC_BASENAME}"
cp "${PODSPEC_BASENAME}" "${ARTIFACTS_STAGING_DIR}/${PODSPEC_BASENAME}"
popd

View file

@ -89,18 +89,52 @@ def _build_for_apple_sysroot(
pathlib.Path(framework_dir).mkdir(parents=True, exist_ok=True)
# copy the Info.plist, framework_info.json, and header files
shutil.copy(info_plist_path, framework_dir)
shutil.copy(framework_info_path, os.path.dirname(framework_dir))
header_dir = os.path.join(framework_dir, "Headers")
pathlib.Path(header_dir).mkdir(parents=True, exist_ok=True)
for _header in headers:
shutil.copy(_header, header_dir)
# use lipo to create a fat ort library
lipo_command = ["lipo", "-create"]
lipo_command += ort_libs
lipo_command += ["-output", os.path.join(framework_dir, "onnxruntime")]
subprocess.run(lipo_command, shell=False, check=True)
# macos requires different framework structure:
# https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html
if sysroot == "macosx" or sysroot == "macabi":
# create headers and resources directory
header_dir = os.path.join(framework_dir, "Versions", "A", "Headers")
resource_dir = os.path.join(framework_dir, "Versions", "A", "Resources")
pathlib.Path(header_dir).mkdir(parents=True, exist_ok=True)
pathlib.Path(resource_dir).mkdir(parents=True, exist_ok=True)
shutil.copy(info_plist_path, resource_dir)
shutil.copy(framework_info_path, os.path.dirname(framework_dir))
for _header in headers:
shutil.copy(_header, header_dir)
# use lipo to create a fat ort library
lipo_command = ["lipo", "-create"]
lipo_command += ort_libs
lipo_command += ["-output", os.path.join(framework_dir, "Versions", "A", "onnxruntime")]
subprocess.run(lipo_command, shell=False, check=True)
# create the symbolic link
pathlib.Path(os.path.join(framework_dir, "Versions", "Current")).symlink_to("A", target_is_directory=True)
pathlib.Path(os.path.join(framework_dir, "Headers")).symlink_to(
"Versions/Current/Headers", target_is_directory=True
)
pathlib.Path(os.path.join(framework_dir, "Resources")).symlink_to(
"Versions/Current/Resources", target_is_directory=True
)
pathlib.Path(os.path.join(framework_dir, "onnxruntime")).symlink_to("Versions/Current/onnxruntime")
else:
shutil.copy(info_plist_path, framework_dir)
shutil.copy(framework_info_path, os.path.dirname(framework_dir))
header_dir = os.path.join(framework_dir, "Headers")
pathlib.Path(header_dir).mkdir(parents=True, exist_ok=True)
for _header in headers:
shutil.copy(_header, header_dir)
# use lipo to create a fat ort library
lipo_command = ["lipo", "-create"]
lipo_command += ort_libs
lipo_command += ["-output", os.path.join(framework_dir, "onnxruntime")]
subprocess.run(lipo_command, shell=False, check=True)
return framework_dir