[vlc-devel] [PATCH 2/2] configure: split dynamic plugins from dynamic loader

Alexandre Janniaux ajanni at videolabs.io
Thu Mar 5 19:25:26 CET 2020


As we can embed static and dynamic plugins at the same time, it makes
sense to build LibVLC-provided modules inside VLC but still allow
external out-of-tree plugins to be added later.

It allows extending LibVLC through the dynamic loader while keeping the
official binaries, which make sense on iOS and Android. Indeed, on those
platform, shared library are either limited (support since iOS 8/9 on
one side and limit to 128 shared objects including system libraries on
the other side until API 23 [1] thanks to patch [2]) or with a
non-negligeable performance cost.

It is also much better than providing a plugin interface in which you
merge all modules from LibVLC and force the use of the dynamic loader as
the current inheritance mechanism doesn't play nicely with such
construction, and current buildsystem for Android and iOS are conceived
for static builds.

[1] https://android.googlesource.com/platform/bionic/+/android-n-mr2-preview-1/android-changes-for-ndk-developers.md
[2] https://android.googlesource.com/platform/bionic/+/ba98d9237b0eabc1d8caf2600fd787b988645249%5E%21/
---
 configure.ac          | 17 +++++++++++++++++
 src/Makefile.am       |  3 +++
 src/libvlc-module.c   |  4 ++--
 src/modules/bank.c    | 10 +++++-----
 src/modules/cache.c   |  4 ++--
 src/modules/entry.c   |  8 ++++----
 src/modules/modules.h |  2 +-
 7 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/configure.ac b/configure.ac
index bc1874cb97..925772f87c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -869,11 +869,28 @@ AS_VAR_IF(with_libfuzzer, no, [], [
 ])
 AM_CONDITIONAL([HAVE_LIBFUZZER], [test "${with_libfuzzer}" != "no"])
 
+dnl
+dnl When building dynamic objects only, both the dynamic plugin and the
+dnl dynamic loader are built. When building static plugins, the dynamic
+dnl loader can be specifically enabled or not using --enable-dynamic-loader.
+dnl
 AS_IF([test "${enable_shared}" = "no"], [
   have_dynamic_objects=no
 ])
 AM_CONDITIONAL([HAVE_DYNAMIC_PLUGINS], [test "${have_dynamic_objects}" != "no"])
 
+AC_ARG_ENABLE([dynamic-loader],
+  AS_HELP_STRING([--enable-dynamic-loader],
+    [compile VLC with dynamic plugin loader, only makes sense for static build (default disabled for static build)]))
+
+have_dynamic_loader="no"
+AS_IF([test "${enable_dynamic_loader}" = "yes"], [have_dynamic_loader="yes"])
+AM_CONDITIONAL([HAVE_DYNAMIC_LOADER],
+  [test "${have_dynamic_loader}" = "yes" -o "${have_dynamic_objects}" = "yes"])
+
+AS_IF([test "${enable_shared}" != "no" -a "${enable_dynamic_loader}" = "no"], [
+  AC_MSG_ERROR([Dynamic loaders cannot be disabled when building dynamic plugins.])])
+
 AC_SUBST([LIBDL])
 
 AS_IF([test "${SYS}" != "mingw32"], [
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b4dfcb7dd..d19bd47d93 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -187,6 +187,9 @@ AM_CFLAGS = $(CFLAGS_libvlccore)
 if HAVE_DYNAMIC_PLUGINS
 AM_CPPFLAGS += -DHAVE_DYNAMIC_PLUGINS
 endif
+if HAVE_DYNAMIC_LOADER
+AM_CPPFLAGS += -DHAVE_DYNAMIC_LOADER
+endif
 if HAVE_DBUS
 AM_CPPFLAGS += -DHAVE_DBUS
 AM_CFLAGS += $(DBUS_CFLAGS)
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 1da7fa6e79..8f255a1766 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -2152,7 +2152,7 @@ vlc_module_begin ()
                VOD_SERVER_TEXT, VOD_SERVER_LONGTEXT)
 
     set_section( N_("Plugins" ), NULL )
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     add_bool( "plugins-cache", true, PLUGINS_CACHE_TEXT,
               PLUGINS_CACHE_LONGTEXT, true )
         change_volatile ()
@@ -2918,7 +2918,7 @@ vlc_module_begin ()
     add_obsolete_bool( "save-config" )
     add_bool( "reset-config", false, RESET_CONFIG_TEXT, "", false )
         change_volatile ()
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     add_bool( "reset-plugins-cache", false,
               RESET_PLUGINS_CACHE_TEXT, "", false )
         change_volatile ()
diff --git a/src/modules/bank.c b/src/modules/bank.c
index e8c956ebe6..7dbad48856 100644
--- a/src/modules/bank.c
+++ b/src/modules/bank.c
@@ -165,14 +165,14 @@ static vlc_plugin_t *module_InitStatic(vlc_plugin_cb entry)
     if (unlikely(lib == NULL))
         return NULL;
 
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     atomic_init(&lib->handle, 0);
     lib->unloadable = false;
 #endif
     return lib;
 }
 
-#if defined(__ELF__) || defined(__MACH__) || !HAVE_DYNAMIC_PLUGINS
+#if defined(__ELF__) || defined(__MACH__) || !HAVE_DYNAMIC_LOADER
 VLC_WEAK
 extern vlc_plugin_cb vlc_static_modules[];
 
@@ -192,7 +192,7 @@ static void module_InitStaticModules(void)
 static void module_InitStaticModules(void) { }
 #endif
 
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
 static const char *module_GetVersion(void *handle)
 {
     const char *(*get_api_version)(void);
@@ -629,7 +629,7 @@ void *module_Symbol(struct vlc_logger *log,
     (void) log; (void) plugin; (void) name;
     return NULL;
 }
-#endif /* HAVE_DYNAMIC_PLUGINS */
+#endif /* HAVE_DYNAMIC_LOADER */
 
 /**
  * Init bank
@@ -723,7 +723,7 @@ void module_LoadPlugins(vlc_object_t *obj)
     if (modules.usage == 1)
     {
         module_InitStaticModules ();
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
         msg_Dbg (obj, "searching plug-in modules");
         AllocateAllPlugins (obj);
 #endif
diff --git a/src/modules/cache.c b/src/modules/cache.c
index c1428bd9f5..8493a8c287 100644
--- a/src/modules/cache.c
+++ b/src/modules/cache.c
@@ -53,7 +53,7 @@
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
 /* Sub-version number
  * (only used to avoid breakage in dev version when cache structure changes) */
 #define CACHE_SUBVERSION_NUM 36
@@ -707,4 +707,4 @@ vlc_plugin_t *vlc_cache_lookup(vlc_plugin_t **cache, const char *path)
 
     return NULL;
 }
-#endif /* HAVE_DYNAMIC_PLUGINS */
+#endif /* HAVE_DYNAMIC_LOADER */
diff --git a/src/modules/entry.c b/src/modules/entry.c
index 70f9a8c932..a5eb36aee3 100644
--- a/src/modules/entry.c
+++ b/src/modules/entry.c
@@ -103,7 +103,7 @@ vlc_plugin_t *vlc_plugin_create(void)
     plugin->conf.size = 0;
     plugin->conf.count = 0;
     plugin->conf.booleans = 0;
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     plugin->abspath = NULL;
     plugin->unloadable = true;
     atomic_init(&plugin->handle, 0);
@@ -123,7 +123,7 @@ vlc_plugin_t *vlc_plugin_create(void)
 void vlc_plugin_destroy(vlc_plugin_t *plugin)
 {
     assert(plugin != NULL);
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     assert(!plugin->unloadable || atomic_load(&plugin->handle) == 0);
 #endif
 
@@ -131,7 +131,7 @@ void vlc_plugin_destroy(vlc_plugin_t *plugin)
         vlc_module_destroy(plugin->module);
 
     config_Free(plugin->conf.items, plugin->conf.size);
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     free(plugin->abspath);
     free(plugin->path);
 #endif
@@ -278,7 +278,7 @@ static int vlc_plugin_desc_cb(void *ctx, void *tgt, int propid, ...)
             break;
 
         case VLC_MODULE_NO_UNLOAD:
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
             plugin->unloadable = false;
 #endif
             break;
diff --git a/src/modules/modules.h b/src/modules/modules.h
index 264b40344c..5785ba544d 100644
--- a/src/modules/modules.h
+++ b/src/modules/modules.h
@@ -45,7 +45,7 @@ typedef struct vlc_plugin_t
         size_t booleans; /**< Number of booleal config items */
     } conf;
 
-#ifdef HAVE_DYNAMIC_PLUGINS
+#ifdef HAVE_DYNAMIC_LOADER
     bool unloadable; /**< Whether the plug-in can be unloaded safely */
     atomic_uintptr_t handle; /**< Run-time linker handle (or nul) */
     char *abspath; /**< Absolute path */
-- 
2.25.1



More information about the vlc-devel mailing list