mirror of
https://github.com/flutter/flutter
synced 2024-09-19 16:21:58 +00:00
Automatically wire dependencies for native plugins (#8891)
Go through all packages brought in by pub, and write the name and path of every one that is a flutter plugin into .flutter-plugins. In android/settings.gradle and ios/Podfile, read in .flutter-plugins, if that file exists. The Android / iOS code from the plugins is automatically added as dependencies of the native code of the app.
This commit is contained in:
parent
2d29c62590
commit
b61e169011
|
@ -34,13 +34,22 @@ class FlutterPlugin implements Plugin<Project> {
|
|||
private String localEngineSrcPath
|
||||
private Properties localProperties
|
||||
|
||||
private File flutterJar
|
||||
private File debugFlutterJar
|
||||
private File profileFlutterJar
|
||||
private File releaseFlutterJar
|
||||
|
||||
private Properties readPropertiesIfExist(File propertiesFile) {
|
||||
Properties result = new Properties()
|
||||
if (propertiesFile.exists()) {
|
||||
propertiesFile.withInputStream { stream -> result.load(stream) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private String resolveProperty(Project project, String name, String defaultValue) {
|
||||
if (localProperties == null) {
|
||||
localProperties = new Properties()
|
||||
def localPropertiesFile = project.rootProject.file("local.properties")
|
||||
if (localPropertiesFile.exists()) {
|
||||
localProperties.load(localPropertiesFile.newDataInputStream())
|
||||
}
|
||||
localProperties = readPropertiesIfExist(project.rootProject.file("local.properties"))
|
||||
}
|
||||
String result
|
||||
if (project.hasProperty(name)) {
|
||||
|
@ -82,7 +91,7 @@ class FlutterPlugin implements Plugin<Project> {
|
|||
if (!engineOut.isDirectory()) {
|
||||
throw new GradleException('localEngineOut must point to a local engine build')
|
||||
}
|
||||
File flutterJar = Paths.get(engineOut.absolutePath, "flutter.jar").toFile()
|
||||
flutterJar = Paths.get(engineOut.absolutePath, "flutter.jar").toFile()
|
||||
if (!flutterJar.isFile()) {
|
||||
throw new GradleException('Local engine build does not contain flutter.jar')
|
||||
}
|
||||
|
@ -95,9 +104,9 @@ class FlutterPlugin implements Plugin<Project> {
|
|||
}
|
||||
} else {
|
||||
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
|
||||
File debugFlutterJar = baseEnginePath.resolve("android-arm").resolve("flutter.jar").toFile()
|
||||
File profileFlutterJar = baseEnginePath.resolve("android-arm-profile").resolve("flutter.jar").toFile()
|
||||
File releaseFlutterJar = baseEnginePath.resolve("android-arm-release").resolve("flutter.jar").toFile()
|
||||
debugFlutterJar = baseEnginePath.resolve("android-arm").resolve("flutter.jar").toFile()
|
||||
profileFlutterJar = baseEnginePath.resolve("android-arm-profile").resolve("flutter.jar").toFile()
|
||||
releaseFlutterJar = baseEnginePath.resolve("android-arm-release").resolve("flutter.jar").toFile()
|
||||
if (!debugFlutterJar.isFile()) {
|
||||
project.exec {
|
||||
executable flutterExecutable.absolutePath
|
||||
|
@ -130,6 +139,32 @@ class FlutterPlugin implements Plugin<Project> {
|
|||
|
||||
project.extensions.create("flutter", FlutterExtension)
|
||||
project.afterEvaluate this.&addFlutterTask
|
||||
|
||||
File pluginsFile = new File(project.rootProject.projectDir.parentFile, '.flutter-plugins')
|
||||
Properties plugins = readPropertiesIfExist(pluginsFile)
|
||||
|
||||
plugins.each { name, _ ->
|
||||
def pluginProject = project.rootProject.findProject(":$name")
|
||||
if (pluginProject != null) {
|
||||
project.dependencies {
|
||||
compile pluginProject
|
||||
}
|
||||
pluginProject.afterEvaluate this.&addFlutterJarDependency
|
||||
} else {
|
||||
project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addFlutterJarDependency(Project project) {
|
||||
project.dependencies {
|
||||
if (flutterJar != null) {
|
||||
provided project.files(flutterJar)
|
||||
} else {
|
||||
debugProvided project.files(debugFlutterJar)
|
||||
releaseProvided project.files(releaseFlutterJar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addFlutterTask(Project project) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import '../base/utils.dart';
|
|||
import '../build_info.dart';
|
||||
import '../cache.dart';
|
||||
import '../globals.dart';
|
||||
import '../plugins.dart';
|
||||
import 'android_sdk.dart';
|
||||
import 'android_studio.dart';
|
||||
|
||||
|
@ -154,6 +155,8 @@ Future<Null> buildGradleProject(BuildMode buildMode, String target, String kerne
|
|||
settings.values['flutter.buildMode'] = buildModeName;
|
||||
settings.writeContents(localProperties);
|
||||
|
||||
writeFlutterPluginsList();
|
||||
|
||||
final String gradle = ensureGradle();
|
||||
|
||||
switch (flutterPluginVersion) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import '../build_info.dart';
|
|||
import '../doctor.dart';
|
||||
import '../flx.dart' as flx;
|
||||
import '../globals.dart';
|
||||
import '../plugins.dart';
|
||||
import '../services.dart';
|
||||
import 'xcodeproj.dart';
|
||||
|
||||
|
@ -127,6 +128,7 @@ Future<XcodeBuildResult> buildXcodeProject({
|
|||
// copied over to a location that is suitable for Xcodebuild to find them.
|
||||
final Directory appDirectory = fs.directory(app.appDirectory);
|
||||
await _addServicesToBundle(appDirectory);
|
||||
writeFlutterPluginsList();
|
||||
|
||||
_runPodInstall(appDirectory, flutterFrameworkDir(mode));
|
||||
|
||||
|
|
52
packages/flutter_tools/lib/src/plugins.dart
Normal file
52
packages/flutter_tools/lib/src/plugins.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2017 The Chromium 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:yaml/yaml.dart';
|
||||
|
||||
import 'base/file_system.dart';
|
||||
import 'dart/package_map.dart';
|
||||
import 'globals.dart';
|
||||
|
||||
dynamic _loadYamlFile(String path) {
|
||||
if (!fs.isFileSync(path))
|
||||
return null;
|
||||
final String manifestString = fs.file(path).readAsStringSync();
|
||||
return loadYaml(manifestString);
|
||||
}
|
||||
|
||||
String _generatePluginManifest() {
|
||||
Map<String, Uri> packages;
|
||||
try {
|
||||
packages = new PackageMap(PackageMap.globalPackagesPath).map;
|
||||
} on FormatException catch(e) {
|
||||
printTrace('Invalid .packages file: $e');
|
||||
return '';
|
||||
}
|
||||
final List<String> plugins = <String>[];
|
||||
packages.forEach((String name, Uri uri) {
|
||||
final Uri packageRoot = uri.resolve('..');
|
||||
final dynamic packageConfig = _loadYamlFile(packageRoot.resolve('pubspec.yaml').path);
|
||||
if (packageConfig != null) {
|
||||
final dynamic flutterConfig = packageConfig['flutter'];
|
||||
if (flutterConfig != null && flutterConfig.containsKey('plugin')) {
|
||||
printTrace('Found plugin $name at ${packageRoot.path}');
|
||||
plugins.add('$name=${packageRoot.path}');
|
||||
}
|
||||
}
|
||||
});
|
||||
return plugins.join('\n');
|
||||
}
|
||||
|
||||
void writeFlutterPluginsList() {
|
||||
final File pluginsProperties = fs.file('.flutter-plugins');
|
||||
|
||||
final String pluginManifest = _generatePluginManifest();
|
||||
if (pluginManifest.isNotEmpty) {
|
||||
pluginsProperties.writeAsStringSync('$pluginManifest\n');
|
||||
} else {
|
||||
if (pluginsProperties.existsSync()) {
|
||||
pluginsProperties.deleteSync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,3 +7,4 @@ build/
|
|||
ios/.generated/
|
||||
packages
|
||||
pubspec.lock
|
||||
.flutter-plugins
|
||||
|
|
|
@ -1 +1,15 @@
|
|||
include ':app'
|
||||
|
||||
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
|
||||
|
||||
def plugins = new Properties()
|
||||
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
|
||||
if (pluginsFile.exists()) {
|
||||
pluginsFile.withInputStream { stream -> plugins.load(stream) }
|
||||
}
|
||||
|
||||
plugins.each { name, path ->
|
||||
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
|
||||
include ":$name"
|
||||
project(":$name").projectDir = pluginDirectory
|
||||
}
|
||||
|
|
|
@ -1,10 +1,38 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '9.0'
|
||||
|
||||
if ENV['FLUTTER_FRAMEWORK_DIR'] == nil
|
||||
abort('Please set FLUTTER_FRAMEWORK_DIR to the directory containing Flutter.framework')
|
||||
end
|
||||
|
||||
target 'Runner' do
|
||||
# Uncomment this line if you're using Swift or would like to use dynamic frameworks
|
||||
# use_frameworks!
|
||||
use_frameworks!
|
||||
|
||||
# Pods for Runner
|
||||
|
||||
# Flutter Pods
|
||||
pod 'Flutter', :path => ENV['FLUTTER_FRAMEWORK_DIR']
|
||||
|
||||
if File.exists? '../.flutter-plugins'
|
||||
flutter_root = File.expand_path('..')
|
||||
File.foreach('../.flutter-plugins') { |line|
|
||||
plugin = line.split(pattern='=')
|
||||
if plugin.length == 2
|
||||
name = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
resolved_path = File.expand_path("#{path}/ios", flutter_root)
|
||||
pod name, :path => resolved_path
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue