Migrator for android 35/16kb page size cmake flags for plugin_ffi (#156221)
Migrates existing instantions of `--template plugin_ffi` to deal with Android 15 16kb memory pages. Issue: * https://github.com/flutter/flutter/issues/155933 @reidbaker I could only find migrations that run from the root application. However the file needing to be migrated is a plugin. The plugin is being referenced from the example in the example dir and that's where the migrator is run, so I wrote the code so that it walks up to find the plugin. Do you know of a way to run migrators to non-root projects? (Can we even safely do so, e.g. the non-root could be in the pub cache, could be a different project on the users' system etc. So maybe checking if we are in the examples dir is the only sane thing to do?) Tests: * Added unit tests in `test/general.shard/android/migrations/cmake_android_16k_pages_migration_test.dart`
This commit is contained in:
parent
d768a72b85
commit
e695cd6e9a
@ -35,6 +35,7 @@ import 'gradle_errors.dart';
|
||||
import 'gradle_utils.dart';
|
||||
import 'java.dart';
|
||||
import 'migrations/android_studio_java_gradle_conflict_migration.dart';
|
||||
import 'migrations/cmake_android_16k_pages_migration.dart';
|
||||
import 'migrations/min_sdk_version_migration.dart';
|
||||
import 'migrations/multidex_removal_migration.dart';
|
||||
import 'migrations/top_level_gradle_build_file_migration.dart';
|
||||
@ -311,6 +312,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
||||
java: globals.java),
|
||||
MinSdkVersionMigration(project.android, _logger),
|
||||
MultidexRemovalMigration(project.android, _logger),
|
||||
CmakeAndroid16kPagesMigration(project.android, _logger),
|
||||
];
|
||||
|
||||
final ProjectMigration migration = ProjectMigration(migrators);
|
||||
|
@ -0,0 +1,74 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import '../../base/file_system.dart';
|
||||
import '../../base/project_migrator.dart';
|
||||
import '../../project.dart';
|
||||
|
||||
/// Adds the snippet to the CMake file to compile for Android 15.
|
||||
///
|
||||
/// Location of CMakeLists.txt is the src/CMakeLists.txt in the plugin
|
||||
/// created with --template plugin_ffi.
|
||||
///
|
||||
/// ```cmake
|
||||
/// if (ANDROID)
|
||||
/// # Support Android 15 16k page size.
|
||||
/// target_link_options({{projectName}} PRIVATE "-Wl,-z,max-page-size=16384")
|
||||
/// endif()
|
||||
/// ```
|
||||
class CmakeAndroid16kPagesMigration extends ProjectMigrator {
|
||||
CmakeAndroid16kPagesMigration(AndroidProject project, super.logger)
|
||||
: _project = project;
|
||||
|
||||
final AndroidProject _project;
|
||||
|
||||
@override
|
||||
Future<void> migrate() async {
|
||||
// If the migrator is run in the example directory, navigate to the
|
||||
// plugin directory which contains src/CMakeLists.txt.
|
||||
final File cmakeLists = _project.parent.directory.parent
|
||||
.childDirectory('src/')
|
||||
.childFile('CMakeLists.txt');
|
||||
|
||||
if (!cmakeLists.existsSync()) {
|
||||
logger.printTrace(
|
||||
'CMake project not found, skipping support Android 15 16k page size migration.');
|
||||
return;
|
||||
}
|
||||
|
||||
final String original = cmakeLists.readAsStringSync();
|
||||
|
||||
if (original.contains('-Wl,-z,max-page-size=16384')) {
|
||||
// Link flags already present.
|
||||
return;
|
||||
}
|
||||
|
||||
final RegExp regex =
|
||||
RegExp(r'target_compile_definitions\(([^ ]*) PUBLIC DART_SHARED_LIB\)');
|
||||
final String? projectName = regex.firstMatch(original)?.group(1);
|
||||
const String before = '''
|
||||
PUBLIC DART_SHARED_LIB)
|
||||
''';
|
||||
|
||||
/// Relevant template: templates/plugin_ffi/src.tmpl/CMakeLists.txt.tmpl
|
||||
final String linkerFlags = '''
|
||||
|
||||
if (ANDROID)
|
||||
# Support Android 15 16k page size.
|
||||
target_link_options($projectName PRIVATE "-Wl,-z,max-page-size=16384")
|
||||
endif()
|
||||
''';
|
||||
|
||||
final String updated = original.replaceFirst(
|
||||
before,
|
||||
'$before$linkerFlags',
|
||||
);
|
||||
|
||||
if (original != updated) {
|
||||
logger.printStatus(
|
||||
'CMake missing support Android 15 16k page size, updating.');
|
||||
cmakeLists.writeAsStringSync(updated);
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ set_target_properties({{projectName}} PROPERTIES
|
||||
|
||||
target_compile_definitions({{projectName}} PUBLIC DART_SHARED_LIB)
|
||||
|
||||
if(ANDROID)
|
||||
if (ANDROID)
|
||||
# Support Android 15 16k page size
|
||||
target_link_options({{projectName}} PRIVATE "-Wl,-z,max-page-size=16384")
|
||||
endif()
|
||||
|
@ -3202,6 +3202,9 @@ void main() {
|
||||
expect(cmakeLists.existsSync(), true);
|
||||
|
||||
final String cmakeListsContent = await cmakeLists.readAsString();
|
||||
// If we ever change the flags, this should be accounted for in the
|
||||
// migration as well:
|
||||
// lib/src/android/migrations/cmake_android_16k_pages_migration.dart
|
||||
const String expected16KbFlags = 'PRIVATE "-Wl,-z,max-page-size=16384")';
|
||||
expect(cmakeListsContent, contains(expected16KbFlags));
|
||||
});
|
||||
|
@ -0,0 +1,136 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/android/migrations/cmake_android_16k_pages_migration.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:test/fake.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
|
||||
const String _sampleCmakeListsTxtUnmigrated = r'''
|
||||
# The Flutter tooling requires that developers have CMake 3.10 or later
|
||||
# installed. You should not increase this version, as doing so will cause
|
||||
# the plugin to fail to compile for some customers of the plugin.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(my_plugin_library VERSION 0.0.1 LANGUAGES C)
|
||||
|
||||
add_library(my_plugin SHARED
|
||||
"my_plugin.c"
|
||||
)
|
||||
|
||||
set_target_properties(my_plugin PROPERTIES
|
||||
PUBLIC_HEADER my_plugin.h
|
||||
OUTPUT_NAME "my_plugin"
|
||||
)
|
||||
|
||||
target_compile_definitions(my_plugin PUBLIC DART_SHARED_LIB)
|
||||
''';
|
||||
|
||||
const String _sampleCmakeListsTxtMigrated = r'''
|
||||
# The Flutter tooling requires that developers have CMake 3.10 or later
|
||||
# installed. You should not increase this version, as doing so will cause
|
||||
# the plugin to fail to compile for some customers of the plugin.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(my_plugin_library VERSION 0.0.1 LANGUAGES C)
|
||||
|
||||
add_library(my_plugin SHARED
|
||||
"my_plugin.c"
|
||||
)
|
||||
|
||||
set_target_properties(my_plugin PROPERTIES
|
||||
PUBLIC_HEADER my_plugin.h
|
||||
OUTPUT_NAME "my_plugin"
|
||||
)
|
||||
|
||||
target_compile_definitions(my_plugin PUBLIC DART_SHARED_LIB)
|
||||
|
||||
if (ANDROID)
|
||||
# Support Android 15 16k page size.
|
||||
target_link_options(my_plugin PRIVATE "-Wl,-z,max-page-size=16384")
|
||||
endif()
|
||||
''';
|
||||
|
||||
void main() {
|
||||
group('Android migration', () {
|
||||
group('CMake file', () {
|
||||
late MemoryFileSystem memoryFileSystem;
|
||||
late File cmakeFile;
|
||||
late BufferLogger bufferLogger;
|
||||
late FakeAndroidProject project;
|
||||
late CmakeAndroid16kPagesMigration migration;
|
||||
|
||||
setUp(() {
|
||||
memoryFileSystem = MemoryFileSystem.test();
|
||||
final Directory pluginDir = memoryFileSystem.currentDirectory;
|
||||
final Directory exampleDir = pluginDir.childDirectory('example');
|
||||
exampleDir.createSync();
|
||||
final Directory androidDir = exampleDir.childDirectory('android');
|
||||
androidDir.createSync();
|
||||
final Directory srcDir = pluginDir.childDirectory('src');
|
||||
srcDir.createSync();
|
||||
cmakeFile = srcDir.childFile('CMakeLists.txt');
|
||||
cmakeFile.writeAsString(_sampleCmakeListsTxtMigrated);
|
||||
|
||||
bufferLogger = BufferLogger.test();
|
||||
project = FakeAndroidProject(
|
||||
parent: FakeFlutterProject(
|
||||
directory: exampleDir,
|
||||
),
|
||||
);
|
||||
migration = CmakeAndroid16kPagesMigration(project, bufferLogger);
|
||||
});
|
||||
|
||||
testWithoutContext('do nothing when files missing', () async {
|
||||
cmakeFile.deleteSync();
|
||||
await migration.migrate();
|
||||
expect(
|
||||
bufferLogger.traceText,
|
||||
contains(
|
||||
'CMake project not found, skipping support Android 15 16k page size migration.',
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('migrate', () async {
|
||||
cmakeFile.writeAsStringSync(_sampleCmakeListsTxtUnmigrated);
|
||||
await migration.migrate();
|
||||
expect(
|
||||
cmakeFile.readAsStringSync(),
|
||||
_sampleCmakeListsTxtMigrated,
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('do nothing when already migrated', () async {
|
||||
expect(
|
||||
cmakeFile.readAsStringSync(),
|
||||
_sampleCmakeListsTxtMigrated,
|
||||
);
|
||||
await migration.migrate();
|
||||
expect(
|
||||
cmakeFile.readAsStringSync(),
|
||||
_sampleCmakeListsTxtMigrated,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class FakeAndroidProject extends Fake implements AndroidProject {
|
||||
FakeAndroidProject({required this.parent});
|
||||
|
||||
@override
|
||||
FlutterProject parent;
|
||||
}
|
||||
|
||||
class FakeFlutterProject extends Fake implements FlutterProject {
|
||||
FakeFlutterProject({required this.directory});
|
||||
|
||||
@override
|
||||
final Directory directory;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user