Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Universal binaries with more than one arch for macOS fail on creating xcframework #57

Closed
Deadpikle opened this issue Jul 30, 2020 · 3 comments · Fixed by #58
Closed

Comments

@Deadpikle
Copy link
Contributor

Deadpikle commented Jul 30, 2020

As reported in #49:

If you try to build a .xcframework file with i386 and x86_64, it will fail with a similar error to the following:

Both macos-i386 and macos-x86_64 represent two equivalent library definitions.

I did a lot of digging, and it turns out the one other case I can find of this is in Firebase by Google. See comments at https://github.com/firebase/firebase-ios-sdk/blob/master/ZipBuilder/Sources/ZipBuilder/FrameworkBuilder.swift#L757

The gist: some binaries need to be lipo'd together before sticking them in the xcframework, especially noticed with macOS. We need to lipo all the macOS (including silicon!) libboost.a files together before putting them in the xcframework file.

This actually makes a lot of sense -- this way, you can distribute one raw binary to all your macOS users, and this has "backwards compatibility" to old versions of macOS because of the lipo -- the end executable you distribute has the lipo'd version, not 2 different libs (one for x64 and one for arm64, for example).

@Deadpikle
Copy link
Contributor Author

Deadpikle commented Jul 30, 2020

Yes, this is indeed the case. In some testing done manually on the command line with arm64 and x86_64, which has a similar error:

lipo -create -output ulibboost.a build/boost/1.71.0/macos/release/build/x86_64/libboost.a build/boost/1.71.0/macos-silicon/release/build/arm64/libboost.a
xcrun xcodebuild -create-xcframework -library ulibboost.a -headers build/boost/1.71.0/macos/release/prefix/include/ -output test.xcframework

generates the following Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AvailableLibraries</key>
	<array>
		<dict>
			<key>HeadersPath</key>
			<string>Headers</string>
			<key>LibraryIdentifier</key>
			<string>macos-arm64_x86_64</string>
			<key>LibraryPath</key>
			<string>ulibboost.a</string>
			<key>SupportedArchitectures</key>
			<array>
				<string>arm64</string>
				<string>x86_64</string>
			</array>
			<key>SupportedPlatform</key>
			<string>macos</string>
		</dict>
	</array>
	<key>CFBundlePackageType</key>
	<string>XFWK</string>
	<key>XCFrameworkFormatVersion</key>
	<string>1.0</string>
</dict>
</plist>

and the following structure:

Screen Shot 2020-07-30 at 9 54 35 AM

I realize the headers and file name aren't set up right (this was only a proof of concept test), but this should show the direction to go for a fix for i386, x86_64, and Apple Silicon support all in one xcframework.

@Deadpikle
Copy link
Contributor Author

Screen Shot 2020-07-30 at 10 28 49 AM

PR coming soon! 😁 (Can't actually test the arm64 build since I don't have a DTK...but it is building!)

@Deadpikle Deadpikle changed the title Universal binaries with i386 and arm64 for macOS fail on creating xcframework Universal binaries with more than one arch for macOS fail on creating xcframework Jul 30, 2020
Deadpikle added a commit to Deadpikle/Apple-Boost-BuildScript that referenced this issue Jul 30, 2020
Also fixes issue where xcframework cannot be made if more than one arch for macOS is used
Closes faithfracture#57
@mackworth
Copy link

I finally got my M1 and used the new script to rebuild my framework. Once I got the command line correct, it worked great! Thank you so much.

I did run into a couple of minor issues. Happy to submit a PR; just let me know if you agree w/ these.

First, I didn't understand why the script wasn't following my instruction to build for multiple architectures. Finally realized that when printing the ARCHs it's going to build for, it's only printing the first element of the array; I fixed by adding [@] to all arches in printVar Calls.

If XCFramework build fails, script still reports success at the end. (Should check status after find on line 1484)

Getting an error now: "ld: warning: option -s is obsolete and being ignored"

There's still the spin lock issue (I'll post on Issue #50 as well).
The pThreads used in EXTRA_ARM_FLAGS is incompatible with iOS; one symptom is that the filesystem directory_iterator fails. It should be:
EXTRA_ARM_FLAGS="-DBOOST_SP_USE_SPINLOCK -g -DNDEBUG"

Default Boost Version should be updated to 1.75.0, no?

Formatting problems:
It'd be nice if BUILD_XXXOS is NO, then don't list SDK/Version info for that system.
Missing a blank line echo after printVar MIN_MACOS_SILICON_VERSION
Need to bump 20 spaces to 25 in PrintVar due to longer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants