mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
plugin: API: GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE
When a plugin declares a dependency using this flag, all the relative paths are considered to be relative to the path of the main executable. We try to determine the path of the executable portably, with implementations provided for Linux, Windows and Mac. If retrieval of the path fails, we will not detect changes. In order for the main executable path to be the same when scanning a plugin in a child process, a new variable is exposed in gst_private.h, _gst_executable_path https://bugzilla.gnome.org/show_bug.cgi?id=788152
This commit is contained in:
parent
0c614a0bd3
commit
6cddce7663
7 changed files with 100 additions and 8 deletions
64
gst/gst.c
64
gst/gst.c
|
@ -106,6 +106,10 @@
|
|||
#define WIN32_LEAN_AND_MEAN /* prevents from including too many things */
|
||||
#include <windows.h> /* GetStdHandle, windows console */
|
||||
#endif
|
||||
#if defined (__APPLE__)
|
||||
#include <errno.h>
|
||||
#include <libproc.h> /* proc_pidpath, PROC_PIDPATHINFO_MAXSIZE */
|
||||
#endif
|
||||
|
||||
#include "gst-i18n-lib.h"
|
||||
#include <locale.h> /* for LC_ALL */
|
||||
|
@ -133,6 +137,8 @@ extern gboolean _priv_gst_disable_registry;
|
|||
extern gboolean _priv_gst_disable_registry_update;
|
||||
#endif
|
||||
|
||||
gchar *_gst_executable_path = NULL;
|
||||
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
const gchar *priv_gst_dump_dot_dir;
|
||||
#endif
|
||||
|
@ -311,6 +317,56 @@ gst_init_get_option_group (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
static void
|
||||
find_executable_path (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *path;
|
||||
|
||||
if (_gst_executable_path)
|
||||
return;
|
||||
|
||||
path = g_file_read_link ("/proc/self/exe", &error);
|
||||
|
||||
if (path) {
|
||||
_gst_executable_path = g_path_get_dirname (path);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
#elif defined(G_OS_WIN32)
|
||||
static void
|
||||
find_executable_path (void)
|
||||
{
|
||||
char buffer[MAX_PATH];
|
||||
|
||||
if (!GetModuleFilename (NULL, buffer, MAX_PATH))
|
||||
return;
|
||||
|
||||
_gst_executable_path = g_strdup (buffer);
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
static void
|
||||
find_executable_path (void)
|
||||
{
|
||||
int ret;
|
||||
pid_t pid;
|
||||
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
|
||||
|
||||
pid = getpid ();
|
||||
ret = proc_pidpath (pid, pathbuf, sizeof (pathbuf));
|
||||
if (ret > 0)
|
||||
_gst_executable_path = g_strdup (pathbuf)
|
||||
}
|
||||
#else
|
||||
static void
|
||||
find_executable_path (void)
|
||||
{
|
||||
GST_FIXME ("Couldn't look up executable path, add support for this platform");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* gst_init_check:
|
||||
* @argc: (inout) (allow-none): pointer to application's argc
|
||||
|
@ -343,6 +399,9 @@ gst_init_check (int *argc, char **argv[], GError ** err)
|
|||
g_mutex_unlock (&init_lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
find_executable_path ();
|
||||
|
||||
#ifndef GST_DISABLE_OPTION_PARSING
|
||||
ctx = g_option_context_new ("- GStreamer initialization");
|
||||
g_option_context_set_ignore_unknown_options (ctx, TRUE);
|
||||
|
@ -1019,6 +1078,11 @@ gst_deinit (void)
|
|||
_priv_gst_plugin_paths = NULL;
|
||||
#endif
|
||||
|
||||
if (_gst_executable_path) {
|
||||
g_free (_gst_executable_path);
|
||||
_gst_executable_path = NULL;
|
||||
}
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
gst_object_unref (clock);
|
||||
gst_object_unref (clock);
|
||||
|
|
|
@ -229,6 +229,10 @@ GstCapsFeatures * __gst_caps_get_features_unchecked (const GstCaps * caps, guint
|
|||
GST_EXPORT gboolean _gst_disable_registry_cache;
|
||||
#endif
|
||||
|
||||
/* Secret variable to let the plugin scanner use the same base path
|
||||
* as the main application in order to determine dependencies */
|
||||
GST_EXPORT gchar *_gst_executable_path;
|
||||
|
||||
/* provide inline gst_g_value_get_foo_unchecked(), used in gststructure.c */
|
||||
#define DEFINE_INLINE_G_VALUE_GET_UNCHECKED(ret_type,name_type,v_field) \
|
||||
static inline ret_type \
|
||||
|
|
|
@ -1702,6 +1702,7 @@ static guint
|
|||
gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep)
|
||||
{
|
||||
gboolean paths_are_default_only;
|
||||
gboolean paths_are_relative_to_exe;
|
||||
GQueue scan_paths = G_QUEUE_INIT;
|
||||
guint scan_hash = 0;
|
||||
gchar *path;
|
||||
|
@ -1710,6 +1711,8 @@ gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep)
|
|||
|
||||
paths_are_default_only =
|
||||
dep->flags & GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY;
|
||||
paths_are_relative_to_exe =
|
||||
dep->flags & GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE;
|
||||
|
||||
gst_plugin_ext_dep_extract_env_vars_paths (plugin, dep, &scan_paths);
|
||||
|
||||
|
@ -1718,12 +1721,26 @@ gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep)
|
|||
|
||||
for (paths = dep->paths; paths != NULL && *paths != NULL; ++paths) {
|
||||
const gchar *path = *paths;
|
||||
gchar *full_path;
|
||||
|
||||
if (!g_queue_find_custom (&scan_paths, path, (GCompareFunc) strcmp)) {
|
||||
GST_LOG_OBJECT (plugin, "path: '%s'", path);
|
||||
g_queue_push_tail (&scan_paths, g_strdup (path));
|
||||
if (paths_are_relative_to_exe && !g_path_is_absolute (path)) {
|
||||
if (!_gst_executable_path) {
|
||||
GST_FIXME_OBJECT (plugin,
|
||||
"Path dependency %s relative to executable path but could not retrieve executable path",
|
||||
path);
|
||||
continue;
|
||||
}
|
||||
full_path = g_build_filename (_gst_executable_path, path, NULL);
|
||||
} else {
|
||||
GST_LOG_OBJECT (plugin, "path: '%s' (duplicate, ignoring)", path);
|
||||
full_path = g_strdup (path);
|
||||
}
|
||||
|
||||
if (!g_queue_find_custom (&scan_paths, full_path, (GCompareFunc) strcmp)) {
|
||||
GST_LOG_OBJECT (plugin, "path: '%s'", full_path);
|
||||
g_queue_push_tail (&scan_paths, full_path);
|
||||
} else {
|
||||
GST_LOG_OBJECT (plugin, "path: '%s' (duplicate, ignoring)", full_path);
|
||||
g_free (full_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,9 @@ typedef enum
|
|||
* @GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX : interpret
|
||||
* filename argument as filter prefix and check all matching files in
|
||||
* the directory. Since 1.8.
|
||||
* @GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE : interpret
|
||||
* non-absolute paths as relative to the main executable directory. Since
|
||||
* 1.14.
|
||||
*
|
||||
* Flags used in connection with gst_plugin_add_dependency().
|
||||
*/
|
||||
|
@ -106,7 +109,8 @@ typedef enum {
|
|||
GST_PLUGIN_DEPENDENCY_FLAG_RECURSE = (1 << 0),
|
||||
GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY = (1 << 1),
|
||||
GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX = (1 << 2),
|
||||
GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX = (1 << 3)
|
||||
GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX = (1 << 3),
|
||||
GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE = (1 << 4)
|
||||
} GstPluginDependencyFlags;
|
||||
|
||||
/**
|
||||
|
|
|
@ -408,7 +408,7 @@ gst_plugin_loader_use_usr_bin_arch (void)
|
|||
static gboolean
|
||||
gst_plugin_loader_try_helper (GstPluginLoader * loader, gchar * location)
|
||||
{
|
||||
char *argv[5] = { NULL, };
|
||||
char *argv[6] = { NULL, };
|
||||
int c = 0;
|
||||
|
||||
#if defined (__APPLE__) && defined (USR_BIN_ARCH_SWITCH)
|
||||
|
@ -419,9 +419,10 @@ gst_plugin_loader_try_helper (GstPluginLoader * loader, gchar * location)
|
|||
#endif
|
||||
argv[c++] = location;
|
||||
argv[c++] = (char *) "-l";
|
||||
argv[c++] = _gst_executable_path;
|
||||
argv[c++] = NULL;
|
||||
|
||||
if (c > 3) {
|
||||
if (c > 4) {
|
||||
GST_LOG ("Trying to spawn gst-plugin-scanner helper at %s with arch %s",
|
||||
location, argv[1]);
|
||||
} else {
|
||||
|
|
|
@ -38,7 +38,7 @@ main (int argc, char *argv[])
|
|||
char **my_argv;
|
||||
int my_argc;
|
||||
|
||||
if (argc != 2 || strcmp (argv[1], "-l"))
|
||||
if (argc != 3 || strcmp (argv[1], "-l"))
|
||||
return 1;
|
||||
|
||||
my_argc = 2;
|
||||
|
@ -50,6 +50,7 @@ main (int argc, char *argv[])
|
|||
_gst_disable_registry_cache = TRUE;
|
||||
#endif
|
||||
|
||||
_gst_executable_path = g_strdup (argv[2]);
|
||||
res = gst_init_check (&my_argc, &my_argv, NULL);
|
||||
|
||||
g_free (my_argv);
|
||||
|
|
|
@ -50,6 +50,7 @@ EXPORTS
|
|||
_gst_debug_nameof_funcptr
|
||||
_gst_debug_register_funcptr
|
||||
_gst_disable_registry_cache DATA
|
||||
_gst_executable_path DATA
|
||||
_gst_double_range_type DATA
|
||||
_gst_element_error_printf
|
||||
_gst_event_type DATA
|
||||
|
|
Loading…
Reference in a new issue