mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
girepository: Move library path functions over from gitypelib.c
This means they’re implemented in the same file as the typelib search path, so it’s easier to refactor the code. This adds `gi_repository_get_library_path()` to expose the library path, both publicly and to internal users in `gitypelib.c`. And unit tests. Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This commit is contained in:
parent
846abed197
commit
5ef1c7e110
@ -77,6 +77,7 @@
|
||||
|
||||
static GIRepository *default_repository = NULL;
|
||||
static GPtrArray *typelib_search_path = NULL;
|
||||
static GPtrArray *library_paths = NULL; /* (element-type filename) (owned) */
|
||||
|
||||
typedef struct {
|
||||
size_t n_interfaces;
|
||||
@ -241,6 +242,9 @@ init_globals (void)
|
||||
g_ptr_array_add (typelib_search_path, g_steal_pointer (&typelib_dir));
|
||||
}
|
||||
|
||||
if (library_paths == NULL)
|
||||
library_paths = g_ptr_array_new_null_terminated (1, g_free, TRUE);
|
||||
|
||||
g_once_init_leave (&initialized, 1);
|
||||
}
|
||||
|
||||
@ -306,6 +310,67 @@ gi_repository_get_search_path (size_t *n_paths_out)
|
||||
return (const char * const *) typelib_search_path->pdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* gi_repository_prepend_library_path:
|
||||
* @directory: (type filename): a single directory to scan for shared libraries
|
||||
*
|
||||
* Prepends @directory to the search path that is used to
|
||||
* search shared libraries referenced by imported namespaces.
|
||||
*
|
||||
* Multiple calls to this function all contribute to the final
|
||||
* list of paths.
|
||||
*
|
||||
* The list of paths is unique and shared for all
|
||||
* [class@GIRepository.Repository] instances across the process, but it doesn’t
|
||||
* affect namespaces imported before the call.
|
||||
*
|
||||
* If the library is not found in the directories configured
|
||||
* in this way, loading will fall back to the system library
|
||||
* path (i.e. `LD_LIBRARY_PATH` and `DT_RPATH` in ELF systems).
|
||||
* See the documentation of your dynamic linker for full details.
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
void
|
||||
gi_repository_prepend_library_path (const char *directory)
|
||||
{
|
||||
init_globals ();
|
||||
g_ptr_array_insert (library_paths, 0, g_strdup (directory));
|
||||
}
|
||||
|
||||
/**
|
||||
* gi_repository_get_library_path:
|
||||
* @n_paths_out: (optional) (out): The number of library paths returned.
|
||||
*
|
||||
* Returns the current search path [class@GIRepository.Repository] will use when
|
||||
* loading shared libraries referenced by imported namespaces.
|
||||
*
|
||||
* The list is internal to [class@GIRepository.Repository] and should not be
|
||||
* freed, nor should its string elements.
|
||||
*
|
||||
* Returns: (element-type filename) (transfer none) (array length=n_paths_out): list of search paths, most
|
||||
* important first
|
||||
* Since: 2.80
|
||||
*/
|
||||
const char * const *
|
||||
gi_repository_get_library_path (size_t *n_paths_out)
|
||||
{
|
||||
if G_UNLIKELY (!library_paths || !library_paths->pdata)
|
||||
{
|
||||
static const char * const empty_search_path[] = {NULL};
|
||||
|
||||
if (n_paths_out)
|
||||
*n_paths_out = 0;
|
||||
|
||||
return empty_search_path;
|
||||
}
|
||||
|
||||
if (n_paths_out)
|
||||
*n_paths_out = library_paths->len;
|
||||
|
||||
return (const char * const *) library_paths->pdata;
|
||||
}
|
||||
|
||||
static char *
|
||||
build_typelib_key (const char *name, const char *source)
|
||||
{
|
||||
|
@ -91,6 +91,9 @@ void gi_repository_prepend_library_path (const char *directory);
|
||||
GI_AVAILABLE_IN_ALL
|
||||
const char * const * gi_repository_get_search_path (size_t *n_paths_out);
|
||||
|
||||
GI_AVAILABLE_IN_ALL
|
||||
const char * const *gi_repository_get_library_path (size_t *n_paths_out);
|
||||
|
||||
GI_AVAILABLE_IN_ALL
|
||||
const char * gi_repository_load_typelib (GIRepository *repository,
|
||||
GITypelib *typelib,
|
||||
|
@ -2213,36 +2213,6 @@ gi_typelib_error_quark (void)
|
||||
return quark;
|
||||
}
|
||||
|
||||
static GSList *library_paths;
|
||||
|
||||
/**
|
||||
* gi_repository_prepend_library_path:
|
||||
* @directory: (type filename): a single directory to scan for shared libraries
|
||||
*
|
||||
* Prepends @directory to the search path that is used to
|
||||
* search shared libraries referenced by imported namespaces.
|
||||
*
|
||||
* Multiple calls to this function all contribute to the final
|
||||
* list of paths.
|
||||
*
|
||||
* The list of paths is unique and shared for all
|
||||
* [class@GIRepository.Repository] instances across the process, but it doesn’t
|
||||
* affect namespaces imported before the call.
|
||||
*
|
||||
* If the library is not found in the directories configured
|
||||
* in this way, loading will fall back to the system library
|
||||
* path (i.e. `LD_LIBRARY_PATH` and `DT_RPATH` in ELF systems).
|
||||
* See the documentation of your dynamic linker for full details.
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
void
|
||||
gi_repository_prepend_library_path (const char *directory)
|
||||
{
|
||||
library_paths = g_slist_prepend (library_paths,
|
||||
g_strdup (directory));
|
||||
}
|
||||
|
||||
/* Note on the GModule flags used by this function:
|
||||
|
||||
* Glade's autoconnect feature and OpenGL's extension mechanism
|
||||
@ -2256,7 +2226,6 @@ gi_repository_prepend_library_path (const char *directory)
|
||||
static GModule *
|
||||
load_one_shared_library (const char *shlib)
|
||||
{
|
||||
GSList *p;
|
||||
GModule *m;
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -2272,9 +2241,11 @@ load_one_shared_library (const char *shlib)
|
||||
#endif
|
||||
{
|
||||
/* First try in configured library paths */
|
||||
for (p = library_paths; p; p = p->next)
|
||||
const char * const *library_paths = gi_repository_get_library_path (NULL);
|
||||
|
||||
for (unsigned int i = 0; library_paths[i] != NULL; i++)
|
||||
{
|
||||
char *path = g_build_filename (p->data, shlib, NULL);
|
||||
char *path = g_build_filename (library_paths[i], shlib, NULL);
|
||||
|
||||
m = g_module_open (path, G_MODULE_BIND_LAZY);
|
||||
|
||||
|
@ -99,6 +99,39 @@ test_repository_search_paths_prepend (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_repository_library_paths_default (void)
|
||||
{
|
||||
const char * const *library_paths;
|
||||
size_t n_library_paths;
|
||||
|
||||
library_paths = gi_repository_get_library_path (&n_library_paths);
|
||||
g_assert_nonnull (library_paths);
|
||||
g_assert_cmpuint (g_strv_length ((char **) library_paths), ==, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_repository_library_paths_prepend (void)
|
||||
{
|
||||
const char * const *library_paths;
|
||||
size_t n_library_paths;
|
||||
|
||||
gi_repository_prepend_library_path (g_test_get_dir (G_TEST_BUILT));
|
||||
library_paths = gi_repository_get_library_path (&n_library_paths);
|
||||
g_assert_nonnull (library_paths);
|
||||
g_assert_cmpuint (g_strv_length ((char **) library_paths), ==, 1);
|
||||
|
||||
g_assert_cmpstr (library_paths[0], ==, g_test_get_dir (G_TEST_BUILT));
|
||||
|
||||
gi_repository_prepend_library_path (g_test_get_dir (G_TEST_DIST));
|
||||
library_paths = gi_repository_get_library_path (&n_library_paths);
|
||||
g_assert_nonnull (library_paths);
|
||||
g_assert_cmpuint (g_strv_length ((char **) library_paths), ==, 2);
|
||||
|
||||
g_assert_cmpstr (library_paths[0], ==, g_test_get_dir (G_TEST_DIST));
|
||||
g_assert_cmpstr (library_paths[1], ==, g_test_get_dir (G_TEST_BUILT));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
@ -109,9 +142,11 @@ main (int argc,
|
||||
g_setenv ("GI_TYPELIB_PATH", g_get_tmp_dir (), TRUE);
|
||||
g_setenv ("GI_GIR_PATH", g_get_user_cache_dir (), TRUE);
|
||||
|
||||
g_test_add_func ("/repository-search-paths/unset", test_repository_search_paths_unset);
|
||||
g_test_add_func ("/repository-search-paths/default", test_repository_search_paths_default);
|
||||
g_test_add_func ("/repository-search-paths/prepend", test_repository_search_paths_prepend);
|
||||
g_test_add_func ("/repository/search-paths/unset", test_repository_search_paths_unset);
|
||||
g_test_add_func ("/repository/search-paths/default", test_repository_search_paths_default);
|
||||
g_test_add_func ("/repository/search-paths/prepend", test_repository_search_paths_prepend);
|
||||
g_test_add_func ("/repository/library-paths/default", test_repository_library_paths_default);
|
||||
g_test_add_func ("/repository/library-paths/prepend", test_repository_library_paths_prepend);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user