Skip to content

Commit

Permalink
Restructure MacOS framework package to fix malformed Framework errors (
Browse files Browse the repository at this point in the history
…microsoft#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](microsoft/onnxruntime-swift-package-manager#19
)
  • Loading branch information
vraspar authored Aug 4, 2024
1 parent 2653226 commit 88c811b
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
58 changes: 46 additions & 12 deletions tools/ci_build/github/apple/build_apple_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 88c811b

Please sign in to comment.