|
| 1 | +import 'dart:io'; |
| 2 | + |
| 3 | +import 'package:package_config/package_config.dart'; |
| 4 | +import 'package:path/path.dart' as p; |
| 5 | + |
| 6 | +final context = p.Context(style: p.Style.windows); |
| 7 | + |
| 8 | +Future<void> collect() async { |
| 9 | + final executable = await _getDumpExecutable(); |
| 10 | + |
| 11 | + const windowsBuildDir = r'build\windows'; |
| 12 | + |
| 13 | + const outputPath = r'build\syms'; |
| 14 | + |
| 15 | + final plugins = Directory(context.join(windowsBuildDir, 'plugins')) |
| 16 | + .listSync() |
| 17 | + .whereType<Directory>(); |
| 18 | + |
| 19 | + Future<void> dumpToFile(String pdbPath, String dumpName) async { |
| 20 | + try { |
| 21 | + final ret = await _dump(executable, pdbPath); |
| 22 | + final file = File(context.join(outputPath, '$dumpName.sym')); |
| 23 | + if (file.existsSync()) { |
| 24 | + file.deleteSync(); |
| 25 | + } |
| 26 | + file.createSync(recursive: true); |
| 27 | + file.writeAsStringSync(ret); |
| 28 | + } catch (error) { |
| 29 | + print('Error while dumping $pdbPath $error'); |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + for (final plugin in plugins) { |
| 34 | + // normal plugin |
| 35 | + var pdbPath = context.join( |
| 36 | + plugin.path, 'Release', '${p.basename(plugin.path)}_plugin.pdb'); |
| 37 | + |
| 38 | + if (!File(pdbPath).existsSync()) { |
| 39 | + // ffi plugin |
| 40 | + pdbPath = context.join( |
| 41 | + plugin.path, 'shared', 'Release', '${p.basename(plugin.path)}.pdb'); |
| 42 | + } |
| 43 | + final dumpName = context.basenameWithoutExtension(pdbPath); |
| 44 | + await dumpToFile(pdbPath, dumpName); |
| 45 | + } |
| 46 | + |
| 47 | + // dump flutter wrapper |
| 48 | + final flutterWrapperAppPath = context.join( |
| 49 | + windowsBuildDir, 'flutter', 'Release', 'flutter_wrapper_app.pdb'); |
| 50 | + await dumpToFile(flutterWrapperAppPath, 'flutter_wrapper_app'); |
| 51 | + final flutterWrapperPluginPath = context.join( |
| 52 | + windowsBuildDir, 'flutter', 'Release', 'flutter_wrapper_plugin.pdb'); |
| 53 | + await dumpToFile(flutterWrapperPluginPath, 'flutter_wrapper_plugin'); |
| 54 | + |
| 55 | + // dump runner app |
| 56 | + final releaseRunnerDir = context.join(windowsBuildDir, 'runner', 'Release'); |
| 57 | + try { |
| 58 | + final exeFile = Directory(releaseRunnerDir) |
| 59 | + .listSync() |
| 60 | + .firstWhere((element) => p.extension(element.path) == '.exe'); |
| 61 | + final runnerName = context.basenameWithoutExtension(exeFile.path); |
| 62 | + final appPath = |
| 63 | + context.join(windowsBuildDir, 'runner', 'Release', '$runnerName.pdb'); |
| 64 | + await dumpToFile(appPath, runnerName); |
| 65 | + } catch (error, stacktrace) { |
| 66 | + print('Error while finding exe file $error $stacktrace'); |
| 67 | + return; |
| 68 | + } |
| 69 | + |
| 70 | + // dump flutter windows |
| 71 | + final flutterWindowsPath = context.join( |
| 72 | + 'windows', 'flutter', 'ephemeral', 'flutter_windows.dll.pdb'); |
| 73 | + await dumpToFile(flutterWindowsPath, 'flutter_windows.dll'); |
| 74 | +} |
| 75 | + |
| 76 | +Future<String> _dump(String executable, String pdb) async { |
| 77 | + final path = File(pdb).absolute.path; |
| 78 | + final result = await Process.run(executable, [path]); |
| 79 | + if (result.exitCode != 0) { |
| 80 | + print('error to dump $path ${result.stderr}'); |
| 81 | + } |
| 82 | + return result.stdout; |
| 83 | +} |
| 84 | + |
| 85 | +Future<String> _getDumpExecutable() async { |
| 86 | + final config = await findPackageConfig(Directory.current); |
| 87 | + if (config == null) { |
| 88 | + throw Exception('Could not find package config'); |
| 89 | + } |
| 90 | + final package = |
| 91 | + config.packages.firstWhere((e) => e.name == 'debug_info_collector'); |
| 92 | + final path = package.packageUriRoot.toFilePath(windows: true); |
| 93 | + return p.join(path, 'assets', 'dump_syms.exe'); |
| 94 | +} |
0 commit comments