Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build_runner/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## 2.9.1-wip

- Internal changes for `build_test`.
- Add the `--dart-jit-vm-arg` option. Its values are passed to `dart run` when
a build script is started in JIT mode. This allows specifying options to
attach a debugger to builders.

## 2.9.0

Expand Down
13 changes: 12 additions & 1 deletion build_runner/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
_Questions? Suggestions? Found a bug? Please
_Questions? Suggestions? Found a bug? Please
[file an issue](https://github.com/dart-lang/build/issues) or
[start a discussion](https://github.com/dart-lang/build/discussions)._

Expand Down Expand Up @@ -203,3 +203,14 @@ targets:
For advanced use cases it's possible to write your own builder.

Get started with the [build package documentation](https://pub.dev/packages/build).
For testing builders, see the [`build_test` package](https://pub.dev/packages/build_test).

## Debugging builds

To debug the build process, note that `build_runner` spawns a child process to run
the build.
Options used to spawn this process can be customized, which allows attaching a debugger:

```shell
dart run build_runner build --dart-jit-vm-arg=--observe --dart-jit-vm-arg=--pause-isolates-on-start
```
2 changes: 2 additions & 0 deletions build_runner/lib/src/bootstrap/bootstrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Bootstrapper {
/// they do not exist or have the wrong types.
Future<int> run(
BuiltList<String> arguments, {
required Iterable<String> jitVmArgs,
Iterable<String>? experiments,
}) async {
while (true) {
Expand All @@ -67,6 +68,7 @@ class Bootstrapper {
script: entrypointDillPath,
arguments: arguments,
message: buildProcessState.serialize(),
jitVmArgs: jitVmArgs,
);
buildProcessState.deserializeAndSet(result.message);
final exitCode = result.exitCode;
Expand Down
6 changes: 6 additions & 0 deletions build_runner/lib/src/bootstrap/processes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@ class ParentProcess {
/// Runs Dart [script] with [arguments], sends it [message], listens for and
/// returns the response.
///
/// When the underlying script is run with `dart run`, the [jitVmArgs] are
/// forwarded to the Dart VM. This can be used to e.g. start the VM with
/// debugging options.
///
/// The child process should use [ChildProcess] to communicate with the
/// parent.
static Future<RunAndSendResult> runAndSend({
required String script,
required Iterable<String> arguments,
required String message,
required Iterable<String> jitVmArgs,
}) async {
final process = await _startWithReaper(Platform.resolvedExecutable, [
'run',
...jitVmArgs,
script,
...arguments,
]);
Expand Down
1 change: 1 addition & 0 deletions build_runner/lib/src/build_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class BuildRunner {

return await Bootstrapper().run(
arguments,
jitVmArgs: commandLine.jitVmArgs ?? const Iterable.empty(),
experiments: commandLine.enableExperiments,
);
}
Expand Down
12 changes: 12 additions & 0 deletions build_runner/lib/src/build_runner_command_line.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class BuildRunnerCommandLine {
final String? config;
final BuiltList<String>? defines;
final BuiltList<String>? enableExperiments;
final BuiltList<String>? jitVmArgs;
final String? hostname;
final bool? liveReload;
final String? logPerformance;
Expand All @@ -67,6 +68,7 @@ class BuildRunnerCommandLine {
config = argResults.stringNamed(configOption),
defines = argResults.listNamed(defineOption),
enableExperiments = argResults.listNamed(enableExperimentOption),
jitVmArgs = argResults.listNamed(dartJitVmArgOption),
hostname = argResults.stringNamed(hostnameOption),
liveReload = argResults.boolNamed(liveReloadOption),
logPerformance = argResults.stringNamed(logPerformanceOption),
Expand Down Expand Up @@ -121,6 +123,7 @@ const configOption = 'config';
const defineOption = 'define';
const deleteFilesByDefaultOption = 'delete-conflicting-outputs';
const enableExperimentOption = 'enable-experiment';
const dartJitVmArgOption = 'dart-jit-vm-arg';
const hostnameOption = 'hostname';
const liveReloadOption = 'live-reload';
const logPerformanceOption = 'log-performance';
Expand Down Expand Up @@ -252,6 +255,15 @@ class _Build extends Command<BuildRunnerCommandLine> {
..addMultiOption(
enableExperimentOption,
help: 'A list of dart language experiments to enable.',
)
..addMultiOption(
dartJitVmArgOption,
help:
'Flags to pass to `dart run` when launching the inner build '
'script\n.'
'For example, `--dart-jit-vm-arg "--observe" '
'--dart-jit-vm-arg "--pause-isolates-on-start"` would start the '
'build script with a debugger attached to it.',
);
}

Expand Down
29 changes: 29 additions & 0 deletions build_runner/test/integration_tests/build_command_vm_arg_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2025, 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 'package:test/test.dart';

import '../common/common.dart';

void main() {
test('passing custom vm args to build script', () async {
final pubspecs = await Pubspecs.load();
final tester = BuildRunnerTester(pubspecs);

tester.writePackage(
name: 'root_pkg',
dependencies: ['build_runner'],
files: {},
);

// This should lauch the inner build script with dart run --help ..., so we
// check that help output is emitted to verify that the option is respected.
final output = await tester.run(
'root_pkg',
'dart run build_runner build --dart-jit-vm-arg=--help',
);

expect(output, contains('Run "dart help" to see global options.'));
});
}
2 changes: 2 additions & 0 deletions build_runner/test/integration_tests/processes_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Future<void> main() async {
final processResult = await ParentProcess.runAndSend(
script: 'bin/child.dart',
arguments: [],
jitVmArgs: [],
message: 'payload');
stdout.write(
'Parent received: '
Expand Down Expand Up @@ -78,6 +79,7 @@ Future<void> main() async {
await ParentProcess.runAndSend(
script: 'bin/child.dart',
arguments: [],
jitVmArgs: [],
message: 'payload');
}
''');
Expand Down