import "dart:io"; import "package:hooks/hooks.dart"; import "package:code_assets/code_assets.dart"; Future main(List args) => build(args, (input, output) async { final buildDir = input.packageRoot.resolve("src/"); if (await File(buildDir.resolve("lock").toFilePath()).exists()) return; final codeConfig = input.config.code; final targetOS = codeConfig.targetOS; final targetArch = codeConfig.targetArchitecture; String libFileName; Map env = {}; switch (targetOS) { case OS.linux: libFileName = "libgomuks.so"; break; case OS.macOS: libFileName = "libgomuks.dylib"; final sdkRoot = await _macSdkRoot(); final goArch = targetArch == Architecture.arm64 ? "arm64" : "amd64"; env = { "GOARCH": goArch, "CGO_ENABLED": "1", "CGO_CFLAGS": "-isysroot $sdkRoot", "CGO_CXXFLAGS": "-isysroot $sdkRoot", "CGO_LDFLAGS": "-isysroot $sdkRoot", }; break; case OS.windows: libFileName = "libgomuks.dll"; break; case OS.android: libFileName = "libgomuks.so"; if (targetArch != Architecture.arm64) { throw UnsupportedError( "only arm64 for now... got: $targetArch", ); } final targetNdkApi = codeConfig.android.targetNdkApi; final ndkHome = Platform.environment["ANDROID_NDK_HOME"] ?? Platform.environment["ANDROID_NDK_ROOT"] ?? Platform.environment["NDK_HOME"]; if (ndkHome == null) { throw Exception( "ANDROID_NDK_HOME, ANDROID_NDK_ROOT, or NDK_HOME must be set for Android builds", ); } final hostTag = _ndkHostTag(); final cc = "$ndkHome/toolchains/llvm/prebuilt/$hostTag/bin/aarch64-linux-android$targetNdkApi-clang"; env = { "CGO_ENABLED": "1", "GOOS": "android", "GOARCH": "arm64", "CC": cc, }; break; default: throw UnsupportedError("Unsupported OS: $targetOS"); } final gomuksBuildDir = buildDir.resolve("gomuks/"); final libFile = gomuksBuildDir.resolve("${targetArch.name}/$libFileName"); print("Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) from source..."); final result = await Process.run("go", [ "build", "-tags", "goolm", "-o", libFile.path, "-buildmode=c-shared", ], 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}"); } final generatedFile = "src/third_party/gomuks.g.dart"; print("Adding $libFileName as asset..."); output ..assets.code.add( CodeAsset( package: "nexus", name: generatedFile, linkMode: DynamicLoadingBundled(), file: libFile, ), ) ..dependencies.add(libFile) ..dependencies.add(gomuksBuildDir); print("Done!"); }); Future _macSdkRoot() async { final result = await Process.run("xcrun", ["--show-sdk-path"]); if (result.exitCode != 0) { throw Exception("Failed to find macOS SDK: ${result.stderr}"); } return (result.stdout as String).trim(); } 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"); }