Polymorphic plugin build gone in Juce 4.2

That was me that deleted my own post i was just saying thanks to you Timur for putting the time in to promptly fix this issue. However I think I accidentally replied to the forum not to your post and after deleting I tried to add exactly the same message as a reply to your post, but it wouldn’t let me complaining about my post being too similar to my previous post (which was pending deletion), so I tried to revert the deletion but it wouldn’t let me do that either so I gave up!

@onqel It would be interesting to know whether all these issues are now fixed for you. The newest JUCE tip on github features statically linked shared code (instead of the framework), smaller binary sizes, the new Projucer option to strip all symbols and various smaller fixes to the stuff that people reported over the last few days. Maybe you (and/or other people here) could now give JUCE 4.2 (from github) a try and let us know how it is doing out there in the field?

We can’t test the copy protection stuff here (we don’t even know what you are using there) so we have to rely on the community to test this particular aspect.

@timur I just tested with the new statically linked shared code and the third party protection software protected the plugin without any warning or errors, so far so good! Thanks :smiley:

I also checked and tried out the “Strip local symbols” option, instead of doing it in a post-build script, and it didn’t remove any symbols (I have only tried the AU target, but it shouldn’t matter I guess)… Usually you need to disable “Deployment Postprocessing” in order for the symbols to be completely removed, and it did the job here after disabling it :wink:

@onqel About the “Strip local symbols” option: it’s odd, because normally it is exactly the other way around: the symbols are stripped if you enable “Deployment Postprocessing” (which is exactly what the Projucer is doing if the option is ticked), not disable it. See for example here and in other threads as well. So for us here it works out of the box.

Try this: open the audio plugin demo in Projucer, tick the “strip symbols” option for the Xcode Release config, re-save, open in Xcode, compile the AU target for Release, go to the folder where Xcode put the binary (by default ~/Library/Audio/Plug-Ins/Components/), then cd into the bundle to get to the actual binary (cd JuceDemoPlugin.component/Contents/MacOS/) and then do nm JuceDemoPlugin to see all symbols. On my machine (and on Fabian’s), the output of this is as below. As you see, the only symbols are unimplemented (U) Apple and POSIX symbols (required to link dynamically to the OS X runtime stuff) and the AU entry points (required so that the host can load the AU). There are no JUCE symbols and no symbols from the plug-in code.

Please let us know if it’s any different for you, but as far as I can tell everything works perfectly.

out.txt (17.3 KB)

You are correct, it works with JuceDemoPlugin :slight_smile:

It appears I had the strip style and deployment post processing flags etc already set in the Projucer custom Xcode flags, so when I turned off stripping in Projucer it actually resaved everything being enabled again, I really managed to confuse myself with this, case solved… I’m sorry for wasting your time, I will check stuff like this with the demo plugin in the future :stuck_out_tongue:

In my experience the only way to absolutely get rid of all unwanted symbols is to use the -exported_symbols_list argument which is easily done in Xcode by setting the EXPORTED_SYMBOLS_FILE build setting.

I wonder if there is any mileage in having the Projucer automatically do this for us? It would have to generate an exported symbol files for each of the formats and set this value to each corresponding file for each of the targets.

At the moment I dynamically generate the file in the pre-build step, I read the AppConfig.h header file to determine which formats are being built and therefore what symbols to export. (I also have to read it to figure out the symbols for AU). This I guess is easier now because I can read the WRAPPER_EXTENSION value to determine which one is building BUT because I can only set one value for EXPORTED_SYMBOLS_FILE (i.e. I can’t have a different file for each format) and because the formats build in parallel I will get race conditions when generating this file (i.e. the file will be the result of the last one to begin regardless of the fact that the linker stage has not yet been run)

The file has to be in the pre-build step because it’s required by the linker and it can not contain symbols that do not exist in the binary being linked.

Come to think of it maybe I could use the WRAPPER_EXTENSION build setting in the name of the file so the name differs for each target. However potentially it might be a nice thing to add to the projucer?

So, I have finally updated a plug-in project from JUCE 3.1.1 to 4.2.2

I didn’t use Introjucer/Projucer for it and don’t intend to use it in the future.
Of course, my project used the polymorphic approach that was in use with JUCE 3, and I am happy to state that it still builds fine with JUCE 4.2.2.

This answers a question I have previously made, that didn’t get an answer:
Q: Is the polymorphic build not supported in Xcode in the sense that it won’t build anymore, or is it only a Projucer limitation due to how it will emit a project for supporting AUv3?
A: I am glad to see that it is the latter, and that an existing project that built polymorphically, still does that. (And it actually makes sense, because on Windows the same code still builds polymorphically without issues).

Now my question: because currently plug-in projects generated with Projucer have separate targets on Mac but a polymorphic single target on Windows, which is the route that I should follow for my just updated projects?

a) Leave it as it is now (polymorphic both on Mac and Win) until something breaks

b) Update it so that it reflects the current structure of plug-in projects (separate targets on Mac, polymorphic on Win)

c) Update it all the way to the intended future situation of juce plug-ins (separate targets both for Mac and Windows)

I’m especially interested in the opinion of the JUCE team on this (perhaps @timur or @jules)

1 Like

Some time ago there was a fix to avoid Objective-C namespace clashes in polymorhic plugins (e.g. simultaneously using AU and VST of the same plugin lead to strange behavior). I think some kind of name prefix was used but I didn’t dig very deep into what really was done so this explanation might be highly inaccurate.

It’d be good to know whether this fix (which isn’t needed anymore as Projucer doesn’t support polymorphic plugins) is still active or has been removed.

We would really like to add a standalone plug-in format to all platforms - and for this polymorphic builds won’t work. All the code is already there, we just need to update the project exporters. So you should prepare for multi-target builds in the future.

This fix is still active. We create almost all objective-C classes at runtime and add random characters at the end to avoid clashes. This is necessary regardless if it is a polymorphic build or not - imagine a DAW loads two different plug-ins both created with JUCE but different JUCE versions. If we used the same objective C class names there would be … well… horrible… horrible things would happen :-).

I would like to request that for developers who are not using the standalone plug-in format that existing polymorphic builds will still work. I plan on staying polymorphic for as long as I can.

2 Likes