• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
.objc_class_name stripped by dead code stripping
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

.objc_class_name stripped by dead code stripping


  • Subject: .objc_class_name stripped by dead code stripping
  • From: Greg Hurrell <email@hidden>
  • Date: Sun, 6 Aug 2006 23:42:25 +0200

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"). Is there any way to set the visibility flag 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:

__attribute__((visibility("default")))

I have tried every combination that I can think of without success. I know that the docs say that:

"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.

There are workarounds but 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).

It could be argued that this is all moot because unit tests occur during development, and development is often done without linking (thanks to ZeroLink) so these linking problems go away, but that's not true in this instance: these unit tests are designed to be shipped to customers along with release builds so that customers can verify on-site that everything works as it should. For now I am going with option "4" above but I don't like it; I'd much rather figure out how to selectively enforce visibility on class symbols only.

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

Cheers,
Greg

_______________________________________________
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


  • Follow-Ups:
    • Re: .objc_class_name stripped by dead code stripping (follow-up)
      • From: Greg Hurrell <email@hidden>
  • Prev by Date: Re: Visual Studio-style indent
  • Next by Date: Random /usr/lib/libsqlite3.0.dylib Linking in Release Mode ONLY
  • Previous by thread: Step Into fails
  • Next by thread: Re: .objc_class_name stripped by dead code stripping (follow-up)
  • Index(es):
    • Date
    • Thread