Skip to content
Snippets Groups Projects
Commit e58bf1fa authored by Ludovico de Nittis's avatar Ludovico de Nittis :palm_tree:
Browse files

Add support for library's hidden dependencies


Some libraries like "libtheoraenc.so.1" or "libCgGL.so" assumes that you
have already linked to other libraries.

With this commit we add support for those situations with the concept of
"hidden dependencies".

Signed-off-by: default avatarLudovico de Nittis <ludovico.denittis@collabora.com>
parent 921748b2
Branches
Tags
1 merge request!67Add support for library's hidden dependencies
Pipeline #1867 passed
Showing
with 335 additions and 22 deletions
...@@ -9,6 +9,7 @@ Build-Depends: ...@@ -9,6 +9,7 @@ Build-Depends:
gtk-doc-tools <!nodoc>, gtk-doc-tools <!nodoc>,
libglib2.0-dev, libglib2.0-dev,
libjson-glib-dev (>= 1.0), libjson-glib-dev (>= 1.0),
libtheora0 <!nocheck>,
libvulkan-dev, libvulkan-dev,
libxcb1-dev, libxcb1-dev,
locales <!nocheck> | locales-all <!nocheck>, locales <!nocheck> | locales-all <!nocheck>,
...@@ -88,6 +89,7 @@ Section: misc ...@@ -88,6 +89,7 @@ Section: misc
Depends: Depends:
${misc:Depends}, ${misc:Depends},
${shlibs:Depends}, ${shlibs:Depends},
libtheora0,
steam-runtime-tools-bin, steam-runtime-tools-bin,
zlib1g, zlib1g,
Description: Description:
......
...@@ -16,6 +16,7 @@ variables: ...@@ -16,6 +16,7 @@ variables:
libgles2-mesa-dev libgles2-mesa-dev
libglib2.0-dev libglib2.0-dev
libjson-glib-dev libjson-glib-dev
libtheora-dev
libx11-dev libx11-dev
libxcb1-dev libxcb1-dev
libxcomposite-dev libxcomposite-dev
......
...@@ -76,10 +76,12 @@ enum ...@@ -76,10 +76,12 @@ enum
{ {
OPTION_HELP = 1, OPTION_HELP = 1,
OPTION_DEB_SYMBOLS, OPTION_DEB_SYMBOLS,
OPTION_HIDDEN_DEPENDENCY,
}; };
struct option long_options[] = struct option long_options[] =
{ {
{ "hidden-dependency", required_argument, NULL, OPTION_HIDDEN_DEPENDENCY },
{ "deb-symbols", no_argument, NULL, OPTION_DEB_SYMBOLS }, { "deb-symbols", no_argument, NULL, OPTION_DEB_SYMBOLS },
{ "help", no_argument, NULL, OPTION_HELP }, { "help", no_argument, NULL, OPTION_HELP },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
...@@ -126,12 +128,17 @@ main (int argc, ...@@ -126,12 +128,17 @@ main (int argc,
ssize_t chars; ssize_t chars;
bool first; bool first;
bool deb_symbols = false; bool deb_symbols = false;
size_t dependency_counter = 0;
int opt; int opt;
while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1) while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1)
{ {
switch (opt) switch (opt)
{ {
case OPTION_HIDDEN_DEPENDENCY:
dependency_counter++;
break;
case OPTION_DEB_SYMBOLS: case OPTION_DEB_SYMBOLS:
deb_symbols = true; deb_symbols = true;
break; break;
...@@ -152,11 +159,47 @@ main (int argc, ...@@ -152,11 +159,47 @@ main (int argc,
usage (1); usage (1);
} }
const char *hidden_deps[dependency_counter + 1];
if (dependency_counter > 0)
{
/* Reset getopt */
optind = 1;
size_t i = 0;
while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1)
{
switch (opt)
{
case OPTION_HIDDEN_DEPENDENCY:
hidden_deps[i] = optarg;
i++;
break;
default:
break;
}
}
}
soname = argv[optind]; soname = argv[optind];
printf ("{\n"); printf ("{\n");
printf (" \""); printf (" \"");
print_json_string_content (soname); print_json_string_content (soname);
printf ("\": {"); printf ("\": {");
for (size_t i = 0; i < dependency_counter; i++)
{
/* We don't call "dlclose" on global hidden dependencies, otherwise ubsan
* will report an indirect memory leak */
if (dlopen (hidden_deps[i], RTLD_NOW|RTLD_GLOBAL) == NULL)
{
fprintf (stderr, "Unable to find the dependency library: %s\n", dlerror ());
clean_exit (handle);
return 1;
}
}
handle = dlopen (soname, RTLD_NOW); handle = dlopen (soname, RTLD_NOW);
if (handle == NULL) if (handle == NULL)
{ {
......
...@@ -89,5 +89,6 @@ SrtLibraryIssues _srt_check_library_presence (const char *helpers_path, ...@@ -89,5 +89,6 @@ SrtLibraryIssues _srt_check_library_presence (const char *helpers_path,
const char *soname, const char *soname,
const char *multiarch, const char *multiarch,
const char *symbols_path, const char *symbols_path,
const char * const *hidden_deps,
SrtLibrarySymbolsFormat symbols_format, SrtLibrarySymbolsFormat symbols_format,
SrtLibrary **more_details_out); SrtLibrary **more_details_out);
...@@ -474,8 +474,8 @@ srt_check_library_presence (const char *soname, ...@@ -474,8 +474,8 @@ srt_check_library_presence (const char *soname,
SrtLibrary **more_details_out) SrtLibrary **more_details_out)
{ {
return _srt_check_library_presence (NULL, soname, multiarch, return _srt_check_library_presence (NULL, soname, multiarch,
symbols_path, symbols_format, symbols_path, NULL,
more_details_out); symbols_format, more_details_out);
} }
SrtLibraryIssues SrtLibraryIssues
...@@ -483,17 +483,14 @@ _srt_check_library_presence (const char *helpers_path, ...@@ -483,17 +483,14 @@ _srt_check_library_presence (const char *helpers_path,
const char *soname, const char *soname,
const char *multiarch, const char *multiarch,
const char *symbols_path, const char *symbols_path,
const char * const *hidden_deps,
SrtLibrarySymbolsFormat symbols_format, SrtLibrarySymbolsFormat symbols_format,
SrtLibrary **more_details_out) SrtLibrary **more_details_out)
{ {
gchar *helper = NULL; GPtrArray *argv = NULL;
gchar *output = NULL; gchar *output = NULL;
gchar *child_stderr = NULL; gchar *child_stderr = NULL;
gchar *absolute_path = NULL; gchar *absolute_path = NULL;
const gchar *argv[] =
{
"inspect-library", "--deb-symbols", soname, symbols_path, NULL
};
int exit_status = -1; int exit_status = -1;
JsonParser *parser = NULL; JsonParser *parser = NULL;
JsonNode *node = NULL; JsonNode *node = NULL;
...@@ -509,6 +506,7 @@ _srt_check_library_presence (const char *helpers_path, ...@@ -509,6 +506,7 @@ _srt_check_library_presence (const char *helpers_path,
GStrv my_environ = NULL; GStrv my_environ = NULL;
const gchar *ld_preload; const gchar *ld_preload;
gchar *filtered_preload = NULL; gchar *filtered_preload = NULL;
argv = g_ptr_array_new_with_free_func (g_free);
g_return_val_if_fail (soname != NULL, SRT_LIBRARY_ISSUES_INTERNAL_ERROR); g_return_val_if_fail (soname != NULL, SRT_LIBRARY_ISSUES_INTERNAL_ERROR);
g_return_val_if_fail (multiarch != NULL, SRT_LIBRARY_ISSUES_INTERNAL_ERROR); g_return_val_if_fail (multiarch != NULL, SRT_LIBRARY_ISSUES_INTERNAL_ERROR);
...@@ -516,31 +514,40 @@ _srt_check_library_presence (const char *helpers_path, ...@@ -516,31 +514,40 @@ _srt_check_library_presence (const char *helpers_path,
SRT_LIBRARY_ISSUES_INTERNAL_ERROR); SRT_LIBRARY_ISSUES_INTERNAL_ERROR);
g_return_val_if_fail (_srt_check_not_setuid (), SRT_LIBRARY_ISSUES_INTERNAL_ERROR); g_return_val_if_fail (_srt_check_not_setuid (), SRT_LIBRARY_ISSUES_INTERNAL_ERROR);
if (helpers_path == NULL)
helpers_path = _srt_get_helpers_path ();
g_ptr_array_add (argv, g_strdup_printf ("%s/%s-inspect-library", helpers_path, multiarch));
g_debug ("Checking library %s integrity with %s", soname, (gchar *)g_ptr_array_index (argv, 0));
switch (symbols_format) switch (symbols_format)
{ {
case SRT_LIBRARY_SYMBOLS_FORMAT_PLAIN: case SRT_LIBRARY_SYMBOLS_FORMAT_PLAIN:
argv[1] = soname; g_ptr_array_add (argv, g_strdup (soname));
argv[2] = symbols_path; g_ptr_array_add (argv, g_strdup (symbols_path));
argv[3] = NULL;
break; break;
case SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS: case SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS:
/* do nothing, argv is already set up for this */ g_ptr_array_add (argv, g_strdup ("--deb-symbols"));
g_ptr_array_add (argv, g_strdup (soname));
g_ptr_array_add (argv, g_strdup (symbols_path));
break; break;
default: default:
g_return_val_if_reached (SRT_LIBRARY_ISSUES_CANNOT_LOAD); g_return_val_if_reached (SRT_LIBRARY_ISSUES_CANNOT_LOAD);
} }
if (symbols_path == NULL) for (gsize i = 0; hidden_deps != NULL && hidden_deps[i] != NULL; i++)
issues |= SRT_LIBRARY_ISSUES_UNKNOWN_EXPECTATIONS; {
g_ptr_array_add (argv, g_strdup ("--hidden-dependency"));
g_ptr_array_add (argv, g_strdup (hidden_deps[i]));
}
if (helpers_path == NULL) /* NULL terminate the array */
helpers_path = _srt_get_helpers_path (); g_ptr_array_add (argv, NULL);
helper = g_strdup_printf ("%s/%s-inspect-library", helpers_path, multiarch); if (symbols_path == NULL)
argv[0] = helper; issues |= SRT_LIBRARY_ISSUES_UNKNOWN_EXPECTATIONS;
g_debug ("Checking library %s integrity with %s", soname, helper);
my_environ = g_get_environ (); my_environ = g_get_environ ();
ld_preload = g_environ_getenv (my_environ, "LD_PRELOAD"); ld_preload = g_environ_getenv (my_environ, "LD_PRELOAD");
...@@ -551,7 +558,7 @@ _srt_check_library_presence (const char *helpers_path, ...@@ -551,7 +558,7 @@ _srt_check_library_presence (const char *helpers_path,
} }
if (!g_spawn_sync (NULL, /* working directory */ if (!g_spawn_sync (NULL, /* working directory */
(gchar **) argv, (gchar **) argv->pdata,
my_environ, /* envp */ my_environ, /* envp */
0, /* flags */ 0, /* flags */
NULL, /* child setup */ NULL, /* child setup */
...@@ -658,9 +665,9 @@ out: ...@@ -658,9 +665,9 @@ out:
g_strfreev (missing_symbols); g_strfreev (missing_symbols);
g_strfreev (misversioned_symbols); g_strfreev (misversioned_symbols);
g_strfreev (dependencies); g_strfreev (dependencies);
g_ptr_array_free (argv, TRUE);
g_free (absolute_path); g_free (absolute_path);
g_free (child_stderr); g_free (child_stderr);
g_free (helper);
g_free (output); g_free (output);
g_free (filtered_preload); g_free (filtered_preload);
g_clear_error (&error); g_clear_error (&error);
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <json-glib/json-glib.h>
/** /**
* SECTION:system-info * SECTION:system-info
...@@ -92,6 +93,7 @@ struct _SrtSystemInfo ...@@ -92,6 +93,7 @@ struct _SrtSystemInfo
/* Multiarch tuple to use for helper executables in cases where it /* Multiarch tuple to use for helper executables in cases where it
* shouldn't matter, or %NULL to use the compiled-in default */ * shouldn't matter, or %NULL to use the compiled-in default */
GQuark primary_multiarch_tuple; GQuark primary_multiarch_tuple;
GHashTable *cached_hidden_deps;
struct struct
{ {
/* GQuark => MaybeLocale */ /* GQuark => MaybeLocale */
...@@ -409,6 +411,8 @@ srt_system_info_finalize (GObject *object) ...@@ -409,6 +411,8 @@ srt_system_info_finalize (GObject *object)
g_free (self->expectations); g_free (self->expectations);
g_free (self->helpers_path); g_free (self->helpers_path);
g_strfreev (self->env); g_strfreev (self->env);
if (self->cached_hidden_deps)
g_hash_table_unref (self->cached_hidden_deps);
G_OBJECT_CLASS (srt_system_info_parent_class)->finalize (object); G_OBJECT_CLASS (srt_system_info_parent_class)->finalize (object);
} }
...@@ -607,6 +611,111 @@ ensure_expectations (SrtSystemInfo *self) ...@@ -607,6 +611,111 @@ ensure_expectations (SrtSystemInfo *self)
return self->expectations[0] != '\0'; return self->expectations[0] != '\0';
} }
static void
ensure_hidden_deps (SrtSystemInfo *self)
{
if (self->cached_hidden_deps == NULL)
{
JsonParser *parser = NULL;
JsonNode *node = NULL;
JsonArray *libraries_array = NULL;
JsonArray *hidden_libraries_array = NULL;
JsonObject *object;
gchar *soname = NULL;
gchar *path = NULL;
GPtrArray *arr = NULL;
GError *error = NULL;
self->cached_hidden_deps = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) g_strfreev);
if (!ensure_expectations (self))
{
g_debug ("Hidden dependencies parsing skipped because of unknown expectations");
goto out;
}
path = g_build_filename (self->expectations, "steam-runtime-abi.json", NULL);
/* Currently, in a standard Steam installation, we have the abi JSON one level up
* from the expectations folder */
if (!g_file_test (path, G_FILE_TEST_EXISTS))
{
g_free (path);
path = g_build_filename (self->expectations, "..", "steam-runtime-abi.json", NULL);
}
parser = json_parser_new ();
if (!json_parser_load_from_file (parser, path, &error))
{
g_debug ("Error parsing the expected JSON object in \"%s\": %s", path, error->message);
goto out;
}
node = json_parser_get_root (parser);
object = json_node_get_object (node);
if (!json_object_has_member (object, "shared_libraries"))
{
g_debug ("No \"shared_libraries\" in the JSON object \"%s\"", path);
goto out;
}
libraries_array = json_object_get_array_member (object, "shared_libraries");
/* If there are no libraries in the parsed JSON file we simply return */
if (libraries_array == NULL || json_array_get_length (libraries_array) == 0)
goto out;
for (guint i = 0; i < json_array_get_length (libraries_array); i++)
{
node = json_array_get_element (libraries_array, i);
if (!JSON_NODE_HOLDS_OBJECT (node))
continue;
object = json_node_get_object (node);
GList *members = json_object_get_members (object);
if (members == NULL)
continue;
soname = g_strdup (members->data);
g_list_free (members);
object = json_object_get_object_member (object, soname);
if (!json_object_has_member (object, "hidden_dependencies"))
{
g_free (soname);
continue;
}
hidden_libraries_array = json_object_get_array_member (object, "hidden_dependencies");
if (hidden_libraries_array == NULL || json_array_get_length (hidden_libraries_array) == 0)
{
g_free (soname);
continue;
}
arr = g_ptr_array_new_full (json_array_get_length (hidden_libraries_array) + 1, g_free);
for (guint j = 0; j < json_array_get_length (hidden_libraries_array); j++)
g_ptr_array_add (arr, g_strdup (json_array_get_string_element (hidden_libraries_array, j)));
g_ptr_array_add (arr, NULL);
g_debug ("%s soname hidden dependencies have been parsed", soname);
g_hash_table_insert (self->cached_hidden_deps, g_steal_pointer (&soname), g_ptr_array_free (arr, FALSE));
}
out:
g_free (path);
g_clear_error (&error);
if (parser)
g_clear_object (&parser);
}
}
static void static void
ensure_overrides_cached (SrtSystemInfo *self) ensure_overrides_cached (SrtSystemInfo *self)
{ {
...@@ -974,6 +1083,8 @@ srt_system_info_check_libraries (SrtSystemInfo *self, ...@@ -974,6 +1083,8 @@ srt_system_info_check_libraries (SrtSystemInfo *self,
goto out; goto out;
} }
ensure_hidden_deps (self);
while ((filename = g_dir_read_name (dir))) while ((filename = g_dir_read_name (dir)))
{ {
char *line = NULL; char *line = NULL;
...@@ -1007,10 +1118,12 @@ srt_system_info_check_libraries (SrtSystemInfo *self, ...@@ -1007,10 +1118,12 @@ srt_system_info_check_libraries (SrtSystemInfo *self,
* found it, as an argument. */ * found it, as an argument. */
SrtLibrary *library = NULL; SrtLibrary *library = NULL;
char *soname = g_strdup (strsep (&pointer_into_line, " \t")); char *soname = g_strdup (strsep (&pointer_into_line, " \t"));
gchar **hidden_deps = g_hash_table_lookup (self->cached_hidden_deps, soname);
abi->cached_combined_issues |= _srt_check_library_presence (self->helpers_path, abi->cached_combined_issues |= _srt_check_library_presence (self->helpers_path,
soname, soname,
multiarch_tuple, multiarch_tuple,
symbols_file, symbols_file,
(const gchar * const *)hidden_deps,
SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS,
&library); &library);
g_hash_table_insert (abi->cached_results, soname, library); g_hash_table_insert (abi->cached_results, soname, library);
...@@ -1042,7 +1155,6 @@ srt_system_info_check_libraries (SrtSystemInfo *self, ...@@ -1042,7 +1155,6 @@ srt_system_info_check_libraries (SrtSystemInfo *self,
g_dir_close (dir); g_dir_close (dir);
return ret; return ret;
} }
/** /**
...@@ -1110,6 +1222,8 @@ srt_system_info_check_library (SrtSystemInfo *self, ...@@ -1110,6 +1222,8 @@ srt_system_info_check_library (SrtSystemInfo *self,
} }
} }
ensure_hidden_deps (self);
while (dir != NULL && (filename = g_dir_read_name (dir))) while (dir != NULL && (filename = g_dir_read_name (dir)))
{ {
if (!g_str_has_suffix (filename, ".symbols")) if (!g_str_has_suffix (filename, ".symbols"))
...@@ -1141,10 +1255,12 @@ srt_system_info_check_library (SrtSystemInfo *self, ...@@ -1141,10 +1255,12 @@ srt_system_info_check_library (SrtSystemInfo *self,
char *soname_found = g_strdup (strsep (&pointer_into_line, " \t")); char *soname_found = g_strdup (strsep (&pointer_into_line, " \t"));
if (g_strcmp0 (soname_found, soname) == 0) if (g_strcmp0 (soname_found, soname) == 0)
{ {
gchar **hidden_deps = g_hash_table_lookup (self->cached_hidden_deps, soname);
issues = _srt_check_library_presence (self->helpers_path, issues = _srt_check_library_presence (self->helpers_path,
soname_found, soname_found,
multiarch_tuple, multiarch_tuple,
symbols_file, symbols_file,
(const gchar * const *)hidden_deps,
SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS,
&library); &library);
g_hash_table_insert (abi->cached_results, soname_found, library); g_hash_table_insert (abi->cached_results, soname_found, library);
...@@ -1169,6 +1285,7 @@ srt_system_info_check_library (SrtSystemInfo *self, ...@@ -1169,6 +1285,7 @@ srt_system_info_check_library (SrtSystemInfo *self,
soname, soname,
multiarch_tuple, multiarch_tuple,
NULL, NULL,
NULL,
SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS,
&library); &library);
g_hash_table_insert (abi->cached_results, g_strdup (soname), library); g_hash_table_insert (abi->cached_results, g_strdup (soname), library);
...@@ -1299,7 +1416,7 @@ srt_system_info_check_graphics (SrtSystemInfo *self, ...@@ -1299,7 +1416,7 @@ srt_system_info_check_graphics (SrtSystemInfo *self,
* *
* Returns: (transfer full) (type SrtGraphics): A list of #SrtGraphics objects * Returns: (transfer full) (type SrtGraphics): A list of #SrtGraphics objects
* representing the items tested and results. * representing the items tested and results.
* Free with 'glist_free_full(list, g_object_unref)`. * Free with 'g_list_free_full(list, g_object_unref)`.
*/ */
GList * srt_system_info_check_all_graphics (SrtSystemInfo *self, GList * srt_system_info_check_all_graphics (SrtSystemInfo *self,
const char *multiarch_tuple) const char *multiarch_tuple)
......
# Cut-down version of libtheora0:i386.symbols, to illustrate what we expect
# to find here
libtheoraenc.so.1 libtheora0 #MINVER#
# No symbols listed here yet
{
"architectures": {
"i386-linux-gnu": {
"dpkg_name": "i386"
},
"x86_64-linux-gnu": {
"dpkg_name": "amd64"
}
},
"extra_debs": {
"libs": [
"dconf-gsettings-backend",
"gtk2-engines"
]
},
"private_libraries": [
{
"libVkLayer_*.so": {
"deb": "libvulkan1"
}
}
],
"shared_libraries": [
{
"libglut.so.3": {
"deb": "freeglut3"
}
},
"libacl.so.1",
{
"libtheoraenc.so.1": {
"deb": "libtheora0",
"hidden_dependencies": [
"libtheoradec.so.1"
]
}
},
{
"libtWithHiddens.so.1": {
"deb": "libtWithHiddens0",
"hidden_dependencies": [
"firstHidden.so.0",
"secondHidden.so.3"
]
}
}
]
}
# Cut-down version of libtheora0:amd64.symbols, to illustrate what we expect
# to find here
libtheoraenc.so.1 libtheora0 #MINVER#
# No symbols listed here yet
# Cut-down version of libtheora0:i386.symbols, to illustrate what we expect
# to find here
libtheoraenc.so.1 libtheora0 #MINVER#
# No symbols listed here yet
# Cut-down version of libtheora0:amd64.symbols, to illustrate what we expect
# to find here
libtheoraenc.so.1 libtheora0 #MINVER#
# No symbols listed here yet
{
"architectures": {
"i386-linux-gnu": {
"dpkg_name": "i386"
},
"x86_64-linux-gnu": {
"dpkg_name": "amd64"
}
},
"extra_debs": {
"libs": [
"dconf-gsettings-backend",
"gtk2-engines"
]
},
"private_libraries": [
{
"libVkLayer_*.so": {
"deb": "libvulkan1"
}
}
],
"shared_libraries": [
{
"libglut.so.3": {
"deb": "freeglut3"
}
},
"libacl.so.1",
{
"libtheoraenc.so.1": {
"deb": "libtheora0",
"hidden_dependencies": [
"libtheoradec.so.1"
]
}
},
{
"libtWithHiddens.so.1": {
"deb": "libtWithHiddens0",
"hidden_dependencies": [
"firstHidden.so.0",
"secondHidden.so.3"
]
}
}
]
}
...@@ -225,6 +225,36 @@ check_libraries_result (GList *libraries) ...@@ -225,6 +225,36 @@ check_libraries_result (GList *libraries)
g_assert_true (seen_libc); g_assert_true (seen_libc);
/* Test third library */
l = g_list_next (l);
library = l->data;
g_assert_nonnull (library);
g_assert_cmpstr (srt_library_get_soname (library), ==, "libtheoraenc.so.1");
missing_symbols = srt_library_get_missing_symbols (library);
g_assert_nonnull (missing_symbols);
g_assert_cmpstr (missing_symbols[0], ==, NULL);
g_assert_cmpint (srt_library_get_issues (library), ==, SRT_LIBRARY_ISSUES_NONE);
misversioned_symbols = srt_library_get_misversioned_symbols (library);
g_assert_nonnull (misversioned_symbols);
g_assert_cmpstr (misversioned_symbols[0], ==, NULL);
dependencies = srt_library_get_dependencies (library);
g_assert_nonnull (dependencies);
g_assert_cmpstr (dependencies[0], !=, NULL);
seen_libc = FALSE;
for (gsize i = 0; dependencies[i] != NULL; i++)
{
g_debug ("libtheoraenc.so.1 depends on %s", dependencies[i]);
if (strstr (dependencies[i], "/libc.so.") != NULL)
seen_libc = TRUE;
}
g_assert_true (seen_libc);
/* Test last library */ /* Test last library */
l = g_list_next (l); l = g_list_next (l);
library = l->data; library = l->data;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment