Re: .objc_class_name stripped by dead code stripping (follow-up)
Re: .objc_class_name stripped by dead code stripping (follow-up)
- Subject: Re: .objc_class_name stripped by dead code stripping (follow-up)
- From: Greg Hurrell <email@hidden>
- Date: Fri, 18 Aug 2006 12:04:19 +0200
Didn't receive any replies to my original post but I've noticed that
one key piece of information was incorrect in the original post so
going to ask again... Also if anyone has a recommendation for a more
appropriate list to ask this question (objc-language?) please let me
know.
The one line summary is that dead-code stripping seems to break the
BUNDLE_LOADER build setting and I'd like to figure out a solution.
Details follow:
I have an application and a bundle of unit tests. When building the
test bundle I would like to use the BUNDLE_LOADER build setting to
tell the linker to look in the application executable for undefined
symbols. The trouble is that performing dead code stripping on the
application strips away the symbols that the bundle needs (symbols
like ".objc_class_name_MYClass"), leading to linker errors when
trying to build the bundle. Is there any way to set the visibility or
used flags on only those symbols? I know I can use the following for
functions and other symbols, but I have not been able to find a way
to apply it to Objective-C classes:
This marks things so that they won't be eliminated by dead-code
stripping:
__attribute__((used))
And this marks symbols so that they'll be visible as global symbols
even if symbols are set to "private by
default" (GCC_SYMBOLS_PRIVATE_EXTERN):
__attribute__((visibility("default")))
I have tried every combination that I can think of without success. I
know that the docs say that "Objective-C runtime data" doesn't get
stripped by dead-code stripping, and they also say:
"Objective-C class and message names are bound by the Objective-C
runtime, not by the linker, so the notion of visibility does not
apply to them. There is no mechanism for hiding an Objective-C class
defined in a dynamic library from the clients of that library."
But this doesn't seem to be true; there is a mechanism and that
mechanism is dead-code stripping. If you use "nm" to compare an
executable built with and without dead code stripping you'll see that
the former has the .objc_class_name symbols stripped.
These are the workarounds that I've tried: some work others don't and
none of them are ideal:
1. Turn off dead-code stripping (throwing the baby out with the bath
water).
2. Enclosing the entire class implementation with pragmas (no effect):
#pragma GCC visibility push(default)
#pragma GCC visibility pop
3. Enclosing the entire class interface with the same pragmas (no
effect).
4. Pass "-undefined dynamic_lookup" when linking the bundle (the
problem with this is it is too aggressive and applies to all symbols,
not just the ones which got stripped by dead-code stripping, meaning
what should be link-time errors could turn into nastier run-time
errors).
5. Use the EXPORTED_SYMBOLS_FILE build setting (you have to include
lots of symbols in the file, not just the class symbols, or you'll
get lots of linker warnings).
6. Build the app without dead code stripping, build the bundle, then
re-build the app with code stripping (too time consuming for complex
apps and horribly kludgy to boot).
7. Specify symbols that are ok to be undefined using "-Wl,-
U,symbol" (not allowed with two-level namespaces and unworkable for
large numbers of symbols).
8. Apply "-fvisibility=default" compiler flags to specific files in
the app (applies to entire files, not just class symbols; and doesn't
work anyway... dead code stripping still wipes out the class names).
Here are all my build settings related to symbols, linking and
stripping, but I have tried toggling them all one by one and the only
one which seems to break BUNDLE_LOADER is DEAD_CODE_STRIPPING:
DEBUG_INFORMATION_FORMAT = stabs
DEAD_CODE_STRIPPING = YES
GCC_GENERATE_DEBUGGING_SYMBOLS = YES
GCC_DEBUGGING_SYMBOLS = full
DEPLOYMENT_POSTPROCESSING = YES
SKIP_INSTALL = NO
STRIP_INSTALLED_PRODUCT = NO
SEPARATE_STRIP = NO
STRIP_STYLE = all
GCC_SYMBOLS_PRIVATE_EXTERN = YES
GCC_INLINES_ARE_PRIVATE_EXTERN = YES
ONLY_LINK_ESSENTIAL_SYMBOLS = NO
KEEP_PRIVATE_EXTERNS = NO
GCC_ENABLE_SYMBOL_SEPARATION = YES
I'm hoping that someone can tell me how to workaround this. If
someone can confirm that dead-code stripping does render
BUNDLE_LOADER ineffective I'll file a bug report, either against the
documentation for saying the Objective-C runtime data doesn't get
stripped, or against the linker for stripping the class name symbols.
Cheers,
G
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden