base-dirs: add support for finding modules and remove wp_get_module_dir()

This makes things more consistent and allows us also to add more
search paths in the future if necessary.

Also, stop using g_module_build_path() because it's deprecated and
build the path manually. This obviously is not portable to Windows/Mac
or other exotic platforms, but portability is not important at this
point. PipeWire is also not portable beyond Linux & BSD.
This commit is contained in:
George Kiagiadakis
2024-02-27 11:59:33 +02:00
parent c8feaad7a9
commit f76f45124e
5 changed files with 73 additions and 42 deletions

View File

@@ -15,18 +15,39 @@ WP_DEFINE_LOCAL_LOG_TOPIC ("wp-base-dirs")
* \defgroup wpbasedirs Base Directories File Lookup * \defgroup wpbasedirs Base Directories File Lookup
*/ */
/* Returns /basedir/subdir/filename, with filename treated as a module
* if WP_BASE_DIRS_FLAG_MODULE is set.
* The basedir is assumed to be either an absolute path or NULL.
* The subdir is assumed to be a path relative to basedir or NULL.
*/
static gchar * static gchar *
check_path (const gchar *basedir, const gchar *subdir, const gchar *filename) make_path (guint flags, const gchar *basedir, const gchar *subdir,
const gchar *filename)
{ {
g_autofree gchar *path = g_build_filename (basedir, g_autofree gchar *full_basedir = NULL;
subdir ? subdir : filename, g_autofree gchar *full_filename = NULL;
subdir ? filename : NULL,
NULL); /* merge subdir into basedir, if necessary */
g_autofree gchar *abspath = g_canonicalize_filename (path, NULL); if (subdir) {
wp_trace ("checking %s", abspath); full_basedir = g_canonicalize_filename (subdir, basedir);
if (g_file_test (abspath, G_FILE_TEST_IS_REGULAR)) basedir = full_basedir;
return g_steal_pointer (&abspath); }
return NULL;
if (flags & WP_BASE_DIRS_FLAG_MODULE) {
g_autofree gchar *basename = g_path_get_basename (filename);
g_autofree gchar *dirname = g_path_get_dirname (filename);
const gchar *prefix = "";
const gchar *suffix = "";
if (!g_str_has_prefix (basename, "lib"))
prefix = "lib";
if (!g_str_has_suffix (basename, ".so"))
suffix = ".so";
full_filename = g_strconcat (dirname, G_DIR_SEPARATOR_S,
prefix, basename, suffix, NULL);
filename = full_filename;
}
return g_canonicalize_filename (filename, basedir);
} }
static GPtrArray * static GPtrArray *
@@ -57,6 +78,13 @@ lookup_dirs (guint flags)
g_ptr_array_add (dirs, g_canonicalize_filename (env_dirs[i], NULL)); g_ptr_array_add (dirs, g_canonicalize_filename (env_dirs[i], NULL));
} }
} }
else if ((flags & WP_BASE_DIRS_ENV_MODULE) &&
(dir = g_getenv ("WIREPLUMBER_MODULE_DIR"))) {
g_auto (GStrv) env_dirs = g_strsplit (dir, G_SEARCHPATH_SEPARATOR_S, 0);
for (guint i = 0; env_dirs[i]; i++) {
g_ptr_array_add (dirs, g_canonicalize_filename (env_dirs[i], NULL));
}
}
else { else {
if (flags & WP_BASE_DIRS_XDG_CONFIG_HOME) { if (flags & WP_BASE_DIRS_XDG_CONFIG_HOME) {
dir = g_get_user_config_dir (); dir = g_get_user_config_dir ();
@@ -88,6 +116,10 @@ lookup_dirs (guint flags)
g_ptr_array_add (dirs, g_ptr_array_add (dirs,
g_canonicalize_filename(WIREPLUMBER_DEFAULT_DATA_DIR, NULL)); g_canonicalize_filename(WIREPLUMBER_DEFAULT_DATA_DIR, NULL));
} }
if (flags & WP_BASE_DIRS_PREFIX_LIB) {
g_ptr_array_add (dirs,
g_canonicalize_filename (WIREPLUMBER_DEFAULT_MODULE_DIR, NULL));
}
} }
return g_steal_pointer (&dirs); return g_steal_pointer (&dirs);
@@ -124,16 +156,23 @@ gchar *
wp_base_dirs_find_file (WpBaseDirsFlags flags, const gchar * subdir, wp_base_dirs_find_file (WpBaseDirsFlags flags, const gchar * subdir,
const gchar * filename) const gchar * filename)
{ {
g_autoptr(GPtrArray) dir_paths = lookup_dirs (flags); g_autoptr (GPtrArray) dir_paths = NULL;
if (g_path_is_absolute (filename)) if (g_path_is_absolute (filename)) {
return g_strdup (filename); g_autofree gchar *path = make_path (flags, NULL, NULL, filename);
wp_trace ("test file: %s", path);
if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
return g_steal_pointer (&path);
}
dir_paths = lookup_dirs (flags);
for (guint i = 0; i < dir_paths->len; i++) { for (guint i = 0; i < dir_paths->len; i++) {
gchar *path = check_path (g_ptr_array_index (dir_paths, i), g_autofree gchar *path = make_path (flags, g_ptr_array_index (dir_paths, i),
subdir, filename); subdir, filename);
if (path) wp_trace ("test file: %s", path);
return path; if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
return g_steal_pointer (&path);
} }
return NULL; return NULL;
@@ -288,8 +327,8 @@ wp_base_dirs_new_files_iterator (WpBaseDirsFlags flags,
continue; continue;
/* verify the file is regular and canonicalize the path */ /* verify the file is regular and canonicalize the path */
g_autofree gchar *path = check_path (dirpath, NULL, filename); g_autofree gchar *path = make_path (flags, dirpath, NULL, filename);
if (!path) if (!g_file_test (path, G_FILE_TEST_IS_REGULAR))
continue; continue;
/* remove item with the same filename from the global items array, /* remove item with the same filename from the global items array,

View File

@@ -21,6 +21,7 @@ G_BEGIN_DECLS
typedef enum { /*< flags >*/ typedef enum { /*< flags >*/
WP_BASE_DIRS_ENV_CONFIG = (1 << 0), /*!< $WIREPLUMBER_CONFIG_DIR */ WP_BASE_DIRS_ENV_CONFIG = (1 << 0), /*!< $WIREPLUMBER_CONFIG_DIR */
WP_BASE_DIRS_ENV_DATA = (1 << 1), /*!< $WIREPLUMBER_DATA_DIR */ WP_BASE_DIRS_ENV_DATA = (1 << 1), /*!< $WIREPLUMBER_DATA_DIR */
WP_BASE_DIRS_ENV_MODULE = (1 << 2), /*!< $WIREPLUMBER_MODULE_DIR */
WP_BASE_DIRS_XDG_CONFIG_HOME = (1 << 8), /*!< XDG_CONFIG_HOME/wireplumber */ WP_BASE_DIRS_XDG_CONFIG_HOME = (1 << 8), /*!< XDG_CONFIG_HOME/wireplumber */
WP_BASE_DIRS_XDG_DATA_HOME = (1 << 9), /*!< XDG_DATA_HOME/wireplumber */ WP_BASE_DIRS_XDG_DATA_HOME = (1 << 9), /*!< XDG_DATA_HOME/wireplumber */
@@ -30,6 +31,9 @@ typedef enum { /*< flags >*/
WP_BASE_DIRS_ETC = (1 << 16), /*!< ($prefix)/etc/wireplumber */ WP_BASE_DIRS_ETC = (1 << 16), /*!< ($prefix)/etc/wireplumber */
WP_BASE_DIRS_PREFIX_SHARE = (1 << 17), /*!< $prefix/share/wireplumber */ WP_BASE_DIRS_PREFIX_SHARE = (1 << 17), /*!< $prefix/share/wireplumber */
WP_BASE_DIRS_PREFIX_LIB = (1 << 18), /*!< $prefix/$libdir/wireplumber-$ABI_version */
WP_BASE_DIRS_FLAG_MODULE = (1 << 24), /*!< the file is a loadable module */
WP_BASE_DIRS_CONFIGURATION = WP_BASE_DIRS_CONFIGURATION =
WP_BASE_DIRS_ENV_CONFIG | WP_BASE_DIRS_ENV_CONFIG |
@@ -44,6 +48,11 @@ typedef enum { /*< flags >*/
WP_BASE_DIRS_XDG_DATA_HOME | WP_BASE_DIRS_XDG_DATA_HOME |
WP_BASE_DIRS_XDG_DATA_DIRS | WP_BASE_DIRS_XDG_DATA_DIRS |
WP_BASE_DIRS_PREFIX_SHARE, WP_BASE_DIRS_PREFIX_SHARE,
WP_BASE_DIRS_MODULE =
WP_BASE_DIRS_ENV_MODULE |
WP_BASE_DIRS_PREFIX_LIB |
WP_BASE_DIRS_FLAG_MODULE,
} WpBaseDirsFlags; } WpBaseDirsFlags;
WP_API WP_API

View File

@@ -698,10 +698,12 @@ load_module (WpCore * core, const gchar * module_name, WpSpaJson * args,
GModule *gmodule; GModule *gmodule;
gpointer module_init; gpointer module_init;
if (!g_file_test (module_name, G_FILE_TEST_EXISTS)) module_path = wp_base_dirs_find_file (WP_BASE_DIRS_MODULE, NULL, module_name);
module_path = g_module_build_path (wp_get_module_dir (), module_name); if (!module_path) {
else g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
module_path = g_strdup (module_name); "Failed to locate module %s", module_name);
return NULL;
}
wp_trace_object (core, "loading %s from %s", module_name, module_path); wp_trace_object (core, "loading %s from %s", module_name, module_path);

View File

@@ -77,20 +77,4 @@ wp_get_library_api_version (void)
return WIREPLUMBER_API_VERSION; return WIREPLUMBER_API_VERSION;
} }
/*!
* \brief Gets the WirePlumber module directory
* \returns WirePlumber's module directory
*/
const gchar *
wp_get_module_dir (void)
{
static const gchar *module_dir = NULL;
if (!module_dir) {
module_dir = g_getenv ("WIREPLUMBER_MODULE_DIR");
if (!module_dir)
module_dir = WIREPLUMBER_DEFAULT_MODULE_DIR;
}
return module_dir;
}
/*! \} */ /*! \} */

View File

@@ -76,9 +76,6 @@ const char * wp_get_library_version (void);
WP_API WP_API
const char * wp_get_library_api_version (void); const char * wp_get_library_api_version (void);
WP_API
const gchar * wp_get_module_dir (void);
G_END_DECLS G_END_DECLS
#endif #endif