/ app / rust_builder / cargokit / build_tool / lib / src / build_pod.dart
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  }