| // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:async'; | |
| import 'dart:io'; | |
| import 'package:expect/expect.dart'; | |
| import 'package:test_runner/src/command.dart'; | |
| import 'package:test_runner/src/compiler_configuration.dart'; | |
| import 'utils.dart'; | |
| void main() { | |
| testCoffFiltersSaveDebuggingInfo(); | |
| testElfKeepsSaveDebuggingInfo(); | |
| testCoffRemovesObjectFile(); | |
| testCoffLinkTargetRequiresX64(); | |
| } | |
| void testCoffFiltersSaveDebuggingInfo() { | |
| final command = _precompilerCommandFor( | |
| [ | |
| '--system=win', | |
| '--arch=x64', | |
| '--compiler=dartkp', | |
| '--runtime=dart_precompiled', | |
| '--gen-snapshot-format=coff', | |
| ], | |
| ['--dwarf-stack-traces', '--save-debugging-info=C:/tmp/debug.so'], | |
| ); | |
| Expect.isTrue(command.arguments.contains('--dwarf-stack-traces')); | |
| Expect.isFalse( | |
| command.arguments.any((argument) { | |
| return argument.startsWith('--save-debugging-info'); | |
| }), | |
| ); | |
| } | |
| void testElfKeepsSaveDebuggingInfo() { | |
| final command = _precompilerCommandFor( | |
| [ | |
| '--system=linux', | |
| '--arch=x64', | |
| '--compiler=dartkp', | |
| '--runtime=dart_precompiled', | |
| '--gen-snapshot-format=elf', | |
| ], | |
| ['--dwarf-stack-traces', '--save-debugging-info=/tmp/debug.so'], | |
| ); | |
| Expect.isTrue(command.arguments.contains('--dwarf-stack-traces')); | |
| Expect.isTrue( | |
| command.arguments.contains('--save-debugging-info=/tmp/debug.so'), | |
| ); | |
| } | |
| void testCoffRemovesObjectFile() { | |
| if (!Platform.isWindows) return; | |
| final artifact = _compilationArtifactFor([ | |
| '--system=win', | |
| '--arch=x64', | |
| '--compiler=dartkp', | |
| '--runtime=dart_precompiled', | |
| '--gen-snapshot-format=coff', | |
| ], []); | |
| Expect.listEquals([ | |
| 'vm_compile_to_kernel', | |
| 'precompiler', | |
| 'remove_kernel_file', | |
| 'link_coff', | |
| 'remove_coff_object_file', | |
| ], artifact.commands.map((command) => command.displayName).toList()); | |
| final removeObjectFileCommand = artifact.commands.last as ProcessCommand; | |
| Expect.equals('cmd.exe', removeObjectFileCommand.executable); | |
| Expect.listEquals([ | |
| '/c', | |
| 'del', | |
| r'\tmp\out\out.obj', | |
| ], removeObjectFileCommand.arguments); | |
| } | |
| void testCoffLinkTargetRequiresX64() { | |
| if (!Platform.isWindows) return; | |
| final command = _coffLinkCommandFor('x64'); | |
| Expect.isTrue(command.arguments.contains('--target=x86_64-windows')); | |
| Expect.throws(() { | |
| runZoned( | |
| () => _coffLinkCommandFor('arm64'), | |
| zoneSpecification: ZoneSpecification(print: (_, _, _, _) {}), | |
| ); | |
| }); | |
| } | |
| ProcessCommand _precompilerCommandFor( | |
| List<String> configurationOptions, | |
| List<String> vmOptions, | |
| ) { | |
| final configuration = makeConfiguration(configurationOptions, 'language'); | |
| final testFile = createTestFile( | |
| source: '', | |
| path: 'coff_debug_info_test.dart', | |
| ); | |
| final compilerConfiguration = | |
| configuration.compilerConfiguration as PrecompilerCompilerConfiguration; | |
| final arguments = compilerConfiguration.computeCompilerArguments( | |
| testFile, | |
| vmOptions, | |
| [testFile.path.toNativePath()], | |
| ); | |
| return compilerConfiguration.computeGenSnapshotCommand( | |
| '/tmp/out', | |
| arguments, | |
| {}, | |
| ) | |
| as ProcessCommand; | |
| } | |
| CommandArtifact _compilationArtifactFor( | |
| List<String> configurationOptions, | |
| List<String> vmOptions, | |
| ) { | |
| final configuration = makeConfiguration(configurationOptions, 'language'); | |
| final testFile = createTestFile(source: '', path: 'coff_artifact_test.dart'); | |
| final compilerConfiguration = | |
| configuration.compilerConfiguration as PrecompilerCompilerConfiguration; | |
| final arguments = compilerConfiguration.computeCompilerArguments( | |
| testFile, | |
| vmOptions, | |
| [testFile.path.toNativePath()], | |
| ); | |
| return compilerConfiguration.computeCompilationArtifact( | |
| '/tmp/out', | |
| arguments, | |
| {}, | |
| ); | |
| } | |
| ProcessCommand _coffLinkCommandFor(String architecture) { | |
| final configuration = makeConfiguration([ | |
| '--system=win', | |
| '--arch=$architecture', | |
| '--compiler=dartkp', | |
| '--runtime=dart_precompiled', | |
| '--gen-snapshot-format=coff', | |
| ], 'language'); | |
| final compilerConfiguration = | |
| configuration.compilerConfiguration as PrecompilerCompilerConfiguration; | |
| return compilerConfiguration.computeCoffLinkCommand('/tmp/out', {}) | |
| as ProcessCommand; | |
| } |