mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
soup: Re-enable libsoup dlopen on macOS
Move from GModule to libdl for loading libraries on all platforms. This is necessary due to a macOS bug where dyld uses the incorrect @loader_path value for RPATH entries, and fails to find libsoup. More details here: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1171#note_2290789 Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3792 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7635>
This commit is contained in:
parent
fb6a5c8a0c
commit
7c3ee65d60
4 changed files with 121 additions and 107 deletions
|
@ -56,13 +56,19 @@ hls_dep = dependency('', required : false)
|
|||
adaptivedemux2_dep = dependency('', required : false)
|
||||
|
||||
adaptivedemux2_opt = get_option('adaptivedemux2')
|
||||
soup_opt = get_option('soup')
|
||||
soup_ver_opt = get_option('soup-version')
|
||||
if adaptivedemux2_opt.disabled()
|
||||
message('Not building adaptivedemux2 plugin because it was disabled')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if soup_lookup_dep and not libsoup3_dep.found() and not libsoup2_dep.found()
|
||||
if adaptivedemux2_opt.enabled()
|
||||
error(f'adaptivedemux2: Either libsoup2 or libsoup3 is needed')
|
||||
endif
|
||||
message(f'Not building adaptivedemux2: must link to either libsoup2 or libsoup3')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
adaptive_xml2_dep = dependency('libxml-2.0', version : '>= 2.8', allow_fallback: true, required: adaptivedemux2_opt)
|
||||
|
||||
if not adaptive_xml2_dep.found()
|
||||
|
@ -78,35 +84,6 @@ plugin_sources += hls_sources
|
|||
|
||||
libdl = cc.find_library('dl', required: false)
|
||||
soup_loader_args = ['-DBUILDING_ADAPTIVEDEMUX2']
|
||||
soup_link_args = []
|
||||
soup_link_deps = []
|
||||
|
||||
default_library = get_option('default_library')
|
||||
if host_system != 'linux' or default_library in ['static', 'both']
|
||||
if soup_ver_opt in ['auto', '3']
|
||||
libsoup3_dep = dependency('libsoup-3.0', allow_fallback: true,
|
||||
required: soup_ver_opt == '3' and soup_opt.enabled())
|
||||
endif
|
||||
if soup_ver_opt in ['auto', '2']
|
||||
libsoup2_dep = dependency('libsoup-2.4', version : '>=2.48', allow_fallback: true,
|
||||
default_options: ['sysprof=disabled'],
|
||||
required: soup_ver_opt == '2' and soup_opt.enabled())
|
||||
endif
|
||||
|
||||
if libsoup3_dep.found()
|
||||
soup_link_deps += [libsoup3_dep]
|
||||
soup_link_args = ['-DLINK_SOUP=3']
|
||||
elif libsoup2_dep.found()
|
||||
soup_link_deps += [libsoup2_dep]
|
||||
soup_link_args = ['-DLINK_SOUP=2']
|
||||
else
|
||||
if adaptivedemux2_opt.enabled()
|
||||
error(f'adaptivedemux2: Either libsoup2 or libsoup3 is needed')
|
||||
endif
|
||||
message(f'Not building adaptivedemux2 plugin: either libsoup2 or libsoup3 is needed')
|
||||
subdir_done()
|
||||
endif
|
||||
endif
|
||||
|
||||
# Shared plugin doesn't link to libsoup but dlopen()s it at runtime
|
||||
adaptive_kwargs = {
|
||||
|
@ -120,10 +97,11 @@ adaptive_deps = [gmodule_dep, gst_dep, gsttag_dep, gstnet_dep, gstbase_dep, gstp
|
|||
adaptive_args = [gst_plugins_good_args, soup_loader_args, hls_cargs,
|
||||
'-DGST_ISOFF_API=G_GNUC_INTERNAL']
|
||||
|
||||
if host_system != 'linux'
|
||||
if host_system == 'windows'
|
||||
assert(soup_linked_target)
|
||||
adaptivedemux2 = library('gstadaptivedemux2',
|
||||
c_args: [adaptive_args, soup_link_args],
|
||||
dependencies: [adaptive_deps, soup_link_deps],
|
||||
c_args: [adaptive_args, soup_linked_target_args],
|
||||
dependencies: [adaptive_deps, soup_linked_target_deps],
|
||||
kwargs: adaptive_kwargs)
|
||||
adaptivedemux2_static = adaptivedemux2
|
||||
adaptivedemux2_shared = adaptivedemux2
|
||||
|
@ -131,15 +109,15 @@ else
|
|||
if default_library in ['static', 'both']
|
||||
# Static plugin links to libsoup directly at build time
|
||||
adaptivedemux2_static = static_library('gstadaptivedemux2',
|
||||
c_args: [adaptive_args, soup_link_args],
|
||||
dependencies: [adaptive_deps, soup_link_deps],
|
||||
c_args: [adaptive_args, soup_linked_target_args],
|
||||
dependencies: [adaptive_deps, soup_linked_target_deps],
|
||||
kwargs: adaptive_kwargs)
|
||||
endif
|
||||
if default_library in ['shared', 'both']
|
||||
adaptivedemux2_shared = shared_library('gstadaptivedemux2',
|
||||
c_args: adaptive_args,
|
||||
dependencies: adaptive_deps,
|
||||
kwargs: adaptive_kwargs)
|
||||
kwargs: adaptive_kwargs + soup_dlopen_target_kwargs)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -1,3 +1,59 @@
|
|||
# We need libsoup for the soup plugin and for adaptivedemux2, and we can link
|
||||
# to either libsoup-2.4 or libsoup-3.0. There's a few cases here:
|
||||
#
|
||||
# 1. Windows, where we do not support dlopen()
|
||||
# 2. UNIX, and we build only a shared library
|
||||
# 3. UNIX, and we build only a static library
|
||||
# 4. UNIX, and we build both (static and shared)
|
||||
#
|
||||
# In cases 1,2,3: we look up the dependency
|
||||
# In case 1: we create one library() target that always links to libsoup
|
||||
# In cases 3,4: we create one static_library() target that links to libsoup
|
||||
# In cases 2,4: we create one shared_library() target that dlopen()s libsoup
|
||||
|
||||
libsoup2_dep = disabler()
|
||||
libsoup3_dep = disabler()
|
||||
soup_ver_opt = get_option('soup-version')
|
||||
|
||||
default_library = get_option('default_library')
|
||||
soup_linked_target = host_system == 'windows' or default_library != 'shared'
|
||||
soup_lookup_dep = get_option('soup-lookup-dep') or soup_linked_target
|
||||
if soup_ver_opt in ['auto', '3']
|
||||
libsoup3_dep = dependency('libsoup-3.0', allow_fallback: true,
|
||||
required: soup_ver_opt == '3' and soup_lookup_dep)
|
||||
endif
|
||||
if soup_ver_opt in ['auto', '2']
|
||||
libsoup2_dep = dependency('libsoup-2.4', version : '>=2.48', allow_fallback: true,
|
||||
default_options: ['sysprof=disabled'],
|
||||
required: soup_ver_opt == '2' and soup_lookup_dep)
|
||||
endif
|
||||
|
||||
if soup_linked_target
|
||||
if libsoup3_dep.found()
|
||||
soup_linked_target_deps = [libsoup3_dep]
|
||||
soup_linked_target_args = ['-DLINK_SOUP=3']
|
||||
message('soup and adaptivedemux2 plugins: linking to libsoup-3.0')
|
||||
elif libsoup2_dep.found()
|
||||
soup_linked_target_deps = [libsoup2_dep]
|
||||
soup_linked_target_args = ['-DLINK_SOUP=2']
|
||||
message('soup and adaptivedemux2 plugins: linking to libsoup-2.4')
|
||||
endif
|
||||
endif
|
||||
|
||||
# Hack to set the right RPATH for making dlopen() work inside the devenv on
|
||||
# macOS when using libsoup as a subproject.
|
||||
soup_dlopen_target_kwargs = {}
|
||||
if host_system == 'darwin'
|
||||
foreach dep : [libsoup3_dep, libsoup2_dep]
|
||||
if dep.found() and dep.type_name() == 'internal'
|
||||
soup_dlopen_target_kwargs += {
|
||||
'build_rpath': '@loader_path/../../../libsoup-' + dep.version() / 'libsoup',
|
||||
}
|
||||
break
|
||||
endif
|
||||
endforeach
|
||||
endif
|
||||
|
||||
subdir('aalib')
|
||||
subdir('adaptivedemux2')
|
||||
subdir('amrnb')
|
||||
|
|
|
@ -34,26 +34,36 @@ GST_DEBUG_CATEGORY (gst_soup_debug);
|
|||
|
||||
#ifndef LINK_SOUP
|
||||
|
||||
#if defined(__APPLE__) || defined(G_OS_WIN32)
|
||||
#error "dlopen of libsoup is only supported on Linux"
|
||||
#if !defined(G_OS_UNIX)
|
||||
#error "dlopen of libsoup is only supported on UNIX"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define LIBSOUP_3_SONAME "libsoup-3.0.0.dylib"
|
||||
#define LIBSOUP_2_SONAME "libsoup-2.4.1.dylib"
|
||||
#else
|
||||
#define LIBSOUP_3_SONAME "libsoup-3.0.so.0"
|
||||
#define LIBSOUP_2_SONAME "libsoup-2.4.so.1"
|
||||
#endif
|
||||
|
||||
#define LOAD_SYMBOL(name) G_STMT_START { \
|
||||
if (!g_module_symbol (module, G_STRINGIFY (name), (gpointer *) &G_PASTE (vtable->_, name))) { \
|
||||
GST_ERROR ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), g_module_name (module), g_module_error()); \
|
||||
gpointer sym = NULL; \
|
||||
if (!(sym = dlsym (handle, G_STRINGIFY (name)))) { \
|
||||
GST_ERROR ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), \
|
||||
libsoup_sonames[i], dlerror()); \
|
||||
goto error; \
|
||||
} \
|
||||
G_PASTE (vtable->_, name) = sym; \
|
||||
} G_STMT_END;
|
||||
|
||||
#define LOAD_VERSIONED_SYMBOL(version, name) G_STMT_START { \
|
||||
if (!g_module_symbol(module, G_STRINGIFY(name), (gpointer *)&G_PASTE(vtable->_, G_PASTE(name, G_PASTE(_, version))))) { \
|
||||
gpointer sym = NULL; \
|
||||
if (!(sym = dlsym(handle, G_STRINGIFY(name)))) { \
|
||||
GST_WARNING ("Failed to load '%s' from %s, %s", G_STRINGIFY(name), \
|
||||
g_module_name(module), g_module_error()); \
|
||||
libsoup_sonames[i], dlerror()); \
|
||||
goto error; \
|
||||
} \
|
||||
G_PASTE(vtable->_, G_PASTE(name, G_PASTE(_, version))) = sym; \
|
||||
} G_STMT_END;
|
||||
|
||||
typedef struct _GstSoupVTable
|
||||
|
@ -136,19 +146,18 @@ typedef struct _GstSoupVTable
|
|||
|
||||
static GstSoupVTable gst_soup_vtable = { 0, };
|
||||
|
||||
#define SOUP_NAMES 2
|
||||
|
||||
gboolean
|
||||
gst_soup_load_library (void)
|
||||
{
|
||||
GModule *module;
|
||||
GstSoupVTable *vtable;
|
||||
const gchar *libsoup_sonames[5] = { 0 };
|
||||
guint len = 0;
|
||||
const char *libsoup_sonames[SOUP_NAMES + 1] = { 0 };
|
||||
gpointer handle = NULL;
|
||||
|
||||
if (gst_soup_vtable.loaded)
|
||||
return TRUE;
|
||||
|
||||
g_assert (g_module_supported ());
|
||||
|
||||
#ifdef BUILDING_ADAPTIVEDEMUX2
|
||||
GST_DEBUG_CATEGORY_INIT (gst_adaptivedemux_soup_debug, "adaptivedemux2-soup",
|
||||
0, "adaptivedemux2-soup");
|
||||
|
@ -158,8 +167,6 @@ gst_soup_load_library (void)
|
|||
|
||||
#ifdef HAVE_RTLD_NOLOAD
|
||||
{
|
||||
gpointer handle = NULL;
|
||||
|
||||
/* In order to avoid causing conflicts we detect if libsoup 2 or 3 is loaded already.
|
||||
* If so use that. Otherwise we will try to load our own version to use preferring 3. */
|
||||
|
||||
|
@ -183,14 +190,12 @@ gst_soup_load_library (void)
|
|||
#endif /* HAVE_RTLD_NOLOAD */
|
||||
|
||||
vtable = &gst_soup_vtable;
|
||||
len = g_strv_length ((gchar **) libsoup_sonames);
|
||||
|
||||
for (guint i = 0; i < len; i++) {
|
||||
module =
|
||||
g_module_open (libsoup_sonames[i],
|
||||
G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
if (module) {
|
||||
GST_DEBUG ("Loaded %s", g_module_name (module));
|
||||
for (guint i = 0; i < SOUP_NAMES; i++) {
|
||||
if (!handle)
|
||||
handle = dlopen (libsoup_sonames[i], RTLD_NOW | RTLD_GLOBAL);
|
||||
if (handle) {
|
||||
GST_DEBUG ("Loaded %s", libsoup_sonames[i]);
|
||||
if (g_strstr_len (libsoup_sonames[i], -1, "soup-2")) {
|
||||
vtable->lib_version = 2;
|
||||
LOAD_VERSIONED_SYMBOL (2, soup_logger_new);
|
||||
|
@ -251,7 +256,7 @@ gst_soup_load_library (void)
|
|||
|
||||
error:
|
||||
GST_DEBUG ("Failed to find all libsoup symbols");
|
||||
g_clear_pointer (&module, g_module_close);
|
||||
g_clear_pointer (&handle, dlclose);
|
||||
continue;
|
||||
} else {
|
||||
GST_DEBUG ("Module %s not found", libsoup_sonames[i]);
|
||||
|
|
|
@ -13,43 +13,16 @@ if soup_opt.disabled()
|
|||
subdir_done()
|
||||
endif
|
||||
|
||||
libdl_dep = cc.find_library('dl', required: false)
|
||||
|
||||
soup_link_args = []
|
||||
soup_link_deps = []
|
||||
libsoup2_dep = disabler()
|
||||
libsoup3_dep = disabler()
|
||||
default_library = get_option('default_library')
|
||||
soup_lookup_dep = get_option('soup-lookup-dep') and host_system == 'linux'
|
||||
if host_system != 'linux' or default_library in ['static', 'both'] or soup_lookup_dep
|
||||
if soup_ver_opt in ['auto', '3']
|
||||
libsoup3_dep = dependency('libsoup-3.0', allow_fallback: true,
|
||||
required: soup_ver_opt == '3' and soup_opt.enabled())
|
||||
endif
|
||||
if soup_ver_opt in ['auto', '2']
|
||||
libsoup2_dep = dependency('libsoup-2.4', version : '>=2.48', allow_fallback: true,
|
||||
default_options: ['sysprof=disabled'],
|
||||
required: soup_ver_opt == '2' and soup_opt.enabled())
|
||||
endif
|
||||
endif
|
||||
|
||||
if host_system != 'linux' or default_library in ['static', 'both']
|
||||
if libsoup3_dep.found()
|
||||
soup_link_deps += libsoup3_dep
|
||||
soup_link_args += '-DLINK_SOUP=3'
|
||||
message('soup plugin: linking to libsoup-3.0')
|
||||
elif libsoup2_dep.found()
|
||||
soup_link_deps += libsoup2_dep
|
||||
soup_link_args += '-DLINK_SOUP=2'
|
||||
message('soup plugin: linking to libsoup-2.4')
|
||||
else
|
||||
if soup_lookup_dep and not libsoup3_dep.found() and not libsoup2_dep.found()
|
||||
if soup_opt.enabled()
|
||||
error('Either libsoup2 or libsoup3 is needed')
|
||||
error(f'soup: Either libsoup2 or libsoup3 is needed')
|
||||
endif
|
||||
message(f'Not building soup plugin: must link to either libsoup2 or libsoup3')
|
||||
subdir_done()
|
||||
endif
|
||||
endif
|
||||
|
||||
libdl_dep = cc.find_library('dl', required: false)
|
||||
|
||||
soup_library_kwargs = {
|
||||
'sources' : soup_sources,
|
||||
'link_args' : noseh_link_args,
|
||||
|
@ -60,19 +33,21 @@ soup_library_kwargs = {
|
|||
soup_library_deps = [gst_dep, gstbase_dep, gsttag_dep, gmodule_dep, gio_dep, libdl_dep]
|
||||
soup_library_c_args = gst_plugins_good_args
|
||||
|
||||
if host_system != 'linux'
|
||||
if host_system == 'windows'
|
||||
assert(soup_linked_target)
|
||||
gstsouphttpsrc = library('gstsoup',
|
||||
c_args : soup_library_c_args + soup_link_args,
|
||||
dependencies : soup_library_deps + soup_link_deps,
|
||||
c_args : soup_library_c_args + soup_linked_target_args,
|
||||
dependencies : soup_library_deps + soup_linked_target_deps,
|
||||
kwargs: soup_library_kwargs,
|
||||
)
|
||||
gstsouphttpsrc_shared = gstsouphttpsrc
|
||||
gstsouphttpsrc_static = gstsouphttpsrc
|
||||
else
|
||||
if default_library in ['static', 'both']
|
||||
assert(soup_linked_target)
|
||||
gstsouphttpsrc_static = static_library('gstsoup',
|
||||
c_args : soup_library_c_args + soup_link_args,
|
||||
dependencies : soup_library_deps + soup_link_deps,
|
||||
c_args : soup_library_c_args + soup_linked_target_args,
|
||||
dependencies : soup_library_deps + soup_linked_target_deps,
|
||||
kwargs: soup_library_kwargs,
|
||||
)
|
||||
endif
|
||||
|
@ -80,7 +55,7 @@ else
|
|||
gstsouphttpsrc_shared = shared_library('gstsoup',
|
||||
c_args : soup_library_c_args,
|
||||
dependencies : soup_library_deps,
|
||||
kwargs: soup_library_kwargs,
|
||||
kwargs: soup_library_kwargs + soup_dlopen_target_kwargs,
|
||||
)
|
||||
endif
|
||||
endif
|
||||
|
|
Loading…
Reference in a new issue