Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Your read me says to use "-all_load" but you should use -force_load #169
When someone uses "-all_load", every imported library is forced into memory whether its needed or not. A much better technique is "-force_load":
This insures that ONLY your library is loaded, not every library.
IMPORTANT: 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.
OK - will send in a pull request. The issue is that for users of your library, adding -all_load means that other libraries they link too - even c based ones - get loaded into memory immediately when their app launches (bloating the size of their runtime). On the Mac it would not be so bad - you have virtual memory - but on the iPhone this is REAL precious ram getting used for no reason.
Hah - yes, I stand corrected on the memory. However, I still suspect the behavior is different although I cannot think of how at this moment. If the behavior was the same, why would Apple provide the two flags? We know that classes do not get their initialize message until they are loaded, and categories do not receive a "load" message til loaded. Perhaps the all_load flag forces internal categories to load immediately before they are really needed. I cannot find anything on the web on this, yet if all_load was the same as force_load, why provide both? Apple's own doc's say you get a "finer grain control" with force_load.
OK - there is a thread on this in the email@example.com forum on Apple's site. Note that Greg Parker is the compiler guru at Apple with thread "iOS -force_load versus -all_load":
-all_load and -force_load act a link time, not at load time. -all_load and -force_load tell the linker to link the entire static archive in the final executable, even if the linker thinks that parts of the archive are unused.
When you link a traditional C static archive (.a file), any code from the archive that is never referenced in the final executable is simply omitted from the executable. So if you had a static archive with 999 functions you did not call and 1 function that you did call, your final executable would include only that one function.
Objective-C categories break the C static archive model, because you want the Objective-C category to appear in the final executable even though there are no C symbol references to it from the executable.
The best solution for Objective-C categories in static archives is the -ObjC linker option, which tells the linker that all Objective-C categories in the archives are "used" but to apply the usual reference algorithm for everything else in the archives.
The -ObjC option is broken in some versions of the linker. For those cases the -force_load and -all_load options work. The final executable may be larger than necessary with those options, if there were classes or C functions that could have been omitted by the linker. If you have multiple archives and only some of them have Objective-C code then -force_load may generate smaller output than -all_load.
-- Greg Parker Runtime Wrangler
D Hoerl comment:
If you want to minimize your footprint, use -force_load, not -all_load
I understand this as: try first only the -ObjC flag. If the app crashes due to an unrecognized selector use one of the force parameters.
Since you probably only have one or two static libraries then there will be no difference in binary size between these two flags, since dynamic libraries code is not merged into your app. So a force load and an all load with a single library should produce identical output.
When in doubt I prefer the simpler solution, which is force load since it does not require to determine the path of the lib.
Well sort of. -ObjC should work for all ObjC libraries, but it has a bug and does not link in files with just categories. So the force_load flag, as is on the thread but not posted here, really a linker flag.
The issue with with you using -all_load in your README is that people incorporating your library may have many other libraries loaded as well (as I do).
In case you don't have the exact line handy, here it is: -force_load $(BUILT_PRODUCTS_DIR)/libarc.a