Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is -force_load no longer required for my three20 dependencies in XCode 4.2?

I have project with a dependency on a third-party static library and the three20 libraries. In XCode 3.X, in order to get my project to compile, I had to use the -force_load flag in the "Other Linker Flags" build setting, and specify each of the three20 libraries that I wanted to include.

When attempting to build an archive in XCode 4.2, I was getting a "duplicate symbol" error. I resolved this by removing the seven separate -force_load flags that referred to each of the three20 libraries on which I had a dependency.

My project now builds successfully.

I wonder if someone can explain to my why this change worked? Was there a bug that XCode 4.2 fixed, or is the a behavioral change? This post suggests there was a bug in XCode 3.2, but it would be great if someone could shed additional light on this topic for me so I can be sure I haven't potentially done something wrong by removing these -force_load flags.

Thanks!

like image 708
esilver Avatar asked Oct 30 '11 00:10

esilver


1 Answers

When building a static library (as required for iOS), one of the issues you'll encounter is how to include symbols from categories in that library so they're usable by an application. The linker flag -ObjC should pull in enough information to include categories in these built frameworks, as Dave Dribin describes in his article here.

However, between iPhone OS 2.0 and 3.0, this stopped working right. As I mentioned in this answer, we encountered this problem in the Core Plot framework and found that we needed to add the -all_load linker flag to make the framework work right. Apple themselves posted Technical Q&A QA1490 which mentions this issue:

For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -all_load or -force_load flags.

-all_load forces the linker to load all object files from every archive it sees, even those without Objective-C code. -force_load is available in Xcode 3.2 and later. It allows finer grain control of archive loading. Each -force_load option must be followed by a path to an archive, and every object file in that archive will be loaded.

Unfortunately, the side effect of this is that duplicate symbols linked in from multiple libraries can cause errors like the ones you experienced.

I filed a bug report about this (back in 2009), and it appears that the latest version of LLVM now used in Xcode no longer suffers from this linker bug. I tried just using -ObjC with the Core Plot iOS static library target and it works fine now. That's welcome news.

like image 119
Brad Larson Avatar answered Nov 15 '22 17:11

Brad Larson