Well, I finally succeeded with it, stripping anything to my heart’s content, and letting Xcode do everything without any post-processing or extra scripting. I had several problems, that I will hereby describe, each capable of ruining the stripping. Let others beware of these pitfalls. Generally, I have a C++ based project (some OS-X Daemon) depending on several private frameworks (of our making too), a few dylib’s, one System-Preferences panel, and one Installer Extension plugin (the last two are cocoa code-bundles). All these are targets within a single Xcode project.
I also have quite a few script build-phases that combine this mess into beautiful single Code-bundle (a preferences panel) containing all the rest.
My first mistake - I didn’t turn on “symbols hidden by default”. This made all my symbols global - hence no stripping could ever remove them.
My second mistake - some of my private frameworks, are really wrappers, re-exporting sets of 3rd-party dylibs (boost, ahemmm). here I forgot to strip the original 3rd-party dylibs before re-exporting them. since all this is done in script build-phases, Xcode didn’t know about them, and so they couldn’t be stripped normally.
My third mistake: Xcode only applies stripping linked-product, if you turn on “deployment post-processing”. This is written in the help tab of the “strip linked product”, but almost impossible to see. I could not understand why Xcode was ignoring all my strip settings. So - you must turn post-processing on.
My fourth and most severe mistake - I misunderstood Xcode UI. Trying to be clever programmer, I usually keep as much of my build-settings at the Project level, in the hopes that targets will inherit these settings, and will so be aligned well (same compiler, language settings, etc.) The normal way to do that, is by simply deleting any setting at the target level- and when it is empty — Xcode usually inherits from upper level (project). This is NOT true… When no value exists for a setting, this means “default” and not “inherited” however - in most cases, but not all, Xcode “defaults” to inherited behavior.
In the case of strip style setting, EACH TARGET TYPE has its own default! so when I set the project level to “strip local symbols”, I was sure it will be applied to all my targets - but executables default to “strip all”, Code-bundles default to “strip local symbols” and shared libraries (like frameworks and dylibs) default to only “strip debug symbols”. The moment I manually set all my framework and dylib targets to strip local symbols —
it finally all worked fine. Stripping like a charm. My final product is now 2/3 its original size, and hackers will find it harder to decipher.