Facebook-ios-sdk: Many linker errors on objective-c & c++ project when updating from 5.15.0 to latest

Created on 9 Jul 2020  路  22Comments  路  Source: facebook/facebook-ios-sdk

Checklist

Environment

  • Xcode Version: 11.5
  • Installation Platform & Verison: frameworks manually downloaded from releases and force loaded to the project

As the title says, I updated the sdk in my project (which is c++ and objective-c combined) from version 5.15.0 to the latest, 7.1.1 and got a bunch of linking errors, which I'll post bellow. It seems like most (if not all) are related to Swift types from the SDK so maybe some define is missing to disable their definition on non-Swift projects?

Undefined symbols for architecture arm64:
  "method descriptor for Swift.CustomStringConvertible.description.getter : Swift.String", referenced from:
      l_got.$ss23CustomStringConvertibleP11descriptionSSvgTq in FBSDKShareKit(Enums+Extensions.o)
  "protocol descriptor for Swift.CustomStringConvertible", referenced from:
      l_got.$ss23CustomStringConvertibleMp in FBSDKShareKit(Enums+Extensions.o)
  "associated conformance descriptor for Foundation._ErrorCodeProtocol.Foundation._ErrorCodeProtocol._ErrorType: Foundation._BridgedStoredNSError", referenced from:
      l_got.$s10Foundation18_ErrorCodeProtocolP01_B4TypeAC_AA21_BridgedStoredNSErrorTn in FBSDKLoginKit(LoginManager.o)
  "protocol descriptor for Foundation._ErrorCodeProtocol", referenced from:
      l_got.$s10Foundation18_ErrorCodeProtocolMp in FBSDKLoginKit(LoginManager.o)
  "method descriptor for Foundation._BridgedStoredNSError.init(_nsError: __C.NSError) -> A", referenced from:
      l_got.$s10Foundation21_BridgedStoredNSErrorP8_nsErrorxSo0D0C_tcfCTq in FBSDKLoginKit(LoginManager.o)
  "associated conformance descriptor for Foundation._BridgedStoredNSError.Foundation._BridgedStoredNSError.Code: Swift.RawRepresentable", referenced from:
      l_got.$s10Foundation21_BridgedStoredNSErrorP4CodeAC_SYTn in FBSDKLoginKit(LoginManager.o)
  "base conformance descriptor for Foundation._ErrorCodeProtocol: Swift.Equatable", referenced from:
      l_got.$s10Foundation18_ErrorCodeProtocolPSQTb in FBSDKLoginKit(LoginManager.o)
  "associated conformance descriptor for Foundation._BridgedStoredNSError.Foundation._BridgedStoredNSError.Code: Foundation._ErrorCodeProtocol", referenced from:
      l_got.$s10Foundation21_BridgedStoredNSErrorP4CodeAC_AA06_ErrorE8ProtocolTn in FBSDKLoginKit(LoginManager.o)
  "base conformance descriptor for Foundation._BridgedStoredNSError: Swift.Hashable", referenced from:
      l_got.$s10Foundation21_BridgedStoredNSErrorPSHTb in FBSDKLoginKit(LoginManager.o)
  "base conformance descriptor for Foundation._BridgedStoredNSError: Foundation.CustomNSError", referenced from:
      l_got.$s10Foundation21_BridgedStoredNSErrorPAA06CustomD0Tb in FBSDKLoginKit(LoginManager.o)
  "method descriptor for static Foundation.CustomNSError.errorDomain.getter : Swift.String", referenced from:
      l_got.$s10Foundation13CustomNSErrorP11errorDomainSSvgZTq in FBSDKLoginKit(LoginManager.o)
  "base conformance descriptor for Foundation.CustomNSError: Swift.Error", referenced from:
      l_got.$s10Foundation13CustomNSErrorPs5ErrorTb in FBSDKLoginKit(LoginManager.o)
  "method descriptor for Foundation._ObjectiveCBridgeableError.init(_bridgedNSError: __shared __C.NSError) -> A?", referenced from:
      l_got.$s10Foundation26_ObjectiveCBridgeableErrorP15_bridgedNSErrorxSgSo0F0Ch_tcfCTq in FBSDKLoginKit(LoginManager.o)
  "method descriptor for Swift.Error._getEmbeddedNSError() -> Swift.AnyObject?", referenced from:
      l_got.$ss5ErrorP19_getEmbeddedNSErroryXlSgyFTq in FBSDKLoginKit(LoginManager.o)
  "method descriptor for Swift.Error._userInfo.getter : Swift.AnyObject?", referenced from:
      l_got.$ss5ErrorP9_userInfoyXlSgvgTq in FBSDKLoginKit(LoginManager.o)
  "method descriptor for Swift.Error._code.getter : Swift.Int", referenced from:
      l_got.$ss5ErrorP5_codeSivgTq in FBSDKLoginKit(LoginManager.o)
  "protocol conformance descriptor for Swift.Int : Swift.FixedWidthInteger in Swift", referenced from:
      lazy protocol witness table accessor for type Swift.Int and conformance Swift.Int : Swift.FixedWidthInteger in Swift in FBSDKLoginKit(LoginManager.o)
  "type metadata for Swift.Int", referenced from:
      lazy protocol witness table accessor for type Swift.Int and conformance Swift.Int : Swift.FixedWidthInteger in Swift in FBSDKLoginKit(LoginManager.o)
  "protocol descriptor for Foundation.CustomNSError", referenced from:
      l_got.$s10Foundation13CustomNSErrorMp in FBSDKLoginKit(LoginManager.o)
  "static Swift._DictionaryStorage.allocate(capacity: Swift.Int) -> Swift._DictionaryStorage<A, B>", referenced from:
      function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Dead> of generic specialization <serialized, Swift.String, Any> of Swift.Dictionary.init(dictionaryLiteral: (A, B)...) -> [A : B] in FBSDKLoginKit(LoginManager.o)

[...]
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Showing first 200 notices only

Most helpful comment

There is an actual fix coming that does not require using a fork or modifying the actual library. Cc @kylinchang

All 22 comments

If you're using CocoaPods does your Podfile include use_frameworks! ?

Hi!
Not using CocoaPods, I download the frameworks manually from the release section here, on git, and force load them in my project (and have the path set in framework dirs and all).
And, to update, I just replace the framework files.
Thanks!

@georgii11, I fixed this with help from this tip from a discussion complaining about the dependence on Swift in v7.

What I did was:

  1. Checkout the v7.1.1 tag
  2. Open FacebookSDK.xcworkspace and remove all the .swift files from the compile sources for the FBSDKCoreKit, FBSDKShareKit, and FBSDKLoginKit targets and their -Dynamic variants
  3. Build the BuildAllKits target for archiving
  4. Grab the resulting .frameworks linked to from the build directory and add them manually to my Swift-free, Objective-C++ project's dependencies

This appears to have worked. I have a fork with those project changes here if you'd like to try it.

There is an actual fix coming that does not require using a fork or modifying the actual library. Cc @kylinchang

Oh, excellent!

@joesus I'm stuck with the same issue, but its coming from the facebook-sdk-for-unity. It includes this lib as a pod dependency:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'

target 'UnityFramework' do
  pod 'FBSDKCoreKit', '~> 7.1.1'
  pod 'FBSDKGamingServicesKit', '~> 7.1.1'
  pod 'FBSDKLoginKit', '~> 7.1.1'
  pod 'FBSDKShareKit', '~> 7.1.1'
end

including use_frameworks! into the podfile fixed the error but did not solve the problem. app crashes after start with

2020-07-16 13:50:43.355688+0200 main[1341:1427280] Error loading /var/containers/Bundle/Application/32D24C22-4879-4DB9-BD04-B6158F936749/main.app/Frameworks/UnityFramework.framework/UnityFramework:  dlopen(/var/containers/Bundle/Application/32D24C22-4879-4DB9-BD04-B6158F936749/main.app/Frameworks/UnityFramework.framework/UnityFramework, 265): Library not loaded: @rpath/FBSDKCoreKit.framework/FBSDKCoreKit
  Referenced from: /private/var/containers/Bundle/Application/32D24C22-4879-4DB9-BD04-B6158F936749/main.app/Frameworks/UnityFramework.framework/UnityFramework
  Reason: image not found
2020-07-16 13:50:43.363578+0200 main[1341:1427280] Error loading /var/containers/Bundle/Application/32D24C22-4879-4DB9-BD04-B6158F936749/main.app/Frameworks/UnityFramework.framework/UnityFramework:  dlopen(/var/containers/Bundle/Application/32D24C22-4879-4DB9-BD04-B6158F936749/main.app/Frameworks/UnityFramework.framework/UnityFramework, 265): Library not loaded: @rpath/FBSDKCoreKit.framework/FBSDKCoreKit
  Referenced from: /private/var/containers/Bundle/Application/32D24C22-4879-4DB9-BD04-B6158F936749/main.app/Frameworks/UnityFramework.framework/UnityFramework
  Reason: image not found

Current workaround is to add an empty swift file or add use_frameworks!. The fix 8fdb57a76d2f5a14c168e91663280d40f274c74c will be released in the next UnitySDK release.

@KylinChang Thanks, I've already checked out the version 8fdb57a76d2, compiled it by hand following the steps in the readme (it took me quite long to figure out the correct versions of unity, mono and java)
After that I've manually added use_frameworks! to Podfile
I did not add an empty .swift file because I think this is what the version 8fdb57a76d2 already does.
It did not compile successfully as I've described in my first post
What am I doing wrong?
Is target 'UnityFramework' do correct?
Need to push out a version this week and not very familiar with Xcode :/
Thank you!

Hi!
@KylinChang What about the non-Unity SDK?
Is there a release planned for it too? Any estimated time?
Thanks!

I finally was able to compile a unity version! Not sure what I did wrong on the first try but it turns out the Facebook.Unity.dll file was not updated correctly after I've imported the "fixed" .unitypackage. I've deleted all the autogenerated files in Unity and the build. Reverted the commit where I've initially imported the bugged .uintypackage (v7.21.1). Build a iOS version without FB SDK. Imported the fixed .unitypackage and the build finally worked!

Hi!
Are there any news of a release @joesus @KylinChang ?
I need to update to 7+ kinda soon and I'm wondering if it's worth waiting for the official fix to be released or should I just try the solution mentioned by _s3cur3_.
Thanks!

@georgii11 we always recommend upgrading to the latest version. The next planned release is unlikely to have many breaking api changes so upgrading to that should also be easy. Hope that helps!

@joesus not having to worry about many breaking api changes sounds good and I do plan to update.
However my concern is more about an estimated date of when the release (which would fix these swift related linking errors) is planned.
That is because I need an update soon so I have to decide if I can just wait for the release, or first do an intermediary update to custom built frameworks, with the swift resources removed, as suggested by s3cur3.

Isn't use_frameworks! negatively impacting the app startup time?

@georgii11 - this was the fix I was planning on using but I'm not sure it's the right direction. https://github.com/facebook/facebook-ios-sdk/pull/1529

I'm pretty sure these linker flags are added automatically if you add a single swift file to your project so it's unclear that this will benefit a majority of our developers. Please weigh in on the PR.

@georgii11, I fixed this with help from this tip from a discussion complaining about the dependence on Swift in v7.

What I did was:

  1. Checkout the v7.1.1 tag
  2. Open FacebookSDK.xcworkspace and remove all the .swift files from the compile sources for the FBSDKCoreKit, FBSDKShareKit, and FBSDKLoginKit targets and their -Dynamic variants
  3. Build the BuildAllKits target for archiving
  4. Grab the resulting .frameworks linked to from the build directory and add them manually to my Swift-free, Objective-C++ project's dependencies

This appears to have worked. I have a fork with those project changes here if you'd like to try it.

One day the SDK will be written in Swift. The strategy you've outlined is risky. It does not benefit from testing improvements, bug fixes, and other quality and safety considerations.

There is an actual fix coming that does not require using a fork or modifying the actual library. Cc @KylinChang

Is that still the case? Would be great to get an update on the status of that fix, as it鈥檚 not clear to me from the discussion above whether that fix is still on the roadmap.

Is that still the case? Would be great to get an update on the status of that fix, as it鈥檚 not clear to me from the discussion above whether that fix is still on the roadmap.

The proposed fix is #1529 - but it's unclear whether this is the correct direction. For example, it may be better to add the linker flags in that PR to an FAQ instead of adding them to the podspec.

This is the discussion I'd like to have on that PR.

Thanks for the update @joesus! So just to clarify, are there no plans to offer an ObjC-only version of the SDK?

Thanks for the update @joesus! So just to clarify, are there no plans to offer an ObjC-only version of the SDK?

Not at this time.

Apple, leading the industry as a whole, is moving towards Swift for a host of good reasons including:

  • Safer and more resilient products
  • Cleaner and more readable codebases
  • A lower barrier to entry for would-be contributors
  • Developer friendly features like generics, strong types, non-optionals and result builders
  • Active language development that continues to mature and improve in terms of size and performance. Now that the language has matured and gained ABI stability, many issues we saw in Swift's early versions are resolved.
  • Support for new features from Apple, such as App Clips

In all, we assess that moving towards an entirely Swift implementation for our iOS SDK gives the most significant benefit to developers overall.

@georgii11, I fixed this with help from this tip from a discussion complaining about the dependence on Swift in v7.

What I did was:

  1. Checkout the v7.1.1 tag
  2. Open FacebookSDK.xcworkspace and remove all the .swift files from the compile sources for the FBSDKCoreKit, FBSDKShareKit, and FBSDKLoginKit targets and their -Dynamic variants
  3. Build the BuildAllKits target for archiving
  4. Grab the resulting .frameworks linked to from the build directory and add them manually to my Swift-free, Objective-C++ project's dependencies

This appears to have worked. I have a fork with those project changes here if you'd like to try it.

I checkout the v8.1.0 tag, remove all swift files, build the BuildAllKits target for archiving, get the following error:

<module-includes>:1:1: umbrella header for module 'FBSDKCoreKit' does not include header 'FBSDKCoreKit-Swift.h' [-Werror,-Wincomplete-umbrella]

It's ok for v7.1.1 tag.

My question is how to delete swift dependency?

FYI these linker errors still happen with the latest 9.0.0 SDK release via CocoaPods in an Objective-C only project.

Meanwhile I saw this tidbit in the readme:

Note for Swift Package Manager Users:
If you explicitly DO NOT want to include Swift, import FBSDKCoreKit FBSDKLoginKit and FBSDKShareKit
For projects that include Swift, use FacebookCore, FacebookLogin, and FacebookShare

Does that mean that it鈥檚 possible to have an ObjC-only SDK via Swift Package Manager?

Was this page helpful?
0 / 5 - 0 ratings