Skip to content

Commit fdec741

Browse files
authored
fix: Unable to Build Projects with FFI Plugins in flutter-elinux (#271)
* fix: Unable to build plugins with ffi
1 parent 70c11a8 commit fdec741

File tree

1 file changed

+76
-13
lines changed

1 file changed

+76
-13
lines changed

lib/elinux_plugins.dart

+76-13
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ class ELinuxPlugin extends PluginPlatform implements NativeOrDartPlugin {
9999
}
100100

101101
String get path => directory.parent.path;
102+
103+
/// Method to return a detailed debug string for the plugin.
104+
@override
105+
String toString() {
106+
return '''
107+
ELinuxPlugin:
108+
name: $name
109+
directory: ${directory.path}
110+
pluginClass: $pluginClass
111+
dartPluginClass: $dartPluginClass
112+
ffiPlugin: $ffiPlugin
113+
defaultPackage: $defaultPackage
114+
dependencies: ${dependencies?.join(', ')}
115+
''';
116+
}
102117
}
103118

104119
/// Source: [_internalCapitalLetterRegex] in `platform_plugins.dart` (exact copy)
@@ -426,12 +441,20 @@ Future<List<ELinuxPlugin>> findELinuxPlugins(
426441
final ELinuxPlugin? plugin = _pluginFromPackage(package.name, packageRoot);
427442
if (plugin == null) {
428443
continue;
429-
} else if (nativeOnly &&
430-
(plugin.pluginClass == null || plugin.pluginClass == 'none')) {
444+
}
445+
446+
final bool isFfi = plugin.ffiPlugin ?? false;
447+
448+
if (nativeOnly &&
449+
((plugin.pluginClass == null || plugin.pluginClass == 'none') &&
450+
!isFfi)) {
431451
continue;
432-
} else if (dartOnly && plugin.dartPluginClass == null) {
452+
}
453+
454+
if (dartOnly && (plugin.dartPluginClass == null || isFfi)) {
433455
continue;
434456
}
457+
435458
plugins.add(plugin);
436459
}
437460
return plugins;
@@ -513,18 +536,47 @@ void registerPlugins() {
513536
);
514537
}
515538

539+
/// Filters out any plugins that don't use method channels, and thus shouldn't be added to the native generated registrants.
540+
List<ELinuxPlugin> _filterMethodChannelPlugins(List<ELinuxPlugin> plugins) {
541+
return plugins.where((ELinuxPlugin plugin) {
542+
return (plugin as NativeOrDartPlugin).hasMethodChannel();
543+
}).toList();
544+
}
545+
546+
/// Filters out Dart-only and method channel plugins.
547+
///
548+
/// FFI plugins do not need native code registration, but their binaries need to be bundled.
549+
List<ELinuxPlugin> _filterFfiPlugins(List<ELinuxPlugin> plugins) {
550+
return plugins.where((ELinuxPlugin plugin) {
551+
final NativeOrDartPlugin plugin_ = plugin as NativeOrDartPlugin;
552+
return plugin_.hasFfi();
553+
}).toList();
554+
}
555+
516556
/// See: [_writeWindowsPluginFiles] in `plugins.dart`
517557
void _writePluginCmakefileTemplate(
518558
ELinuxProject eLinuxProject,
519559
Directory registryDirectory,
520560
List<ELinuxPlugin> plugins,
521561
) {
522-
final List<Map<String, dynamic>> pluginConfigs =
523-
plugins.map((ELinuxPlugin plugin) => plugin.toMap()).toList();
562+
final List<ELinuxPlugin> methodChannelPlugins =
563+
_filterMethodChannelPlugins(plugins);
564+
final List<ELinuxPlugin> ffiPlugins = _filterFfiPlugins(plugins)
565+
..removeWhere(methodChannelPlugins.contains);
566+
567+
final List<Map<String, dynamic>> methodChannelPluginsMap =
568+
methodChannelPlugins
569+
.map((ELinuxPlugin plugin) => plugin.toMap())
570+
.toList();
571+
final List<Map<String, dynamic>> ffiPluginsMap =
572+
ffiPlugins.map((ELinuxPlugin plugin) => plugin.toMap()).toList();
573+
524574
final Map<String, dynamic> context = <String, dynamic>{
525-
'plugins': pluginConfigs,
575+
'methodChannelPlugins': methodChannelPluginsMap,
576+
'ffiPlugins': ffiPluginsMap,
526577
'pluginsDir': _cmakeRelativePluginSymlinkDirectoryPath(eLinuxProject),
527578
};
579+
528580
_renderTemplateToFile(
529581
'''
530582
//
@@ -547,22 +599,22 @@ void RegisterPlugins(flutter::PluginRegistry* registry);
547599
_renderTemplateToFile(
548600
'''
549601
//
550-
// Generated file. Do not edit.
602+
// Generated file. Do not edit.
551603
//
552604
553605
// clang-format off
554606
555607
#include "generated_plugin_registrant.h"
556608
557-
{{#plugins}}
609+
{{#methodChannelPlugins}}
558610
#include <{{name}}/{{filename}}.h>
559-
{{/plugins}}
611+
{{/methodChannelPlugins}}
560612
561613
void RegisterPlugins(flutter::PluginRegistry* registry) {
562-
{{#plugins}}
614+
{{#methodChannelPlugins}}
563615
{{class}}RegisterWithRegistrar(
564616
registry->GetRegistrarForPlugin("{{class}}"));
565-
{{/plugins}}
617+
{{/methodChannelPlugins}}
566618
}
567619
''',
568620
context,
@@ -575,9 +627,15 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
575627
#
576628
577629
list(APPEND FLUTTER_PLUGIN_LIST
578-
{{#plugins}}
630+
{{#methodChannelPlugins}}
579631
{{name}}
580-
{{/plugins}}
632+
{{/methodChannelPlugins}}
633+
)
634+
635+
list(APPEND FLUTTER_FFI_PLUGIN_LIST
636+
{{#ffiPlugins}}
637+
{{name}}
638+
{{/ffiPlugins}}
581639
)
582640
583641
set(PLUGIN_BUNDLED_LIBRARIES)
@@ -588,6 +646,11 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
588646
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
589647
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
590648
endforeach(plugin)
649+
650+
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
651+
add_subdirectory({{pluginsDir}}/${ffi_plugin}/elinux plugins/${ffi_plugin})
652+
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
653+
endforeach(ffi_plugin)
591654
''',
592655
context,
593656
registryDirectory.childFile('generated_plugins.cmake').path,

0 commit comments

Comments
 (0)