rsend reproducible builds ========================= How rsend stays reproducible and what F-Droid needs to build it. Pinning ------- Every tool and source version lives in ./versions: the rsync source and its sha256, the Go version, the JDK release, the Android NDK, SDK platform, build-tools, Gradle, the Android Gradle Plugin, and Kotlin. The build never floats a version. The gradle files and go.mod repeat some pins because gradle cannot source a shell file; ci/test.sh fails if they drift from ./versions. Determinism ----------- - rsh (Go): built with the NDK clang, -trimpath, -ldflags "-s -w -buildid=", and CGO_CFLAGS=-ffile-prefix-map to drop build paths. - rsync (C): cross-compiled with -ffile-prefix-map and stripped; optional dependencies are disabled and zlib and popt come from rsync's bundled copies, so the binary needs nothing outside Bionic. - APK: no code shrinking (minifyEnabled false), the Google dependency-metadata block is dropped (dependenciesInfo off), and native libs use legacy packaging. Verify locally by building twice and diffing the native libs: make verify-repro F-Droid ------- The build recipe lives in fdroiddata, not in this repo. F-Droid supplies the NDK named by the recipe's ndk field and exports ANDROID_NDK_HOME. It pins Go through the go srclib (the official Go source) and builds it with make.bash, and installs make and g++ for rsync. The native lib*.so are then built in the recipe's build step, which runs after F-Droid's source scanner and calls rsync/build.sh and rsh/build.sh; Gradle then assembles the APK. The release build is unsigned unless a local keystore.properties is present, so F-Droid signs the published APK with its own key. All-files access ---------------- rsend requests MANAGE_EXTERNAL_STORAGE. It is required: backup targets such as OEM call-recording directories and app-specific media folders live outside the scoped-media buckets, and rsync needs real filesystem paths rather than SAF content URIs. The app makes no network access other than the SSH connection to the host the user configures.