Codesigning is skipping bundled dylibs in a binary framework

I have a framework in my project that is composed of a main framework binary, with a number of dylibs that it depends on bundled with it:

MyFramework.framework/
	Versions/
		A/
			Frameworks/
				foo.dylib
				bar.dylib
			Resources/
				...
			MyFramework
			_CodeSignature/
				...

It is signed to run locally before being bundled into my main app project.

Unfortunately, when embedding and signing the framework into my app, codesign is skipping re-signing the dylibs, which causes my hardened app to reject them from being loaded.

Am I doing something wrong, or is this a bug?

Replies

I’ve been working an issue recently that’s has very similar symptoms. Is your final product a standalone app? Or something more complex?

The reason I ask is that, if it’s a standalone app, I’d like you try something for me, namely, to export the app from the Organizer (either for Mac App Store or Developer ID, depending on your distribution channel). My experience is that Xcode will do the right thing in this case, and I’m hoping that’s true for you as well.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • The final product is a standalone macOS app - this framework is the only framework dependency, but I do have 3-4 other Swift Packages integrated.

    You're correct that exporting the app from the Organiser did the right thing. The binary and dylibs are all signed as expected.

Add a Comment

Yeah, this sounds very much like the issue I’ve been chasing.

So who builds MyFramework and the nested foo.dylib and bar.dylib dynamic libraries? Are they built by Xcode? Or SPM? Or externally?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • It’s great to hear that it sounds like the issue you’re investigating, Quinn!

    The dynamic libraries are built by conan (https://conan.io/), and then copied into an Xcode framework that bundles them into the Frameworks directory of the framework.

    The framework is then archived via Xcode, and I grab the export from that archive for inclusion in my application’s project.

Add a Comment

The framework is then archived via Xcode, and I grab the export from that archive

How do you export the archive? I don’t think any of the nice export workflows are enabled for a framework, so the button will be Distribute Content, right?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

It's all done via a script, but the basic gist is:

xcrun xcodebuild archive -archivePath MyFramework.xcarchive -scheme MyFramework

xcrun xcodebuild -create-xcframework \
        -framework MyFramework.xcarchive/Products/@rpath/MyFramework.framework \
        -debug-symbols MyFramework.xcarchive/dSYMs/MyFramework.framework \
        -output MyFramework.xcframework

ditto -c -k --rsrc --keepParent MyFramework.xcframework MyFramework.xcframework.zip

The zip file is attached to a GitHub release, and I download it in the app project, expand it and link to it as normal.

I can see looking at this how the signing might be a bit "off" by reaching into the xcarchive directly, rather than exporting the framework first. I might try using xcodebuild -exportArchive prior to creating the XCFramework, and see if that helps.

So, just to be clear, you’re building an XCFramework but the only platform in that framework is the Mac, right? Because iOS-based platforms don’t support either standalone dynamic libraries or frameworks nested within frameworks.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Yes, that is correct - the XCFramework that I'm building is for use in a macOS app, built using AppKit and SwiftUI. It won't be used on iOS.

Add a Comment

Yes, that is correct

OK.

I think your best option here is to sign the dynamic libraries nested within your XCFramework with your development signing identity before you add that to your project. That will fix your problem with day-to-day development. Moreover, I don’t think you’ll have problems with distribution. My experience is that Xcode is better about re-signing nested code like this when you export from the organizer.

Oh, and please do file a bug about this. If you tell Xcode to re-sign a framework, it should re-sign any nested code as part of that process. I suspect that the only reason it doesn’t do this this is that iOS-based platform don’t allow this sort of nesting.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Sorry that it's taken so long - I've just filed FB9750037. It's pretty light on details, because I can't share the framework itself to demonstrate the issue.

  • Ta!

Add a Comment