plugdata-team / plugdata

Pure Data as a plugin, with a new GUI
https://plugdata.org
GNU General Public License v3.0
1.54k stars 66 forks source link

Externals don't work in plugin (only in standalone) #34

Open FlachyJoe opened 2 years ago

FlachyJoe commented 2 years ago

Hi, I tried to add the purr-data external path to PlugData ( /opt/purr-data/lib/pd-l2ork/extra ) and C coded libraries fail to load. Adding [iemlib/init] : _undefined symbol sfloat [iem_ambi/ambi_decode] : _undefined symbol slist [lyonpotpourri/bv_play~] : _undefined symbol garrayclass

NB: These types are defined in Libraries/pure-data/src/m_pd.h

timothyschoen commented 2 years ago

Do these libraries load on vanilla pd? PlugData has the same core as pd-vanilla, it's possible that some externals for purr-data don't work because they use a different pd core.

FlachyJoe commented 2 years ago

They load in vanilla.

timothyschoen commented 2 years ago

Then they should load in PlugData, I'll check it out!

timothyschoen commented 2 years ago

This problem is caused by the fact that the externals are compiled without the PDINSTANCE and PDTHREAD flag, while PlugData needs to be compiled with those flags. I need to compile with PDINSTANCE because we need to be able to use multiple instances to make it work as a plugin. Camomile suffers from the same issue, there's unfortunately not much I can do about it.

I'll leave the issue open, so people can see that this doesn't work yet.

timothyschoen commented 2 years ago

Externals now work in the standalone! I'll have to do some more testing but it's looking good.

For the plugin, support for externals is still a problem because we need to have multiple instance support.

PS: For M1 Mac users: remember to use PlugData in Rosetta if you want support for x64 externals.

FlachyJoe commented 2 years ago

Hi, I still have the error in Standalone : Capture d’écran_2022-04-07_22-58-01

CMakeCache.txt

timothyschoen commented 2 years ago

Looks like I made a mistake in the cmakefile, I'll fix it right now.

timothyschoen commented 2 years ago
Screenshot 2022-04-07 at 23 20 48

Can reproduce that it doesn't work on linux

timothyschoen commented 2 years ago
Screenshot 2022-04-08 at 00 49 12

It works now! Turns out I needed to pass the -export-dynamic linker flag on Linux to get this kind of backwards linking to work.

timothyschoen commented 2 years ago

I don't know if you're building from source, but if you're not I'll create a release soon when I'm done with some other bug fixes!

timothyschoen commented 2 years ago

I see that windows has the same problem (unfortunately not with the same solution), so I'll look into that as well. My bad for assuming that it'd just work on all platforms, oops!

FlachyJoe commented 2 years ago

I confirm it works on linux. Thank you !

timothyschoen commented 2 years ago

I may have found a solution...

If we define PD_THIS with a function, get_this() which is defined in an .c file instead of a header, we can make any new externals that are compiled work both with and without PDINSTANCE.

I still need to investigate this further, but it would mean that externals only need to be recompiled against the new header in order to work, without having to change any source code at all. If it works, I hope the pd devs will accept this change. It would also mean that Camomile could start supporting this (also by just recompiling!).

Because the PD_THIS external in existing externals already points to the &pd_maininstance symbol (which still exists), it shouldn't break anything.

EDIT: Okay, so I think the only problem would be that newly built externals would stop working in old pd versions. So maybe this is not a perfect solution after all... It's an interesting discussion. It might be possible to add some kind of fallback mechanism for this.

EDIT 2: I've managed to make externals built with new the PDINSTANCE system work in an unmodified pd-vanilla! Basically, you can just add a backup definition for these functions into your external, since dlopen won't overwrite these when it finds a duplicate. This can be done automatically in m_pd.h.

alfonso73 commented 2 years ago

Edit 2 almost deserve a "wont fix" tag removal from the issue :-D Great stuff tho! Finger crossed

Leamucho commented 5 months ago

I may have found a solution...

If we define PD_THIS with a function, get_this() which is defined in an .c file instead of a header, we can make any new externals that are compiled work both with and without PDINSTANCE.

I still need to investigate this further, but it would mean that externals only need to be recompiled against the new header in order to work, without having to change any source code at all. If it works, I hope the pd devs will accept this change. It would also mean that Camomile could start supporting this (also by just recompiling!).

Because the PD_THIS external in existing externals already points to the &pd_maininstance symbol (which still exists), it shouldn't break anything.

EDIT: Okay, so I think the only problem would be that newly built externals would stop working in old pd versions. So maybe this is not a perfect solution after all... It's an interesting discussion. It might be possible to add some kind of fallback mechanism for this.

EDIT 2: I've managed to make externals built with new the PDINSTANCE system work in an unmodified pd-vanilla! Basically, you can just add a backup definition for these functions into your external, since dlopen won't overwrite these when it finds a duplicate. This can be done automatically in m_pd.h.

Hi, can you elaborate a little on where to find m_pd.h. ? And could you upload your .h file from your system?, as a reference off course, as I understand, it would need the specific externals I would install...

timothyschoen commented 5 months ago

The m_pd.h file I use should be identical to the one in the pure-data version that is reported in the console. If you want to be sure though, it should be located at Libraries/pure-data/src/m_pd.h, relative to plugdata's repo folder. Hope that helps!

mathiasbredholt commented 2 months ago

Hi, I tried compiling fftease against the modified header from here plugdata-pd#0.54-0

I tried both with and without adding -DPDINSTANCE to CFLAGS. Works in standalone but not in plugin. Still getting the same error. I'm on macOS Apple silicon.

Any pointers to what to try? Thanks!

plugdata/Externals/fftease/pvtuner~.pd_darwin, 0x000A): symbol not found in flat namespace '_class_domainsignalin'