diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2019-04-03 08:52:38 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2019-04-03 08:52:38 +0200 |
commit | b027723e00679f2b709880407a6ff24583faeae3 (patch) | |
tree | b972843460a92d737edb7512444b24791118f9de /libnm | |
parent | 61aad8cda475a07d579a85f209696d1ff8fd3e84 (diff) | |
download | NetworkManager-b027723e00679f2b709880407a6ff24583faeae3.tar.gz |
Revert "all: goodbye libnm-glib"
We need this for a little little longer :(
This reverts commit 1de8383ad9fdfc8f552117e5d109bdfa7005634b.
Diffstat (limited to 'libnm')
-rw-r--r-- | libnm/fake-typelib/NMClient.gir | 9 | ||||
-rw-r--r-- | libnm/fake-typelib/NetworkManager.gir | 10 | ||||
-rw-r--r-- | libnm/fake-typelib/meson.build | 30 | ||||
-rw-r--r-- | libnm/fake-typelib/typelibs.gresource.xml | 7 | ||||
-rw-r--r-- | libnm/meson.build | 5 | ||||
-rw-r--r-- | libnm/nm-libnm-utils.c | 82 |
6 files changed, 143 insertions, 0 deletions
diff --git a/libnm/fake-typelib/NMClient.gir b/libnm/fake-typelib/NMClient.gir new file mode 100644 index 0000000000..3002f8d630 --- /dev/null +++ b/libnm/fake-typelib/NMClient.gir @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<!-- A lame duck typelib which prevents GIR from loading the + real one (which would crash due to conflict with libnm) --> +<repository version="1.2" + xmlns="http://www.gtk.org/introspection/core/1.0" + xmlns:c="http://www.gtk.org/introspection/c/1.0" + xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> + <namespace name="NMClient" version="0.0" /> +</repository> diff --git a/libnm/fake-typelib/NetworkManager.gir b/libnm/fake-typelib/NetworkManager.gir new file mode 100644 index 0000000000..d15d29afc7 --- /dev/null +++ b/libnm/fake-typelib/NetworkManager.gir @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- A lame duck typelib which prevents GIR from loading the + real one (which would crash due to conflict with libnm) --> +<repository version="1.2" + xmlns="http://www.gtk.org/introspection/core/1.0" + xmlns:c="http://www.gtk.org/introspection/c/1.0" + xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> + <namespace name="NetworkManager" version="0.0"> + </namespace> +</repository> diff --git a/libnm/fake-typelib/meson.build b/libnm/fake-typelib/meson.build new file mode 100644 index 0000000000..fdbb29202e --- /dev/null +++ b/libnm/fake-typelib/meson.build @@ -0,0 +1,30 @@ +g_ir_compiler = find_program('g-ir-compiler') + +girs = [ + 'NetworkManager', + 'NMClient', +] + +resource_data = [] + +foreach gir: girs + gir_typelib = gir + '.typelib' + + resource_data += custom_target( + gir_typelib, + input: gir + '.gir', + output: gir_typelib, + command: [g_ir_compiler, '@INPUT@', '-o', '@OUTPUT@'], + ) +endforeach + +resource = 'typelibs' + +libnm_utils_sources += gnome.compile_resources( + resource, + resource + '.gresource.xml', + source_dir: '.', + dependencies: resource_data, + extra_args: '--manual-register', + export: true, +) diff --git a/libnm/fake-typelib/typelibs.gresource.xml b/libnm/fake-typelib/typelibs.gresource.xml new file mode 100644 index 0000000000..9a71d97544 --- /dev/null +++ b/libnm/fake-typelib/typelibs.gresource.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/org/freedesktop/libnm/fake-typelib"> + <file>NetworkManager.typelib</file> + <file>NMClient.typelib</file> + </gresource> +</gresources> diff --git a/libnm/meson.build b/libnm/meson.build index 86345c7a6d..558a587b4a 100644 --- a/libnm/meson.build +++ b/libnm/meson.build @@ -13,6 +13,11 @@ deps = [ nm_core_dep, ] +if have_fake_typelibs + deps += gir_dep + subdir('fake-typelib') +endif + libnm_utils = static_library( 'nm-utils', sources: libnm_utils_sources, diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c index 580d576be6..f740c37caf 100644 --- a/libnm/nm-libnm-utils.c +++ b/libnm/nm-libnm-utils.c @@ -561,3 +561,85 @@ nm_utils_fixup_product_string (const char *desc) return desc_full; } + +#if WITH_FAKE_TYPELIBS + +/* + * Here we register empty "NMClient" and "NetworkManager" GIR modules as soon + * as we are loaded (if gnome-introspection is being used). This prevents the + * real modules from being loaded because they would in turn load libnm-glib + * and abort() and crash. + * + * For the high level languages that utilize GIR the crash is highly inconvenient + * while the inability to resolve any methods and attributes is potentially + * recoverable. + */ + +#include <girepository.h> + +GResource *typelibs_get_resource (void); +void typelibs_register_resource (void); + +static void __attribute__((constructor)) +_nm_libnm_utils_init (void) +{ + GITypelib *typelib; + GBytes *data; + const char *namespace; + GModule *self; + GITypelib *(*_g_typelib_new_from_const_memory) (const guint8 *memory, + gsize len, + GError **error) = NULL; + const char *(*_g_irepository_load_typelib) (GIRepository *repository, + GITypelib *typelib, + GIRepositoryLoadFlags flags, + GError **error) = NULL; + const char *names[] = { "/org/freedesktop/libnm/fake-typelib/NetworkManager.typelib", + "/org/freedesktop/libnm/fake-typelib/NMClient.typelib" }; + int i; + + self = g_module_open (NULL, 0); + if (!self) + return; + g_module_symbol (self, "g_typelib_new_from_const_memory", + (gpointer *) &_g_typelib_new_from_const_memory); + if (_g_typelib_new_from_const_memory) { + g_module_symbol (self, "g_irepository_load_typelib", + (gpointer *) &_g_irepository_load_typelib); + } + g_module_close (self); + + if (!_g_typelib_new_from_const_memory || !_g_irepository_load_typelib) + return; + + typelibs_register_resource (); + + for (i = 0; i < 2; i++) { + gs_free_error GError *error = NULL; + + data = g_resource_lookup_data (typelibs_get_resource (), + names[i], + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + if (!data) { + g_warning ("Fake typelib %s could not be loaded: %s", names[i], error->message); + return; + } + + typelib = _g_typelib_new_from_const_memory (g_bytes_get_data (data, NULL), + g_bytes_get_size (data), + &error); + if (!typelib) { + g_warning ("Could not create fake typelib instance %s: %s", names[i], error->message); + return; + } + + namespace = _g_irepository_load_typelib (NULL, typelib, 0, &error); + if (!namespace) { + g_warning ("Could not load fake typelib %s: %s", names[i], error->message); + return; + } + } +} + +#endif /* WITH_FAKE_TYPELIBS */ |