kaliber/build/android/app/build.gradle

329 lines
10 KiB
Groovy
Raw Normal View History

@CacheableTask
abstract class WriteFileTask extends DefaultTask {
@Input
abstract Property<String> getContent()
@OutputFile
abstract RegularFileProperty getTarget()
@TaskAction
void run() {
def file = target.get().asFile
file.parentFile.mkdirs()
def text = content.get()
if (!file.exists() || text != file.text)
file.text = text
}
}
class Utils implements Plugin<Project> {
2023-09-05 16:04:47 +00:00
final def ABI_CODES = ["Arm": "armeabi-v7a",
"Arm64": "arm64-v8a",
"X64": "x86_64",
"X86": "x86"].asImmutable()
2023-09-05 16:04:47 +00:00
final def ARCH_CODES = ["armeabi-v7a": "Arm",
"arm64-v8a": "Arm64",
"x86_64": "X64",
2023-09-05 09:14:04 +00:00
"x86": "X86"].asImmutable()
def project
@Inject
Utils(Project project) {
this.project = project
}
void apply(Project project) {
project.extensions.create('utils', Utils)
}
void addTask(String prefix, Closure taskClosure) {
2023-09-03 19:33:10 +00:00
forEachBuildVariant { String game, String arch, String buildType ->
def taskName = "${prefix}${game}${arch}${buildType}"
taskClosure(taskName, buildType, arch, game)
}
}
void forEachBuildVariant(Closure callback) {
project.android.productFlavors.each { game ->
if (game.dimension == 'game') {
project.android.productFlavors.each { arch ->
2023-09-05 15:50:32 +00:00
// Only need to add tasks for arch types which maps to a single ABI
if (arch.dimension == 'arch' && arch.ndk.abiFilters.size() == 1) {
project.android.buildTypes.each { buildType ->
callback(game.name.capitalize(), arch.name.capitalize(), buildType.name.capitalize())
}
2023-09-05 09:14:04 +00:00
}
2023-09-03 19:33:10 +00:00
}
}
}
}
void forEachBuildType(Closure callback) {
project.android.buildTypes.each { buildType ->
2023-09-05 15:50:32 +00:00
callback(buildType.name)
}
}
def getBuildTypesRegExp() {
def outList = []
project.android.buildTypes.each { buildType ->
outList += buildType.name.capitalize()
}
return outList
}
2023-09-05 15:50:32 +00:00
def getArchTypesRegExp() {
def outList = []
project.android.productFlavors.each { flavor ->
if (flavor.dimension == 'arch') {
outList += flavor.name.capitalize()
}
}
return outList
}
2023-09-05 15:50:32 +00:00
def getGnTargetFor(String game) {
def outStr = ''
project.android.productFlavors.find { flavor ->
if (flavor.dimension == 'game' && flavor.name.capitalize() == game) {
outStr = flavor.ext.gnTarget
return true
}
}
return outStr
}
2023-09-05 15:50:32 +00:00
def generateGnArgsContent(String buildType, String arch) {
def content = 'target_os="android"\n'
2023-09-05 16:04:47 +00:00
content += 'target_cpu="' + arch.uncapitalize() + '"\n'
2023-09-05 15:50:32 +00:00
content += "is_debug=${buildType != 'Release'}\n"
content += 'ndk="' + project.android.ndkDirectory + '"\n'
content += "ndk_api=${project.rootProject.ext.minSdk}\n"
return content
}
2023-09-05 15:50:32 +00:00
def getOutDir(String buildType) {
return "${project.buildDir}/gn_out/${buildType.toLowerCase()}"
}
2023-09-05 15:50:32 +00:00
def getAssetsDir(String buildType) {
return "${project.buildDir}/gn_out/${buildType.toLowerCase()}/assets"
2023-09-03 19:33:10 +00:00
}
2023-09-05 15:50:32 +00:00
def getJniLibsDir(String buildType) {
return "${project.buildDir}/gn_out/jniLibs/${buildType.toLowerCase()}"
2023-09-05 09:14:04 +00:00
}
}
2020-04-13 11:24:53 +00:00
apply plugin: 'com.android.application'
apply plugin: Utils
2020-04-13 11:24:53 +00:00
android {
compileSdk rootProject.ext.compileSdk
ndkVersion rootProject.ext.ndkVersion
2020-04-13 11:24:53 +00:00
defaultConfig {
minSdk rootProject.ext.minSdk
targetSdk rootProject.ext.targetSdk
ndk {
abiFilters = []
}
2020-04-13 11:24:53 +00:00
}
2023-09-03 19:33:10 +00:00
2020-04-13 11:24:53 +00:00
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
2023-09-03 19:33:10 +00:00
2023-09-05 09:14:04 +00:00
flavorDimensions 'game', 'arch'
2023-09-03 19:33:10 +00:00
productFlavors {
helloWorld {
dimension 'game'
applicationId 'com.kaliber.helloworld'
resValue "string", "provider_name", "${applicationId}.fileprovider"
resValue "string", "app_name", "Kaliber Hello World"
resValue "string", "interstitial_ad_unit_id", ""
2023-09-03 19:33:10 +00:00
ext {
gnTarget = "hello_world"
}
}
demo {
dimension 'game'
applicationId 'com.kaliber.woom'
resValue "string", "provider_name", "${applicationId}.fileprovider"
resValue "string", "app_name", "Kaliber Demo"
resValue "string", "interstitial_ad_unit_id", "ca-app-pub-1321063817979967/8373182022"
2023-09-03 19:33:10 +00:00
ext {
gnTarget = "demo"
}
}
2023-09-05 09:14:04 +00:00
2023-09-05 16:04:47 +00:00
arm {
2023-09-05 09:14:04 +00:00
dimension 'arch'
ndk {
abiFilters = ["armeabi-v7a"]
}
}
2023-09-05 16:04:47 +00:00
arm64 {
2023-09-05 09:14:04 +00:00
dimension 'arch'
ndk {
abiFilters = ["arm64-v8a"]
}
}
x86 {
dimension 'arch'
ndk {
abiFilters = ["x86"]
}
}
2023-09-05 16:04:47 +00:00
x64 {
2023-09-05 09:14:04 +00:00
dimension 'arch'
ndk {
abiFilters = ["x86_64"]
}
}
2023-09-05 15:50:32 +00:00
2023-09-05 09:14:04 +00:00
allArchs {
dimension 'arch'
ndk {
abiFilters = ["armeabi-v7a", "arm64-v8a", "x86_64", "x86"]
}
}
armOnly {
dimension 'arch'
ndk {
abiFilters = ["armeabi-v7a", "arm64-v8a"]
}
}
x86Only {
dimension 'arch'
ndk {
abiFilters = ["x86_64", "x86"]
}
}
2023-09-03 19:33:10 +00:00
}
2020-04-13 11:24:53 +00:00
sourceSets {
main {
2021-10-29 11:42:49 +00:00
java.srcDirs += ['../../../src/engine/platform/java/com/kaliber/base']
utils.forEachBuildType { buildType ->
2023-09-05 15:50:32 +00:00
"${buildType}" {
assets.srcDirs = [utils.getAssetsDir(buildType)]
}
}
}
utils.forEachBuildType { buildType ->
2023-09-05 15:50:32 +00:00
"${buildType}" {
jniLibs.srcDirs = [utils.getJniLibsDir(buildType)]
}
2020-04-13 11:24:53 +00:00
}
}
2023-09-03 19:33:10 +00:00
namespace "com.kaliber.base"
2020-04-13 11:24:53 +00:00
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.gms:play-services-ads:22.0.0'
2020-04-13 11:24:53 +00:00
}
2023-09-03 19:33:10 +00:00
utils.addTask('generateGnArgsFor') { String taskName, String buildType, String arch, String game ->
task(taskName, type: WriteFileTask) {
2023-09-05 15:50:32 +00:00
content = utils.generateGnArgsContent(buildType, arch)
target = project.layout.file(provider { new File("${utils.getOutDir(buildType)}/${arch}", 'args.gn') })
}
}
2023-09-03 19:33:10 +00:00
utils.addTask('runGnFor') { String taskName, String buildType, String arch, String game ->
task(taskName, type: Exec) {
2023-09-03 19:33:10 +00:00
dependsOn "generateGnArgsFor${game}${arch}${buildType}"
executable rootProject.ext.gn
2023-09-05 15:50:32 +00:00
args '--fail-on-unused-args', 'gen', "${utils.getOutDir(buildType)}/${arch}"
2023-09-05 15:50:32 +00:00
inputs.file(new File("${utils.getOutDir(buildType)}/${arch}", 'args.gn'))
outputs.file(new File("${utils.getOutDir(buildType)}/${arch}", 'build.ninja'))
}
}
2023-09-03 19:33:10 +00:00
utils.addTask('runNinjaFor') { String taskName, String buildType, String arch, String game ->
task(taskName, type: Exec) {
2023-09-03 19:33:10 +00:00
dependsOn "runGnFor${game}${arch}${buildType}"
executable rootProject.ext.ninja
2023-09-05 15:50:32 +00:00
args '-C', "${utils.getOutDir(buildType)}/${arch}", utils.getGnTargetFor(game)
2023-09-05 15:50:32 +00:00
// Always run ninja and let it figure out what needs to be compiled.
2023-09-02 15:08:19 +00:00
outputs.upToDateWhen { false }
}
}
2023-09-03 19:33:10 +00:00
utils.addTask('copyAssetsFor') { String taskName, String buildType, String arch, String game ->
task(taskName, type: Copy) {
2023-09-03 19:33:10 +00:00
dependsOn "runNinjaFor${game}${arch}${buildType}"
2023-09-05 15:50:32 +00:00
from "${utils.getOutDir(buildType)}/${arch}/assets"
into utils.getAssetsDir(buildType)
}
}
2023-09-03 19:33:10 +00:00
utils.addTask('copyJniLibsFor') { String taskName, String buildType, String arch, String game ->
task(taskName, type: Copy) {
2023-09-03 19:33:10 +00:00
dependsOn "runNinjaFor${game}${arch}${buildType}"
2023-09-05 15:50:32 +00:00
from("${utils.getOutDir(buildType)}/${arch}") {
include "lib${utils.getGnTargetFor(game)}.so"
rename "lib${utils.getGnTargetFor(game)}.so", "libkaliber.so"
}
2023-09-05 15:50:32 +00:00
into "${utils.getJniLibsDir(buildType)}/${utils.ABI_CODES[arch]}"
}
}
tasks.configureEach { task ->
2023-09-05 15:50:32 +00:00
def variantPattern = /(\w+)(${utils.getArchTypesRegExp().join('|')})(${utils.getBuildTypesRegExp().join('|')})/
2023-09-05 09:14:04 +00:00
def match = task.name =~ /^merge/ + variantPattern + /JniLibFolders$/
if (match) {
2023-09-05 09:14:04 +00:00
android.productFlavors.find { flavor ->
if (flavor.dimension == 'arch' && flavor.name.capitalize() == match.group(2)) {
flavor.ndk.abiFilters.each { abi ->
task.dependsOn "copyJniLibsFor${match.group(1)}${utils.ARCH_CODES[abi]}${match.group(3)}"
}
return true
}
}
2023-09-03 19:33:10 +00:00
return
}
2023-09-05 09:14:04 +00:00
match = task.name =~ /^merge/ + variantPattern + /Assets$/
if (match) {
2023-09-05 09:14:04 +00:00
android.productFlavors.find { flavor ->
if (flavor.dimension == 'arch' && flavor.name.capitalize() == match.group(2)) {
flavor.ndk.abiFilters.each { abi ->
task.dependsOn "copyAssetsFor${match.group(1)}${utils.ARCH_CODES[abi]}${match.group(3)}"
}
return true
}
}
2023-09-03 19:33:10 +00:00
return
}
2023-09-05 09:14:04 +00:00
match = task.name =~ /^lintVitalAnalyze/ + variantPattern + /$/
if (match) {
2023-09-05 09:14:04 +00:00
android.productFlavors.find { flavor ->
if (flavor.dimension == 'arch' && flavor.name.capitalize() == match.group(2)) {
flavor.ndk.abiFilters.each { abi ->
task.dependsOn "copyAssetsFor${match.group(1)}${utils.ARCH_CODES[abi]}${match.group(3)}"
}
return true
}
}
2023-09-03 19:33:10 +00:00
return
}
}