build_pod.dart
1 /// This is copied from Cargokit (which is the official way to use it currently) 2 /// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin 3 4 import 'dart:io'; 5 6 import 'package:path/path.dart' as path; 7 8 import 'artifacts_provider.dart'; 9 import 'builder.dart'; 10 import 'environment.dart'; 11 import 'options.dart'; 12 import 'target.dart'; 13 import 'util.dart'; 14 15 class BuildPod { 16 BuildPod({required this.userOptions}); 17 18 final CargokitUserOptions userOptions; 19 20 Future<void> build() async { 21 final targets = Environment.darwinArchs.map((arch) { 22 final target = Target.forDarwin( 23 platformName: Environment.darwinPlatformName, darwinAarch: arch); 24 if (target == null) { 25 throw Exception( 26 "Unknown darwin target or platform: $arch, ${Environment.darwinPlatformName}"); 27 } 28 return target; 29 }).toList(); 30 31 final environment = BuildEnvironment.fromEnvironment(isAndroid: false); 32 final provider = 33 ArtifactProvider(environment: environment, userOptions: userOptions); 34 final artifacts = await provider.getArtifacts(targets); 35 36 void performLipo(String targetFile, Iterable<String> sourceFiles) { 37 runCommand("lipo", [ 38 '-create', 39 ...sourceFiles, 40 '-output', 41 targetFile, 42 ]); 43 } 44 45 final outputDir = Environment.outputDir; 46 47 Directory(outputDir).createSync(recursive: true); 48 49 final staticLibs = artifacts.values 50 .expand((element) => element) 51 .where((element) => element.type == AritifactType.staticlib) 52 .toList(); 53 final dynamicLibs = artifacts.values 54 .expand((element) => element) 55 .where((element) => element.type == AritifactType.dylib) 56 .toList(); 57 58 final libName = environment.crateInfo.packageName; 59 60 // If there is static lib, use it and link it with pod 61 if (staticLibs.isNotEmpty) { 62 final finalTargetFile = path.join(outputDir, "lib$libName.a"); 63 performLipo(finalTargetFile, staticLibs.map((e) => e.path)); 64 } else { 65 // Otherwise try to replace bundle dylib with our dylib 66 final bundlePaths = [ 67 '$libName.framework/Versions/A/$libName', 68 '$libName.framework/$libName', 69 ]; 70 71 for (final bundlePath in bundlePaths) { 72 final targetFile = path.join(outputDir, bundlePath); 73 if (File(targetFile).existsSync()) { 74 performLipo(targetFile, dynamicLibs.map((e) => e.path)); 75 76 // Replace absolute id with @rpath one so that it works properly 77 // when moved to Frameworks. 78 runCommand("install_name_tool", [ 79 '-id', 80 '@rpath/$bundlePath', 81 targetFile, 82 ]); 83 return; 84 } 85 } 86 throw Exception('Unable to find bundle for dynamic library'); 87 } 88 } 89 }