mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
Update gradle example to support x86 in debug mode. (#7606)
* Update gradle example to support x86 in debug mode. Changed the Flutter Gradle plugin a bit to better fit in with the Android build. Fixes #6136 Fixes #6864 Fixes #7539
This commit is contained in:
parent
4cace66dbc
commit
a0f0c42fe3
|
@ -2,8 +2,8 @@ apply plugin: 'com.android.application'
|
||||||
apply plugin: 'flutter'
|
apply plugin: 'flutter'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 22
|
compileSdkVersion 25
|
||||||
buildToolsVersion '22.0.1'
|
buildToolsVersion '24.0.2'
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
disable 'InvalidPackage'
|
disable 'InvalidPackage'
|
||||||
|
@ -12,6 +12,14 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// TODO: Add your own signing config for the release build.
|
||||||
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
|
@ -19,7 +27,7 @@ flutter {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
androidTestCompile 'com.android.support:support-annotations:22.0.0'
|
androidTestCompile 'com.android.support:support-annotations:25.0.0'
|
||||||
androidTestCompile 'com.android.support.test:runner:0.5'
|
androidTestCompile 'com.android.support.test:runner:0.5'
|
||||||
androidTestCompile 'com.android.support.test:rules:0.5'
|
androidTestCompile 'com.android.support.test:rules:0.5'
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
package org.domokit.sky.gradle
|
package io.flutter.gradle
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
|
||||||
import com.android.builder.model.AndroidProject
|
import com.android.builder.model.AndroidProject
|
||||||
import com.google.common.base.Joiner
|
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
@ -14,71 +16,102 @@ import org.gradle.api.Task
|
||||||
import org.gradle.api.file.CopySpec
|
import org.gradle.api.file.CopySpec
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.tasks.Copy
|
import org.gradle.api.tasks.Copy
|
||||||
import org.gradle.api.tasks.InputDirectory
|
import org.gradle.api.tasks.InputFiles
|
||||||
import org.gradle.api.tasks.OutputDirectory
|
import org.gradle.api.tasks.OutputDirectory
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
|
|
||||||
class FlutterPlugin implements Plugin<Project> {
|
class FlutterPlugin implements Plugin<Project> {
|
||||||
private File flutterRoot
|
private File flutterRoot
|
||||||
private String buildMode
|
|
||||||
private String localEngine
|
private String localEngine
|
||||||
|
private Properties localProperties
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String result;
|
||||||
|
if (project.hasProperty(name)) {
|
||||||
|
result = project.property(name)
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
result = localProperties.getProperty(name)
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
result = defaultValue
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void apply(Project project) {
|
void apply(Project project) {
|
||||||
Properties properties = new Properties()
|
// Add a 'profile' build type
|
||||||
properties.load(project.rootProject.file("local.properties").newDataInputStream())
|
project.android.buildTypes {
|
||||||
|
profile {
|
||||||
|
initWith debug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String flutterRootPath = properties.getProperty("flutter.sdk")
|
String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_HOME)
|
||||||
if (flutterRootPath == null) {
|
if (flutterRootPath == null) {
|
||||||
throw new GradleException("flutter.sdk must be defined in local.properties")
|
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_HOME environment variable.")
|
||||||
}
|
}
|
||||||
flutterRoot = project.file(flutterRootPath)
|
flutterRoot = project.file(flutterRootPath)
|
||||||
if (!flutterRoot.isDirectory()) {
|
if (!flutterRoot.isDirectory()) {
|
||||||
throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
|
throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
buildMode = properties.getProperty("flutter.buildMode")
|
String flutterJarPath = localProperties.getProperty("flutter.jar")
|
||||||
if (buildMode == null) {
|
|
||||||
buildMode = "release"
|
|
||||||
}
|
|
||||||
if (!["debug", "profile", "release"].contains(buildMode)) {
|
|
||||||
throw new GradleException("flutter.buildMode must be one of \"debug\", \"profile\", or \"release\" but was \"${buildMode}\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
File flutterJar
|
|
||||||
String flutterJarPath = properties.getProperty("flutter.jar")
|
|
||||||
if (flutterJarPath != null) {
|
if (flutterJarPath != null) {
|
||||||
flutterJar = project.file(flutterJarPath)
|
File flutterJar = project.file(flutterJarPath)
|
||||||
if (!flutterJar.isFile()) {
|
if (!flutterJar.isFile()) {
|
||||||
throw new GradleException("flutter.jar must point to a Flutter engine JAR")
|
throw new GradleException("flutter.jar must point to a Flutter engine JAR")
|
||||||
}
|
}
|
||||||
} else {
|
project.dependencies {
|
||||||
// TODO(abarth): Support x64 and x86 in addition to arm.
|
compile project.files(flutterJar)
|
||||||
String artifactType = "unknown";
|
|
||||||
if (buildMode == "debug") {
|
|
||||||
artifactType = "android-arm"
|
|
||||||
} else if (buildMode == "profile") {
|
|
||||||
artifactType = "android-arm-profile"
|
|
||||||
} else if (buildMode == "release") {
|
|
||||||
artifactType = "android-arm-release"
|
|
||||||
}
|
}
|
||||||
flutterJar = new File(flutterRoot, Joiner.on(File.separatorChar).join(
|
} else {
|
||||||
"bin", "cache", "artifacts", "engine", artifactType, "flutter.jar"))
|
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
|
||||||
if (!flutterJar.isFile()) {
|
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()
|
||||||
|
if (!debugFlutterJar.isFile()) {
|
||||||
project.exec {
|
project.exec {
|
||||||
executable "${flutterRoot}/bin/flutter"
|
executable "${flutterRoot}/bin/flutter"
|
||||||
args "precache"
|
args "precache"
|
||||||
}
|
}
|
||||||
if (!flutterJar.isFile()) {
|
if (!debugFlutterJar.isFile()) {
|
||||||
throw new GradleException("Unable to find flutter.jar in SDK: ${flutterJar}")
|
throw new GradleException("Unable to find flutter.jar in SDK: ${debugFlutterJar}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add x86/x86_64 native library. Debug mode only, for now.
|
||||||
|
File flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar")
|
||||||
|
project.tasks.create("flutterBuildX86Jar", Jar) {
|
||||||
|
destinationDir flutterX86Jar.parentFile
|
||||||
|
archiveName flutterX86Jar.name
|
||||||
|
from("${flutterRoot}/bin/cache/artifacts/engine/android-x86/libsky_shell.so") {
|
||||||
|
into "lib/x86"
|
||||||
|
}
|
||||||
|
from("${flutterRoot}/bin/cache/artifacts/engine/android-x64/libsky_shell.so") {
|
||||||
|
into "lib/x86_64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.dependencies {
|
||||||
|
debugCompile project.files(flutterX86Jar, debugFlutterJar)
|
||||||
|
profileCompile project.files(profileFlutterJar)
|
||||||
|
releaseCompile project.files(releaseFlutterJar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localEngine = properties.getProperty("flutter.localEngine")
|
localEngine = localProperties.getProperty("flutter.localEngine")
|
||||||
|
|
||||||
project.extensions.create("flutter", FlutterExtension)
|
project.extensions.create("flutter", FlutterExtension)
|
||||||
project.dependencies.add("compile", project.files(flutterJar))
|
|
||||||
project.afterEvaluate this.&addFlutterTask
|
project.afterEvaluate this.&addFlutterTask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,21 +120,27 @@ class FlutterPlugin implements Plugin<Project> {
|
||||||
throw new GradleException("Must provide Flutter source directory")
|
throw new GradleException("Must provide Flutter source directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
String target = project.flutter.target;
|
String target = project.flutter.target
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
target = 'lib/main.dart'
|
target = 'lib/main.dart'
|
||||||
}
|
}
|
||||||
|
|
||||||
FlutterTask flutterTask = project.tasks.create("flutterBuild", FlutterTask) {
|
project.compileDebugJavaWithJavac.dependsOn project.flutterBuildX86Jar
|
||||||
flutterRoot this.flutterRoot
|
|
||||||
buildMode this.buildMode
|
|
||||||
localEngine this.localEngine
|
|
||||||
targetPath target
|
|
||||||
sourceDir project.file(project.flutter.source)
|
|
||||||
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter")
|
|
||||||
}
|
|
||||||
|
|
||||||
project.android.applicationVariants.all { variant ->
|
project.android.applicationVariants.all { variant ->
|
||||||
|
if (!["debug", "profile", "release"].contains(variant.name)) {
|
||||||
|
throw new GradleException("Build variant must be one of \"debug\", \"profile\", or \"release\" but was \"${variant.name}\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
FlutterTask flutterTask = project.tasks.create("flutterBuild${variant.name.capitalize()}", FlutterTask) {
|
||||||
|
flutterRoot this.flutterRoot
|
||||||
|
buildMode variant.name
|
||||||
|
localEngine this.localEngine
|
||||||
|
targetPath target
|
||||||
|
sourceDir project.file(project.flutter.source)
|
||||||
|
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
|
||||||
|
}
|
||||||
|
|
||||||
Task copyFlxTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
|
Task copyFlxTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
|
||||||
dependsOn flutterTask
|
dependsOn flutterTask
|
||||||
dependsOn variant.mergeAssets
|
dependsOn variant.mergeAssets
|
||||||
|
@ -124,7 +163,6 @@ class FlutterTask extends DefaultTask {
|
||||||
String localEngine
|
String localEngine
|
||||||
String targetPath
|
String targetPath
|
||||||
|
|
||||||
@InputDirectory
|
|
||||||
File sourceDir
|
File sourceDir
|
||||||
|
|
||||||
@OutputDirectory
|
@OutputDirectory
|
||||||
|
@ -142,6 +180,11 @@ class FlutterTask extends DefaultTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InputFiles
|
||||||
|
FileCollection getSourceFiles() {
|
||||||
|
return project.fileTree(dir: sourceDir, exclude: ['android', 'ios'], include: ['**/*.dart', 'pubspec.yaml', 'flutter.yaml'])
|
||||||
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
void build() {
|
void build() {
|
||||||
if (!sourceDir.isDirectory()) {
|
if (!sourceDir.isDirectory()) {
|
||||||
|
@ -151,34 +194,34 @@ class FlutterTask extends DefaultTask {
|
||||||
intermediateDir.mkdirs()
|
intermediateDir.mkdirs()
|
||||||
|
|
||||||
if (buildMode != "debug") {
|
if (buildMode != "debug") {
|
||||||
project.exec {
|
project.exec {
|
||||||
executable "${flutterRoot}/bin/flutter"
|
executable "${flutterRoot}/bin/flutter"
|
||||||
workingDir sourceDir
|
workingDir sourceDir
|
||||||
if (localEngine != null) {
|
if (localEngine != null) {
|
||||||
args "--local-engine", localEngine
|
args "--local-engine", localEngine
|
||||||
|
}
|
||||||
|
args "build", "aot"
|
||||||
|
args "--target", targetPath
|
||||||
|
args "--target-platform", "android-arm"
|
||||||
|
args "--output-dir", "${intermediateDir}"
|
||||||
|
args "--${buildMode}"
|
||||||
}
|
}
|
||||||
args "build", "aot"
|
|
||||||
args "--target", targetPath
|
|
||||||
args "--target-platform", "android-arm"
|
|
||||||
args "--output-dir", "${intermediateDir}"
|
|
||||||
args "--${buildMode}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.exec {
|
project.exec {
|
||||||
executable "${flutterRoot}/bin/flutter"
|
executable "${flutterRoot}/bin/flutter"
|
||||||
workingDir sourceDir
|
workingDir sourceDir
|
||||||
if (localEngine != null) {
|
if (localEngine != null) {
|
||||||
args "--local-engine", localEngine
|
args "--local-engine", localEngine
|
||||||
}
|
}
|
||||||
args "build", "flx"
|
args "build", "flx"
|
||||||
args "--target", targetPath
|
args "--target", targetPath
|
||||||
args "--output-file", "${intermediateDir}/app.flx"
|
args "--output-file", "${intermediateDir}/app.flx"
|
||||||
if (buildMode != "debug") {
|
if (buildMode != "debug") {
|
||||||
args "--precompiled"
|
args "--precompiled"
|
||||||
} else {
|
} else {
|
||||||
args "--snapshot", "${intermediateDir}/snapshot_blob.bin"
|
args "--snapshot", "${intermediateDir}/snapshot_blob.bin"
|
||||||
args "--depfile", "${intermediateDir}/snapshot_blob.bin.d"
|
args "--depfile", "${intermediateDir}/snapshot_blob.bin.d"
|
||||||
}
|
}
|
||||||
args "--working-dir", "${intermediateDir}/flx"
|
args "--working-dir", "${intermediateDir}/flx"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
implementation-class=org.domokit.sky.gradle.FlutterPlugin
|
implementation-class=io.flutter.gradle.FlutterPlugin
|
||||||
|
|
1
examples/hello_services/android/gradle.properties
Normal file
1
examples/hello_services/android/gradle.properties
Normal file
|
@ -0,0 +1 @@
|
||||||
|
org.gradle.jvmargs=-Xmx1536M
|
|
@ -274,6 +274,11 @@ class AndroidDevice extends Device {
|
||||||
if (!_checkForSupportedAdbVersion() || !_checkForSupportedAndroidVersion())
|
if (!_checkForSupportedAdbVersion() || !_checkForSupportedAndroidVersion())
|
||||||
return new LaunchResult.failed();
|
return new LaunchResult.failed();
|
||||||
|
|
||||||
|
if (platform != TargetPlatform.android_arm && mode != BuildMode.debug) {
|
||||||
|
printError('Profile and release builds are only supported on ARM targets.');
|
||||||
|
return new LaunchResult.failed();
|
||||||
|
}
|
||||||
|
|
||||||
printTrace("Stopping app '${package.name}' on $name.");
|
printTrace("Stopping app '${package.name}' on $name.");
|
||||||
await stopApp(package);
|
await stopApp(package);
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,44 @@ import '../globals.dart';
|
||||||
import 'android_sdk.dart';
|
import 'android_sdk.dart';
|
||||||
|
|
||||||
const String gradleManifestPath = 'android/app/src/main/AndroidManifest.xml';
|
const String gradleManifestPath = 'android/app/src/main/AndroidManifest.xml';
|
||||||
const String gradleAppOut = 'android/app/build/outputs/apk/app-debug.apk';
|
const String gradleAppOutV1 = 'android/app/build/outputs/apk/app-debug.apk';
|
||||||
|
const String gradleAppOutV2 = 'android/app/build/outputs/apk/app.apk';
|
||||||
|
const String gradleAppOutDir = 'android/app/build/outputs/apk';
|
||||||
|
|
||||||
|
enum FlutterPluginVersion {
|
||||||
|
none,
|
||||||
|
v1,
|
||||||
|
v2,
|
||||||
|
}
|
||||||
|
|
||||||
bool isProjectUsingGradle() {
|
bool isProjectUsingGradle() {
|
||||||
return fs.isFileSync('android/build.gradle');
|
return fs.isFileSync('android/build.gradle');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlutterPluginVersion get flutterPluginVersion {
|
||||||
|
File plugin = fs.file('android/buildSrc/src/main/groovy/FlutterPlugin.groovy');
|
||||||
|
if (!plugin.existsSync()) {
|
||||||
|
return FlutterPluginVersion.none;
|
||||||
|
}
|
||||||
|
String packageLine = plugin.readAsLinesSync().skip(4).first;
|
||||||
|
if (packageLine == "package io.flutter.gradle") {
|
||||||
|
return FlutterPluginVersion.v2;
|
||||||
|
}
|
||||||
|
return FlutterPluginVersion.v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String get gradleAppOut {
|
||||||
|
switch (flutterPluginVersion) {
|
||||||
|
case FlutterPluginVersion.none:
|
||||||
|
// Fall through. Pretend we're v1, and just go with it.
|
||||||
|
case FlutterPluginVersion.v1:
|
||||||
|
return gradleAppOutV1;
|
||||||
|
case FlutterPluginVersion.v2:
|
||||||
|
return gradleAppOutV2;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String locateSystemGradle({ bool ensureExecutable: true }) {
|
String locateSystemGradle({ bool ensureExecutable: true }) {
|
||||||
String gradle = _locateSystemGradle();
|
String gradle = _locateSystemGradle();
|
||||||
if (ensureExecutable && gradle != null) {
|
if (ensureExecutable && gradle != null) {
|
||||||
|
@ -91,29 +123,14 @@ String locateProjectGradlew({ bool ensureExecutable: true }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Null> buildGradleProject(BuildMode buildMode) async {
|
Future<String> ensureGradlew() async {
|
||||||
// Create android/local.properties.
|
|
||||||
File localProperties = fs.file('android/local.properties');
|
|
||||||
if (!localProperties.existsSync()) {
|
|
||||||
localProperties.writeAsStringSync(
|
|
||||||
'sdk.dir=${androidSdk.directory}\n'
|
|
||||||
'flutter.sdk=${Cache.flutterRoot}\n'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the local.settings file with the build mode.
|
|
||||||
// TODO(devoncarew): It would be nicer if we could pass this information in via a cli flag.
|
|
||||||
SettingsFile settings = new SettingsFile.parseFromFile(localProperties);
|
|
||||||
settings.values['flutter.buildMode'] = getModeName(buildMode);
|
|
||||||
settings.writeContents(localProperties);
|
|
||||||
|
|
||||||
String gradlew = locateProjectGradlew();
|
String gradlew = locateProjectGradlew();
|
||||||
|
|
||||||
if (gradlew == null) {
|
if (gradlew == null) {
|
||||||
String gradle = locateSystemGradle();
|
String gradle = locateSystemGradle();
|
||||||
if (gradle == null) {
|
if (gradle == null) {
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
'Unable to locate gradle. Please configure the path to gradle using \'flutter config --gradle-dir\'.'
|
'Unable to locate gradle. Please configure the path to gradle using \'flutter config --gradle-dir\'.'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
printTrace('Using gradle from $gradle.');
|
printTrace('Using gradle from $gradle.');
|
||||||
|
@ -130,12 +147,15 @@ Future<Null> buildGradleProject(BuildMode buildMode) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run 'gradle wrapper'.
|
// Run 'gradle wrapper'.
|
||||||
|
List<String> command = logger.isVerbose
|
||||||
|
? <String>[gradle, 'wrapper']
|
||||||
|
: <String>[gradle, '-q', 'wrapper'];
|
||||||
try {
|
try {
|
||||||
Status status = logger.startProgress('Running \'gradle wrapper\'...');
|
Status status = logger.startProgress('Running \'gradle wrapper\'...');
|
||||||
int exitcode = await runCommandAndStreamOutput(
|
int exitcode = await runCommandAndStreamOutput(
|
||||||
<String>[gradle, 'wrapper'],
|
command,
|
||||||
workingDirectory: 'android',
|
workingDirectory: 'android',
|
||||||
allowReentrantFlutter: true
|
allowReentrantFlutter: true
|
||||||
);
|
);
|
||||||
status.stop();
|
status.stop();
|
||||||
if (exitcode != 0)
|
if (exitcode != 0)
|
||||||
|
@ -149,10 +169,44 @@ Future<Null> buildGradleProject(BuildMode buildMode) async {
|
||||||
throwToolExit('Unable to build android/gradlew.');
|
throwToolExit('Unable to build android/gradlew.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return gradlew;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> buildGradleProject(BuildMode buildMode) async {
|
||||||
|
// Create android/local.properties.
|
||||||
|
File localProperties = fs.file('android/local.properties');
|
||||||
|
if (!localProperties.existsSync()) {
|
||||||
|
localProperties.writeAsStringSync(
|
||||||
|
'sdk.dir=${androidSdk.directory}\n'
|
||||||
|
'flutter.sdk=${Cache.flutterRoot}\n'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Update the local.properties file with the build mode.
|
||||||
|
// FlutterPlugin v1 reads local.properties to determine build mode. Plugin v2
|
||||||
|
// uses the standard Android way to determine what to build, but we still
|
||||||
|
// update local.properties, in case we want to use it in the future.
|
||||||
|
String buildModeName = getModeName(buildMode);
|
||||||
|
SettingsFile settings = new SettingsFile.parseFromFile(localProperties);
|
||||||
|
settings.values['flutter.buildMode'] = buildModeName;
|
||||||
|
settings.writeContents(localProperties);
|
||||||
|
|
||||||
|
String gradlew = await ensureGradlew();
|
||||||
|
|
||||||
|
switch (flutterPluginVersion) {
|
||||||
|
case FlutterPluginVersion.none:
|
||||||
|
// Fall through. Pretend it's v1, and just go for it.
|
||||||
|
case FlutterPluginVersion.v1:
|
||||||
|
return buildGradleProjectV1(gradlew);
|
||||||
|
case FlutterPluginVersion.v2:
|
||||||
|
return buildGradleProjectV2(gradlew, buildModeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> buildGradleProjectV1(String gradlew) async {
|
||||||
// Run 'gradlew build'.
|
// Run 'gradlew build'.
|
||||||
Status status = logger.startProgress('Running \'gradlew build\'...');
|
Status status = logger.startProgress('Running \'gradlew build\'...');
|
||||||
int exitcode = await runCommandAndStreamOutput(
|
int exitcode = await runCommandAndStreamOutput(
|
||||||
<String>[fs.file('android/gradlew').absolute.path, 'build'],
|
<String>[fs.file(gradlew).absolute.path, 'build'],
|
||||||
workingDirectory: 'android',
|
workingDirectory: 'android',
|
||||||
allowReentrantFlutter: true
|
allowReentrantFlutter: true
|
||||||
);
|
);
|
||||||
|
@ -161,8 +215,34 @@ Future<Null> buildGradleProject(BuildMode buildMode) async {
|
||||||
if (exitcode != 0)
|
if (exitcode != 0)
|
||||||
throwToolExit('Gradlew failed: $exitcode', exitCode: exitcode);
|
throwToolExit('Gradlew failed: $exitcode', exitCode: exitcode);
|
||||||
|
|
||||||
File apkFile = fs.file(gradleAppOut);
|
File apkFile = fs.file(gradleAppOutV1);
|
||||||
printStatus('Built $gradleAppOut (${getSizeAsMB(apkFile.lengthSync())}).');
|
printStatus('Built $gradleAppOutV1 (${getSizeAsMB(apkFile.lengthSync())}).');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> buildGradleProjectV2(String gradlew, String buildModeName) async {
|
||||||
|
String assembleTask = "assemble${toTitleCase(buildModeName)}";
|
||||||
|
|
||||||
|
// Run 'gradlew assemble<BuildMode>'.
|
||||||
|
Status status = logger.startProgress('Running \'gradlew $assembleTask\'...');
|
||||||
|
String gradlewPath = fs.file(gradlew).absolute.path;
|
||||||
|
List<String> command = logger.isVerbose
|
||||||
|
? <String>[gradlewPath, assembleTask]
|
||||||
|
: <String>[gradlewPath, '-q', assembleTask];
|
||||||
|
int exitcode = await runCommandAndStreamOutput(
|
||||||
|
command,
|
||||||
|
workingDirectory: 'android',
|
||||||
|
allowReentrantFlutter: true
|
||||||
|
);
|
||||||
|
status.stop();
|
||||||
|
|
||||||
|
if (exitcode != 0)
|
||||||
|
throwToolExit('Gradlew failed: $exitcode', exitCode: exitcode);
|
||||||
|
|
||||||
|
String apkFilename = 'app-$buildModeName.apk';
|
||||||
|
File apkFile = fs.file('$gradleAppOutDir/$apkFilename');
|
||||||
|
// Copy the APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
|
||||||
|
apkFile.copySync('$gradleAppOutDir/app.apk');
|
||||||
|
printStatus('Built $apkFilename (${getSizeAsMB(apkFile.lengthSync())}).');
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GradleFile {
|
class _GradleFile {
|
||||||
|
|
|
@ -227,21 +227,20 @@ class BuildApkCommand extends BuildSubCommand {
|
||||||
await super.runCommand();
|
await super.runCommand();
|
||||||
|
|
||||||
TargetPlatform targetPlatform = _getTargetPlatform(argResults['target-arch']);
|
TargetPlatform targetPlatform = _getTargetPlatform(argResults['target-arch']);
|
||||||
if (targetPlatform != TargetPlatform.android_arm && getBuildMode() != BuildMode.debug)
|
BuildMode buildMode = getBuildMode();
|
||||||
|
if (targetPlatform != TargetPlatform.android_arm && buildMode != BuildMode.debug)
|
||||||
throwToolExit('Profile and release builds are only supported on ARM targets.');
|
throwToolExit('Profile and release builds are only supported on ARM targets.');
|
||||||
|
|
||||||
if (isProjectUsingGradle()) {
|
if (isProjectUsingGradle()) {
|
||||||
if (targetPlatform != TargetPlatform.android_arm)
|
|
||||||
throwToolExit('Gradle builds only support ARM targets.');
|
|
||||||
await buildAndroidWithGradle(
|
await buildAndroidWithGradle(
|
||||||
TargetPlatform.android_arm,
|
targetPlatform,
|
||||||
getBuildMode(),
|
buildMode,
|
||||||
target: targetFile
|
target: targetFile
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await buildAndroid(
|
await buildAndroid(
|
||||||
targetPlatform,
|
targetPlatform,
|
||||||
getBuildMode(),
|
buildMode,
|
||||||
force: true,
|
force: true,
|
||||||
manifest: argResults['manifest'],
|
manifest: argResults['manifest'],
|
||||||
resources: argResults['resources'],
|
resources: argResults['resources'],
|
||||||
|
@ -595,6 +594,9 @@ Future<Null> buildAndroidWithGradle(
|
||||||
bool force: false,
|
bool force: false,
|
||||||
String target
|
String target
|
||||||
}) async {
|
}) async {
|
||||||
|
if (platform != TargetPlatform.android_arm && buildMode != BuildMode.debug) {
|
||||||
|
throwToolExit('Profile and release builds are only supported on ARM targets.');
|
||||||
|
}
|
||||||
// Validate that we can find an android sdk.
|
// Validate that we can find an android sdk.
|
||||||
if (androidSdk == null)
|
if (androidSdk == null)
|
||||||
throwToolExit('No Android SDK found. Try setting the ANDROID_HOME environment variable.');
|
throwToolExit('No Android SDK found. Try setting the ANDROID_HOME environment variable.');
|
||||||
|
|
Loading…
Reference in a new issue