12

OK, I know there have been other posts about how you can't actually strip Objective-C symbols from an OS X binary because they're necessary for Obj-C to work at all, but my case is a bit different.

I have a single binary which is a bundle. It is intended to be used as either a VST plugin, or an AudioUnit plugin. The idea is that the binary contains all the entry points for both formats, and you just compile it once, and then name one copy with ".vst" for the VST version, and ".component" for the AU version. (This is using the JUCE framework BTW.)

The problem is that for the AU side, you must export an Obj-C class for creating the Cocoa UI view. On the VST side, this class will never be used. But if you have a host like Ableton Live which allows you to simultaneously load both AU and VST versions of the same plugin, now we run into the typical Obj-C namespace collision issue.

On the VST side, that particular Obj-C class will never get used. So what I'd like to do is to strip those Obj-C classes from the resulting binary using "strip". This still maintains the advantage of just compiling everything once for both formats.

Anyway, I've tried using "strip -R stripfile.txt <path to binary>", where stripfile.txt contains the symbols I want to strip, but it always fails saying that the symbols can't be found in the binary. I've tried mangling the names in the strip file, but that doesn't help (or I'm doing it wrong).

Here are the relevant symbols that I want to strip, as output by "nm -m":

000000000003bb00 (__TEXT,__text) non-external -[JuceDemoProjectAU description]
000000000003bb60 (__TEXT,__text) non-external -[JuceDemoProjectAU interfaceVersion]
000000000003ba00 (__TEXT,__text) non-external -[JuceDemoProjectAU uiViewForAudioUnit:withSize:]
0000000000b02398 (__DATA,__objc_data) external _OBJC_CLASS_$_JuceDemoProjectAU
0000000000b023c0 (__DATA,__objc_data) external _OBJC_METACLASS_$_JuceDemoProjectAU

Any ideas?

BTW, I have subsequently been able to dynamically register the class in question (using a unique name), which also solves the problem. However, if I could get strip working, I could potentially deploy a solution for already existing binaries in the field.

Vineet Singh
  • 4,009
  • 1
  • 28
  • 39
jimw
  • 121
  • 3
  • 6
    just don't compile and link them into the AU/VST in the first place -- set up multiple targets instead. – justin Mar 05 '13 at 06:51
  • 1
    I know I can do that, and in fact as mentioned I've already got it working via dynamically registering the class in question, which is nicer because it still allows compiling everything once and not having separate targets/binaries - the resulting binary can still be used as either an AU or VST (can't do that via the don't-compile-it-for-VST approach). I'm still curious if there's any way to strip the Obj-C binaries from existing binaries, as this would allow for a fix to existing in-the-field installs before my "better" fix is ready to ship. – jimw Mar 05 '13 at 11:16
  • Removing the symbols would not remove the class structures, so it probably wouldn't prevent the class from being loaded (I don't know how the runtime finds classes, but searching symbols would be harder than just looking at the section which is reserved for class information). You could try changing the name of the class in the binary, but would have to be careful that you don't affect anything else. I would agree with justin that compiling twice is the best choice, since it is easier than dynamic registration. – ughoavgfhw Mar 13 '13 at 19:46

2 Answers2

3

You can not just simply strip a class from a binary. What you can do however is to trick the Objective-C runtime into believing your plugin does not contain any Objective-C code. Just change __objc_imageinfo into __objc_imageinfX for example in your VST plugin binary. You can do it easily with perl:

perl -pi -e 's/__objc_imageinfo/__objc_imageinfX/g' <path to binary>

After patching the VST plugin, all the Objective-C initialization will be bypassed and you won’t see this error message: Class JuceDemoProjectAU is implemented in both …/VSTPlugin and …/AUPlugin. One of the two will be used. Which one is undefined.

Beware, you should really not use this trick! The appropriate solution to your problem is either to compile two different version of your plugin or to register classes dynamically as others suggested.

0xced
  • 25,219
  • 10
  • 103
  • 255
  • For some reason I was not able to get this too work, the Objective C symbols remain in the binary even after executing the command. Good idea though, in principle. – Perception Mar 20 '13 at 13:45
  • I forgot to mention this assumes 64-bit plugins. For 32-bit plugins, you might want to change `__image_info` into `__image_infX` instead. – 0xced Mar 20 '13 at 13:56
2

There was a thread about something similar to this on the coreaudio-list last year: Collision between Cocoa classes for AU and VST plugins.

The solution offered was to register the classes dynamically which is what you say you already have working. If there was a way to strip the symbols like you wanted, I'm sure these guys would have known about it.

iain
  • 5,660
  • 1
  • 30
  • 51