build: new option to build plugins within the daemon binary

Instead of creating libmm-plugin* and libmm-shared* libraries that are
dlopen()-ed on runtime, allow incorporating all plugins into the
daemon binary itself.

This makes the startup of the daemon much faster and also avoids
issues with builds that require linker namespace isolation.

Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/674
This commit is contained in:
Aleksander Morgado
2022-12-08 14:37:56 +00:00
committed by Aleksander Morgado
parent 1dd70be4c8
commit 1c4da332ee
17 changed files with 594 additions and 147 deletions

View File

@@ -1,9 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2022 Aleksander Morgado <aleksander@aleksander.es> # Copyright (C) 2022 Aleksander Morgado <aleksander@aleksander.es>
test_plugin_dir = ''
if not enable_builtin_plugins
test_plugin_dir = '--test-plugin-dir="' + build_root + '/src/plugins"'
endif
test_conf = { test_conf = {
'abs_top_builddir': build_root, 'abs_top_builddir': build_root,
'PLUGIN_BUILD_SUBDIR': 'src/plugins/', 'test_plugin_dir': test_plugin_dir,
} }
configure_file( configure_file(

View File

@@ -2,4 +2,4 @@
[D-BUS Service] [D-BUS Service]
Name=org.freedesktop.ModemManager1 Name=org.freedesktop.ModemManager1
Exec=@abs_top_builddir@/src/ModemManager --test-session --no-auto-scan --test-enable --test-plugin-dir="@abs_top_builddir@/@PLUGIN_BUILD_SUBDIR@" --debug Exec=@abs_top_builddir@/src/ModemManager --test-session --no-auto-scan --test-enable @test_plugin_dir@ --debug

View File

@@ -242,6 +242,10 @@ config_h.set('WITH_POLKIT', enable_polkit)
enable_at_command_via_dbus = get_option('at_command_via_dbus') enable_at_command_via_dbus = get_option('at_command_via_dbus')
config_h.set('WITH_AT_COMMAND_VIA_DBUS', enable_at_command_via_dbus) config_h.set('WITH_AT_COMMAND_VIA_DBUS', enable_at_command_via_dbus)
# Builtin plugin support (disabled by default)
enable_builtin_plugins = get_option('builtin_plugins')
config_h.set('WITH_BUILTIN_PLUGINS', enable_builtin_plugins)
# MBIM support (enabled by default) # MBIM support (enabled by default)
enable_mbim = get_option('mbim') enable_mbim = get_option('mbim')
if enable_mbim if enable_mbim
@@ -444,6 +448,7 @@ summary({
'powerd suspend/resume': enable_powerd_suspend_resume, 'powerd suspend/resume': enable_powerd_suspend_resume,
'systemd journal': enable_systemd_journal, 'systemd journal': enable_systemd_journal,
'at command via dbus': enable_at_command_via_dbus, 'at command via dbus': enable_at_command_via_dbus,
'builtin plugins': enable_builtin_plugins,
}, section: 'Features') }, section: 'Features')
summary(plugins_shared, section: 'Shared utils') summary(plugins_shared, section: 'Shared utils')

View File

@@ -17,6 +17,8 @@ option('polkit', type: 'combo', choices: ['strict', 'permissive', 'no'], value:
option('at_command_via_dbus', type: 'boolean', value: false, description: 'enable at commands vida d-bus') option('at_command_via_dbus', type: 'boolean', value: false, description: 'enable at commands vida d-bus')
option('builtin_plugins', type: 'boolean', value: false, description: 'integrate all built plugins within the daemon binary')
option('mbim', type: 'boolean', value: true, description: 'enable MBIM support') option('mbim', type: 'boolean', value: true, description: 'enable MBIM support')
option('qmi', type: 'boolean', value: true, description: 'enable QMI support') option('qmi', type: 'boolean', value: true, description: 'enable QMI support')
option('qrtr', type: 'boolean', value: true, description: 'enable QRTR support') option('qrtr', type: 'boolean', value: true, description: 'enable QRTR support')

View File

@@ -93,7 +93,9 @@ bus_acquired_cb (GDBusConnection *connection,
/* Create Manager object */ /* Create Manager object */
g_assert (!manager); g_assert (!manager);
manager = mm_base_manager_new (connection, manager = mm_base_manager_new (connection,
#if !defined WITH_BUILTIN_PLUGINS
mm_context_get_test_plugin_dir (), mm_context_get_test_plugin_dir (),
#endif
!mm_context_get_no_auto_scan (), !mm_context_get_no_auto_scan (),
mm_context_get_filter_policy (), mm_context_get_filter_policy (),
mm_context_get_initial_kernel_events (), mm_context_get_initial_kernel_events (),

View File

@@ -4,6 +4,7 @@
# helpers library # helpers library
src_inc = include_directories('.') src_inc = include_directories('.')
kerneldevice_inc = include_directories('kerneldevice') kerneldevice_inc = include_directories('kerneldevice')
plugins_inc = include_directories('plugins')
headers = files( headers = files(
'mm-modem-helpers.h', 'mm-modem-helpers.h',
@@ -177,6 +178,9 @@ libport_dep = declare_dependency(
link_with: libport, link_with: libport,
) )
# Additional vendor plugins
subdir('plugins')
# ModemManager daemon # ModemManager daemon
headers = files( headers = files(
'mm-base-bearer.h', 'mm-base-bearer.h',
@@ -229,15 +233,14 @@ sources = files(
enums_types = 'mm-daemon-enums-types' enums_types = 'mm-daemon-enums-types'
daemon_enums_sources = [] sources += gnome.mkenums(
daemon_enums_sources += gnome.mkenums(
enums_types + '.c', enums_types + '.c',
sources: headers, sources: headers,
c_template: build_aux_dir / enums_types + '.c.template', c_template: build_aux_dir / enums_types + '.c.template',
fhead: '#include "mm-daemon-enums-types.h"', fhead: '#include "mm-daemon-enums-types.h"',
) )
daemon_enums_sources += gnome.mkenums( sources += gnome.mkenums(
enums_types + '.h', enums_types + '.h',
sources: headers, sources: headers,
h_template: build_aux_dir / enums_types + '.h.template', h_template: build_aux_dir / enums_types + '.h.template',
@@ -309,20 +312,13 @@ if enable_mbim
) )
endif endif
# Daemon related variables before processing plugins
daemon_sources = sources + daemon_enums_sources
daemon_deps = deps
daemon_c_args = c_args
# Additional vendor plugins
subdir('plugins')
executable( executable(
'ModemManager', 'ModemManager',
sources: daemon_sources, sources: [sources, builtin_sources],
include_directories: top_inc, include_directories: [ top_inc, plugins_inc ],
dependencies: daemon_deps, dependencies: deps,
c_args: daemon_c_args, c_args: c_args,
link_whole: builtin_plugins,
install: true, install: true,
install_dir: mm_sbindir, install_dir: mm_sbindir,
) )

View File

@@ -68,7 +68,9 @@ enum {
PROP_CONNECTION, PROP_CONNECTION,
PROP_AUTO_SCAN, PROP_AUTO_SCAN,
PROP_FILTER_POLICY, PROP_FILTER_POLICY,
#if !defined WITH_BUILTIN_PLUGINS
PROP_PLUGIN_DIR, PROP_PLUGIN_DIR,
#endif
PROP_INITIAL_KERNEL_EVENTS, PROP_INITIAL_KERNEL_EVENTS,
#if defined WITH_TESTS #if defined WITH_TESTS
PROP_ENABLE_TEST, PROP_ENABLE_TEST,
@@ -83,8 +85,10 @@ struct _MMBaseManagerPrivate {
gboolean auto_scan; gboolean auto_scan;
/* Filter policy (mask of enabled rules) */ /* Filter policy (mask of enabled rules) */
MMFilterRule filter_policy; MMFilterRule filter_policy;
#if !defined WITH_BUILTIN_PLUGINS
/* Path to look for plugins */ /* Path to look for plugins */
gchar *plugin_dir; gchar *plugin_dir;
#endif
/* Path to the list of initial kernel events */ /* Path to the list of initial kernel events */
gchar *initial_kernel_events; gchar *initial_kernel_events;
/* The authorization provider */ /* The authorization provider */
@@ -1380,7 +1384,9 @@ log_object_build_id (MMLogObject *_self)
MMBaseManager * MMBaseManager *
mm_base_manager_new (GDBusConnection *connection, mm_base_manager_new (GDBusConnection *connection,
#if !defined WITH_BUILTIN_PLUGINS
const gchar *plugin_dir, const gchar *plugin_dir,
#endif
gboolean auto_scan, gboolean auto_scan,
MMFilterRule filter_policy, MMFilterRule filter_policy,
const gchar *initial_kernel_events, const gchar *initial_kernel_events,
@@ -1395,7 +1401,9 @@ mm_base_manager_new (GDBusConnection *connection,
NULL, /* cancellable */ NULL, /* cancellable */
error, error,
MM_BASE_MANAGER_CONNECTION, connection, MM_BASE_MANAGER_CONNECTION, connection,
#if !defined WITH_BUILTIN_PLUGINS
MM_BASE_MANAGER_PLUGIN_DIR, plugin_dir, MM_BASE_MANAGER_PLUGIN_DIR, plugin_dir,
#endif
MM_BASE_MANAGER_AUTO_SCAN, auto_scan, MM_BASE_MANAGER_AUTO_SCAN, auto_scan,
MM_BASE_MANAGER_FILTER_POLICY, filter_policy, MM_BASE_MANAGER_FILTER_POLICY, filter_policy,
MM_BASE_MANAGER_INITIAL_KERNEL_EVENTS, initial_kernel_events, MM_BASE_MANAGER_INITIAL_KERNEL_EVENTS, initial_kernel_events,
@@ -1445,10 +1453,12 @@ set_property (GObject *object,
case PROP_FILTER_POLICY: case PROP_FILTER_POLICY:
self->priv->filter_policy = g_value_get_flags (value); self->priv->filter_policy = g_value_get_flags (value);
break; break;
#if !defined WITH_BUILTIN_PLUGINS
case PROP_PLUGIN_DIR: case PROP_PLUGIN_DIR:
g_free (self->priv->plugin_dir); g_free (self->priv->plugin_dir);
self->priv->plugin_dir = g_value_dup_string (value); self->priv->plugin_dir = g_value_dup_string (value);
break; break;
#endif
case PROP_INITIAL_KERNEL_EVENTS: case PROP_INITIAL_KERNEL_EVENTS:
g_free (self->priv->initial_kernel_events); g_free (self->priv->initial_kernel_events);
self->priv->initial_kernel_events = g_value_dup_string (value); self->priv->initial_kernel_events = g_value_dup_string (value);
@@ -1482,9 +1492,11 @@ get_property (GObject *object,
case PROP_FILTER_POLICY: case PROP_FILTER_POLICY:
g_value_set_flags (value, self->priv->filter_policy); g_value_set_flags (value, self->priv->filter_policy);
break; break;
#if !defined WITH_BUILTIN_PLUGINS
case PROP_PLUGIN_DIR: case PROP_PLUGIN_DIR:
g_value_set_string (value, self->priv->plugin_dir); g_value_set_string (value, self->priv->plugin_dir);
break; break;
#endif
case PROP_INITIAL_KERNEL_EVENTS: case PROP_INITIAL_KERNEL_EVENTS:
g_value_set_string (value, self->priv->initial_kernel_events); g_value_set_string (value, self->priv->initial_kernel_events);
break; break;
@@ -1548,7 +1560,11 @@ initable_init (GInitable *initable,
return FALSE; return FALSE;
/* Create plugin manager */ /* Create plugin manager */
self->priv->plugin_manager = mm_plugin_manager_new (self->priv->plugin_dir, self->priv->filter, error); self->priv->plugin_manager = mm_plugin_manager_new (self->priv->filter,
#if !defined WITH_BUILTIN_PLUGINS
self->priv->plugin_dir,
#endif
error);
if (!self->priv->plugin_manager) if (!self->priv->plugin_manager)
return FALSE; return FALSE;
@@ -1613,7 +1629,9 @@ finalize (GObject *object)
MMBaseManager *self = MM_BASE_MANAGER (object); MMBaseManager *self = MM_BASE_MANAGER (object);
g_free (self->priv->initial_kernel_events); g_free (self->priv->initial_kernel_events);
#if !defined WITH_BUILTIN_PLUGINS
g_free (self->priv->plugin_dir); g_free (self->priv->plugin_dir);
#endif
g_hash_table_destroy (self->priv->inhibited_devices); g_hash_table_destroy (self->priv->inhibited_devices);
g_hash_table_destroy (self->priv->devices); g_hash_table_destroy (self->priv->devices);
@@ -1704,6 +1722,7 @@ mm_base_manager_class_init (MMBaseManagerClass *manager_class)
MM_FILTER_RULE_NONE, MM_FILTER_RULE_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
#if !defined WITH_BUILTIN_PLUGINS
g_object_class_install_property g_object_class_install_property
(object_class, PROP_PLUGIN_DIR, (object_class, PROP_PLUGIN_DIR,
g_param_spec_string (MM_BASE_MANAGER_PLUGIN_DIR, g_param_spec_string (MM_BASE_MANAGER_PLUGIN_DIR,
@@ -1711,6 +1730,7 @@ mm_base_manager_class_init (MMBaseManagerClass *manager_class)
"Where to look for plugins", "Where to look for plugins",
NULL, NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
#endif
g_object_class_install_property g_object_class_install_property
(object_class, PROP_INITIAL_KERNEL_EVENTS, (object_class, PROP_INITIAL_KERNEL_EVENTS,

View File

@@ -57,7 +57,9 @@ GType mm_base_manager_get_type (void);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBaseManager, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBaseManager, g_object_unref)
MMBaseManager *mm_base_manager_new (GDBusConnection *bus, MMBaseManager *mm_base_manager_new (GDBusConnection *bus,
#if !defined WITH_BUILTIN_PLUGINS
const gchar *plugin_dir, const gchar *plugin_dir,
#endif
gboolean auto_scan, gboolean auto_scan,
MMFilterRule filter_policy, MMFilterRule filter_policy,
const gchar *initial_kernel_events, const gchar *initial_kernel_events,

View File

@@ -229,7 +229,9 @@ static gboolean test_session;
#if defined WITH_TESTS #if defined WITH_TESTS
static gboolean test_enable; static gboolean test_enable;
#endif #endif
#if !defined WITH_BUILTIN_PLUGINS
static gchar *test_plugin_dir; static gchar *test_plugin_dir;
#endif
#if defined WITH_UDEV #if defined WITH_UDEV
static gboolean test_no_udev; static gboolean test_no_udev;
#endif #endif
@@ -258,11 +260,13 @@ static const GOptionEntry test_entries[] = {
NULL NULL
}, },
#endif #endif
#if !defined WITH_BUILTIN_PLUGINS
{ {
"test-plugin-dir", 0, 0, G_OPTION_ARG_FILENAME, &test_plugin_dir, "test-plugin-dir", 0, 0, G_OPTION_ARG_FILENAME, &test_plugin_dir,
"Path to look for plugins", "Path to look for plugins",
"[PATH]" "[PATH]"
}, },
#endif
#if defined WITH_UDEV #if defined WITH_UDEV
{ {
"test-no-udev", 0, 0, G_OPTION_ARG_NONE, &test_no_udev, "test-no-udev", 0, 0, G_OPTION_ARG_NONE, &test_no_udev,
@@ -332,11 +336,13 @@ mm_context_get_test_enable (void)
} }
#endif #endif
#if !defined WITH_BUILTIN_PLUGINS
const gchar * const gchar *
mm_context_get_test_plugin_dir (void) mm_context_get_test_plugin_dir (void)
{ {
return test_plugin_dir ? test_plugin_dir : PLUGINDIR; return test_plugin_dir ? test_plugin_dir : PLUGINDIR;
} }
#endif
#if defined WITH_UDEV #if defined WITH_UDEV
gboolean gboolean

View File

@@ -48,7 +48,9 @@ gboolean mm_context_get_test_session (void);
#if defined WITH_TESTS #if defined WITH_TESTS
gboolean mm_context_get_test_enable (void); gboolean mm_context_get_test_enable (void);
#endif #endif
#if !defined WITH_BUILTIN_PLUGINS
const gchar *mm_context_get_test_plugin_dir (void); const gchar *mm_context_get_test_plugin_dir (void);
#endif
#if defined WITH_UDEV #if defined WITH_UDEV
gboolean mm_context_get_test_no_udev (void); gboolean mm_context_get_test_no_udev (void);
#endif #endif

View File

@@ -33,8 +33,12 @@
#include "mm-utils.h" #include "mm-utils.h"
#include "mm-log-object.h" #include "mm-log-object.h"
#define SHARED_PREFIX "libmm-shared" #if defined WITH_BUILTIN_PLUGINS
#define PLUGIN_PREFIX "libmm-plugin" # include "mm-builtin-plugins.h"
#else
# define SHARED_PREFIX "libmm-shared"
# define PLUGIN_PREFIX "libmm-plugin"
#endif
static void initable_iface_init (GInitableIface *iface); static void initable_iface_init (GInitableIface *iface);
static void log_object_iface_init (MMLogObjectInterface *iface); static void log_object_iface_init (MMLogObjectInterface *iface);
@@ -45,14 +49,19 @@ G_DEFINE_TYPE_EXTENDED (MMPluginManager, mm_plugin_manager, G_TYPE_OBJECT, 0,
enum { enum {
PROP_0, PROP_0,
#if !defined WITH_BUILTIN_PLUGINS
PROP_PLUGIN_DIR, PROP_PLUGIN_DIR,
#endif
PROP_FILTER, PROP_FILTER,
LAST_PROP LAST_PROP
}; };
struct _MMPluginManagerPrivate { struct _MMPluginManagerPrivate {
#if !defined WITH_BUILTIN_PLUGINS
/* Path to look for plugins */ /* Path to look for plugins */
gchar *plugin_dir; gchar *plugin_dir;
#endif
/* Device filter */ /* Device filter */
MMFilter *filter; MMFilter *filter;
@@ -1681,9 +1690,90 @@ register_plugin_allowlist_subsystem_vendor_ids (MMPluginManager *self,
mm_filter_register_plugin_allowlist_subsystem_vendor_id (self->priv->filter, subsystem_vendor_ids[i].l, subsystem_vendor_ids[i].r); mm_filter_register_plugin_allowlist_subsystem_vendor_id (self->priv->filter, subsystem_vendor_ids[i].l, subsystem_vendor_ids[i].r);
} }
static gboolean
track_plugin (MMPluginManager *self,
MMPlugin *plugin,
GPtrArray **subsystems,
GError **error)
{
const gchar **plugin_subsystems;
guint i;
/* Ignore plugins that don't specify subsystems */
plugin_subsystems = mm_plugin_get_allowed_subsystems (plugin);
if (!plugin_subsystems) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Allowed subsystems not specified");
return FALSE;
}
/* Process generic plugin */
if (mm_plugin_is_generic (plugin)) {
if (self->priv->generic) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Another generic plugin already registered");
return FALSE;
}
self->priv->generic = g_object_ref (plugin);
} else
self->priv->plugins = g_list_append (self->priv->plugins, g_object_ref (plugin));
/* Track required subsystems, avoiding duplicates in the list */
for (i = 0; plugin_subsystems[i]; i++) {
if (!g_ptr_array_find_with_equal_func (*subsystems, plugin_subsystems[i], g_str_equal, NULL))
g_ptr_array_add (*subsystems, g_strdup (plugin_subsystems[i]));
}
/* Register plugin allowlist rules in filter, if any */
register_plugin_allowlist_tags (self, plugin);
register_plugin_allowlist_vendor_ids (self, plugin);
register_plugin_allowlist_product_ids (self, plugin);
register_plugin_allowlist_subsystem_vendor_ids (self, plugin);
return TRUE;
}
static gboolean
validate_tracked_plugins (MMPluginManager *self,
GPtrArray *subsystems_take,
GError **error)
{
g_autofree gchar *subsystems_str = NULL;
/* Check the generic plugin once all looped */
if (!self->priv->generic)
mm_obj_dbg (self, "generic plugin not loaded");
/* Treat as error if we don't find any plugin */
if (!self->priv->plugins && !self->priv->generic) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, "no plugins found");
return FALSE;
}
/* Validate required subsystems */
if (!subsystems_take->len) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS,
"empty list of subsystems required by plugins");
return FALSE;
}
/* Add trailing NULL and store as GStrv */
g_ptr_array_add (subsystems_take, NULL);
self->priv->subsystems = (gchar **) g_ptr_array_free (subsystems_take, FALSE);
subsystems_str = g_strjoinv (", ", self->priv->subsystems);
mm_obj_dbg (self, "successfully loaded %u plugins registering %u subsystems: %s",
g_list_length (self->priv->plugins) + !!self->priv->generic,
g_strv_length (self->priv->subsystems), subsystems_str);
return TRUE;
}
#if !defined WITH_BUILTIN_PLUGINS
static MMPlugin * static MMPlugin *
load_plugin (MMPluginManager *self, load_external_plugin (MMPluginManager *self,
const gchar *path) const gchar *path)
{ {
MMPlugin *plugin = NULL; MMPlugin *plugin = NULL;
GModule *module; GModule *module;
@@ -1729,10 +1819,9 @@ load_plugin (MMPluginManager *self,
} }
plugin = (*plugin_create_func) (); plugin = (*plugin_create_func) ();
if (plugin) { if (plugin)
mm_obj_dbg (self, "loaded plugin '%s' from '%s'", mm_plugin_get_name (plugin), path_display); mm_obj_dbg (self, "loaded plugin '%s' from '%s'", mm_plugin_get_name (plugin), path_display);
g_object_weak_ref (G_OBJECT (plugin), (GWeakNotify) g_module_close, module); else
} else
mm_obj_warn (self, "could not load plugin '%s': initialization failed", path_display); mm_obj_warn (self, "could not load plugin '%s': initialization failed", path_display);
out: out:
@@ -1745,8 +1834,8 @@ out:
} }
static void static void
load_shared (MMPluginManager *self, load_external_shared (MMPluginManager *self,
const gchar *path) const gchar *path)
{ {
GModule *module; GModule *module;
gchar *path_display; gchar *path_display;
@@ -1802,8 +1891,8 @@ out:
} }
static gboolean static gboolean
load_plugins (MMPluginManager *self, load_external_plugins (MMPluginManager *self,
GError **error) GError **error)
{ {
GDir *dir = NULL; GDir *dir = NULL;
const gchar *fname; const gchar *fname;
@@ -1811,8 +1900,8 @@ load_plugins (MMPluginManager *self,
GList *plugin_paths = NULL; GList *plugin_paths = NULL;
GList *l; GList *l;
GPtrArray *subsystems = NULL; GPtrArray *subsystems = NULL;
g_autofree gchar *subsystems_str = NULL;
g_autofree gchar *plugindir_display = NULL; g_autofree gchar *plugindir_display = NULL;
gboolean valid_plugins = FALSE;
if (!g_module_supported ()) { if (!g_module_supported ()) {
g_set_error (error, g_set_error (error,
@@ -1828,11 +1917,8 @@ load_plugins (MMPluginManager *self,
mm_obj_dbg (self, "looking for plugins in '%s'", plugindir_display); mm_obj_dbg (self, "looking for plugins in '%s'", plugindir_display);
dir = g_dir_open (self->priv->plugin_dir, 0, NULL); dir = g_dir_open (self->priv->plugin_dir, 0, NULL);
if (!dir) { if (!dir) {
g_set_error (error, g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS,
MM_CORE_ERROR, "plugin directory '%s' not found", plugindir_display);
MM_CORE_ERROR_NO_PLUGINS,
"plugin directory '%s' not found",
plugindir_display);
goto out; goto out;
} }
@@ -1847,81 +1933,23 @@ load_plugins (MMPluginManager *self,
/* Load all shared utils */ /* Load all shared utils */
for (l = shared_paths; l; l = g_list_next (l)) for (l = shared_paths; l; l = g_list_next (l))
load_shared (self, (const gchar *)(l->data)); load_external_shared (self, (const gchar *)(l->data));
/* Load all plugins */ /* Load all plugins */
subsystems = g_ptr_array_new (); subsystems = g_ptr_array_new ();
for (l = plugin_paths; l; l = g_list_next (l)) { for (l = plugin_paths; l; l = g_list_next (l)) {
MMPlugin *plugin; g_autoptr(MMPlugin) plugin = NULL;
const gchar **plugin_subsystems; g_autoptr(GError) inner_error = NULL;
guint i;
plugin = load_plugin (self, (const gchar *)(l->data)); plugin = load_external_plugin (self, (const gchar *)(l->data));
if (!plugin) if (!plugin)
continue; continue;
/* Ignore plugins that don't specify subsystems */ if (!track_plugin (self, plugin, &subsystems, &inner_error))
plugin_subsystems = mm_plugin_get_allowed_subsystems (plugin); mm_obj_warn (self, "ignored plugin '%s': %s", mm_plugin_get_name (plugin), inner_error->message);
if (!plugin_subsystems) {
mm_obj_warn (self, "plugin '%s' doesn't specify allowed subsystems: ignored",
mm_plugin_get_name (plugin));
continue;
}
/* Process generic plugin */
if (mm_plugin_is_generic (plugin)) {
if (self->priv->generic) {
mm_obj_warn (self, "plugin '%s' is generic and another one is already registered: ignored",
mm_plugin_get_name (plugin));
continue;
}
self->priv->generic = plugin;
} else
self->priv->plugins = g_list_append (self->priv->plugins, plugin);
/* Track required subsystems, avoiding duplicates in the list */
for (i = 0; plugin_subsystems[i]; i++) {
if (!g_ptr_array_find_with_equal_func (subsystems, plugin_subsystems[i], g_str_equal, NULL))
g_ptr_array_add (subsystems, g_strdup (plugin_subsystems[i]));
}
/* Register plugin allowlist rules in filter, if any */
register_plugin_allowlist_tags (self, plugin);
register_plugin_allowlist_vendor_ids (self, plugin);
register_plugin_allowlist_product_ids (self, plugin);
register_plugin_allowlist_subsystem_vendor_ids (self, plugin);
} }
/* Check the generic plugin once all looped */ valid_plugins = validate_tracked_plugins (self, subsystems, error);
if (!self->priv->generic)
mm_obj_dbg (self, "generic plugin not loaded");
/* Treat as error if we don't find any plugin */
if (!self->priv->plugins && !self->priv->generic) {
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_NO_PLUGINS,
"no plugins found in plugin directory '%s'",
plugindir_display);
goto out;
}
/* Validate required subsystems */
if (!subsystems->len) {
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_NO_PLUGINS,
"empty list of subsystems required by plugins");
goto out;
}
/* Add trailing NULL and store as GStrv */
g_ptr_array_add (subsystems, NULL);
self->priv->subsystems = (gchar **) g_ptr_array_free (subsystems, FALSE);
subsystems_str = g_strjoinv (", ", self->priv->subsystems);
mm_obj_dbg (self, "successfully loaded %u plugins registering %u subsystems: %s",
g_list_length (self->priv->plugins) + !!self->priv->generic,
g_strv_length (self->priv->subsystems), subsystems_str);
out: out:
g_list_free_full (shared_paths, g_free); g_list_free_full (shared_paths, g_free);
@@ -1929,10 +1957,38 @@ out:
if (dir) if (dir)
g_dir_close (dir); g_dir_close (dir);
/* Return TRUE if at least one plugin found */ return valid_plugins;
return (self->priv->plugins || self->priv->generic);
} }
#else
static gboolean
load_builtin_plugins (MMPluginManager *self,
GError **error)
{
GList *builtin_plugins;
GList *l;
GPtrArray *subsystems = NULL;
subsystems = g_ptr_array_new ();
builtin_plugins = mm_builtin_plugins_load ();
for (l = builtin_plugins; l; l = g_list_next (l)) {
gboolean tracked;
MMPlugin *plugin;
plugin = MM_PLUGIN (l->data);
mm_obj_dbg (self, "loaded builtin plugin '%s'", mm_plugin_get_name (plugin));
tracked = track_plugin (self, plugin, &subsystems, NULL);
g_assert (tracked);
}
g_list_free_full (builtin_plugins, (GDestroyNotify)g_object_unref);
return validate_tracked_plugins (self, subsystems, error);
}
#endif /* !WITH_BUILTIN_PLUGINS */
/*****************************************************************************/ /*****************************************************************************/
static gchar * static gchar *
@@ -1944,15 +2000,19 @@ log_object_build_id (MMLogObject *_self)
/*****************************************************************************/ /*****************************************************************************/
MMPluginManager * MMPluginManager *
mm_plugin_manager_new (const gchar *plugin_dir, mm_plugin_manager_new (MMFilter *filter,
MMFilter *filter, #if !defined WITH_BUILTIN_PLUGINS
const gchar *plugin_dir,
#endif
GError **error) GError **error)
{ {
return g_initable_new (MM_TYPE_PLUGIN_MANAGER, return g_initable_new (MM_TYPE_PLUGIN_MANAGER,
NULL, NULL,
error, error,
MM_PLUGIN_MANAGER_FILTER, filter,
#if !defined WITH_BUILTIN_PLUGINS
MM_PLUGIN_MANAGER_PLUGIN_DIR, plugin_dir, MM_PLUGIN_MANAGER_PLUGIN_DIR, plugin_dir,
MM_PLUGIN_MANAGER_FILTER, filter, #endif
NULL); NULL);
} }
@@ -1966,18 +2026,20 @@ mm_plugin_manager_init (MMPluginManager *self)
} }
static void static void
set_property (GObject *object, set_property (GObject *object,
guint prop_id, guint prop_id,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv; MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv;
switch (prop_id) { switch (prop_id) {
#if !defined WITH_BUILTIN_PLUGINS
case PROP_PLUGIN_DIR: case PROP_PLUGIN_DIR:
g_free (priv->plugin_dir); g_free (priv->plugin_dir);
priv->plugin_dir = g_value_dup_string (value); priv->plugin_dir = g_value_dup_string (value);
break; break;
#endif
case PROP_FILTER: case PROP_FILTER:
priv->filter = g_value_dup_object (value); priv->filter = g_value_dup_object (value);
break; break;
@@ -1988,17 +2050,19 @@ set_property (GObject *object,
} }
static void static void
get_property (GObject *object, get_property (GObject *object,
guint prop_id, guint prop_id,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv; MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv;
switch (prop_id) { switch (prop_id) {
#if !defined WITH_BUILTIN_PLUGINS
case PROP_PLUGIN_DIR: case PROP_PLUGIN_DIR:
g_value_set_string (value, priv->plugin_dir); g_value_set_string (value, priv->plugin_dir);
break; break;
#endif
case PROP_FILTER: case PROP_FILTER:
g_value_set_object (value, priv->filter); g_value_set_object (value, priv->filter);
break; break;
@@ -2009,12 +2073,16 @@ get_property (GObject *object,
} }
static gboolean static gboolean
initable_init (GInitable *initable, initable_init (GInitable *initable,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
/* Load the list of plugins */ #if defined WITH_BUILTIN_PLUGINS
return load_plugins (MM_PLUGIN_MANAGER (initable), error); return load_builtin_plugins (MM_PLUGIN_MANAGER (initable), error);
#else
/* Load the list of plugins from the filesystem*/
return load_external_plugins (MM_PLUGIN_MANAGER (initable), error);
#endif
} }
static void static void
@@ -2024,9 +2092,11 @@ dispose (GObject *object)
g_list_free_full (g_steal_pointer (&self->priv->plugins), g_object_unref); g_list_free_full (g_steal_pointer (&self->priv->plugins), g_object_unref);
g_clear_object (&self->priv->generic); g_clear_object (&self->priv->generic);
g_clear_pointer (&self->priv->plugin_dir, g_free);
g_clear_object (&self->priv->filter); g_clear_object (&self->priv->filter);
g_clear_pointer (&self->priv->subsystems, g_strfreev); g_clear_pointer (&self->priv->subsystems, g_strfreev);
#if !defined WITH_BUILTIN_PLUGINS
g_clear_pointer (&self->priv->plugin_dir, g_free);
#endif
G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object); G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object);
} }
@@ -2056,6 +2126,7 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class)
object_class->get_property = get_property; object_class->get_property = get_property;
/* Properties */ /* Properties */
#if !defined WITH_BUILTIN_PLUGINS
g_object_class_install_property g_object_class_install_property
(object_class, PROP_PLUGIN_DIR, (object_class, PROP_PLUGIN_DIR,
g_param_spec_string (MM_PLUGIN_MANAGER_PLUGIN_DIR, g_param_spec_string (MM_PLUGIN_MANAGER_PLUGIN_DIR,
@@ -2063,6 +2134,8 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class)
"Where to look for plugins", "Where to look for plugins",
NULL, NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
#endif
g_object_class_install_property g_object_class_install_property
(object_class, PROP_FILTER, (object_class, PROP_FILTER,
g_param_spec_object (MM_PLUGIN_MANAGER_FILTER, g_param_spec_object (MM_PLUGIN_MANAGER_FILTER,

View File

@@ -32,7 +32,9 @@
#define MM_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MM_TYPE_PLUGIN_MANAGER)) #define MM_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MM_TYPE_PLUGIN_MANAGER))
#define MM_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_MANAGER, MMPluginManagerClass)) #define MM_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_MANAGER, MMPluginManagerClass))
#define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */ #if !defined WITH_BUILTIN_PLUGINS
# define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */
#endif
#define MM_PLUGIN_MANAGER_FILTER "filter" /* Construct-only */ #define MM_PLUGIN_MANAGER_FILTER "filter" /* Construct-only */
typedef struct _MMPluginManager MMPluginManager; typedef struct _MMPluginManager MMPluginManager;
@@ -51,8 +53,10 @@ struct _MMPluginManagerClass {
GType mm_plugin_manager_get_type (void); GType mm_plugin_manager_get_type (void);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPluginManager, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPluginManager, g_object_unref)
MMPluginManager *mm_plugin_manager_new (const gchar *plugindir, MMPluginManager *mm_plugin_manager_new (MMFilter *filter,
MMFilter *filter, #if !defined WITH_BUILTIN_PLUGINS
const gchar *plugindir,
#endif
GError **error); GError **error);
void mm_plugin_manager_device_support_check (MMPluginManager *self, void mm_plugin_manager_device_support_check (MMPluginManager *self,
MMDevice *device, MMDevice *device,

View File

@@ -1,8 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2021 Iñigo Martinez <inigomartinez@gmail.com> # Copyright (C) 2021 Iñigo Martinez <inigomartinez@gmail.com>
symbol_map = plugins_dir / 'symbol.map' if not enable_builtin_plugins
ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map)) symbol_map = plugins_dir / 'symbol.map'
ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map))
endif
# common service test support # common service test support
plugins_common_test_dep = [] plugins_common_test_dep = []
@@ -36,7 +38,6 @@ if enable_tests
endif endif
# plugins # plugins
plugins_inc = include_directories('.')
plugins = {} plugins = {}
plugins_data = [] plugins_data = []
plugins_udev_rules = [] plugins_udev_rules = []
@@ -958,6 +959,13 @@ if plugins_options['zte']
plugins_udev_rules += files('zte/77-mm-zte-port-types.rules') plugins_udev_rules += files('zte/77-mm-zte-port-types.rules')
endif endif
builtin_sources = []
builtin_plugins = []
if enable_builtin_plugins
builtin_sources += files('mm-builtin-plugins.c')
endif
foreach plugin_name, plugin_data: plugins foreach plugin_name, plugin_data: plugins
libpluginhelpers = [] libpluginhelpers = []
if plugin_data.has_key('helper') if plugin_data.has_key('helper')
@@ -969,21 +977,31 @@ foreach plugin_name, plugin_data: plugins
endif endif
module_args = plugin_data['module'] module_args = plugin_data['module']
if plugin_data['plugin'] if not enable_builtin_plugins
module_args += { if plugin_data['plugin']
'link_args': ldflags, module_args += {
'link_depends': symbol_map, 'link_args': ldflags,
} 'link_depends': symbol_map,
endif }
endif
shared_module( shared_module(
'mm-' + plugin_name, 'mm-' + plugin_name,
dependencies: plugins_deps, dependencies: plugins_deps,
link_with: libpluginhelpers, link_with: libpluginhelpers,
kwargs: module_args, kwargs: module_args,
install: true, install: true,
install_dir: mm_pkglibdir, install_dir: mm_pkglibdir,
) )
else
libplugin = static_library(
'mm-' + plugin_name,
dependencies: plugins_deps,
link_with: libpluginhelpers,
kwargs: module_args,
)
builtin_plugins += libplugin
endif
if enable_tests if enable_tests
if plugin_data.has_key('test') if plugin_data.has_key('test')

View File

@@ -0,0 +1,273 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* Copyright (C) 2022 Google Inc.
*/
#include <config.h>
#include <glib.h>
#include "mm-plugin.h"
#include "mm-builtin-plugins.h"
#if defined ENABLE_PLUGIN_ALTAIR_LTE
MMPlugin *mm_plugin_create_altair_lte (void);
#endif
#if defined ENABLE_PLUGIN_ANYDATA
MMPlugin *mm_plugin_create_anydata (void);
#endif
#if defined ENABLE_PLUGIN_BROADMOBI
MMPlugin *mm_plugin_create_broadmobi (void);
#endif
#if defined ENABLE_PLUGIN_CINTERION
MMPlugin *mm_plugin_create_cinterion (void);
#endif
#if defined ENABLE_PLUGIN_DELL
MMPlugin *mm_plugin_create_dell (void);
#endif
#if defined ENABLE_PLUGIN_DLINK
MMPlugin *mm_plugin_create_dlink (void);
#endif
#if defined ENABLE_PLUGIN_FIBOCOM
MMPlugin *mm_plugin_create_fibocom (void);
#endif
#if defined ENABLE_PLUGIN_FOXCONN
MMPlugin *mm_plugin_create_foxconn (void);
#endif
#if defined ENABLE_PLUGIN_GENERIC
MMPlugin *mm_plugin_create_generic (void);
#endif
#if defined ENABLE_PLUGIN_GOSUNCN
MMPlugin *mm_plugin_create_gosuncn (void);
#endif
#if defined ENABLE_PLUGIN_HAIER
MMPlugin *mm_plugin_create_haier (void);
#endif
#if defined ENABLE_PLUGIN_HUAWEI
MMPlugin *mm_plugin_create_huawei (void);
#endif
#if defined ENABLE_PLUGIN_INTEL
MMPlugin *mm_plugin_create_intel (void);
#endif
#if defined ENABLE_PLUGIN_IRIDIUM
MMPlugin *mm_plugin_create_iridium (void);
#endif
#if defined ENABLE_PLUGIN_LINKTOP
MMPlugin *mm_plugin_create_linktop (void);
#endif
#if defined ENABLE_PLUGIN_LONGCHEER
MMPlugin *mm_plugin_create_longcheer (void);
#endif
#if defined ENABLE_PLUGIN_MBM
MMPlugin *mm_plugin_create_mbm (void);
#endif
#if defined ENABLE_PLUGIN_MOTOROLA
MMPlugin *mm_plugin_create_motorola (void);
#endif
#if defined ENABLE_PLUGIN_MTK
MMPlugin *mm_plugin_create_mtk (void);
#endif
#if defined ENABLE_PLUGIN_NOKIA
MMPlugin *mm_plugin_create_nokia (void);
#endif
#if defined ENABLE_PLUGIN_NOKIA_ICERA
MMPlugin *mm_plugin_create_nokia_icera (void);
#endif
#if defined ENABLE_PLUGIN_NOVATEL
MMPlugin *mm_plugin_create_novatel (void);
#endif
#if defined ENABLE_PLUGIN_NOVATEL_LTE
MMPlugin *mm_plugin_create_novatel_lte (void);
#endif
#if defined ENABLE_PLUGIN_OPTION
MMPlugin *mm_plugin_create_option (void);
#endif
#if defined ENABLE_PLUGIN_OPTION_HSO
MMPlugin *mm_plugin_create_hso (void);
#endif
#if defined ENABLE_PLUGIN_PANTECH
MMPlugin *mm_plugin_create_pantech (void);
#endif
#if defined ENABLE_PLUGIN_QCOM_SOC
MMPlugin *mm_plugin_create_qcom_soc (void);
#endif
#if defined ENABLE_PLUGIN_QUECTEL
MMPlugin *mm_plugin_create_quectel (void);
#endif
#if defined ENABLE_PLUGIN_SAMSUNG
MMPlugin *mm_plugin_create_samsung (void);
#endif
#if defined ENABLE_PLUGIN_SIERRA
MMPlugin *mm_plugin_create_sierra (void);
#endif
#if defined ENABLE_PLUGIN_SIERRA_LEGACY
MMPlugin *mm_plugin_create_sierra_legacy (void);
#endif
#if defined ENABLE_PLUGIN_SIMTECH
MMPlugin *mm_plugin_create_simtech (void);
#endif
#if defined ENABLE_PLUGIN_TELIT
MMPlugin *mm_plugin_create_telit (void);
#endif
#if defined ENABLE_PLUGIN_THURAYA
MMPlugin *mm_plugin_create_thuraya (void);
#endif
#if defined ENABLE_PLUGIN_TPLINK
MMPlugin *mm_plugin_create_tplink (void);
#endif
#if defined ENABLE_PLUGIN_UBLOX
MMPlugin *mm_plugin_create_ublox (void);
#endif
#if defined ENABLE_PLUGIN_VIA
MMPlugin *mm_plugin_create_via (void);
#endif
#if defined ENABLE_PLUGIN_WAVECOM
MMPlugin *mm_plugin_create_wavecom (void);
#endif
#if defined ENABLE_PLUGIN_X22X
MMPlugin *mm_plugin_create_x22x (void);
#endif
#if defined ENABLE_PLUGIN_ZTE
MMPlugin *mm_plugin_create_zte (void);
#endif
GList *
mm_builtin_plugins_load (void)
{
GList *builtin_plugins = NULL;
#define PREPEND_PLUGIN(my_plugin) \
builtin_plugins = g_list_prepend (builtin_plugins, mm_plugin_create_##my_plugin ())
#if defined ENABLE_PLUGIN_ALTAIR_LTE
PREPEND_PLUGIN (altair_lte);
#endif
#if defined ENABLE_PLUGIN_ANYDATA
PREPEND_PLUGIN (anydata);
#endif
#if defined ENABLE_PLUGIN_BROADMOBI
PREPEND_PLUGIN (broadmobi);
#endif
#if defined ENABLE_PLUGIN_CINTERION
PREPEND_PLUGIN (cinterion);
#endif
#if defined ENABLE_PLUGIN_DELL
PREPEND_PLUGIN (dell);
#endif
#if defined ENABLE_PLUGIN_DLINK
PREPEND_PLUGIN (dlink);
#endif
#if defined ENABLE_PLUGIN_FIBOCOM
PREPEND_PLUGIN (fibocom);
#endif
#if defined ENABLE_PLUGIN_FOXCONN
PREPEND_PLUGIN (foxconn);
#endif
#if defined ENABLE_PLUGIN_GENERIC
PREPEND_PLUGIN (generic);
#endif
#if defined ENABLE_PLUGIN_GOSUNCN
PREPEND_PLUGIN (gosuncn);
#endif
#if defined ENABLE_PLUGIN_HAIER
PREPEND_PLUGIN (haier);
#endif
#if defined ENABLE_PLUGIN_HUAWEI
PREPEND_PLUGIN (huawei);
#endif
#if defined ENABLE_PLUGIN_INTEL
PREPEND_PLUGIN (intel);
#endif
#if defined ENABLE_PLUGIN_IRIDIUM
PREPEND_PLUGIN (iridium);
#endif
#if defined ENABLE_PLUGIN_LINKTOP
PREPEND_PLUGIN (linktop);
#endif
#if defined ENABLE_PLUGIN_LONGCHEER
PREPEND_PLUGIN (longcheer);
#endif
#if defined ENABLE_PLUGIN_MBM
PREPEND_PLUGIN (mbm);
#endif
#if defined ENABLE_PLUGIN_MOTOROLA
PREPEND_PLUGIN (motorola);
#endif
#if defined ENABLE_PLUGIN_MTK
PREPEND_PLUGIN (mtk);
#endif
#if defined ENABLE_PLUGIN_NOKIA
PREPEND_PLUGIN (nokia);
#endif
#if defined ENABLE_PLUGIN_NOKIA_ICERA
PREPEND_PLUGIN (nokia_icera);
#endif
#if defined ENABLE_PLUGIN_NOVATEL
PREPEND_PLUGIN (novatel);
#endif
#if defined ENABLE_PLUGIN_NOVATEL_LTE
PREPEND_PLUGIN (novatel_lte);
#endif
#if defined ENABLE_PLUGIN_OPTION
PREPEND_PLUGIN (option);
#endif
#if defined ENABLE_PLUGIN_OPTION_HSO
PREPEND_PLUGIN (hso);
#endif
#if defined ENABLE_PLUGIN_PANTECH
PREPEND_PLUGIN (pantech);
#endif
#if defined ENABLE_PLUGIN_QCOM_SOC
PREPEND_PLUGIN (qcom_soc);
#endif
#if defined ENABLE_PLUGIN_QUECTEL
PREPEND_PLUGIN (quectel);
#endif
#if defined ENABLE_PLUGIN_SAMSUNG
PREPEND_PLUGIN (samsung);
#endif
#if defined ENABLE_PLUGIN_SIERRA
PREPEND_PLUGIN (sierra);
#endif
#if defined ENABLE_PLUGIN_SIERRA_LEGACY
PREPEND_PLUGIN (sierra_legacy);
#endif
#if defined ENABLE_PLUGIN_SIMTECH
PREPEND_PLUGIN (simtech);
#endif
#if defined ENABLE_PLUGIN_TELIT
PREPEND_PLUGIN (telit);
#endif
#if defined ENABLE_PLUGIN_THURAYA
PREPEND_PLUGIN (thuraya);
#endif
#if defined ENABLE_PLUGIN_TPLINK
PREPEND_PLUGIN (tplink);
#endif
#if defined ENABLE_PLUGIN_UBLOX
PREPEND_PLUGIN (ublox);
#endif
#if defined ENABLE_PLUGIN_VIA
PREPEND_PLUGIN (via);
#endif
#if defined ENABLE_PLUGIN_WAVECOM
PREPEND_PLUGIN (wavecom);
#endif
#if defined ENABLE_PLUGIN_X22X
PREPEND_PLUGIN (x22x);
#endif
#if defined ENABLE_PLUGIN_ZTE
PREPEND_PLUGIN (zte);
#endif
#undef PREPEND_PLUGIN
return builtin_plugins;
}

View File

@@ -0,0 +1,28 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
*
* Copyright (C) 2022 Google Inc.
*/
#ifndef MM_BUILTIN_PLUGINS_H
#define MM_BUILTIN_PLUGINS_H
#include <config.h>
#include <glib.h>
#if !defined WITH_BUILTIN_PLUGINS
# error Build with builtin plugins was not enabled
#endif
GList *mm_builtin_plugins_load (void);
#endif /* MM_BUILTIN_PLUGINS_H */

View File

@@ -26,20 +26,28 @@
#include "mm-plugin.h" #include "mm-plugin.h"
#define MM_PLUGIN_NAMED_CREATOR_SCOPE static #if defined (G_HAVE_GNUC_VISIBILITY)
# define MM_VISIBILITY __attribute__((visibility("protected")))
#else
# define MM_VISIBILITY
#endif
#define MM_PLUGIN_CREATOR(my_plugin) \ #if defined WITH_BUILTIN_PLUGINS
# define MM_PLUGIN_VERSION
# define MM_PLUGIN_NAMED_CREATOR_SCOPE
# define MM_PLUGIN_CREATOR(unused)
#else
# define MM_PLUGIN_VERSION \
MM_VISIBILITY int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; \
MM_VISIBILITY int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
# define MM_PLUGIN_NAMED_CREATOR_SCOPE static
# define MM_PLUGIN_CREATOR(my_plugin) \
G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); \ G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); \
G_MODULE_EXPORT MMPlugin * \ G_MODULE_EXPORT MMPlugin * \
mm_plugin_create (void) \ mm_plugin_create (void) \
{ \ { \
return mm_plugin_create_##my_plugin (); \ return mm_plugin_create_##my_plugin (); \
} }
#if defined (G_HAVE_GNUC_VISIBILITY)
# define MM_VISIBILITY __attribute__((visibility("protected")))
#else
# define MM_VISIBILITY
#endif #endif
#define MM_DEFINE_PLUGIN(MY_PLUGIN, my_plugin, MyPlugin) \ #define MM_DEFINE_PLUGIN(MY_PLUGIN, my_plugin, MyPlugin) \
@@ -49,8 +57,7 @@
}; \ }; \
G_DEFINE_TYPE (MMPlugin##MyPlugin, mm_plugin_##my_plugin, MM_TYPE_PLUGIN) \ G_DEFINE_TYPE (MMPlugin##MyPlugin, mm_plugin_##my_plugin, MM_TYPE_PLUGIN) \
\ \
MM_VISIBILITY int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; \ MM_PLUGIN_VERSION \
MM_VISIBILITY int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; \
\ \
MM_PLUGIN_NAMED_CREATOR_SCOPE MMPlugin *mm_plugin_create_##my_plugin (void); \ MM_PLUGIN_NAMED_CREATOR_SCOPE MMPlugin *mm_plugin_create_##my_plugin (void); \
MM_PLUGIN_CREATOR(my_plugin) MM_PLUGIN_CREATOR(my_plugin)

View File

@@ -33,9 +33,13 @@
#define MM_VISIBILITY #define MM_VISIBILITY
#endif #endif
#define MM_DEFINE_SHARED(MyShared) \ #if defined WITH_BUILTIN_PLUGINS
# define MM_DEFINE_SHARED(unused)
#else
# define MM_DEFINE_SHARED(MyShared) \
MM_VISIBILITY int mm_shared_major_version = MM_SHARED_MAJOR_VERSION; \ MM_VISIBILITY int mm_shared_major_version = MM_SHARED_MAJOR_VERSION; \
MM_VISIBILITY int mm_shared_minor_version = MM_SHARED_MINOR_VERSION; \ MM_VISIBILITY int mm_shared_minor_version = MM_SHARED_MINOR_VERSION; \
MM_VISIBILITY const char *mm_shared_name = #MyShared; MM_VISIBILITY const char *mm_shared_name = #MyShared;
#endif
#endif /* MM_SHARED_COMMON_H */ #endif /* MM_SHARED_COMMON_H */