2
votes

I am building a dynamic library which depends on another static library I built before. The static library has a dependency on WebRTC. However, the new dynamic library will be used in a Swift app, which also depends on WebRTC. This caused lots of symbol collisions at build time, so I followed this doc and added an Export Symbols File in the dynamic lib.

Now the dynamic lib and the Swift app both built fine, however I got a lot of console warnings regarding duplicate ObjC class symbols when the Swift app started:

objc[63026]: Class RTCCVPixelBuffer is implemented in both /path/to/the/dynamic/framework/binary and /path/to/existing/webrtc/in/the/swift/app. One of the two will be used. Which one is undefined.

I checked my dynamic framework and these WebRTC ObjC symbols are all local (non-extern) symbols. Now I have two questions:

  1. Will local symbol collision cause any runtime issue like undefined app behavior and app crash? I understand duplicate global symbols won't work, but what's the worst outcome of having duplicate local symbols?
  2. Are those local symbols needed, and how can I remove them? I first tried to prelink the object files in the static library by setting GENERATE_MASTER_OBJECT_FILE, STRIP_STYLE and DEPLOYMENT_POSTPROCESSING in build settings, hoping to have all symbols resolved before they come to the dynamic library, but still I can see these local ObjC class symbols in my dynamic library binary. I also tried to set -R option in Additional strip flags to strip out local symbols, but that also failed. Are these symbols required and cannot be removed because ObjC message sending depends on them? What's the proper way to resolve this kind of symbol collision issue?
1
May be build static library instead?Cy-4AH
@Cy-4AH I actually resolved the build time symbol collision by changing the library from static to dynamic and add a Export Symbols File. Also there are some other benefits for keeping it dynamic (much smaller artifact, etc.) so I'd rather having a solution in dynamic framework, unless it's not possible.Cloudy
Static framework is better. Something wrong, there is no symbol collisions when all libraries and frameworks are static. I don't know about which smaller artifacts you are talking about, but app is actually smaller when you are using static libraries, because not used object files isn't linked with app.Cy-4AH

1 Answers

0
votes

I end up with adding a prefix to all ObjC interfaces using the objc_runtime_name attribute. This essentially changes the metadata name of the interface into the specified string argument, which solved the duplicate symbol issue.