I have a plugin configured to use a webview for UI. With the JUCE CMake tools, this looks like:
juce_add_plugin(MyPlugin
IS_SYNTH TRUE
NEEDS_MIDI_INPUT TRUE
NEEDS_WEB_BROWSER TRUE
NEEDS_CURL TRUE
# ...etc
)
On Linux, JUCE does the correct thing and launches the actual WebKit X window in a subprocess, with an especially elegant solution of dlopen’ing the original plugin shared library which does dlsym dynamic lookups of webkit symbols. The point of all this is to prevent symbol conflicts with the GUI library the host might be using, especially hosts that use GTK2.
But. It turns out the plugin still directly links against these libraries! This defeats most of the point of doing the above subprocess technique:
$ readelf -d MyPlugin_artefacts/RelWithDebInfo/VST3/MyPlugin.vst3/Contents/x86_64-linux/MyPlugin.so | grep 'NEEDED'
0x0000000000000001 (NEEDED) Shared library: [libcurl.so.4]
0x0000000000000001 (NEEDED) Shared library: [libwebkit2gtk-4.1.so.0]
0x0000000000000001 (NEEDED) Shared library: [libharfbuzz.so.0]
0x0000000000000001 (NEEDED) Shared library: [libpangocairo-1.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libpango-1.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libsoup-3.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgmodule-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libjavascriptcoregtk-4.1.so.0]
0x0000000000000001 (NEEDED) Shared library: [libglib-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgobject-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgtk-3.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgdk-3.so.0]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libatk-1.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libcairo.so.2]
0x0000000000000001 (NEEDED) Shared library: [libcairo-gobject.so.2]
0x0000000000000001 (NEEDED) Shared library: [libgdk_pixbuf-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgio-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libblas.so.3]
0x0000000000000001 (NEEDED) Shared library: [liblapack.so.3]
0x0000000000000001 (NEEDED) Shared library: [libarpack.so.2]
0x0000000000000001 (NEEDED) Shared library: [libfontconfig.so.1]
0x0000000000000001 (NEEDED) Shared library: [libfreetype.so.6]
0x0000000000000001 (NEEDED) Shared library: [libasound.so.2]
0x0000000000000001 (NEEDED) Shared library: [libatomic.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
The root cause of this is that the CMake helper is propagating pkgconfig’s specified link libraries, which is normally what is wanted but in this case, again, defeats the point of the dlsym dynamic symbol lookups JUCE goes to so much trouble to do.
The following quick and dirty experiment skips adding the LINK_LIBRARIES for the browser (yes, this can be improved - goal is just to demonstrate the root of the problem):
diff --git a/extras/Build/CMake/JUCEModuleSupport.cmake b/extras/Build/CMake/JUCEModuleSupport.cmake
index cac20db12..82234c802 100644
--- a/extras/Build/CMake/JUCEModuleSupport.cmake
+++ b/extras/Build/CMake/JUCEModuleSupport.cmake
@@ -381,7 +381,10 @@ function(_juce_create_pkgconfig_target name)
list(GET pair 1 value)
if(${name}_${value})
- set_target_properties(pkgconfig_${name} PROPERTIES INTERFACE_${key} "${${name}_${value}}")
+ if(NOT (name STREQUAL JUCE_BROWSER_LINUX_DEPS AND key STREQUAL LINK_LIBRARIES))
+ set_target_properties(pkgconfig_${name} PROPERTIES INTERFACE_${key} "${${name}_${value}}")
+ endif()
endif()
endforeach()
endfunction()
which makes the linked libraries look much nicer (and the web UI continues to work):
$ readelf -d MyPlugin_artefacts/RelWithDebInfo/VST3/MyPlugin.vst3/Contents/x86_64-linux/MyPlugin.so | grep 'NEEDED'
0x0000000000000001 (NEEDED) Shared library: [libcurl.so.4]
0x0000000000000001 (NEEDED) Shared library: [libblas.so.3]
0x0000000000000001 (NEEDED) Shared library: [liblapack.so.3]
0x0000000000000001 (NEEDED) Shared library: [libarpack.so.2]
0x0000000000000001 (NEEDED) Shared library: [libfontconfig.so.1]
0x0000000000000001 (NEEDED) Shared library: [libfreetype.so.6]
0x0000000000000001 (NEEDED) Shared library: [libasound.so.2]
0x0000000000000001 (NEEDED) Shared library: [libatomic.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
I consider this behavior a bug; is the direct linking intended? Is there something I am missing? Or can this be fixed? Thanks!
