buildscript { repositories { google() mavenCentral() } // Detect flavors from the task name. def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase() def isFdroid = taskName.contains('fdroid') def isBeta = taskName.contains('beta') dependencies { classpath libs.android.tools classpath(libs.triplet.play.publisher) classpath(libs.huawei.publish) } } repositories { google() mavenCentral() maven { url 'https://www.jitpack.io' } // MPAndroidChart } apply plugin: 'com.android.application' apply plugin: 'com.github.triplet.play' apply plugin: 'ru.cian.huawei-publish-gradle-plugin' def run(cmd) { def stdout = new ByteArrayOutputStream() exec { commandLine = cmd standardOutput = stdout } return stdout.toString() } import com.github.triplet.gradle.androidpublisher.ReleaseStatus import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform def getVersion() { def isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows() def bash = isWindows ? 'C:\\Program Files\\Git\\bin\\bash.exe' : 'bash' def versionCode = Integer.parseInt(run([bash, '../../tools/unix/version.sh', 'android_code']).trim()) def versionName = run([bash, '../../tools/unix/version.sh', 'android_name']).trim() return new Tuple2(versionCode, versionName) } def getCommitMessage() { return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim() } def osName = System.properties['os.name'].toLowerCase() project.ext.appId = 'app.comaps' project.ext.appName = 'CoMaps' // I have Java 21 installed, but this doesn't work on MacOS. //java { // toolchain { // languageVersion.set(JavaLanguageVersion.of(17)) // } //} android { namespace 'app.organicmaps' buildFeatures { dataBinding = true buildConfig = true } // All properties are read from gradle.properties file compileSdk propCompileSdkVersion.toInteger() ndkVersion '27.2.12479018' defaultConfig { // Default package name is taken from the manifest and should be app.comaps def ver = getVersion() versionCode = ver.V1 versionName = ver.V2 println('Version: ' + versionName) println('VersionCode: ' + versionCode) minSdk propMinSdkVersion.toInteger() targetSdk propTargetSdkVersion.toInteger() applicationId project.ext.appId buildConfigField 'String', 'SUPPORT_MAIL', '"android@comaps.app"' // Should be customized in flavors. buildConfigField 'String', 'REVIEW_URL', '""' externalNativeBuild { def pchFlag = 'OFF' if (project.hasProperty('pch')) pchFlag = 'ON' def njobs = '' if (project.hasProperty('njobs')) njobs = project.getProperty('njobs') def enableVulkanDiagnostics = 'OFF' if (project.hasProperty('enableVulkanDiagnostics')) { enableVulkanDiagnostics = project.getProperty('enableVulkanDiagnostics') } def enableTrace = 'OFF' if (project.hasProperty('enableTrace')) { enableTrace = project.getProperty('enableTrace') } cmake { cppFlags '-fexceptions', '-frtti' // There is no sense to enable sections without gcc's --gc-sections flag. cFlags '-fno-function-sections', '-fno-data-sections', '-Wno-extern-c-compat' arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static', "-DOS=$osName", '-DSKIP_TESTS=ON', '-DSKIP_TOOLS=ON', "-DUSE_PCH=$pchFlag", "-DNJOBS=$njobs", "-DENABLE_VULKAN_DIAGNOSTICS=$enableVulkanDiagnostics", "-DENABLE_TRACE=$enableTrace" targets 'organicmaps' } } // Use, for example, -Parm32 gradle parameter to build only for armeabi-v7a. ndk { abiFilters = new HashSet<>() if (project.hasProperty('arm32') || project.hasProperty('armeabi-v7a')) { abiFilters.add('armeabi-v7a') } if (project.hasProperty('arm64') || project.hasProperty('arm64-v8a')) { abiFilters.add('arm64-v8a') } if (project.hasProperty('x86')) { abiFilters.add('x86') } if (project.hasProperty('x86_64') || project.hasProperty('x64')) { abiFilters.add('x86_64') } if (abiFilters.isEmpty()) { abiFilters.add('armeabi-v7a') abiFilters.add('arm64-v8a') // For the emulator, chromebooks and some Intel Atom devices. abiFilters.add('x86_64') } println('Building for ' + abiFilters + ' archs.') } setProperty('archivesBaseName', appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode) } flavorDimensions += 'default' productFlavors { // 01 is a historical artefact, sorry. final int HUAWEI_VERSION_CODE_BASE = 01_00_00_00_00 google { dimension 'default' applicationIdSuffix '.google' versionName = android.defaultConfig.versionName + '-Google' buildConfigField 'String', 'SUPPORT_MAIL', '"gplay@comaps.app"' buildConfigField 'String', 'REVIEW_URL', '"market://details?id=app.comaps.google"' } // Distributed directly by the project, e.g. in repo releases, chats, etc. web { dimension 'default' versionName = android.defaultConfig.versionName buildConfigField 'String', 'SUPPORT_MAIL', '"apk@comaps.app"' } fdroid { dimension 'default' applicationIdSuffix '.fdroid' versionName = android.defaultConfig.versionName + '-FDroid' buildConfigField 'String', 'SUPPORT_MAIL', '"fdroid@comaps.app"' } huawei { dimension 'default' applicationIdSuffix '.huawei' versionName = android.defaultConfig.versionName + '-Huawei' versionCode = HUAWEI_VERSION_CODE_BASE + android.defaultConfig.versionCode buildConfigField 'String', 'SUPPORT_MAIL', '"huawei@comaps.app"' buildConfigField 'String', 'REVIEW_URL', '"appmarket://details?id=app.comaps"' } } playConfigs { googleRelease { enabled.set(true) } } splits.abi { boolean enabled = project.hasProperty('splitApk') println ('Create separate apks: ' + enabled) enable enabled reset() include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64' universalApk true } lint { disable 'MissingTranslation' // https://github.com/organicmaps/organicmaps/issues/3551 disable 'MissingQuantity', 'UnusedQuantity' // https://github.com/organicmaps/organicmaps/issues/3550 disable 'ByteOrderMark' // https://github.com/organicmaps/organicmaps/issues/1077 disable 'CustomSplashScreen' // https://github.com/organicmaps/organicmaps/issues/3610 disable 'InsecureBaseConfiguration' abortOnError true } gradle.projectsEvaluated { android.applicationVariants.all { variant -> def task = variant.name.capitalize() project.task(type: Exec, "run${task}", dependsOn: "install${task}") { commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "$applicationId/app.organicmaps.DownloadResourcesActivity", '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER' } } } def secureReleasePropertiesFileExists = file('secure.properties.release').exists() if (secureReleasePropertiesFileExists) { apply from: 'secure.properties.release' } def secureTestPropertiesFileExists = file('secure.properties.test').exists() if (secureTestPropertiesFileExists) { apply from: 'secure.properties.test' } signingConfigs { debug { storeFile file('comaps-debug.keystore') storePassword '12345678' keyAlias 'CoMaps Debug' keyPassword '12345678' } test { if (secureTestPropertiesFileExists) { storeFile file(secretTestStoreFile) storePassword secretTestStorePassword keyAlias secretTestKeyAlias keyPassword secretTestKeyPassword } else { println('secure.properties.test doesn\'t exist') } } release { if (secureReleasePropertiesFileExists) { storeFile file(secretReleaseStoreFile) storePassword secretReleaseStorePassword keyAlias secretReleaseKeyAlias keyPassword secretReleaseKeyPassword } else { println('secure.properties.release doesn\'t exist') } } } buildTypes { def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase() debug { applicationIdSuffix '.debug' // Allows to install debug and release builds together versionNameSuffix '-debug' jniDebuggable true // Enable jni debug build zipAlignEnabled true signingConfig signingConfigs.debug resValue 'string', 'app_name', 'CoMaps Debug' // Do not generate separate debug symbols for debug apps, because we don't distribute them. ndk.debugSymbolLevel = 'none' } release { if (taskName.contains('release')) { if (secureReleasePropertiesFileExists) { println('Using RELEASE signing keys from secure.properties.release') signingConfig signingConfigs.release } else { println('NO RELEASE signing keys found') println('Using DEBUG signing keys') signingConfig signingConfigs.debug } } minifyEnabled true shrinkResources true // Includes the default ProGuard rules files that are packaged with the Android Gradle plugin. // To learn more, go to the documentation section about R8 configuration files. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' resValue 'string', 'app_name', project.ext.appName // Full size symbols are too big for Google, 217mb aab vs 95mb. ndk.debugSymbolLevel = 'symbol_table' } // TODO(@pastk): rename to "test" everywhere in code beta { applicationIdSuffix '.test' versionNameSuffix '-test' if (taskName.contains('beta')) { if (secureTestPropertiesFileExists) { println('Using TEST signing keys from secure.properties.test') signingConfig signingConfigs.test } else { println('NO TEST signing keys found') println('Using DEBUG signing keys') signingConfig signingConfigs.debug } } minifyEnabled true shrinkResources true // Includes the default ProGuard rules files that are packaged with the Android Gradle plugin. // To learn more, go to the documentation section about R8 configuration files. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' matchingFallbacks = ['release'] // use dependencies of "release" build type resValue 'string', 'app_name', 'CoMaps Test' // Full size symbols are too big for Google, 217mb aab vs 95mb. ndk.debugSymbolLevel = 'symbol_table' } } externalNativeBuild { cmake { version '3.22.1+' buildStagingDirectory './nativeOutputs' path '../../CMakeLists.txt' } } // We don't compress these extensions in assets/ because our random FileReader can't read zip-compressed files from apk. // TODO: Load all minor files via separate call to ReadAsString which can correctly handle compressed files in zip containers. androidResources { ignoreAssetsPattern '!.svn:!.git:!.DS_Store:!*.scc:.*: