Hallo Konrad,
vielen Dank für die Erklärungen. LD_DEBUG könnte ich mir mal angucken.
Das Problem besteht darin, dass Du bei VST keine Kontrolle über die
Plugin-Bibliotheken hast. Da geht es darum, dass Leute ihre proprietären
Plugins verkaufen, die in eine nicht näher zu benennende Software von
Steinberg eingeklinkt werden sollen. Die Schnittstelle wird vom SDK
bereitgestellt und darübr hinaus darf man keine Annahmen was sonst noch
verfügbar sein sollte (d.h. keine GUI usw). Das geht auch mit
Windows-DLLs ganz gut, unter *nix muss man wohl die libdl komplett
ersetzten.
Inzwischen ist man soweit, dass man auch GPL3-Plugins und GPL3-Hosts
zulässt.
Was JUCE angeht: Das ist ein Plattformübergreifendes GUI-Toolkit mit
komfortabler Audio- und MIDI-Integration und Schnittstellen zu den
üblichen Audio- und MIDI-Plugin-Systemen. Ein wichtiges Merkmal ist,
dass es normalerweise statisch gelinkt wird. Es gibt keine gepflegte
ABI. Es hat noch weitere Nachteile: Sprachunterstützung und Screenreader
sind relativ neu.
Ich mags nicht, aber ich komme nicht drum herum.
Und: Es gibt für mich keine Entscheidungsfreiheit bezüglich Plugins und
JUCE-Versionen. Wenn die JUCE-Version nicht stimmt, ist die ABI im Eimer
und ich muss es einfach hinnehmen.
Wie kriege ich raus, ob es am Plugin-Verbindungscode oder an der
Anwendung oder an inkompatible Bibliotheken liegt?
Viele Grüße
Tobias.
Am 12.02.22 um 18:51 schrieb Konrad Rosenbaum:
Hi,
vorweg: ich habe keine Ahnung was JUCE ist und welche Link-Anforderungen
es hat.
Fast immer sollte man so eine Situation vermeiden. Du hast keinerlei
Garantie dass es funktioniert.
Der Runtime-Linker macht ein paar Annahmen zu dem Zeug das er in den
Speicher lädt:
* Jede Bibliothek kommt nur einmal vor, der selbe Name kann auf die
selbe Datei abgebildet werden
* Niemand kommt auf die tollkühne Idee absichtlich zwei Versionen der
selben Bibliothek zu linken
* Unterschiedliche Module, die gelinkt werden, haben auch
unterschiedliche Symbole - wenn ich ein Symbol gefunden habe,
brauche ich nicht weiter zu suchen.
* Weak-Symbole zeigen auf identische Funktionalität und es ist egal
welche Instanz ich wohin verlinke.
Es gibt noch ein paar mehr Annahmen, aber in jedem Fall ist eine
Verletzung der Annahmen keine gute Idee und führt zu viel Ärger und
Kopfschmerz.
On 12/02/2022 18:14, Tobias Schlemmer wrote:
Ein VST-Plugin-Host wurde mit JUCE version A gebaut.
Ein VST-Plugin wurde mid JUCE version B gebaut.
Der VST-Plugin-Host verwendet ein shared object mit JUCE-Symbolen.
Das VST-Plugin ist ein shared object mit JUCE-Symbolen.
Wie kann ich herausfinden, ob der Host ausschließlich gegen seine
eigenen JUCE-Symbole gelinkt wird und ob das Plugin ausschließlich gegen
seine version gelinkt wird.
Host: Du müsstest den Host zwingen seine Symbole gleich beim Laden
aufzulösen und nach Möglichkeit die Symbole im Plugin verstecken
(visibility=hidden).
Plugin: du hast keine Garantie. Selbst wenn Du statisch linkst, mit
private linkage und visibility=hidden. Selbst interne Symbole werden
erst zur Laufzeit aufgelöst, weil der Linker vorher nicht weiß an
welcher Adresse eine Funktion landen wird. Symbole im Host zu verstecken
ist vermutlich keine gute Idee, wenn andere Plugins noch funktionieren
sollen. Selbst wenn das gehen sollte ist es keine Garantie dass die
versteckten Symbole wirklich auch nur lokal verlinkt werden.
Wenn das VST-SDK das unterstützt könnte ich gcc anweisen, das Plugin mit
visibility=hidden zu compilieren.
Beim Host ist mir das nicht so klar.
Außerdem möchte ich gern anhand der shared objects sehen, welche Symbole
exportiert werden. Das geht doch irgendwie mit objdump oder nm. Hat das
schonmal jemand gemacht? Wie geht das genau?
ldd zeigt Dir welche Bibliotheken gefunden werden und wo sie hingelegt
werden.
nm zeigt Dir welche Symbole exportiert und importiert werden, aber nicht
wo sie hergeholt werden.
objdump kann Dir relativ low-level alles anzeigen was an Export, Import,
Symboltabellen, Relocations etc. in einer Datei drin ist. Aber Du musst
selbst wissen was der Runtime-Linker damit anstellt.
Setze die Variable LD_DEBUG=all und starte Dein Programm - auf stderr
bekommst Du eine Liste aller Symbolauflösungen so wie sie live passieren.
Du wirst sehen dass Du eine Menge Möglichkeiten hast, aber bis Du diese
Möglichkeiten gelernt hast und rausgefunden hast wie Du den Linker dazu
bewegst Symbole umzubiegen, zu verstecken, hart zu binden, etc.pp. bist
Du wahrscheinlich wesentlich schneller und effektiver fertig wenn Du
einfach alles auf eine einheitliche Version von JUCE portierst und
identisch linkst.
Je nachdem was JUCE macht kann es auch unmöglich sein es stabil zu
machen: Qt zum Beispiel dreht komplett frei wenn man zwei Versionen der
Core-Bibliothek in den Speicher lädt.
Konrad