Differing Name Mangling Issues Creating Shared Object in Linux


#1

Hello,

I'm porting a server application we made originally in Windows using juce to Linux. It works as a dynamic lib that the server loads. I'm using cmake, not introjucer to manage my project because I need too many complex features to build other components that it would be hard to make it work using introjucer alone. We have modifications to juce that we maintain in our own git repo that I merge the official one into, but they're fairly minimal (and I'm willing to share them with Jules, but that's a separate issue).

So anyway, using introjucer on the juce introjucer project (builds/JUCE.introjucer), if I add a Linux Makefile, it just generates a static lib but I want a shared object (which is how I do it in Windows, dll). I manually edited the generated Makefile and added -fPIC to CFLAGS and -shared to the LDFLAGS. Changing the introjucer project to shared had no effect on the generated Makefile so I had to do this manually.

So when I load the dynamic lib, I get this:

undefined symbol: _ZThn232_N4juce19AudioProcessorGraph17handleAsyncUpdateEv

Other symbols it can find. Running nm on libJUCE.so, I see that it does have AudioProcessorGraph::handleAsyncUpdate in it:

_ZThn240_N4juce19AudioProcessorGraph17handleAsyncUpdateEv

The number in the name mangling is slightly different, 240 vs. 232. I don't know what that means, but if I use c++filt on these, they both look identical when unmangled:

non-virtual thunk to juce::AudioProcessorGraph::handleAsyncUpdate()

So if anyone is a guru at name mangling or compiling JUCE as a shared lib in Linux, it would help if they had any suggestions. I'm totally stuck.

-Thomas

 


#2

Please make sure that you are using the newest Introjucer and JUCE version from the git master branch. We have recently fixed an issue related to undefined symbols in shared libraries on Linux.

Also, the Introjucer should now correctly create a shared library instead of a static one.


#3

See http://www.juce.com/forum/topic/suggestion-use-wl-no-undefined-catch-missing-symbols-shared-libs

Maybe you're not building the juce files, or are building a different version than your app/dll is using.

I'd also check if the build visibility is the same for the shared lib and application that is loading it.
If you for example build juce as shared lib without debug + hidden symbols, but your app is debug you might get errors like those.

 

In any case, juce was not made to be used as shared library.
There are a few pieces of code that will fail to work if you used as it shared, File::currentExecutable comes to mind.

 


#4

That File::currentExecutable issue has been recently fixed and Juce should now work just fine as a shared library.


#5

This:
https://github.com/julianstorer/JUCE/blob/master/modules/juce_core/native/juce_posix_SharedCode.h#L585

Will not work on shared libraries.
The 'dladdr' function will return info about a function that is inside the shared library, which will be some random libjuce.so file, not the application calling it.

But you're right. On applications that method is not called, only on plugins.

What can fail here is when a plugin uses juce as a shared library, but that just seems wrong in the first place.

 


#6

Yes, you definitely want to avoid having audio plugin (= itself a shared library, typically installed in some system folder) depending on the presence of other shared libraries that need to be located somewhere else...


#7

I got the latest master from git, rebuilt Introjucer and still have the same problem. It just wants to generate a static lib.


#8

I've been using it as a dll in Windows for the past 4 years at least in this project. It looks like whatever doesn't work that way I'm not using (I'm not using currentExecutable). Since I have control over the environment it's being deployed in - my servers, not end-user's desktop - it's advantageous to not spend that extra time to statically link different things together when recompiling so I hope I don't have to go static to fix this problem.

I'm using the same version that I built. There's not another juce floating around on my system (I checked). I verified that the same version of the headers used to compile and to build are being used. I have also verified that both are debug and I've tried setting both to release.


#9

I fixed the problem by just completely ignoring introjuicer (except maybe to edit the AppConfig.h file). I think you have to commit to either using the introjucer or using something else. So using cmake to do everything (making my own cmake project for juce) fixed the problem and I'm able to dynamically or statically link it without the missing symbols.