plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } // Release signing is configured only if a local keystore.properties exists // (gitignored). Otherwise the release build is unsigned, which is what F-Droid // and reproducible-build verification want. def keystoreProps = rootProject.file('keystore.properties') android { namespace 'invalid.lena.rsend' compileSdk 35 buildToolsVersion '35.0.0' defaultConfig { applicationId 'invalid.lena.rsend' minSdk 30 targetSdk 35 versionCode 5 versionName '0.2.0' // Ship only the ABIs we build native libs for. ndk { abiFilters 'arm64-v8a', 'x86_64' } } signingConfigs { if (keystoreProps.exists()) { def props = new Properties() keystoreProps.withInputStream { props.load(it) } release { storeFile rootProject.file(props['storeFile']) storePassword props['storePassword'] keyAlias props['keyAlias'] keyPassword props['keyPassword'] // Include v1 (JAR) signing too; some sideload installers // (Samsung One UI on Android 11/12) reject v2-only APKs with // "problem parsing the package". enableV1Signing true enableV2Signing true enableV3Signing true } } } buildTypes { release { minifyEnabled false // Do not stamp the git revision into the APK. It makes two builds // of the same source differ by checkout state, which is exactly // what reproducible-build verification is supposed to detect. vcsInfo { include false } if (keystoreProps.exists()) { signingConfig signingConfigs.release } } } compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = '17' } buildFeatures { buildConfig true } // Native executables ship as lib*.so and must be extracted so we can exec // them from nativeLibraryDir (useLegacyPackaging => extractNativeLibs=true). packaging { jniLibs { useLegacyPackaging true // Native build scripts already strip these PIE executables. keepDebugSymbols += ['**/libxrsync.so', '**/libxrsh.so'] } } // Reproducible / F-Droid: do not embed the Google dependency metadata block. dependenciesInfo { includeInApk false includeInBundle false } lint { warningsAsErrors true // rsend is deliberately English-only. Keeping short operational text // beside the behavior is clearer than a large indirection table. disable 'HardcodedText', 'SetTextI18n' // These two checks enforce Google Play policy; rsend targets F-Droid // and sideloading, and both permissions are core to unattended sync. disable 'BatteryLife', 'ScopedStorage' // Core 1.17+ requires a different platform and AGP toolchain. The pin // below is the newest version compatible with this release's stack. disable 'GradleDependency' // OldTargetApi fires the moment Google publishes a newer SDK, against // a targetSdk this repo pins deliberately in ./versions and enforces // in ci/test.sh. With warningsAsErrors that turns the calendar into a // build break: the same commit passes today and fails next quarter, // which is the opposite of what every other pin here exists for. // Bumping the target is a deliberate, tested change, not lint's call. disable 'OldTargetApi' } } dependencies { // 1.16.0 is the newest Core release supported by the pinned API 35 and // AGP 8.7 toolchain. Core 1.17+ requires a newer platform and AGP. implementation 'androidx.core:core-ktx:1.16.0' implementation 'androidx.appcompat:appcompat:1.7.1' implementation 'androidx.work:work-runtime:2.11.2' // The real org.json shadows the android.jar stub so JSON tests run on the JVM. testImplementation 'junit:junit:4.13.2' testImplementation 'org.json:json:20240303' }