Skip to content

Instantly share code, notes, and snippets.

@x42
Created December 8, 2022 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x42/3bdae519d5c2b11f004ee184666ff03e to your computer and use it in GitHub Desktop.
Save x42/3bdae519d5c2b11f004ee184666ff03e to your computer and use it in GitHub Desktop.

Recommendations for Linux Plugin Vendors

Plugins should not rely on external (system-wide) resources, and must be statically linked (except for libc, libX11, and lib/server interfaces).

First of all, one cannot reply that a given compatible shared library is present on the target system. But the real issue however are ABI conflicts:

Say you have one plugin linking against system-wide libaubio.so.2 and another plugin using libaubio.so.3. Those libraries have conflicting APIs and many distros still package both for applications to use them. But when loading the plugins there will be a symbol conflict. Other real world examples include libavresample, QT4/Qt5 and libwebkit2gtk-3/4.

Loading one plugin will prevent loading another.

By induction this also include the host (which may use libraries), but the host is a singleton. To avoid ABI conflicts, the only option other than statically linking plugins is to process-separate plugins. But many hosts (incl. Ardour) do not do that: https://ardour.org/plugins-in-process.html

It is established procedure to statically link on macOS and Windows for the same reasons.


ldd  /path/to/the/plugin.so

A sane subset for a plugin to use is libpthread.so libm.so librt.so libstdc++.so libgcc_s.so libc.so for GUIs include libX11.so libGL.so libGLX.so those have a stable ABI.

Hint: use pkg-config --static to pull in dependent libraries, and explicitly use .a files to link against.

objdump -T /path/to/the/plugin.so

ideally only lists undefined dynamic symbol,s and the entry-point (e.g. ModuleEntry and ModuleExit for VST3).

Hints: to hide symbols, use

CFLAGS="-fvisibility=hidden -fdata-sections -ffunction-sections"
LDFLAGS="-Wl,--gc-sections -Wl,-O1 -Wl,--as-needed -Wl,--strip-all

then expose the entry point using __attribute__ ((visibility ("default"))), which corresponds to __declspec(dllexport) in the windows world.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment