This project provides simple Kotlin DSL working over Android Gradle Plugin.
The following features are supported:
- Build flavors for differrent application variants
- Build flavors for differrent Android API versions
- Build flavors for differrent Android native platforms (ndk-build only, cmake will be added later)
- Different build variants for release/debug versions
- Various project configuration parameters which may be inherited from parent project or defined separately
- javaVersion
- kotlinVersion
- useKotlinInProd
- useKotlinInTest
- useViewBindings
- buildToolsVersion
- minSdkVersion
- compileSdkVersion
- Various project build properties loaded from build.properties and local.properties which which may be inherited from parent project or defined separately too
- package.name
- package.version.name
- package.version.code.major
- package.version.code.minor
- release.keystore.file
- release.keystore.password
- release.key.alias
- release.key.password
- debug.keystore.file
- debug.keystore.password
- debug.key.alias
- debug.key.password
Below you may find examples for various cases.
build.gradle.kts
androidLibrary {
dependsOn {
compileOnly += library("androidx.annotation:annotation:1.1.0")
compileOnly += library("org.jetbrains:annotations:13.0")
}
}
build.gradle.kts
androidLibrary {
dependsOn {
api += module(":projects:modules:utils")
}
}
build.gradle.kts
import org.ak2.android.build.flavors.AndroidPlatforms.*
androidLibrary {
dependsOn {
api += modules(":projects:modules:utils")
compileOnly += library("androidx.annotation:annotation:1.1.0")
implementation += library("androidx.core:core:1.1.0")
implementation += library("androidx.appcompat:appcompat:1.1.0")
}
buildFor(android41x) { native(actual(native32())) }
buildFor(android5xx) { native(actual(native64())) }
nativeOptions {
args("NDK_TOOLCHAIN_VERSION=4.9", "APP_STL=gnustl_static", "APP_LDFLAGS+=-Wl,-s")
c_flags("-O3", "-fvisibility=hidden")
cpp_flags("-std=c++11", "-frtti", "-fexceptions", "-fvisibility=hidden", "-Wno-write-strings")
libraries("mynative")
}
}
build.gradle.kts
androidApp {
config.minSdkVersion = ANDROID_8_0
dependsOn {
api += modules(":projects:modules:utils")
compileOnly += library("androidx.annotation:annotation:1.1.0")
implementation += library("androidx.core:core:1.1.0")
implementation += library("androidx.appcompat:appcompat:1.1.0")
}
}
Also the following files should be placed in the same folder with
build.properties
package.name=my-apk-name
package.version.name=3.2.1
package.version.code.major=321
package.version.code.minor=000
local.properties - optional file overriding build.properties values, typically excluded from GIT or other VCS
release.keystore.file=<path-to-keystore-relative-to-root-project>
release.keystore.password=<key-store-password>
release.key.alias=<key-alias>
release.key.password=<key-password>
debug.keystore.file=<path-to-keystore-relative-to-root-project>
debug.keystore.password=<key-store-password>
debug.key.alias=<key-alias>
debug.key.password=<key-password>
The layout for these applications is
app/
- build.gradle.kts
- local.properties
- multidex.cfg
+ libs/
+ common/
+ app2/
+ src/
+ app1
+ assets/
+ java/
+ res/
- AndroidManifest.xml
- build.properties
- proguard.cfg
+ app2
+ assets/
+ java/
+ res/
- AndroidManifest.xml
- build.properties
- proguard.cfg
+ main
+ assets/
+ java/
+ jni/
+ res/
- AndroidManifest.xml
build.gradle.kts
import org.ak2.android.build.AndroidVersion.ANDROID_10_0
import org.ak2.android.build.configurators.config
import org.ak2.android.build.dependencies.ThirdParties
import org.ak2.android.build.flavors.AndroidPlatforms.*
import org.ak2.android.build.flavors.NativePlatforms.*
import org.ak2.android.build.release.createI18nArchives
/**
* These optional properties are loaded from local.properties
*/
val app1Enabled: Boolean? by config.buildProperties
val app2Enabled: Boolean? by config.buildProperties
androidAppSet {
config.compileSdkVersion = ANDROID_10_0
dependsOn {
compileOnly += library("androidx.annotation:annotation:1.1.0")
compileOnly += library("org.jetbrains:annotations:13.0")
implementation += library("androidx.viewpager2:viewpager2:1.0.0")
implementation += library("androidx.documentfile:documentfile:1.0.1")
implementation += library("com.google.android.material:material:1.1.0-beta01")
implementation += library("androidx.constraintlayout:constraintlayout:2.0.0-beta4")
implementation += library("androidx.multidex:multidex:2.0.1")
implementation += local("libs/common/jcifs-1.3.18.jar")
implementation += local("libs/common/JSnappy-0.9.1.jar")
}
before {
defaultConfig.multiDexEnabled = true
defaultConfig.multiDexKeepProguard = file("multidex.cfg")
}
app("app1", "org.my.app1", app1Enabled) {
release {
buildFor(android41x) { native(actual(native32())) }
buildFor(android5xx) { native(actual(native64())) }
onRelease { appName, appVersion ->
createI18nArchives(project, appName, appVersion, languages)
}
proguard { shrinkResources = true }
}
debug {
buildFor(android41x) { native(arm7) }
}
languages += setOf("en", "ru", "it", "tt", "pl", "de", "es", "sk", "ko", "bg")
checkStrings {
languagesToCheck += languages
}
}
app("app2", "org.my.app2", app2Enabled) {
release {
buildFor(android41x) { native(actual(native32())) }
buildFor(android5xx) { native(actual(native64())) }
proguard { shrinkResources = true }
}
debug {
buildFor(android41x) { native(arm7) }
}
dependsOn {
implementation += local("libs/app2/libspen23.small.jar")
}
languages += setOf("en", "ru")
checkStrings {
languagesToCheck += languages
}
}
nativeOptions {
c_flags("-D__TEST__")
args("NDK_TOOLCHAIN_VERSION=4.9", "APP_STL=gnustl_static", "APP_LDFLAGS+=-Wl,-s")
c_flags("-DHAVE_CONFIG_H", "-DDEBUGLVL=0", "-D__ANDROID__", "-O3", "-fvisibility=hidden")
cpp_flags("-std=c++11", "-frtti", "-fexceptions", "-fvisibility=hidden", "-Wno-write-strings")
libraries("app")
}
}
The src/app1 folder contains the following files
build.properties
package.name=my-app1-apk-name
package.version.name=2.7.0-rc2
package.version.code.major=263
package.version.code.minor=110
proguard.cfg
...
The src/app2 folder contains the following files
build.properties
package.name=my-app2-apk-name
package.version.name=1.0.0
package.version.code.major=100
package.version.code.minor=000
proguard.cfg
...
After assembling, APK files are moved into the following locations (it was true for 3.5.3 - 3.6.0, in 4.1.0 apks are placed in standard output location) :
app/
+ build/
+ outputs/
+ packages/
+ debug/
+ app1/
- my-app1-apk-name-android41x-arm7-debug.apk
+ app2/
- my-app2-apk-name-debug.apk
+ release
+ app1/
+ app1-version1/
- my-app1-apk-name-2.7.0-rc2-android41x-arm7-263110.apk
- my-app1-apk-name-2.7.0-rc2-android41x-x86-263111.apk
- my-app1-apk-name-2.7.0-rc2-android5xx-arm8-263112.apk
- my-app1-apk-name-2.7.0-rc2-android5xx-x64-263113.apk
+ i18n/
- my-app1-apk-name-i18n-bg-2.7.0-rc2.zip
- my-app1-apk-name-i18n-de-2.7.0-rc2.zip
- my-app1-apk-name-i18n-en-2.7.0-rc2.zip
- my-app1-apk-name-i18n-es-2.7.0-rc2.zip
- my-app1-apk-name-i18n-it-2.7.0-rc2.zip
- my-app1-apk-name-i18n-ko-2.7.0-rc2.zip
- my-app1-apk-name-i18n-pl-2.7.0-rc2.zip
- my-app1-apk-name-i18n-ru-2.7.0-rc2.zip
- my-app1-apk-name-i18n-sk-2.7.0-rc2.zip
+ app2/
+ app2-version2/
- my-app2-apk-name-1.0.0-android41x-arm7-100000.apk
- my-app2-apk-name-1.0.0-android41x-x86-100001.apk
- my-app2-apk-name-1.0.0-android5xx-arm8-100002.apk
- my-app2-apk-name-1.0.0-android5xx-x64-100003.apk