Initial flutter android build #4

Open
zaaach wants to merge 1 commit from zaaach/nexus:android into main
5 changed files with 96 additions and 16 deletions
Showing only changes of commit 91516c2f20 - Show all commits

initial flutter android build

Zach Russell 2026-03-20 12:15:10 -06:00

View file

@ -39,6 +39,11 @@ android {
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
// do we want to update.. eventually?
jvmTarget = "17"
}
defaultConfig {
applicationId = "nexus.federated.Nexus"
minSdk = 29
@ -50,7 +55,8 @@ android {
signingConfigs {
release {
keyAlias "key"
storeFile keystoreProperties['path'] ? file(keystoreProperties['path']) : file(System.getenv("KEYSTORE_PATH"))
def storePath = keystoreProperties['path'] ?: System.getenv("KEYSTORE_PATH")
storeFile storePath ? file(storePath) : null
keyPassword keystoreProperties['password'] ?: System.getenv("KEYSTORE_PASSWORD")
storePassword keystoreProperties['password'] ?: System.getenv("KEYSTORE_PASSWORD")
}

View file

@ -10,7 +10,7 @@
android:label="Nexus"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/nexus_round"
android:roundIcon="@mipmap/ic_launcher"
android:allowBackup="false"
android:fullBackupContent="false">
<activity

View file

@ -33,7 +33,6 @@
_module.args.pkgs = import nixpkgs {
inherit system;
config = {
permittedInsecurePackages = [ "olm-3.2.16" ];
android_sdk.accept_license = true;
allowUnfree = true;
};
@ -43,7 +42,6 @@
let
packages = with pkgs; [
go
olm
git
];

View file

@ -6,8 +6,12 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
final buildDir = input.packageRoot.resolve("src/");
if (await File(buildDir.resolve("lock").toFilePath()).exists()) return;
final targetOS = input.config.code.targetOS;
final codeConfig = input.config.code;
final targetOS = codeConfig.targetOS;
final targetArch = codeConfig.targetArchitecture;
String libFileName;
Map<String, String> env = {};
switch (targetOS) {
case OS.linux:
libFileName = "libgomuks.so";
@ -18,20 +22,51 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
case OS.windows:
libFileName = "libgomuks.dll";
break;
case OS.android:
libFileName = "libgomuks.so";
final targetNdkApi = codeConfig.android.targetNdkApi;
final ndkHome = Platform.environment["ANDROID_NDK_HOME"]
?? Platform.environment["ANDROID_NDK_ROOT"]
?? Platform.environment["NDK_HOME"]
?? await _findNdkFromSdk();
if (ndkHome == null) {
throw Exception(
"Could not find Android NDK. Set ANDROID_NDK_HOME or install via sdkmanager.",
);
}
final hostTag = _ndkHostTag();
final (goArch, ccTriple) = _androidArch(targetArch);
final cc = "$ndkHome/toolchains/llvm/prebuilt/$hostTag/bin/$ccTriple$targetNdkApi-clang";
env = {
"CGO_ENABLED": "1",
"GOOS": "android",
"GOARCH": goArch,
"CC": cc,
};
break;
default:
throw UnsupportedError("Unsupported OS: $targetOS");
}
final gomuksBuildDir = buildDir.resolve("gomuks/");
final libFile = gomuksBuildDir.resolve(libFileName);
final libFile = gomuksBuildDir.resolve("${targetArch.name}/$libFileName");
print("Building Gomuks shared library $libFileName from source...");
// goheif/dav1d supported on Android would need to fix upstream
final tags = targetOS == OS.android ? "goolm,noheic" : "goolm";
print("Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) from source...");
final result = await Process.run("go", [
"build",
"-tags", tags,
"-o",
libFile.path,
"-buildmode=c-shared",
], workingDirectory: gomuksBuildDir.resolve("source/pkg/ffi/").toFilePath());
], workingDirectory: gomuksBuildDir.resolve("source/pkg/ffi/").toFilePath(),
environment: env.isNotEmpty ? env : null);
if (result.exitCode != 0) {
throw Exception("Failed to build Gomuks shared library\n${result.stderr}");
@ -52,3 +87,42 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
..dependencies.add(gomuksBuildDir);
print("Done!");
});
Future<String?> _findNdkFromSdk() async {
// pretty sure this wont be needed with nix, i'll get this removed

Yeah, if this stuff could be removed that'd be great.

Yeah, if this stuff could be removed that'd be great.
final androidHome = Platform.environment["ANDROID_HOME"]
?? Platform.environment["ANDROID_SDK_ROOT"];
if (androidHome == null) return null;
final ndkDir = Directory("$androidHome/ndk");
if (!await ndkDir.exists()) return null;
final versions = await ndkDir.list().toList();
if (versions.isEmpty) return null;
versions.sort((a, b) => a.path.compareTo(b.path));
return versions.last.path;
}
String _ndkHostTag() {
if (Platform.isMacOS) {
return "darwin-x86_64";
} else if (Platform.isLinux) {
return "linux-x86_64";
} else if (Platform.isWindows) {
return "windows-x86_64";
}
throw UnsupportedError("Unsupported host platform for Android NDK");
}
(String goArch, String ccTriple) _androidArch(Architecture arch) {
switch (arch) {
case Architecture.arm64:
return ("arm64", "aarch64-linux-android");
case Architecture.arm:
return ("arm", "armv7a-linux-androideabi");
case Architecture.x64:
return ("amd64", "x86_64-linux-android");
case Architecture.ia32:
return ("386", "i686-linux-android");
default:
throw UnsupportedError("Unsupported Android architecture: $arch");
}
}

View file

@ -59,15 +59,17 @@ void showError(Object error, [StackTrace? stackTrace]) {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await windowManager.ensureInitialized();
await windowManager.waitUntilReadyToShow(
WindowOptions(titleBarStyle: TitleBarStyle.hidden),
);
if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
await windowManager.ensureInitialized();

Changes may also be needed in widgets/appbar.dart, specifically the onPanStart callback, but it may just be ignored as is. We can test once launch works.

Changes may also be needed in `widgets/appbar.dart`, specifically the `onPanStart` callback, but it may just be ignored as is. We can test once launch works.
await windowManager.waitUntilReadyToShow(
WindowOptions(titleBarStyle: TitleBarStyle.hidden),
);
if (Platform.isLinux) {
setWindowMinSize(const Size.square(500));
} else {
await windowManager.setMinimumSize(Size.square(500));
if (Platform.isLinux) {
setWindowMinSize(const Size.square(500));
} else {
await windowManager.setMinimumSize(Size.square(500));
}
}
FlutterError.onError = (FlutterErrorDetails details) =>