2019-07-23 16:27:42 +00:00
// Copyright 2019 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 static groovy . io . FileType . FILES
2016-03-12 00:30:56 +00:00
import com.android.builder.model.AndroidProject
2019-06-10 20:16:09 +00:00
import com.android.build.OutputFile
2019-07-23 16:27:42 +00:00
import java.nio.file.Path
import java.nio.file.Paths
2017-02-16 22:17:09 +00:00
import org.apache.tools.ant.taskdefs.condition.Os
2016-03-12 00:30:56 +00:00
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.Task
2016-06-06 19:56:04 +00:00
import org.gradle.api.file.CopySpec
2016-03-12 00:30:56 +00:00
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.Copy
2017-01-31 22:48:48 +00:00
import org.gradle.api.tasks.InputFiles
2016-03-12 00:30:56 +00:00
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
2017-01-31 22:48:48 +00:00
import org.gradle.api.tasks.bundling.Jar
2016-03-12 00:30:56 +00:00
2017-02-10 08:37:38 +00:00
buildscript {
2017-07-31 11:57:24 +00:00
repositories {
2018-10-24 21:33:39 +00:00
google ( )
2017-12-14 14:38:39 +00:00
jcenter ( )
2017-07-31 11:57:24 +00:00
}
dependencies {
2019-09-14 02:37:07 +00:00
classpath 'com.android.tools.build:gradle:3.5.0'
2017-07-31 11:57:24 +00:00
}
2017-02-10 08:37:38 +00:00
}
2018-12-17 22:40:48 +00:00
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
2017-02-10 08:37:38 +00:00
apply plugin: FlutterPlugin
2016-03-12 00:30:56 +00:00
class FlutterPlugin implements Plugin < Project > {
2019-06-10 20:16:09 +00:00
// The platforms that can be passed to the `--Ptarget-platform` flag.
private static final String PLATFORM_ARM32 = "android-arm" ;
private static final String PLATFORM_ARM64 = "android-arm64" ;
private static final String PLATFORM_X86 = "android-x86" ;
private static final String PLATFORM_X86_64 = "android-x64" ;
// The ABI architectures.
private static final String ARCH_ARM32 = "armeabi-v7a" ;
private static final String ARCH_ARM64 = "arm64-v8a" ;
private static final String ARCH_X86 = "x86" ;
private static final String ARCH_X86_64 = "x86_64" ;
// Maps platforms to ABI architectures.
private static final Map PLATFORM_ARCH_MAP = [
( PLATFORM_ARM32 ) : ARCH_ARM32 ,
( PLATFORM_ARM64 ) : ARCH_ARM64 ,
( PLATFORM_X86 ) : ARCH_X86 ,
( PLATFORM_X86_64 ) : ARCH_X86_64 ,
]
// The version code that gives each ABI a value.
// For each APK variant, use the following versions to override the version of the Universal APK.
// Otherwise, the Play Store will complain that the APK variants have the same version.
private static final Map ABI_VERSION = [
( ARCH_ARM32 ) : 1 ,
( ARCH_ARM64 ) : 2 ,
( ARCH_X86 ) : 3 ,
( ARCH_X86_64 ) : 4 ,
]
// When split is enabled, multiple APKs are generated per each ABI.
private static final List DEFAULT_PLATFORMS = [
PLATFORM_ARM32 ,
PLATFORM_ARM64 ,
]
// The name prefix for flutter builds. This is used to identify gradle tasks
// where we expect the flutter tool to provide any error output, and skip the
// standard Gradle error output in the FlutterEventLogger. If you change this,
// be sure to change any instances of this string in symbols in the code below
// to match.
static final String FLUTTER_BUILD_PREFIX = "flutterBuild"
2019-06-13 23:05:28 +00:00
private Map baseJar = [ : ]
2016-06-06 19:56:04 +00:00
private File flutterRoot
2017-02-16 22:17:09 +00:00
private File flutterExecutable
2016-05-28 00:12:52 +00:00
private String localEngine
2017-02-23 13:56:19 +00:00
private String localEngineSrcPath
2017-01-31 22:48:48 +00:00
private Properties localProperties
2017-03-23 13:59:12 +00:00
private File flutterJar
2019-06-10 20:16:09 +00:00
2016-03-12 00:30:56 +00:00
@Override
void apply ( Project project ) {
2019-05-20 20:09:20 +00:00
project . extensions . create ( "flutter" , FlutterExtension )
2019-07-23 16:27:42 +00:00
project . afterEvaluate this . & addFlutterTasks
2019-09-04 00:49:10 +00:00
2019-06-10 20:16:09 +00:00
// By default, assembling APKs generates fat APKs if multiple platforms are passed.
// Configuring split per ABI allows to generate separate APKs for each abi.
// This is a noop when building a bundle.
2019-09-04 00:49:10 +00:00
if ( splitPerAbi ( project ) ) {
2019-06-10 20:16:09 +00:00
project . android {
splits {
abi {
// Enables building multiple APKs per ABI.
enable true
// Resets the list of ABIs that Gradle should create APKs for to none.
reset ( )
// Specifies that we do not want to also generate a universal APK that includes all ABIs.
universalApk false
}
}
}
}
2019-09-04 00:49:10 +00:00
getTargetPlatforms ( project ) . each { targetArch - >
2019-06-10 20:16:09 +00:00
String abiValue = PLATFORM_ARCH_MAP [ targetArch ]
2019-05-20 20:09:20 +00:00
project . android {
2019-09-04 00:49:10 +00:00
packagingOptions {
// Prevent the ELF library from getting corrupted.
doNotStrip "*/${abiValue}/libapp.so"
}
if ( splitPerAbi ( project ) ) {
2019-06-10 20:16:09 +00:00
splits {
abi {
include abiValue
}
}
2019-05-20 20:09:20 +00:00
}
}
}
2019-09-04 00:49:10 +00:00
String flutterRootPath = resolveProperty ( project , "flutter.sdk" , System . env . FLUTTER_ROOT )
2016-06-06 19:56:04 +00:00
if ( flutterRootPath = = null ) {
2017-05-22 14:50:31 +00:00
throw new GradleException ( "Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment variable." )
2016-03-12 00:30:56 +00:00
}
2016-06-06 19:56:04 +00:00
flutterRoot = project . file ( flutterRootPath )
if ( ! flutterRoot . isDirectory ( ) ) {
2016-03-12 00:30:56 +00:00
throw new GradleException ( "flutter.sdk must point to the Flutter SDK directory" )
}
2017-02-16 22:17:09 +00:00
String flutterExecutableName = Os . isFamily ( Os . FAMILY_WINDOWS ) ? "flutter.bat" : "flutter"
flutterExecutable = Paths . get ( flutterRoot . absolutePath , "bin" , flutterExecutableName ) . toFile ( ) ;
2019-09-11 00:22:55 +00:00
// Add custom build types.
project . android . buildTypes {
profile {
initWith debug
if ( it . hasProperty ( "matchingFallbacks" ) ) {
matchingFallbacks = [ "debug" , "release" ]
}
}
}
2019-09-16 22:27:05 +00:00
if ( shouldShrinkResources ( project ) ) {
2019-09-11 00:22:55 +00:00
String flutterProguardRules = Paths . get ( flutterRoot . absolutePath , "packages" , "flutter_tools" ,
"gradle" , "flutter_proguard_rules.pro" )
project . android . buildTypes {
release {
2019-09-14 02:06:40 +00:00
// Enables code shrinking, obfuscation, and optimization for only
// your project's release build type.
2019-09-11 00:22:55 +00:00
minifyEnabled true
2019-09-14 02:06:40 +00:00
// Enables resource shrinking, which is performed by the
// Android Gradle plugin.
2019-09-16 22:27:05 +00:00
// NOTE: The resource shrinker can't be used for libraries.
shrinkResources isBuiltAsApp ( project )
2019-09-11 00:22:55 +00:00
// Fallback to `android/app/proguard-rules.pro`.
// This way, custom Proguard rules can be configured as needed.
proguardFiles project . android . getDefaultProguardFile ( "proguard-android.txt" ) , flutterProguardRules , "proguard-rules.pro"
}
}
}
2019-09-04 00:49:10 +00:00
if ( useLocalEngine ( project ) ) {
String engineOutPath = project . property ( 'localEngineOut' )
File engineOut = project . file ( engineOutPath )
2017-02-23 13:56:19 +00:00
if ( ! engineOut . isDirectory ( ) ) {
throw new GradleException ( 'localEngineOut must point to a local engine build' )
}
2019-06-13 23:05:28 +00:00
Path baseEnginePath = Paths . get ( engineOut . absolutePath )
2019-05-20 20:09:20 +00:00
flutterJar = baseEnginePath . resolve ( "flutter.jar" ) . toFile ( )
2016-04-12 21:26:22 +00:00
if ( ! flutterJar . isFile ( ) ) {
2019-06-13 23:05:28 +00:00
throw new GradleException ( "Local engine jar not found: $flutterJar" )
2016-04-12 21:26:22 +00:00
}
2017-02-23 13:56:19 +00:00
localEngine = engineOut . name
localEngineSrcPath = engineOut . parentFile . parent
2019-05-20 20:09:20 +00:00
// The local engine is built for one of the build type.
// However, we use the same engine for each of the build types.
2019-06-13 23:05:28 +00:00
project . android . buildTypes . each {
2019-06-19 05:37:42 +00:00
addApiDependencies ( project , it . name , project . files {
2019-06-17 04:52:44 +00:00
flutterJar
2019-06-13 23:05:28 +00:00
} )
}
2017-01-31 22:48:48 +00:00
} else {
2019-09-04 00:49:10 +00:00
String basePlatformArch = getBasePlatform ( project )
// This is meant to include the compiled classes only, however it will include `libflutter.so` as well.
Path baseEnginePath = Paths . get ( flutterRoot . absolutePath , "bin" , "cache" , "artifacts" , "engine" )
File debugJar = baseEnginePath . resolve ( "${basePlatformArch}" ) . resolve ( "flutter.jar" ) . toFile ( )
baseJar [ "debug" ] = debugJar
if ( ! debugJar . isFile ( ) ) {
project . exec {
executable flutterExecutable . absolutePath
args "--suppress-analytics"
args "precache"
}
if ( ! debugJar . isFile ( ) ) {
throw new GradleException ( "Unable to find flutter.jar in SDK: ${debugJar}" )
2019-06-13 23:05:28 +00:00
}
2016-04-12 21:26:22 +00:00
}
2019-09-04 00:49:10 +00:00
baseJar [ "profile" ] = baseEnginePath . resolve ( "${basePlatformArch}-profile" ) . resolve ( "flutter.jar" ) . toFile ( )
baseJar [ "release" ] = baseEnginePath . resolve ( "${basePlatformArch}-release" ) . resolve ( "flutter.jar" ) . toFile ( )
2019-06-13 23:05:28 +00:00
2019-09-04 00:49:10 +00:00
// Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones
// added after applying the Flutter plugin.
project . android . buildTypes . each {
def buildMode = buildModeFor ( it )
addApiDependencies ( project , it . name , project . files {
baseJar [ buildMode ]
} )
}
project . android . buildTypes . whenObjectAdded {
def buildMode = buildModeFor ( it )
addApiDependencies ( project , it . name , project . files {
baseJar [ buildMode ]
} )
}
2016-04-12 21:26:22 +00:00
}
2019-07-23 16:27:42 +00:00
}
/ * *
* Returns the directory where the plugins are built .
* /
2019-09-04 00:49:10 +00:00
private File getPluginBuildDir ( Project project ) {
2019-07-23 16:27:42 +00:00
// Module projects specify this flag to include plugins in the same repo as the module project.
if ( project . ext . has ( "pluginBuildDir" ) ) {
return project . ext . get ( "pluginBuildDir" )
}
return project . buildDir
}
2017-03-23 13:59:12 +00:00
2019-09-04 00:49:10 +00:00
private Properties getPluginList ( Project project ) {
2018-06-20 14:07:05 +00:00
File pluginsFile = new File ( project . projectDir . parentFile . parentFile , '.flutter-plugins' )
2019-07-23 16:27:42 +00:00
return readPropertiesIfExist ( pluginsFile )
}
2019-09-04 00:49:10 +00:00
private void addPluginTasks ( Project project ) {
Properties plugins = getPluginList ( project )
2019-07-23 16:27:42 +00:00
project . android . buildTypes . each { buildType - >
plugins . each { name , path - >
String buildModeValue = buildType . debuggable ? "debug" : "release"
List < String > taskNameParts = [ "build" , "plugin" , buildModeValue ]
taskNameParts . addAll ( name . split ( "_" ) )
String taskName = toCammelCase ( taskNameParts )
// Build types can be extended. For example, a build type can extend the `debug` mode.
// In such cases, prevent creating the same task.
if ( project . tasks . findByName ( taskName ) = = null ) {
project . tasks . create ( name: taskName , type: FlutterPluginTask ) {
flutterExecutable this . flutterExecutable
buildMode buildModeValue
2019-09-04 00:49:10 +00:00
verbose isVerbose ( project )
2019-07-23 16:27:42 +00:00
pluginDir project . file ( path )
sourceDir project . file ( project . flutter . source )
2019-09-04 00:49:10 +00:00
intermediateDir getPluginBuildDir ( project )
2017-12-13 11:16:22 +00:00
}
2017-03-23 13:59:12 +00:00
}
2019-07-23 16:27:42 +00:00
}
}
}
2019-07-23 03:46:01 +00:00
2019-09-04 00:49:10 +00:00
private void buildPlugins ( Project project , Set buildTypes ) {
2019-07-23 16:27:42 +00:00
List < Project > projects = [ project ]
// Module projects set the `hostProjects` extra property in `include_flutter.groovy`.
// This is required to set the local repository in each host app project.
if ( project . ext . has ( "hostProjects" ) ) {
projects . addAll ( project . ext . get ( "hostProjects" ) )
}
projects . each { hostProject - >
hostProject . repositories {
maven {
2019-09-04 00:49:10 +00:00
url "${getPluginBuildDir(project)}/outputs/repo"
2019-07-23 16:27:42 +00:00
}
}
}
buildTypes . each { buildType - >
project . tasks . withType ( FlutterPluginTask ) . all { pluginTask - >
String buildMode = buildType . debuggable ? "debug" : "release"
if ( pluginTask . buildMode ! = buildMode ) {
return
}
pluginTask . execute ( )
pluginTask . intermediateDir . eachFileRecurse ( FILES ) { file - >
if ( file . name ! = "maven-metadata.xml" ) {
return
2019-07-23 05:07:59 +00:00
}
2019-07-23 16:27:42 +00:00
def mavenMetadata = new XmlParser ( ) . parse ( file )
String groupId = mavenMetadata . groupId . text ( )
String artifactId = mavenMetadata . artifactId . text ( )
if ( ! artifactId . endsWith ( buildMode ) ) {
return
2019-06-25 17:40:55 +00:00
}
2019-07-23 16:27:42 +00:00
// Add the plugin dependency based on the Maven metadata.
addApiDependencies ( project , buildType . name , "$groupId:$artifactId:+@aar" , {
transitive = true
} )
2019-07-23 03:46:01 +00:00
}
}
}
}
2019-07-23 16:27:42 +00:00
/ * *
* Returns a set with the build type names that apply to the given list of tasks
* required to configure the plugin dependencies .
* /
2019-09-04 00:49:10 +00:00
private Set getBuildTypesForTasks ( Project project , List < String > tasksToExecute ) {
2019-07-23 16:27:42 +00:00
Set buildTypes = [ ]
tasksToExecute . each { task - >
project . android . buildTypes . each { buildType - >
if ( task = = "androidDependencies" | | task . endsWith ( "dependencies" ) ) {
// The tasks to query the dependencies includes all the build types.
buildTypes . add ( buildType )
} else if ( task . endsWith ( "assemble" ) ) {
// The `assemble` task includes all the build types.
buildTypes . add ( buildType )
} else if ( task . endsWith ( buildType . name . capitalize ( ) ) ) {
buildTypes . add ( buildType )
}
}
}
return buildTypes
}
private static String toCammelCase ( List < String > parts ) {
if ( parts . empty ) {
return ""
}
return "${parts[0]}${parts[1..-1].collect { it.capitalize() }.join('')}"
}
2019-09-04 00:49:10 +00:00
private String resolveProperty ( Project project , String name , String defaultValue ) {
2019-06-13 23:05:28 +00:00
if ( localProperties = = null ) {
localProperties = readPropertiesIfExist ( new File ( project . projectDir . parentFile , "local.properties" ) )
}
String result
if ( project . hasProperty ( name ) ) {
result = project . property ( name )
}
if ( result = = null ) {
result = localProperties . getProperty ( name )
}
if ( result = = null ) {
result = defaultValue
}
return result
}
private static Properties readPropertiesIfExist ( File propertiesFile ) {
Properties result = new Properties ( )
if ( propertiesFile . exists ( ) ) {
propertiesFile . withReader ( 'UTF-8' ) { reader - > result . load ( reader ) }
}
return result
}
2019-09-04 00:49:10 +00:00
private static List < String > getTargetPlatforms ( Project project ) {
2019-06-13 23:05:28 +00:00
if ( ! project . hasProperty ( 'target-platform' ) ) {
return DEFAULT_PLATFORMS
}
return project . property ( 'target-platform' ) . split ( ',' ) . collect {
if ( ! PLATFORM_ARCH_MAP [ it ] ) {
throw new GradleException ( "Invalid platform: $it." )
}
return it
}
}
2019-09-04 00:49:10 +00:00
private static Boolean splitPerAbi ( Project project ) {
2019-06-13 23:05:28 +00:00
if ( project . hasProperty ( 'split-per-abi' ) ) {
return project . property ( 'split-per-abi' ) . toBoolean ( )
}
return false ;
}
2019-09-04 00:49:10 +00:00
private static Boolean useLocalEngine ( Project project ) {
2019-06-13 23:05:28 +00:00
return project . hasProperty ( 'localEngineOut' )
}
2019-09-04 00:49:10 +00:00
private static Boolean isVerbose ( Project project ) {
2019-07-23 16:27:42 +00:00
if ( project . hasProperty ( 'verbose' ) ) {
return project . property ( 'verbose' ) . toBoolean ( )
}
return false
}
2019-09-16 22:27:05 +00:00
private static Boolean shouldShrinkResources ( Project project ) {
if ( project . hasProperty ( "shrink" ) ) {
return project . property ( "shrink" ) . toBoolean ( )
2019-09-11 00:22:55 +00:00
}
return false
}
2019-09-16 22:27:05 +00:00
private static Boolean isBuiltAsApp ( Project project ) {
// Projects are built as applications when the they use the `com.android.application`
// plugin.
return project . plugins . hasPlugin ( "com.android.application" ) ;
}
2019-07-23 16:27:42 +00:00
private static Boolean buildPluginAsAar ( ) {
return System . getProperty ( 'build-plugins-as-aars' ) = = 'true'
}
2019-09-04 00:49:10 +00:00
/ * *
* Returns the platform that is used to extract the ` libflutter . so ` and the . class files .
*
* Note: This is only needed to add the . class files .
* Unfortunately , the engine artifacts include the . class and libflutter . so files .
* /
private static String getBasePlatform ( Project project ) {
if ( PLATFORM_ARM64 in getTargetPlatforms ( project ) ) {
return PLATFORM_ARM64 ;
}
return PLATFORM_ARM32 ;
}
private void addFlutterJarCompileOnlyDependency ( Project project , String variantName , FileCollection files ) {
2017-08-24 08:44:32 +00:00
if ( project . state . failure ) {
return
}
2019-07-23 16:27:42 +00:00
String configuration ;
if ( project . getConfigurations ( ) . findByName ( "compileOnly" ) ) {
configuration = "${variantName}CompileOnly" ;
} else {
configuration = "${variantName}Provided" ;
2017-03-23 13:59:12 +00:00
}
2019-09-04 00:49:10 +00:00
project . dependencies . add ( configuration , files )
2016-03-12 00:30:56 +00:00
}
2019-07-23 16:27:42 +00:00
private static void addApiDependencies ( Project project , String variantName , Object dependency , Closure config = null ) {
String configuration ;
// `compile` dependencies are now `api` dependencies.
if ( project . getConfigurations ( ) . findByName ( "api" ) ) {
configuration = "${variantName}Api" ;
} else {
configuration = "${variantName}Compile" ;
2017-07-31 11:57:24 +00:00
}
2019-07-23 16:27:42 +00:00
project . dependencies . add ( configuration , dependency , config )
2017-07-31 11:57:24 +00:00
}
/ * *
* Returns a Flutter build mode suitable for the specified Android buildType .
*
* Note: The BuildType DSL type is not public , and is therefore omitted from the signature .
*
2019-06-18 18:11:38 +00:00
* @return "debug" , "profile" , or "release" ( fall - back ) .
2017-07-31 11:57:24 +00:00
* /
private static String buildModeFor ( buildType ) {
if ( buildType . name = = "profile" ) {
return "profile"
} else if ( buildType . debuggable ) {
return "debug"
}
return "release"
}
2019-06-10 20:16:09 +00:00
private static String getEngineArtifactDirName ( buildType , targetArch ) {
if ( buildType . name = = "profile" ) {
return "${targetArch}-profile"
} else if ( buildType . debuggable ) {
return "${targetArch}"
}
return "${targetArch}-release"
}
2019-07-23 16:27:42 +00:00
private void addFlutterTasks ( Project project ) {
2017-08-24 08:44:32 +00:00
if ( project . state . failure ) {
return
}
2016-03-12 00:30:56 +00:00
if ( project . flutter . source = = null ) {
throw new GradleException ( "Must provide Flutter source directory" )
}
2017-01-31 22:48:48 +00:00
String target = project . flutter . target
2016-06-07 20:05:42 +00:00
if ( target = = null ) {
target = 'lib/main.dart'
}
2017-02-23 14:09:05 +00:00
if ( project . hasProperty ( 'target' ) ) {
target = project . property ( 'target' )
}
2019-09-04 00:49:10 +00:00
2018-03-17 19:47:40 +00:00
String [ ] fileSystemRootsValue = null
if ( project . hasProperty ( 'filesystem-roots' ) ) {
fileSystemRootsValue = project . property ( 'filesystem-roots' ) . split ( '\\|' )
}
String fileSystemSchemeValue = null
if ( project . hasProperty ( 'filesystem-scheme' ) ) {
fileSystemSchemeValue = project . property ( 'filesystem-scheme' )
}
2018-02-12 18:44:31 +00:00
Boolean trackWidgetCreationValue = false
if ( project . hasProperty ( 'track-widget-creation' ) ) {
2018-04-24 16:51:25 +00:00
trackWidgetCreationValue = project . property ( 'track-widget-creation' ) . toBoolean ( )
2018-02-12 18:44:31 +00:00
}
2018-08-16 15:46:57 +00:00
String compilationTraceFilePathValue = null
2018-12-21 20:27:59 +00:00
if ( project . hasProperty ( 'compilation-trace-file' ) ) {
compilationTraceFilePathValue = project . property ( 'compilation-trace-file' )
2018-06-15 18:53:30 +00:00
}
2018-12-20 00:27:47 +00:00
Boolean createPatchValue = false
if ( project . hasProperty ( 'patch' ) ) {
createPatchValue = project . property ( 'patch' ) . toBoolean ( )
}
Integer buildNumberValue = null
if ( project . hasProperty ( 'build-number' ) ) {
buildNumberValue = project . property ( 'build-number' ) . toInteger ( )
}
String baselineDirValue = null
if ( project . hasProperty ( 'baseline-dir' ) ) {
baselineDirValue = project . property ( 'baseline-dir' )
2018-09-28 20:58:37 +00:00
}
2017-10-03 19:55:53 +00:00
String extraFrontEndOptionsValue = null
if ( project . hasProperty ( 'extra-front-end-options' ) ) {
extraFrontEndOptionsValue = project . property ( 'extra-front-end-options' )
}
String extraGenSnapshotOptionsValue = null
if ( project . hasProperty ( 'extra-gen-snapshot-options' ) ) {
extraGenSnapshotOptionsValue = project . property ( 'extra-gen-snapshot-options' )
}
2019-09-04 00:49:10 +00:00
def targetPlatforms = getTargetPlatforms ( project )
2019-06-09 01:43:25 +00:00
def addFlutterDeps = { variant - >
2019-09-04 00:49:10 +00:00
if ( splitPerAbi ( project ) ) {
2019-06-10 20:16:09 +00:00
variant . outputs . each { output - >
// Assigns the new version code to versionCodeOverride, which changes the version code
// for only the output APK, not for the variant itself. Skipping this step simply
// causes Gradle to use the value of variant.versionCode for the APK.
// For more, see https://developer.android.com/studio/build/configure-apk-splits
def abiVersionCode = ABI_VERSION . get ( output . getFilter ( OutputFile . ABI ) )
if ( abiVersionCode ! = null ) {
output . versionCodeOverride =
abiVersionCode * 1000 + variant . versionCode
}
}
}
2019-09-04 00:49:10 +00:00
String flutterBuildMode = buildModeFor ( variant . buildType )
if ( flutterBuildMode = = 'debug' & & project . tasks . findByName ( "${FLUTTER_BUILD_PREFIX}X86Jar" ) ) {
Task task = project . tasks . findByName ( "compile${variant.name.capitalize()}JavaWithJavac" )
if ( task ) {
task . dependsOn project . flutterBuildX86Jar
}
task = project . tasks . findByName ( "compile${variant.name.capitalize()}Kotlin" )
if ( task ) {
task . dependsOn project . flutterBuildX86Jar
}
}
2019-07-23 16:27:42 +00:00
def compileTasks = targetPlatforms . collect { targetArch - >
2019-09-04 00:49:10 +00:00
String abiValue = PLATFORM_ARCH_MAP [ targetArch ]
2019-07-23 16:27:42 +00:00
String taskName = toCammelCase ( [ "compile" , FLUTTER_BUILD_PREFIX , variant . name , targetArch . replace ( 'android-' , '' ) ] )
2019-09-04 00:49:10 +00:00
FlutterTask compileTask = project . tasks . create ( name: taskName , type: FlutterTask ) {
2019-05-20 20:09:20 +00:00
flutterRoot this . flutterRoot
flutterExecutable this . flutterExecutable
2019-09-04 00:49:10 +00:00
buildMode flutterBuildMode
2019-05-20 20:09:20 +00:00
localEngine this . localEngine
localEngineSrcPath this . localEngineSrcPath
2019-09-04 00:49:10 +00:00
abi abiValue
2019-05-20 20:09:20 +00:00
targetPath target
2019-09-04 00:49:10 +00:00
verbose isVerbose ( project )
2019-05-20 20:09:20 +00:00
fileSystemRoots fileSystemRootsValue
fileSystemScheme fileSystemSchemeValue
trackWidgetCreation trackWidgetCreationValue
compilationTraceFilePath compilationTraceFilePathValue
createPatch createPatchValue
buildNumber buildNumberValue
baselineDir baselineDirValue
2019-06-10 20:16:09 +00:00
targetPlatform targetArch
2019-05-20 20:09:20 +00:00
sourceDir project . file ( project . flutter . source )
2019-06-10 20:16:09 +00:00
intermediateDir project . file ( "${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/${targetArch}" )
2019-05-20 20:09:20 +00:00
extraFrontEndOptions extraFrontEndOptionsValue
extraGenSnapshotOptions extraGenSnapshotOptionsValue
}
}
2019-09-04 00:49:10 +00:00
2019-06-10 20:16:09 +00:00
def libJar = project . file ( "${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar" )
2019-09-04 00:49:10 +00:00
def libFlutterPlatforms = targetPlatforms . collect ( )
// x86/x86_64 native library used for debugging only, for now.
if ( flutterBuildMode = = 'debug' ) {
libFlutterPlatforms . add ( 'android-x86' )
libFlutterPlatforms . add ( 'android-x64' )
}
Task packFlutterSnapshotsAndLibsTask = project . tasks . create ( name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}" , type: Jar ) {
2019-05-20 20:09:20 +00:00
destinationDir libJar . parentFile
archiveName libJar . name
2019-09-04 00:49:10 +00:00
libFlutterPlatforms . each { targetArch - >
// This check prevents including `libflutter.so` twice, since it's included in the base platform jar.
// Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter`
// is included as an implementation dependency, which causes duplicated `libflutter.so`.
if ( getBasePlatform ( project ) = = targetArch ) {
return
}
// Don't include `libflutter.so` for other architectures when a local engine is specified.
if ( useLocalEngine ( project ) ) {
return
}
def engineArtifactSubdir = getEngineArtifactDirName ( variant . buildType , targetArch ) ;
// Include `libflutter.so`.
// TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded.
from ( project . zipTree ( "${flutterRoot}/bin/cache/artifacts/engine/${engineArtifactSubdir}/flutter.jar" ) ) {
include 'lib/**'
}
}
2019-07-23 16:27:42 +00:00
dependsOn compileTasks
2019-09-04 00:49:10 +00:00
// Add the ELF library.
2019-07-23 16:27:42 +00:00
compileTasks . each { compileTask - >
from ( compileTask . intermediateDir ) {
2019-06-10 20:16:09 +00:00
include '*.so'
rename { String filename - >
2019-07-23 16:27:42 +00:00
return "lib/${compileTask.abi}/lib${filename}"
2019-05-20 20:09:20 +00:00
}
}
}
2017-01-31 22:48:48 +00:00
}
2019-09-04 00:49:10 +00:00
// Include the snapshots and libflutter.so in `lib/`.
2019-06-19 05:37:42 +00:00
addApiDependencies ( project , variant . name , project . files {
2019-09-04 00:49:10 +00:00
packFlutterSnapshotsAndLibsTask
2019-06-13 23:05:28 +00:00
} )
2019-09-04 00:49:10 +00:00
2018-10-09 17:40:03 +00:00
// We know that the flutter app is a subproject in another Android app when these tasks exist.
Task packageAssets = project . tasks . findByPath ( ":flutter:package${variant.name.capitalize()}Assets" )
Task cleanPackageAssets = project . tasks . findByPath ( ":flutter:cleanPackage${variant.name.capitalize()}Assets" )
2018-04-12 08:12:26 +00:00
Task copyFlutterAssetsTask = project . tasks . create ( name: "copyFlutterAssets${variant.name.capitalize()}" , type: Copy ) {
2019-07-23 16:27:42 +00:00
dependsOn compileTasks
2019-01-18 00:33:14 +00:00
if ( packageAssets & & cleanPackageAssets ) {
dependsOn packageAssets
dependsOn cleanPackageAssets
into packageAssets . outputDir
} else {
2019-01-24 22:29:08 +00:00
dependsOn variant . mergeAssets
dependsOn "clean${variant.mergeAssets.name.capitalize()}"
2019-05-28 17:01:20 +00:00
variant . mergeAssets . mustRunAfter ( "clean${variant.mergeAssets.name.capitalize()}" )
2019-01-24 22:29:08 +00:00
into variant . mergeAssets . outputDir
2019-01-18 00:33:14 +00:00
}
2019-07-23 16:27:42 +00:00
compileTasks . each { flutterTask - >
2019-05-20 20:09:20 +00:00
with flutterTask . assets
}
2016-03-12 00:30:56 +00:00
}
2019-07-29 16:26:41 +00:00
variant . outputs . first ( ) . processResources . dependsOn ( copyFlutterAssetsTask )
2016-03-12 00:30:56 +00:00
}
2018-04-06 11:11:47 +00:00
if ( project . android . hasProperty ( "applicationVariants" ) ) {
project . android . applicationVariants . all addFlutterDeps
} else {
project . android . libraryVariants . all addFlutterDeps
}
2019-09-04 00:49:10 +00:00
if ( buildPluginAsAar ( ) ) {
addPluginTasks ( project )
List < String > tasksToExecute = project . gradle . startParameter . taskNames
Set buildTypes = getBuildTypesForTasks ( project , tasksToExecute )
if ( tasksToExecute . contains ( "clean" ) ) {
// Because the plugins are built during configuration, the task "clean"
// cannot run in conjunction with an assembly task.
if ( ! buildTypes . empty ) {
throw new GradleException ( "Can't run the clean task along with other assemble tasks" )
}
}
// Build plugins when a task "assembly*" will be called later.
if ( ! buildTypes . empty ) {
// Build the plugin during configuration.
// This is required when Jetifier is enabled, otherwise the implementation dependency
// cannot be added.
buildPlugins ( project , buildTypes )
}
} else {
getPluginList ( project ) . each { name , _ - >
def pluginProject = project . rootProject . findProject ( ":$name" )
if ( pluginProject ! = null ) {
project . dependencies {
if ( project . getConfigurations ( ) . findByName ( "implementation" ) ) {
implementation pluginProject
} else {
compile pluginProject
}
}
pluginProject . afterEvaluate {
pluginProject . android . buildTypes {
profile {
initWith debug
}
}
pluginProject . android . buildTypes . each {
def buildMode = buildModeFor ( it )
addFlutterJarCompileOnlyDependency ( pluginProject , it . name , project . files ( flutterJar ? : baseJar [ buildMode ] ) )
}
pluginProject . android . buildTypes . whenObjectAdded {
def buildMode = buildModeFor ( it )
addFlutterJarCompileOnlyDependency ( pluginProject , it . name , project . files ( flutterJar ? : baseJar [ buildMode ] ) )
}
}
} else {
project . logger . error ( "Plugin project :$name not found. Please update settings.gradle." )
}
}
}
2016-03-12 00:30:56 +00:00
}
}
class FlutterExtension {
String source
2016-06-07 20:05:42 +00:00
String target
2016-03-12 00:30:56 +00:00
}
2017-05-05 12:53:51 +00:00
abstract class BaseFlutterTask extends DefaultTask {
2016-06-06 19:56:04 +00:00
File flutterRoot
2017-02-16 22:17:09 +00:00
File flutterExecutable
2016-06-06 19:56:04 +00:00
String buildMode
String localEngine
2017-02-23 13:56:19 +00:00
String localEngineSrcPath
2017-02-23 14:09:05 +00:00
@Input
2016-06-07 20:05:42 +00:00
String targetPath
2017-10-03 19:55:53 +00:00
@Optional @Input
2018-06-06 20:43:32 +00:00
Boolean verbose
@Optional @Input
2018-03-17 19:47:40 +00:00
String [ ] fileSystemRoots
@Optional @Input
String fileSystemScheme
2018-10-17 14:39:20 +00:00
@Input
2018-02-12 18:44:31 +00:00
Boolean trackWidgetCreation
@Optional @Input
2018-08-16 15:46:57 +00:00
String compilationTraceFilePath
2018-06-15 18:53:30 +00:00
@Optional @Input
2018-12-20 00:27:47 +00:00
Boolean createPatch
@Optional @Input
Integer buildNumber
@Optional @Input
String baselineDir
2018-09-28 20:58:37 +00:00
@Optional @Input
2018-02-01 23:14:48 +00:00
String targetPlatform
2019-05-20 20:09:20 +00:00
@Input
String abi
2016-03-12 00:30:56 +00:00
File sourceDir
2017-05-05 12:53:51 +00:00
File intermediateDir
2017-10-03 19:55:53 +00:00
@Optional @Input
String extraFrontEndOptions
@Optional @Input
String extraGenSnapshotOptions
2017-05-05 12:53:51 +00:00
Include kernel_compile.d in Gradle depfiles (#17175)
This updates the Android build to declare the kernel compile depfile as
an output and its contents as inputs when running with --preview-dart-2
(the default mode).
The 'flutter build aot' command behaves differently depending on whether
it's running in Dart 1 or Dart 2 mode:
* Dart 1: the entrypoint Dart file (typically main.dart) is passed
directly to gen_snapshot, which then emits snapshot.d, whose contents
list the transitive closure of Dart dependencies (input files) for the
snapshot. snapshot.d is a declared output, its contents (plus
gen_snapshot itself) constitute the set of input files to the Gradle
build action.
* Dart 2: then entrypoint Dart file (typically main.dart) is first
compiled with the Dart kernel frontend. This emits kernel_compile.d,
whose contents list the transitive closure of Dart dependencies (input
files) for the kernel 'dill' output file. This 'dill' file is then
passed to gen_snapshot, which emits snapshot.d, whose contents are
empty. As of this change, both snapshot.d and kernel_compile.d are
declared outputs, and their contents (plus gen_snapshot and the
frontend compiler themselves) constitute the set of input files to the
Gradle build action.
This fixes a bug wherein profile/release AOT outputs were not
invalidated due to snapshot.d being empty, and kernel_compile.d being
ignored. This was introduced during recent refactoring of the AOT build
code, wherein the kernel compile and gen_snapshot actions were changed
to emit independent depfiles (previously one stomped -- or failed to --
on the other's output).
2018-05-02 01:11:57 +00:00
@OutputFiles
FileCollection getDependenciesFiles ( ) {
2018-08-16 15:47:20 +00:00
FileCollection depfiles = project . files ( )
2018-09-04 15:50:05 +00:00
// Include the kernel compiler depfile, since kernel compile is the
// first stage of AOT build in this mode, and it includes all the Dart
// sources.
depfiles + = project . files ( "${intermediateDir}/kernel_compile.d" )
2018-09-07 19:33:05 +00:00
// Include Core JIT kernel compiler depfile, since kernel compile is
// the first stage of JIT builds in this mode, and it includes all the
// Dart sources.
depfiles + = project . files ( "${intermediateDir}/snapshot_blob.bin.d" )
2018-06-15 18:53:30 +00:00
return depfiles
2017-05-05 12:53:51 +00:00
}
2018-04-12 08:12:26 +00:00
void buildBundle ( ) {
2017-05-05 12:53:51 +00:00
if ( ! sourceDir . isDirectory ( ) ) {
throw new GradleException ( "Invalid Flutter source directory: ${sourceDir}" )
}
intermediateDir . mkdirs ( )
2018-08-16 15:43:41 +00:00
if ( buildMode = = "profile" | | buildMode = = "release" ) {
2017-05-05 12:53:51 +00:00
project . exec {
executable flutterExecutable . absolutePath
workingDir sourceDir
if ( localEngine ! = null ) {
args "--local-engine" , localEngine
args "--local-engine-src-path" , localEngineSrcPath
}
args "build" , "aot"
2017-06-16 21:33:59 +00:00
args "--suppress-analytics"
2017-05-05 12:53:51 +00:00
args "--quiet"
args "--target" , targetPath
args "--output-dir" , "${intermediateDir}"
2019-06-10 20:16:09 +00:00
args "--target-platform" , "${targetPlatform}"
2018-02-12 18:44:31 +00:00
if ( trackWidgetCreation ) {
args "--track-widget-creation"
}
2017-10-03 19:55:53 +00:00
if ( extraFrontEndOptions ! = null ) {
2017-11-21 14:44:03 +00:00
args "--extra-front-end-options" , "${extraFrontEndOptions}"
2017-10-03 19:55:53 +00:00
}
if ( extraGenSnapshotOptions ! = null ) {
2017-11-21 14:44:03 +00:00
args "--extra-gen-snapshot-options" , "${extraGenSnapshotOptions}"
}
2017-05-05 12:53:51 +00:00
args "--${buildMode}"
}
}
2016-03-12 00:30:56 +00:00
2017-05-05 12:53:51 +00:00
project . exec {
executable flutterExecutable . absolutePath
workingDir sourceDir
2019-07-17 18:17:04 +00:00
2017-05-05 12:53:51 +00:00
if ( localEngine ! = null ) {
args "--local-engine" , localEngine
args "--local-engine-src-path" , localEngineSrcPath
}
2018-04-12 08:12:26 +00:00
args "build" , "bundle"
2017-05-05 12:53:51 +00:00
args "--target" , targetPath
2019-06-10 20:16:09 +00:00
args "--target-platform" , "${targetPlatform}"
2018-06-06 20:43:32 +00:00
if ( verbose ) {
args "--verbose"
}
2018-03-17 19:47:40 +00:00
if ( fileSystemRoots ! = null ) {
for ( root in fileSystemRoots ) {
args "--filesystem-root" , root
}
}
if ( fileSystemScheme ! = null ) {
args "--filesystem-scheme" , fileSystemScheme
}
2018-02-12 18:44:31 +00:00
if ( trackWidgetCreation ) {
args "--track-widget-creation"
}
2018-08-16 15:46:57 +00:00
if ( compilationTraceFilePath ! = null ) {
2018-12-21 20:27:59 +00:00
args "--compilation-trace-file" , compilationTraceFilePath
2018-06-15 18:53:30 +00:00
}
2018-12-20 00:27:47 +00:00
if ( createPatch ) {
args "--patch"
args "--build-number" , project . android . defaultConfig . versionCode
if ( buildNumber ! = null ) {
assert buildNumber = = project . android . defaultConfig . versionCode
}
}
if ( baselineDir ! = null ) {
args "--baseline-dir" , baselineDir
2018-09-28 20:58:37 +00:00
}
2018-05-14 16:41:58 +00:00
if ( extraFrontEndOptions ! = null ) {
args "--extra-front-end-options" , "${extraFrontEndOptions}"
}
2018-06-15 18:53:30 +00:00
if ( extraGenSnapshotOptions ! = null ) {
args "--extra-gen-snapshot-options" , "${extraGenSnapshotOptions}"
}
2018-08-16 15:43:41 +00:00
if ( buildMode = = "release" | | buildMode = = "profile" ) {
2017-05-05 12:53:51 +00:00
args "--precompiled"
2018-09-07 19:33:05 +00:00
} else {
args "--depfile" , "${intermediateDir}/snapshot_blob.bin.d"
2017-05-05 12:53:51 +00:00
}
2018-04-12 08:12:26 +00:00
args "--asset-dir" , "${intermediateDir}/flutter_assets"
2018-08-16 15:43:41 +00:00
if ( buildMode = = "debug" ) {
args "--debug"
}
2019-06-18 18:11:38 +00:00
if ( buildMode = = "profile" ) {
2018-08-16 15:43:41 +00:00
args "--profile"
}
2019-06-18 18:11:38 +00:00
if ( buildMode = = "release" ) {
2018-08-16 15:43:41 +00:00
args "--release"
}
2017-05-05 12:53:51 +00:00
}
}
}
class FlutterTask extends BaseFlutterTask {
2016-03-12 00:30:56 +00:00
@OutputDirectory
2017-05-05 12:53:51 +00:00
File getOutputDirectory ( ) {
return intermediateDir
}
2016-03-12 00:30:56 +00:00
2016-06-06 19:56:04 +00:00
CopySpec getAssets ( ) {
return project . copySpec {
2017-12-14 16:27:25 +00:00
from "${intermediateDir}"
include "flutter_assets/**" // the working dir and its files
2019-05-20 20:09:20 +00:00
}
}
CopySpec getSnapshots ( ) {
return project . copySpec {
from "${intermediateDir}"
2018-01-15 02:24:07 +00:00
2018-10-09 20:04:06 +00:00
if ( buildMode = = 'release' | | buildMode = = 'profile' ) {
2019-06-10 20:16:09 +00:00
include "app.so"
2016-06-06 19:56:04 +00:00
}
2018-01-15 02:24:07 +00:00
}
2016-03-12 00:30:56 +00:00
}
2017-03-14 11:49:30 +00:00
FileCollection readDependencies ( File dependenciesFile ) {
if ( dependenciesFile . exists ( ) ) {
try {
// Dependencies file has Makefile syntax:
2018-10-19 03:44:38 +00:00
// <target> <files>: <source> <files> <separated> <by> <non-escaped space>
2017-03-14 11:49:30 +00:00
String depText = dependenciesFile . text
2018-10-19 03:44:38 +00:00
// So we split list of files by non-escaped(by backslash) space,
def matcher = depText . split ( ': ' ) [ 1 ] = ~ /(\\ |[^\s])+/
// then we replace all escaped spaces with regular spaces
def depList = matcher . collect { it [ 0 ] . replaceAll ( "\\\\ " , " " ) }
return project . files ( depList )
2017-03-14 11:49:30 +00:00
} catch ( Exception e ) {
logger . error ( "Error reading dependency file ${dependenciesFile}: ${e}" )
}
}
Include kernel_compile.d in Gradle depfiles (#17175)
This updates the Android build to declare the kernel compile depfile as
an output and its contents as inputs when running with --preview-dart-2
(the default mode).
The 'flutter build aot' command behaves differently depending on whether
it's running in Dart 1 or Dart 2 mode:
* Dart 1: the entrypoint Dart file (typically main.dart) is passed
directly to gen_snapshot, which then emits snapshot.d, whose contents
list the transitive closure of Dart dependencies (input files) for the
snapshot. snapshot.d is a declared output, its contents (plus
gen_snapshot itself) constitute the set of input files to the Gradle
build action.
* Dart 2: then entrypoint Dart file (typically main.dart) is first
compiled with the Dart kernel frontend. This emits kernel_compile.d,
whose contents list the transitive closure of Dart dependencies (input
files) for the kernel 'dill' output file. This 'dill' file is then
passed to gen_snapshot, which emits snapshot.d, whose contents are
empty. As of this change, both snapshot.d and kernel_compile.d are
declared outputs, and their contents (plus gen_snapshot and the
frontend compiler themselves) constitute the set of input files to the
Gradle build action.
This fixes a bug wherein profile/release AOT outputs were not
invalidated due to snapshot.d being empty, and kernel_compile.d being
ignored. This was introduced during recent refactoring of the AOT build
code, wherein the kernel compile and gen_snapshot actions were changed
to emit independent depfiles (previously one stomped -- or failed to --
on the other's output).
2018-05-02 01:11:57 +00:00
return project . files ( )
2017-03-14 11:49:30 +00:00
}
2017-01-31 22:48:48 +00:00
@InputFiles
FileCollection getSourceFiles ( ) {
Include kernel_compile.d in Gradle depfiles (#17175)
This updates the Android build to declare the kernel compile depfile as
an output and its contents as inputs when running with --preview-dart-2
(the default mode).
The 'flutter build aot' command behaves differently depending on whether
it's running in Dart 1 or Dart 2 mode:
* Dart 1: the entrypoint Dart file (typically main.dart) is passed
directly to gen_snapshot, which then emits snapshot.d, whose contents
list the transitive closure of Dart dependencies (input files) for the
snapshot. snapshot.d is a declared output, its contents (plus
gen_snapshot itself) constitute the set of input files to the Gradle
build action.
* Dart 2: then entrypoint Dart file (typically main.dart) is first
compiled with the Dart kernel frontend. This emits kernel_compile.d,
whose contents list the transitive closure of Dart dependencies (input
files) for the kernel 'dill' output file. This 'dill' file is then
passed to gen_snapshot, which emits snapshot.d, whose contents are
empty. As of this change, both snapshot.d and kernel_compile.d are
declared outputs, and their contents (plus gen_snapshot and the
frontend compiler themselves) constitute the set of input files to the
Gradle build action.
This fixes a bug wherein profile/release AOT outputs were not
invalidated due to snapshot.d being empty, and kernel_compile.d being
ignored. This was introduced during recent refactoring of the AOT build
code, wherein the kernel compile and gen_snapshot actions were changed
to emit independent depfiles (previously one stomped -- or failed to --
on the other's output).
2018-05-02 01:11:57 +00:00
FileCollection sources = project . files ( )
for ( File depfile in getDependenciesFiles ( ) ) {
sources + = readDependencies ( depfile )
}
if ( ! sources . isEmpty ( ) ) {
2017-03-14 11:49:30 +00:00
// We have a dependencies file. Add a dependency on gen_snapshot as well, since the
// snapshots have to be rebuilt if it changes.
Include kernel_compile.d in Gradle depfiles (#17175)
This updates the Android build to declare the kernel compile depfile as
an output and its contents as inputs when running with --preview-dart-2
(the default mode).
The 'flutter build aot' command behaves differently depending on whether
it's running in Dart 1 or Dart 2 mode:
* Dart 1: the entrypoint Dart file (typically main.dart) is passed
directly to gen_snapshot, which then emits snapshot.d, whose contents
list the transitive closure of Dart dependencies (input files) for the
snapshot. snapshot.d is a declared output, its contents (plus
gen_snapshot itself) constitute the set of input files to the Gradle
build action.
* Dart 2: then entrypoint Dart file (typically main.dart) is first
compiled with the Dart kernel frontend. This emits kernel_compile.d,
whose contents list the transitive closure of Dart dependencies (input
files) for the kernel 'dill' output file. This 'dill' file is then
passed to gen_snapshot, which emits snapshot.d, whose contents are
empty. As of this change, both snapshot.d and kernel_compile.d are
declared outputs, and their contents (plus gen_snapshot and the
frontend compiler themselves) constitute the set of input files to the
Gradle build action.
This fixes a bug wherein profile/release AOT outputs were not
invalidated due to snapshot.d being empty, and kernel_compile.d being
ignored. This was introduced during recent refactoring of the AOT build
code, wherein the kernel compile and gen_snapshot actions were changed
to emit independent depfiles (previously one stomped -- or failed to --
on the other's output).
2018-05-02 01:11:57 +00:00
sources + = readDependencies ( project . file ( "${intermediateDir}/gen_snapshot.d" ) )
2018-09-04 15:50:05 +00:00
sources + = readDependencies ( project . file ( "${intermediateDir}/frontend_server.d" ) )
2017-09-12 06:35:02 +00:00
if ( localEngineSrcPath ! = null ) {
Include kernel_compile.d in Gradle depfiles (#17175)
This updates the Android build to declare the kernel compile depfile as
an output and its contents as inputs when running with --preview-dart-2
(the default mode).
The 'flutter build aot' command behaves differently depending on whether
it's running in Dart 1 or Dart 2 mode:
* Dart 1: the entrypoint Dart file (typically main.dart) is passed
directly to gen_snapshot, which then emits snapshot.d, whose contents
list the transitive closure of Dart dependencies (input files) for the
snapshot. snapshot.d is a declared output, its contents (plus
gen_snapshot itself) constitute the set of input files to the Gradle
build action.
* Dart 2: then entrypoint Dart file (typically main.dart) is first
compiled with the Dart kernel frontend. This emits kernel_compile.d,
whose contents list the transitive closure of Dart dependencies (input
files) for the kernel 'dill' output file. This 'dill' file is then
passed to gen_snapshot, which emits snapshot.d, whose contents are
empty. As of this change, both snapshot.d and kernel_compile.d are
declared outputs, and their contents (plus gen_snapshot and the
frontend compiler themselves) constitute the set of input files to the
Gradle build action.
This fixes a bug wherein profile/release AOT outputs were not
invalidated due to snapshot.d being empty, and kernel_compile.d being
ignored. This was introduced during recent refactoring of the AOT build
code, wherein the kernel compile and gen_snapshot actions were changed
to emit independent depfiles (previously one stomped -- or failed to --
on the other's output).
2018-05-02 01:11:57 +00:00
sources + = project . files ( "$localEngineSrcPath/$localEngine" )
2017-09-12 06:35:02 +00:00
}
2017-03-14 11:49:30 +00:00
// Finally, add a dependency on pubspec.yaml as well.
Include kernel_compile.d in Gradle depfiles (#17175)
This updates the Android build to declare the kernel compile depfile as
an output and its contents as inputs when running with --preview-dart-2
(the default mode).
The 'flutter build aot' command behaves differently depending on whether
it's running in Dart 1 or Dart 2 mode:
* Dart 1: the entrypoint Dart file (typically main.dart) is passed
directly to gen_snapshot, which then emits snapshot.d, whose contents
list the transitive closure of Dart dependencies (input files) for the
snapshot. snapshot.d is a declared output, its contents (plus
gen_snapshot itself) constitute the set of input files to the Gradle
build action.
* Dart 2: then entrypoint Dart file (typically main.dart) is first
compiled with the Dart kernel frontend. This emits kernel_compile.d,
whose contents list the transitive closure of Dart dependencies (input
files) for the kernel 'dill' output file. This 'dill' file is then
passed to gen_snapshot, which emits snapshot.d, whose contents are
empty. As of this change, both snapshot.d and kernel_compile.d are
declared outputs, and their contents (plus gen_snapshot and the
frontend compiler themselves) constitute the set of input files to the
Gradle build action.
This fixes a bug wherein profile/release AOT outputs were not
invalidated due to snapshot.d being empty, and kernel_compile.d being
ignored. This was introduced during recent refactoring of the AOT build
code, wherein the kernel compile and gen_snapshot actions were changed
to emit independent depfiles (previously one stomped -- or failed to --
on the other's output).
2018-05-02 01:11:57 +00:00
return sources + project . files ( 'pubspec.yaml' )
2017-03-14 11:49:30 +00:00
}
// No dependencies file (or problems parsing it). Fall back to source files.
return project . fileTree (
dir: sourceDir ,
exclude: [ 'android' , 'ios' ] ,
include: [ '**/*.dart' , 'pubspec.yaml' ]
)
2017-01-31 22:48:48 +00:00
}
2016-03-12 00:30:56 +00:00
@TaskAction
void build ( ) {
2018-04-12 08:12:26 +00:00
buildBundle ( )
2016-03-12 00:30:56 +00:00
}
}
2018-09-20 22:45:48 +00:00
2019-07-23 16:27:42 +00:00
class FlutterPluginTask extends DefaultTask {
File flutterExecutable
@Optional @Input
Boolean verbose
@Input
String buildMode
@Input
File pluginDir
@Input
File intermediateDir
File sourceDir
@InputFiles
FileCollection getSourceFiles ( ) {
return project . fileTree (
dir: sourceDir ,
exclude: [ "android" , "ios" ] ,
include: [ "pubspec.yaml" ]
)
}
@OutputDirectory
File getOutputDirectory ( ) {
return intermediateDir
}
@TaskAction
void build ( ) {
intermediateDir . mkdirs ( )
project . exec {
executable flutterExecutable . absolutePath
workingDir pluginDir
args "build" , "aar"
args "--quiet"
args "--suppress-analytics"
args "--output-dir" , "${intermediateDir}"
switch ( buildMode ) {
case 'release' :
args "--release"
break
case 'debug' :
args "--debug"
break
default :
assert false
}
if ( verbose ) {
args "--verbose"
}
}
}
}