I want to dynamically add a dependency in an Android Gradle project based on the current buildType. I know I can specify the buildType in the dependency:
compile project(path: ':lib1', configuration: 'debug')
But how can I use the current buildType to specify which variant of the library I want to import, so that a debug or release build automatically imports the debug or release variant of the library? What I want is something like this (where currentBuildType is a variable containing the name of the currently used buildType):
compile project(path: ':lib1', configuration: currentBuildType)
The library project I want to import has set publishNonDefault true
, so all buildTypes are published.
Add a task which depends on each assembleXxx task and property setting up after it invoked
ext {
currentConfig = ""
}
task generateConfigProperty(dependsOn: 'installDebug') {
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def taskName = "taskindicate$output.name"
task "$taskName"() << {
project.ext.set("currentConfig", "$output.name")
}
output.assemble.dependsOn "taskindicate$output.name"
}
}
}
task getConfig(dependsOn: ['installDebug', 'generateConfigProperty']) << {
println("My config is $currentConfig")
}
took idea from the answer
I could not find a clean way to get the current build type during the configuration phase of Gradle. Instead I define the dependency for each build type separately like that:
debugCompile project(path: ':lib1', configuration: 'debug')
releaseCompile project(path: ':lib1', configuration: 'release')
If you have many build types and many project dependencies this can get very verbose, but it is possible to add a function to make the dependency a one-liner. You need to add this to your main Gradle build file:
subprojects {
android {
dependencies.metaClass.allCompile { dependency ->
buildTypes.each { buildType ->
"${buildType.name}Compile" project(path: ":${dependency.name}", configuration: buildType.name)
}
}
}
}
Then you can add project dependencies in your Gradle modules like this:
allCompile project(':lib1')
If you also use build flavors you would have to adapt the solution. See this link for a documentation of the feature:
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication
Please note that the Android team is working on an improvement for this behaviour:
https://code.google.com/p/android/issues/detail?id=52962
You can use
if(gradle.startParameter.taskNames.contains("assembleExample")) {
// do stuff
}
That variable will be set before the buildConfig
block is evaluated
This one is quite simple:
android {
applicationVariants.all { variant ->
variant.buildType.name // this is the value!
}
}
Edit: Apparently at some point with gradle update, this is not working as I mentioned in a comment below. So I'd recommend checking other options.
This is the easiest way to get the result you want. You define the global variable, then updated it for use later where ever needed.
// query git for the SHA, Tag and commit count. Use these to automate versioning.
def gitSha = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
//def gitTag = 'git describe --tags'.execute([], project.rootDir).text.trim()
def gitCommitCount = 100 +
Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
def buildTime = new Date().format("yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"))
def versionMajor = 1
def versionMinor = 5
def versionPatch = 2
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
def buildType // define here to update in loop
android {
applicationVariants.all { variant ->
buildType = variant.buildType.name // sets the current build type
}
defaultConfig {
applicationId "com.example"
minSdkVersion 19
targetSdkVersion 25
vectorDrawables.useSupportLibrary = true
versionCode gitCommitCount
versionName "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}"
versionNameSuffix "-${buildType}-build-${buildTime}"
}
// declare a custom task class so you can reuse it for the different
// variants
class MyTask extends DefaultTask {
String mVariantName;
public void setVariantName(String variant) {mVariantName = variant;}
public String getVariantName() { return mVariantName; }
@TaskAction
void action(){
// do stuff
}
}
// put this after your `android{}` block.
android.applicationVariants.all { variant ->
def taskName = "myTask_$variant.name"
task "$taskName"(type: MyTask) << {
// you can setup this task to various info regarding
// variant
variantName = variant.name
}
variant.assemble.dependsOn (taskName)
}
See Advance customization for more details of what you can extract from the variant
variable.
now you it will properly hookup your MyTask
into to the chain. Doing it this way should also cleanly handle building multiple flavors all at once as it creates a new instance of MyTask for each variant.