Skip to content

Commit 61c198e

Browse files
Switch Linux to the GTK embedding (flutter#59287)
Updates the tooling to use the GTK embedding, rather than the GLFW embedding: - Adds new requirements to `doctor` - Updates the app and plugin templates to make GTK-based runners and plugins - Stops downloading and installing the GLFW artifacts Final part of flutter#54860, other than cleanup.
1 parent 5b14752 commit 61c198e

File tree

22 files changed

+437
-265
lines changed

22 files changed

+437
-265
lines changed

packages/flutter_tools/lib/src/artifacts.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ enum Artifact {
5050
linuxDesktopPath,
5151
// The root of the cpp headers for Linux desktop.
5252
linuxHeaders,
53-
// The root of the cpp client code for Linux desktop.
54-
linuxCppClientWrapper,
5553
/// The root of the Windows desktop sources.
5654
windowsDesktopPath,
5755
/// The root of the cpp client code for Windows desktop.
@@ -125,8 +123,6 @@ String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMo
125123
return '';
126124
case Artifact.windowsCppClientWrapper:
127125
return 'cpp_client_wrapper';
128-
case Artifact.linuxCppClientWrapper:
129-
return 'cpp_client_wrapper_glfw';
130126
case Artifact.skyEnginePath:
131127
return 'sky_engine';
132128
case Artifact.flutterMacOSPodspec:
@@ -370,9 +366,6 @@ class CachedArtifacts extends Artifacts {
370366
case Artifact.windowsCppClientWrapper:
371367
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
372368
return _fileSystem.path.join(engineArtifactsPath, 'windows-x64', _artifactToFileName(artifact, platform, mode));
373-
case Artifact.linuxCppClientWrapper:
374-
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
375-
return _fileSystem.path.join(engineArtifactsPath, 'linux-x64', _artifactToFileName(artifact, platform, mode));
376369
case Artifact.skyEnginePath:
377370
final Directory dartPackageDirectory = _cache.getCacheDir('pkg');
378371
return _fileSystem.path.join(dartPackageDirectory.path, _artifactToFileName(artifact));
@@ -534,8 +527,6 @@ class LocalEngineArtifacts extends Artifacts {
534527
case Artifact.linuxDesktopPath:
535528
case Artifact.linuxHeaders:
536529
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
537-
case Artifact.linuxCppClientWrapper:
538-
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
539530
case Artifact.windowsDesktopPath:
540531
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
541532
case Artifact.windowsCppClientWrapper:

packages/flutter_tools/lib/src/base/user_messages.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,13 @@ class UserMessages {
231231
'It is likely available from your distribution (e.g.: apt install ninja-build), or '
232232
'can be downloaded from https://github.com/ninja-build/ninja/releases';
233233
String ninjaTooOld(String minimumVersion) => 'ninja $minimumVersion or later is required.';
234+
String pkgConfigVersion(String version) => 'pkg-config version $version';
235+
String get pkgConfigMissing => 'pgk-config is required for Linux development.\n'
236+
'It is likely available from your distribution (e.g.: apt install pkg-config), or '
237+
'can be downloaded from https://www.freedesktop.org/wiki/Software/pkg-config/';
238+
String pkgConfigTooOld(String minimumVersion) => 'pkg-config $minimumVersion or later is required.';
239+
String get gtkLibrariesMissing => 'GTK 3.0 development libraries are required for Linux development.\n'
240+
'They are likely available from your distribution (e.g.: apt install libgtk-3-dev)';
234241

235242
// Messages used in FlutterCommand
236243
String flutterElapsedTime(String name, String elapsedTime) => '"flutter $name" took $elapsedTime.';

packages/flutter_tools/lib/src/build_system/targets/linux.dart

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@ import 'icon_tree_shaker.dart';
1515

1616
/// The only files/subdirectories we care out.
1717
const List<String> _kLinuxArtifacts = <String>[
18-
// GLFW. Will be removed after the switch to GTK.
19-
'libflutter_linux_glfw.so',
20-
'flutter_export.h',
21-
'flutter_messenger.h',
22-
'flutter_plugin_registrar.h',
23-
'flutter_glfw.h',
24-
// GTK. Not yet used by the template.
2518
'libflutter_linux_gtk.so',
2619
];
2720

@@ -57,14 +50,6 @@ class UnpackLinux extends Target {
5750
mode: buildMode,
5851
platform: TargetPlatform.linux_x64,
5952
);
60-
// For the GLFW embedding.
61-
final String clientSourcePath = environment.artifacts
62-
.getArtifactPath(
63-
Artifact.linuxCppClientWrapper,
64-
mode: buildMode,
65-
platform: TargetPlatform.linux_x64,
66-
);
67-
// For the GTK embedding.
6853
final String headersPath = environment.artifacts
6954
.getArtifactPath(
7055
Artifact.linuxHeaders,
@@ -83,7 +68,7 @@ class UnpackLinux extends Target {
8368
engineSourcePath: engineSourcePath,
8469
outputDirectory: outputDirectory,
8570
artifacts: _kLinuxArtifacts,
86-
clientSourcePaths: <String>[clientSourcePath, headersPath],
71+
clientSourcePaths: <String>[headersPath],
8772
icuDataPath: environment.artifacts.getArtifactPath(
8873
Artifact.icuData,
8974
platform: TargetPlatform.linux_x64,

packages/flutter_tools/lib/src/cache.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,10 +1400,6 @@ const List<List<String>> _windowsDesktopBinaryDirs = <List<String>>[
14001400
];
14011401

14021402
const List<List<String>> _linuxDesktopBinaryDirs = <List<String>>[
1403-
<String>['linux-x64', 'linux-x64/linux-x64-flutter-glfw.zip'],
1404-
<String>['linux-x64', 'linux-x64/flutter-cpp-client-wrapper-glfw.zip'],
1405-
<String>['linux-x64-profile', 'linux-x64-profile/linux-x64-flutter-glfw.zip'],
1406-
<String>['linux-x64-release', 'linux-x64-release/linux-x64-flutter-glfw.zip'],
14071403
<String>['linux-x64', 'linux-x64/linux-x64-flutter-gtk.zip'],
14081404
<String>['linux-x64-profile', 'linux-x64-profile/linux-x64-flutter-gtk.zip'],
14091405
<String>['linux-x64-release', 'linux-x64-release/linux-x64-flutter-gtk.zip'],

packages/flutter_tools/lib/src/commands/create.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,8 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
590590
final String pluginClass = pluginDartClass.endsWith('Plugin')
591591
? pluginDartClass
592592
: pluginDartClass + 'Plugin';
593+
final String pluginClassSnakeCase = snakeCase(pluginClass);
594+
final String pluginClassCapitalSnakeCase = pluginClassSnakeCase.toUpperCase();
593595
final String appleIdentifier = _createUTIIdentifier(organization, projectName);
594596

595597
return <String, dynamic>{
@@ -605,8 +607,9 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
605607
'androidSdkVersion': android_sdk.minimumAndroidSdkVersion,
606608
'withDriverTest': renderDriverTest,
607609
'pluginClass': pluginClass,
610+
'pluginClassSnakeCase': pluginClassSnakeCase,
611+
'pluginClassCapitalSnakeCase': pluginClassCapitalSnakeCase,
608612
'pluginDartClass': pluginDartClass,
609-
'pluginCppHeaderGuard': projectName.toUpperCase(),
610613
'pluginProjectUUID': Uuid().v4().toUpperCase(),
611614
'withPluginHook': withPluginHook,
612615
'androidLanguage': androidLanguage,

packages/flutter_tools/lib/src/linux/linux_doctor.dart

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class _VersionInfo {
1717
/// This should contain a version number. For example:
1818
/// "clang version 9.0.1-6+build1"
1919
_VersionInfo(this.description) {
20-
final String versionString = RegExp(r'[0-9]+\.[0-9]+\.[0-9]+').firstMatch(description).group(0);
20+
final String versionString = RegExp(r'[0-9]+\.[0-9]+(?:\.[0-9]+)?').firstMatch(description).group(0);
2121
number = Version.parse(versionString);
2222
}
2323

@@ -43,13 +43,21 @@ class LinuxDoctorValidator extends DoctorValidator {
4343
static const String kClangBinary = 'clang++';
4444
static const String kCmakeBinary = 'cmake';
4545
static const String kNinjaBinary = 'ninja';
46+
static const String kPkgConfigBinary = 'pkg-config';
4647

4748
final Map<String, Version> _requiredBinaryVersions = <String, Version>{
4849
kClangBinary: Version(3, 4, 0),
4950
kCmakeBinary: Version(3, 10, 0),
5051
kNinjaBinary: Version(1, 8, 0),
52+
kPkgConfigBinary: Version(0, 29, 0),
5153
};
5254

55+
final List<String> _requiredLibraries = <String>[
56+
'gtk+-3.0',
57+
'glib-2.0',
58+
'gio-2.0',
59+
];
60+
5361
@override
5462
Future<ValidationResult> validate() async {
5563
ValidationType validationType = ValidationType.installed;
@@ -103,7 +111,7 @@ class LinuxDoctorValidator extends DoctorValidator {
103111
if (version == null) {
104112
messages.add(ValidationMessage.error(_userMessages.ninjaMissing));
105113
} else {
106-
// The full version description is just the number, so context.
114+
// The full version description is just the number, so add context.
107115
messages.add(ValidationMessage(_userMessages.ninjaVersion(version.description)));
108116
final Version requiredVersion = _requiredBinaryVersions[kNinjaBinary];
109117
if (version.number < requiredVersion) {
@@ -112,6 +120,36 @@ class LinuxDoctorValidator extends DoctorValidator {
112120
}
113121
}
114122

123+
// Message for pkg-config.
124+
{
125+
final _VersionInfo version = installedVersions[kPkgConfigBinary];
126+
if (version == null) {
127+
messages.add(ValidationMessage.error(_userMessages.pkgConfigMissing));
128+
} else {
129+
// The full version description is just the number, so add context.
130+
messages.add(ValidationMessage(_userMessages.pkgConfigVersion(version.description)));
131+
final Version requiredVersion = _requiredBinaryVersions[kPkgConfigBinary];
132+
if (version.number < requiredVersion) {
133+
messages.add(ValidationMessage.error(_userMessages.pkgConfigTooOld(requiredVersion.toString())));
134+
}
135+
}
136+
}
137+
138+
// Message for libraries.
139+
{
140+
bool libraryMissing = false;
141+
for (final String library in _requiredLibraries) {
142+
if (!await _libraryIsPresent(library)) {
143+
libraryMissing = true;
144+
break;
145+
}
146+
}
147+
if (libraryMissing) {
148+
validationType = ValidationType.missing;
149+
messages.add(ValidationMessage.error(_userMessages.gtkLibrariesMissing));
150+
}
151+
}
152+
115153
return ValidationResult(validationType, messages);
116154
}
117155

@@ -135,4 +173,19 @@ class LinuxDoctorValidator extends DoctorValidator {
135173
final String firstLine = (result.stdout as String).split('\n').first.trim();
136174
return _VersionInfo(firstLine);
137175
}
176+
177+
/// Checks that [library] is available via pkg-config.
178+
Future<bool> _libraryIsPresent(String library) async {
179+
ProcessResult result;
180+
try {
181+
result = await _processManager.run(<String>[
182+
'pkg-config',
183+
'--exists',
184+
library,
185+
]);
186+
} on ArgumentError {
187+
// ignore error.
188+
}
189+
return (result?.exitCode ?? 1) == 0;
190+
}
138191
}

packages/flutter_tools/lib/src/plugins.dart

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,47 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
793793
}
794794
''';
795795

796+
const String _linuxPluginRegistryHeaderTemplate = '''
797+
//
798+
// Generated file. Do not edit.
799+
//
800+
801+
#ifndef GENERATED_PLUGIN_REGISTRANT_
802+
#define GENERATED_PLUGIN_REGISTRANT_
803+
804+
#include <flutter_linux/flutter_linux.h>
805+
806+
// Registers Flutter plugins.
807+
void fl_register_plugins(FlPluginRegistry* registry);
808+
809+
#endif // GENERATED_PLUGIN_REGISTRANT_
810+
''';
811+
812+
const String _linuxPluginRegistryImplementationTemplate = '''
813+
//
814+
// Generated file. Do not edit.
815+
//
816+
817+
#include "generated_plugin_registrant.h"
818+
819+
{{#plugins}}
820+
#include <{{name}}/{{filename}}.h>
821+
{{/plugins}}
822+
823+
void fl_register_plugins(FlPluginRegistry* registry) {
824+
{{#plugins}}
825+
g_autoptr(FlPluginRegistrar) {{name}}_registrar =
826+
fl_plugin_registry_get_registrar_for_plugin(registry, "{{class}}");
827+
{{filename}}_register_with_registrar({{name}}_registrar);
828+
{{/plugins}}
829+
}
830+
''';
831+
796832
const String _linuxPluginCmakefileTemplate = r'''
833+
#
834+
# Generated file, do not edit.
835+
#
836+
797837
list(APPEND FLUTTER_PLUGIN_LIST
798838
{{#plugins}}
799839
{{name}}
@@ -864,10 +904,24 @@ Future<void> _writeLinuxPluginFiles(FlutterProject project, List<Plugin> plugins
864904
from: makefileDirPath,
865905
),
866906
};
867-
await _writeCppPluginRegistrant(project.linux.managedDirectory, context);
907+
await _writeLinuxPluginRegistrant(project.linux.managedDirectory, context);
868908
await _writeLinuxPluginCmakefile(project.linux.generatedPluginCmakeFile, context);
869909
}
870910

911+
Future<void> _writeLinuxPluginRegistrant(Directory destination, Map<String, dynamic> templateContext) async {
912+
final String registryDirectory = destination.path;
913+
_renderTemplateToFile(
914+
_linuxPluginRegistryHeaderTemplate,
915+
templateContext,
916+
globals.fs.path.join(registryDirectory, 'generated_plugin_registrant.h'),
917+
);
918+
_renderTemplateToFile(
919+
_linuxPluginRegistryImplementationTemplate,
920+
templateContext,
921+
globals.fs.path.join(registryDirectory, 'generated_plugin_registrant.cc'),
922+
);
923+
}
924+
871925
Future<void> _writeLinuxPluginCmakefile(File destinationFile, Map<String, dynamic> templateContext) async {
872926
_renderTemplateToFile(
873927
_linuxPluginCmakefileTemplate,

packages/flutter_tools/templates/app/linux.tmpl/CMakeLists.txt.tmpl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,20 @@ set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
2828
# Flutter library and tool build rules.
2929
add_subdirectory(${FLUTTER_MANAGED_DIR})
3030

31+
# System-level dependencies.
32+
find_package(PkgConfig REQUIRED)
33+
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
34+
3135
# Application build
3236
add_executable(${BINARY_NAME}
3337
"main.cc"
38+
"my_application.cc"
3439
"window_configuration.cc"
3540
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
3641
)
3742
apply_standard_settings(${BINARY_NAME})
38-
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
43+
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
44+
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
3945
add_dependencies(${BINARY_NAME} flutter_assemble)
4046

4147
# Generated plugin build rules, which manage building the plugins and adding
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3
1+
4

0 commit comments

Comments
 (0)