FOSS Builds Documentation
Overview
CNVRT supports building FOSS (Free and Open Source Software) variants that exclude proprietary libraries. This makes the app suitable for distribution through F-Droid and other FOSS app stores.
The FOSS flavor excludes all proprietary dependencies while maintaining full functionality through local alternatives. Error logging still works locally through the app's logger.
Build Flavors
1. Standard (Default)
- Includes all features
- Uses Firebase Crashlytics for error reporting
- Suitable for Google Play Store and Apple App Store
Build command:
flutter build apk --flavor standard --release
2. FOSS
- Excludes all proprietary libraries (Firebase, Google Services)
- Fully FOSS-compliant
- Suitable for F-Droid and other FOSS app stores
- No telemetry or remote crash reporting
Build command:
flutter build apk --flavor foss --dart-define=FOSS_BUILD=true --release
What's Different in FOSS Builds?
The FOSS flavor excludes:
| Feature | Standard | FOSS |
|---|---|---|
| Firebase Core | ✅ Included | ❌ Excluded |
| Firebase Crashlytics | ✅ Remote reporting | ❌ Local logging only |
| Google Services | ✅ Included | ❌ Excluded |
| Error Reporting | Cloud-based | Local only |
| Distribution | Play Store, App Store | F-Droid, GitHub |
Building FOSS Variants
Quick Build (Using Scripts)
We provide convenience scripts for building FOSS variants:
# Debug build
./bin/build-foss.sh
# Release build (for distribution)
./bin/build-foss-release.sh
Manual Build Commands
Debug Build
flutter clean
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs
flutter build apk --flavor foss --dart-define=FOSS_BUILD=true --debug
Release Build
flutter clean
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs
flutter build apk --flavor foss --dart-define=FOSS_BUILD=true --release
Output Location
Built APKs are located in:
build/app/outputs/flutter-apk/
├── app-foss-debug.apk # Debug build
└── app-foss-release.apk # Release build
Technical Implementation
Android Configuration
The Android build system uses product flavors to manage the different variants in android/app/build.gradle.kts:
flavorDimensions += "distribution"
productFlavors {
create("standard") {
dimension = "distribution"
// Includes Firebase
}
create("foss") {
dimension = "distribution"
// Excludes Firebase
}
}
Firebase plugins are conditionally applied only when google-services.json exists in the standard flavor directory.
Flavor-Specific Directories
android/app/src/standard/google-services.json- Real Firebase configuration for standard buildsandroid/app/src/foss/google-services.json- Dummy Firebase configuration for FOSS builds
The FOSS build includes a dummy google-services.json file to satisfy the Google Services Gradle plugin,
but since Firebase is never initialized in the Dart code (thanks to FlavorConfig.isFirebaseEnabled),
these dummy values are never used at runtime.
Dart/Flutter Configuration
The flavor is detected at compile time using Dart's const evaluation in lib/config/flavor.dart:
class FlavorConfig {
static const bool isFossBuild =
bool.fromEnvironment('FOSS_BUILD', defaultValue: false);
static bool get isFirebaseEnabled => !isFossBuild;
}
This allows the Dart code to conditionally:
- Skip Firebase initialization
- Disable crash reporting
- Hide Firebase-related UI elements (debug screens)
Conditional Code Execution
Firebase initialization is skipped in FOSS builds:
Future<void> initializeFirebase() async {
if (!FlavorConfig.isFirebaseEnabled) {
log.d('[Firebase] FOSS build detected - skipping initialization');
return;
}
// Standard Firebase initialization continues...
}
Testing FOSS Builds
- Build the FOSS variant using one of the methods above
- Install on a device:
adb install build/app/outputs/flutter-apk/app-foss-release.apk - Verify Firebase is disabled:
- Check app logs for "FOSS build detected" messages
- Verify no Firebase services are initialized
- Check that Crashlytics section is hidden in Debug screen
F-Droid Considerations
For F-Droid submission:
- Use the FOSS flavor exclusively
- Ensure all proprietary code is excluded
- Review
pubspec.yamlto ensure no non-free dependencies remain - Build reproducibly by using consistent Flutter SDK versions
- Sign with F-Droid's keys (F-Droid handles this)
Metadata for F-Droid
When submitting to F-Droid, specify the build commands in the metadata:
Builds:
- versionName: '1.0.6'
versionCode: 1
gradle:
- foss
prebuild: flutter pub get
build: |
flutter build apk --flavor foss --dart-define=FOSS_BUILD=true --release
Verifying FOSS Compliance
1. Check the APK contents
unzip -l build/app/outputs/flutter-apk/app-foss-release.apk | grep -i firebase
Should return no Firebase-related files.
2. Run static analysis
flutter analyze
3. Check for proprietary dependencies
Review pubspec.lock and ensure Firebase dependencies aren't pulled in.
Maintaining FOSS Compatibility
When adding new features:
- Check for proprietary dependencies - Avoid adding new closed-source libraries
- Use flavor checks - Wrap any platform-specific code with
FlavorConfig.isFirebaseEnabled - Test both flavors - Always build and test both standard and FOSS variants
- Document changes - Update this file when adding flavor-specific behavior
Troubleshooting
"FirebaseCrashlytics not found" Error
This usually happens if you forget to add --dart-define=FOSS_BUILD=true. Make sure to include it:
flutter build apk --flavor foss --dart-define=FOSS_BUILD=true
Firebase Still Initializing in FOSS Build
Check that:
- The
--dart-define=FOSS_BUILD=trueflag was passed FlavorConfig.isFirebaseEnabledreturnsfalse- Firebase initialization code checks the flavor before running
Build Fails with Gradle Errors
The Firebase plugins are conditionally applied. If you see Gradle errors:
- Try
flutter clean - Delete
android/.gradleandandroid/app/builddirectories - Rebuild with the full command
Additional Resources
Support
For issues specific to FOSS builds, please open an issue on the
project's issue tracker
with the foss label.