Skip intermediate R8 minification in the library-level standalone build type. The standalone app module performs final R8 with proper proguard rules, making an extra minify pass in the library redundant and wasteful in CI builds. Also add validation checks to enforce this build strategy: ensure library standalone build has minifyEnabled false and app-level standalone retains minifyEnabled true with TMessagesProj proguard rules. Update .gitignore to exclude generated .zip files from tgnet and messenger modules.
323 lines
15 KiB
Groovy
323 lines
15 KiB
Groovy
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
|
|
|
|
apply plugin: 'com.android.library'
|
|
// ZaStoGram plugin engine: embed CPython so .plugin scripts (exteraGram-compatible)
|
|
// can run. Chaquopy may be applied to exactly one module per app; TMessagesProj is the
|
|
// shared library, so every app flavor (Standalone/App/Huawei/...) inherits plugin support.
|
|
apply plugin: 'com.chaquo.python'
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
google()
|
|
}
|
|
|
|
configurations {
|
|
compile.exclude module: 'support-v4'
|
|
}
|
|
|
|
configurations.all {
|
|
exclude group: 'com.google.firebase', module: 'firebase-core'
|
|
exclude group: 'androidx.recyclerview', module: 'recyclerview'
|
|
}
|
|
|
|
dependencies {
|
|
implementation 'androidx.core:core:1.16.0'
|
|
implementation 'androidx.webkit:webkit:1.14.0'
|
|
implementation 'androidx.palette:palette:1.0.0'
|
|
implementation 'androidx.exifinterface:exifinterface:1.3.6'
|
|
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
|
|
implementation "androidx.sharetarget:sharetarget:1.2.0"
|
|
implementation 'androidx.interpolator:interpolator:1.0.0'
|
|
implementation 'androidx.biometric:biometric:1.1.0'
|
|
|
|
implementation 'com.google.android.gms:play-services-cast-framework:21.4.0'
|
|
implementation "androidx.mediarouter:mediarouter:1.7.0"
|
|
|
|
implementation 'androidx.car.app:app:1.4.0'
|
|
implementation 'androidx.car.app:app-projected:1.4.0'
|
|
implementation 'org.nanohttpd:nanohttpd:2.3.1'
|
|
|
|
compileOnly 'org.checkerframework:checker-qual:2.5.2'
|
|
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
|
|
implementation 'com.google.firebase:firebase-messaging:22.0.0'
|
|
implementation 'com.google.firebase:firebase-config:21.0.1'
|
|
implementation 'com.google.firebase:firebase-datatransport:18.1.0'
|
|
implementation 'com.google.firebase:firebase-appindexing:20.0.0'
|
|
implementation 'com.google.android.gms:play-services-maps:18.1.0'
|
|
implementation 'com.google.android.gms:play-services-auth:20.4.0'
|
|
implementation 'com.google.android.gms:play-services-vision:20.1.3'
|
|
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
|
|
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
|
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
|
|
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
|
|
implementation 'com.stripe:stripe-android:2.0.2'
|
|
implementation 'com.google.mlkit:language-id:17.0.6'
|
|
implementation 'com.android.billingclient:billing:7.1.1'
|
|
implementation 'com.google.code.gson:gson:2.11.0'
|
|
implementation 'com.google.guava:guava:31.1-android'
|
|
implementation 'com.google.android.play:integrity:1.3.0'
|
|
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
|
|
|
|
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
|
|
implementation 'com.google.android.gms:play-services-mlkit-image-labeling:16.0.8'
|
|
|
|
implementation "androidx.credentials:credentials:1.6.0-alpha04"
|
|
implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha04"
|
|
|
|
implementation "io.noties.markwon:core:4.6.2"
|
|
implementation "io.noties.markwon:ext-strikethrough:4.6.2"
|
|
implementation "io.noties.markwon:ext-tables:4.6.2"
|
|
implementation "io.noties.markwon:html:4.6.2"
|
|
implementation "io.noties.markwon:inline-parser:4.6.2"
|
|
implementation "io.noties.markwon:ext-latex:4.6.2"
|
|
|
|
// implementation 'com.google.mlkit:translate:17.0.3'
|
|
|
|
constraints {
|
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
|
|
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
|
|
}
|
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
|
|
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
|
|
}
|
|
}
|
|
implementation 'com.google.android.recaptcha:recaptcha:18.7.1'
|
|
|
|
// ZaStoGram plugin engine: Pine — dynamic ART method hooking (Xposed-compatible API).
|
|
// Supports Android 4.4(ART)-15 on arm64/armv7. The :xposed module exposes
|
|
// XC_MethodHook (before/afterHookedMethod + MethodHookParam) used by the bridge.
|
|
implementation 'top.canyie.pine:core:0.3.0'
|
|
// NOTE: the :xposed compat module's latest published version is 0.2.0 (there is no 0.3.0).
|
|
// 0.2.0 declares no dependency on :core, so it coexists with core:0.3.0. If runtime ART
|
|
// hooking ever misbehaves from version skew, pin core down to 0.2.9 to match.
|
|
implementation 'top.canyie.pine:xposed:0.2.0'
|
|
|
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
|
}
|
|
|
|
def isWindows = String.valueOf(DefaultNativePlatform.currentOperatingSystem.toFamilyName() == OperatingSystemFamily.WINDOWS)
|
|
def zastoAllNativeAbis = ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]
|
|
def zastoRequestedAbiFilter = (project.findProperty("zastoAbiFilter") ?: System.getenv("ZASTO_ABI_FILTER"))?.toString()?.trim()
|
|
if (zastoRequestedAbiFilter && !zastoAllNativeAbis.contains(zastoRequestedAbiFilter)) {
|
|
throw new GradleException("Unsupported zastoAbiFilter '${zastoRequestedAbiFilter}'. Expected one of: ${zastoAllNativeAbis.join(', ')}")
|
|
}
|
|
|
|
android {
|
|
compileSdkVersion 35
|
|
buildToolsVersion '35.0.0'
|
|
ndkVersion "27.2.12479018"
|
|
|
|
sourceSets.main.jniLibs.srcDirs = ['./jni/']
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
path 'jni/CMakeLists.txt'
|
|
}
|
|
}
|
|
|
|
lintOptions {
|
|
disable 'MissingTranslation'
|
|
disable 'ExtraTranslation'
|
|
disable 'BlockedPrivateApi'
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_1_8
|
|
targetCompatibility JavaVersion.VERSION_1_8
|
|
|
|
coreLibraryDesugaringEnabled true
|
|
}
|
|
|
|
|
|
defaultConfig {
|
|
minSdkVersion 24 // ZaStoGram: Chaquopy (plugin engine) requires minSdk >= 24
|
|
targetSdkVersion 35
|
|
|
|
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
|
|
|
|
multiDexEnabled true
|
|
|
|
// ZaStoGram: CI matrix jobs pass one ABI so the library module does not rebuild
|
|
// all native outputs before packaging a single-ABI APK. Without the property, keep
|
|
// the universal fallback for local builds and afat.
|
|
ndk {
|
|
abiFilters(*(zastoRequestedAbiFilter ? [zastoRequestedAbiFilter] : zastoAllNativeAbis))
|
|
}
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
version '3.10.2'
|
|
def cmakeArgs = ['-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21'] //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
|
// CI speedup: route NDK compiles through ccache so unchanged native sources
|
|
// (webrtc/openh264/ffmpeg/boringssl) reuse cached object files across runs.
|
|
// Enabled only when USE_CCACHE=1 (GitHub Actions); local builds are unaffected.
|
|
if (System.getenv('USE_CCACHE') == '1') {
|
|
cmakeArgs << '-DCMAKE_C_COMPILER_LAUNCHER=ccache' << '-DCMAKE_CXX_COMPILER_LAUNCHER=ccache'
|
|
}
|
|
arguments(*cmakeArgs)
|
|
}
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
jniDebuggable true
|
|
minifyEnabled false
|
|
shrinkResources false
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PRIVATE_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "0"
|
|
}
|
|
|
|
HA_private {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PRIVATE_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "1"
|
|
}
|
|
|
|
HA_public {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PUBLIC_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "4"
|
|
}
|
|
|
|
HA_hardcore {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_HARDCORE_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "5"
|
|
}
|
|
|
|
standalone {
|
|
jniDebuggable false
|
|
// The standalone app module runs final R8 with this module's proguard rules.
|
|
// Running R8 here first only makes CI do an extra minify pass before the APK pass.
|
|
minifyEnabled false
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"\""
|
|
buildConfigField "String", "BETA_URL", "\"\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "false"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "6"
|
|
}
|
|
|
|
release {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
shrinkResources false
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"\""
|
|
buildConfigField "String", "BETA_URL", "\"\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "false"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "7"
|
|
}
|
|
}
|
|
|
|
namespace 'org.telegram.messenger'
|
|
}
|
|
|
|
// ZaStoGram plugin engine — Python runtime configuration.
|
|
// Host API modules live in src/main/python (base_plugin, client_utils, ui.*, ...).
|
|
// User .plugin scripts are loaded at runtime from the data dir, not bundled here.
|
|
chaquopy {
|
|
defaultConfig {
|
|
version "3.11" // matches exteraGram (Chaquopy 16, CPython 3.11)
|
|
// The build machine needs a CPython 3.11 on PATH. If Android Studio can't find
|
|
// it (common on Windows), uncomment and point at it explicitly:
|
|
// buildPython "C:/Users/<you>/AppData/Local/Programs/Python/Python311/python.exe"
|
|
pyc {
|
|
src false // ship readable .py so plugin tracebacks map to real lines
|
|
}
|
|
pip {
|
|
// Common third-party libs community plugins expect at runtime. Chaquopy can only
|
|
// install these at BUILD time (there is no runtime pip), so they must be declared
|
|
// here once and shipped in the APK — mirrors what exteraGram bundles.
|
|
install "Pillow" // exposes PIL for image-processing plugins
|
|
install "pyfiglet" // ASCIIGenerator and ASCII art plugins
|
|
install "requests" // th3_proxy_tools (country flags via ip-api, URL import) + many others
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
def getProps(String propName) {
|
|
def propsFile = rootProject.file('local.properties')
|
|
if (propsFile.exists()) {
|
|
def props = new Properties()
|
|
props.load(new FileInputStream(propsFile))
|
|
return props[propName]
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
apply plugin: 'com.google.gms.google-services'
|
|
|
|
task checkVisibility {
|
|
doFirst {
|
|
def isPrivateBuild = project.gradle.startParameter.taskNames.find {
|
|
it.contains("HA_private") || it.contains("HA_hardcore") || it.contains("Debug") || it.contains("Release")
|
|
}
|
|
def isPublicAllowed = !project.hasProperty("IS_PRIVATE") || !project.property("IS_PRIVATE").toBoolean()
|
|
if (!isPrivateBuild && !isPublicAllowed) {
|
|
throw new GradleException("Building public version of private code!")
|
|
}
|
|
}
|
|
doLast {
|
|
if (project.gradle.startParameter.taskNames.find { it.contains("HA_public") }) {
|
|
def privateBuild = file("${projectDir}_AppHockeyApp/afat/HA_private/Telegram-Beta.apk")
|
|
if (privateBuild.exists()) {
|
|
privateBuild.delete()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
preBuild.dependsOn checkVisibility
|