feat: Add iOS platform support (#60)

Co-authored-by: Henry-Hiles <henry@henryhiles.com>
Reviewed-on: Nexus/nexus#60
This commit is contained in:
Erwan Leboucher 2026-08-08 16:35:56 -04:00 committed by Henry Hiles
commit 7bb4d87638
66 changed files with 1699 additions and 58 deletions

View file

@ -13,13 +13,42 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
String libFileName;
Map<String, String> extraEnv = {};
IOSSdk? iosSdk;
String? iosSdkPath;
String? iosTargetTriple;
switch (targetOS) {
case OS.linux:
libFileName = "libgomuks.so";
break;
case OS.iOS:
// Go only supports buildmode=c-archive for ios, not c-shared, so the
// archive built below gets linked into a dylib via a separate clang
// invocation before being registered as a normal asset like macOS.
libFileName = "libgomuks.dylib";
final iosConfig = codeConfig.iOS;
iosSdk = iosConfig.targetSdk;
final minVersion = iosConfig.targetVersion;
iosSdkPath = await getXCodeTool(sdkType: iosSdk.type);
final archTriple = switch (targetArch) {
Architecture.arm64 => "arm64",
Architecture.x64 => "x86_64",
_ => throw UnsupportedError(
"Unsupported iOS architecture: $targetArch",
),
};
iosTargetTriple = iosSdk == IOSSdk.iPhoneSimulator
? "$archTriple-apple-ios$minVersion.0-simulator"
: "$archTriple-apple-ios$minVersion.0";
extraEnv = {
"GOOS": "ios",
"CC": await getXCodeTool(sdkType: iosSdk.type, findTool: "clang"),
"CGO_CFLAGS": "-isysroot $iosSdkPath -target $iosTargetTriple",
"CGO_LDFLAGS": "-isysroot $iosSdkPath -target $iosTargetTriple",
};
break;
case OS.macOS:
libFileName = "libgomuks.dylib";
extraEnv = {"SDKROOT": await getXCodeSDK()};
extraEnv = {"SDKROOT": await getXCodeTool()};
break;
case OS.windows:
libFileName = "libgomuks.dll";
@ -86,15 +115,26 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
final tags = [
"sqlite_fts5",
"goolm",
// goheif/dav1d is not supported on Android, would need to be fixed upstream
if (targetOS == OS.android) "noheic",
// goheif/dav1d is not supported on Android or iOS, would need to be fixed upstream
if (targetOS == OS.android || targetOS == OS.iOS) "noheic",
].join(",");
final archiveFile = targetOS == OS.iOS
? buildDir.resolve("${targetArch.name}/libgomuks.a")
: libFile;
print(
"Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${libFile.path}...",
"Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${archiveFile.path}...",
);
final result = await Process.run(
"go",
["build", "-tags", tags, "-o", libFile.path, "-buildmode=c-shared"],
[
"build",
"-tags",
tags,
"-o",
archiveFile.path,
"-buildmode=${targetOS == OS.iOS ? "c-archive" : "c-shared"}",
],
workingDirectory: gomuksBuildDir.resolve("pkg/ffi/").toFilePath(),
environment: {
"CGO_ENABLED": "1",
@ -114,6 +154,35 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
"Failed to build Gomuks shared library\n${result.stderr}",
);
}
if (targetOS == OS.iOS) {
print("Linking $archiveFile into $libFile...");
final linkResult = await Process.run("xcrun", [
"--sdk",
iosSdk!.type,
"clang",
"-dynamiclib",
"-isysroot",
iosSdkPath!,
"-target",
iosTargetTriple!,
"-install_name",
"@rpath/libgomuks.dylib",
"-framework",
"Security",
"-framework",
"CoreFoundation",
"-framework",
"SystemConfiguration",
"-force_load",
archiveFile.path,
"-o",
libFile.path,
]);
if (linkResult.exitCode != 0) {
throw Exception("Failed to link Gomuks dylib\n${linkResult.stderr}");
}
}
}
final generatedFile = "src/third_party/gomuks.g.dart";