From 0edcd1fe50cd711bc9dc18fbc38abb55f1218ea1 Mon Sep 17 00:00:00 2001 From: Daco Harkes Date: Fri, 11 Oct 2024 13:24:50 +0200 Subject: [PATCH] [et] Add support for building Dart SDK from source --- tools/engine_tool/lib/src/build_plan.dart | 56 +++++++- .../lib/src/commands/build_command.dart | 1 + .../lib/src/commands/query_command.dart | 1 + .../lib/src/commands/test_command.dart | 2 + tools/engine_tool/test/build_plan_test.dart | 123 ++++++++++++++++++ 5 files changed, 181 insertions(+), 2 deletions(-) diff --git a/tools/engine_tool/lib/src/build_plan.dart b/tools/engine_tool/lib/src/build_plan.dart index ccfbfeb20e766..cc620e247599b 100644 --- a/tools/engine_tool/lib/src/build_plan.dart +++ b/tools/engine_tool/lib/src/build_plan.dart @@ -11,6 +11,8 @@ import 'build_utils.dart'; import 'environment.dart'; import 'logger.dart'; +const _flagBuildDart = 'build-dart'; +const _flagBuildDartFull = 'build-dart-full'; const _flagConfig = 'config'; const _flagConcurrency = 'concurrency'; const _flagStrategy = 'build-strategy'; @@ -65,6 +67,15 @@ final class BuildPlan { } return !build.gn.contains('--no-lto'); }(), + buildDart: () { + if (args.flag(_flagBuildDartFull)) { + return BuildDart.buildFull; + } + if (args.flag(_flagBuildDart)) { + return BuildDart.build; + } + return BuildDart.prebuilt; + }(), concurrency: () { final value = args.option(_flagConcurrency); if (value == null) { @@ -84,6 +95,7 @@ final class BuildPlan { required this.useRbe, required this.useLto, required this.concurrency, + required this.buildDart, }) { if (!useRbe && strategy == BuildStrategy.remote) { throw FatalError( @@ -156,6 +168,16 @@ final class BuildPlan { }(), ); + /// Adds the --build-dart and --build-dart-full flags. + parser.addFlag( + _flagBuildDart, + help: 'Build Dart from source.', + ); + parser.addFlag( + _flagBuildDartFull, + help: 'Build the full Dart SDK from source.', + ); + // Add --build-strategy. parser.addOption( _flagStrategy, @@ -201,6 +223,9 @@ final class BuildPlan { /// Whether to build with LTO (link-time optimization). final bool useLto; + /// Whether to build Dart from source or not. + final BuildDart buildDart; + @override bool operator ==(Object other) { return other is BuildPlan && @@ -208,12 +233,20 @@ final class BuildPlan { strategy == other.strategy && useRbe == other.useRbe && useLto == other.useLto && - concurrency == other.concurrency; + concurrency == other.concurrency && + buildDart == other.buildDart; } @override int get hashCode { - return Object.hash(build.name, strategy, useRbe, useLto, concurrency); + return Object.hash( + build.name, + strategy, + useRbe, + useLto, + concurrency, + buildDart, + ); } /// Converts this build plan to its equivalent [RbeConfig]. @@ -236,6 +269,12 @@ final class BuildPlan { return [ if (!useRbe) '--no-rbe', if (useLto) '--lto' else '--no-lto', + if (buildDart == BuildDart.build) + '--no-prebuilt-dart-sdk' + else if (buildDart == BuildDart.buildFull) ...[ + '--no-prebuilt-dart-sdk', + '--full-dart-sdk', + ], ]; } @@ -246,6 +285,7 @@ final class BuildPlan { buffer.writeln(' build: ${build.name}'); buffer.writeln(' useLto: $useLto'); buffer.writeln(' useRbe: $useRbe'); + buffer.writeln(' build dart: ${buildDart.name}'); buffer.writeln(' strategy: $strategy'); buffer.writeln(' concurrency: $concurrency'); buffer.write('>'); @@ -277,3 +317,15 @@ enum BuildStrategy { const BuildStrategy(this._help); final String _help; } + +/// Whether to build Dart from source or not. +enum BuildDart { + /// Use the prebuilt Dart. + prebuilt, + + /// Build Dart from source. + build, + + /// Build the full Dart SDK from source. + buildFull, +} diff --git a/tools/engine_tool/lib/src/commands/build_command.dart b/tools/engine_tool/lib/src/commands/build_command.dart index 6094ffd2db0a1..59bf761f032f0 100644 --- a/tools/engine_tool/lib/src/commands/build_command.dart +++ b/tools/engine_tool/lib/src/commands/build_command.dart @@ -55,6 +55,7 @@ et build //flutter/fml:fml_benchmarks # Build a specific target in `//flutter/f environment, plan.build, enableRbe: plan.useRbe, + extraGnArgs: plan.toGnArgs(), )) { return 1; } diff --git a/tools/engine_tool/lib/src/commands/query_command.dart b/tools/engine_tool/lib/src/commands/query_command.dart index 178d2db0bca8a..b7472787280c1 100644 --- a/tools/engine_tool/lib/src/commands/query_command.dart +++ b/tools/engine_tool/lib/src/commands/query_command.dart @@ -182,6 +182,7 @@ et query targets //flutter/fml/... # List all targets under `//flutter/fml` environment, plan.build, enableRbe: plan.useRbe, + extraGnArgs: plan.toGnArgs(), )) { return 1; } diff --git a/tools/engine_tool/lib/src/commands/test_command.dart b/tools/engine_tool/lib/src/commands/test_command.dart index cf857eac0912a..0ead18cc2ce1c 100644 --- a/tools/engine_tool/lib/src/commands/test_command.dart +++ b/tools/engine_tool/lib/src/commands/test_command.dart @@ -55,6 +55,7 @@ et test //flutter/fml:fml_benchmarks # Run a single test target in `//flutter/f environment, plan.build, enableRbe: plan.useRbe, + extraGnArgs: plan.toGnArgs(), )) { return 1; } @@ -96,6 +97,7 @@ et test //flutter/fml:fml_benchmarks # Run a single test target in `//flutter/f targets: testTargets.map((target) => target.label).toList(), enableRbe: plan.useRbe, rbeConfig: plan.toRbeConfig(), + extraGnArgs: plan.toGnArgs(), ); if (buildExitCode != 0) { return buildExitCode; diff --git a/tools/engine_tool/test/build_plan_test.dart b/tools/engine_tool/test/build_plan_test.dart index 529641fa2d8e4..509b3bc29a5e6 100644 --- a/tools/engine_tool/test/build_plan_test.dart +++ b/tools/engine_tool/test/build_plan_test.dart @@ -546,6 +546,129 @@ void main() { ); }); + test('dart build defaults to prebuilt', () { + final testEnv = TestEnvironment.withTestEngine( + withRbe: true, + ); + addTearDown(testEnv.cleanup); + + final testConfig = TestBuilderConfig(); + testConfig.addBuild( + name: 'linux/host_debug', + dimension: TestDroneDimension.linux, + ); + + final parser = ArgParser(); + final builds = BuildPlan.configureArgParser( + parser, + testEnv.environment, + configs: { + 'linux_test_config': testConfig.buildConfig( + path: 'ci/builders/linux_test_config.json', + ), + }, + help: false, + ); + + final plan = BuildPlan.fromArgResults( + parser.parse([]), + testEnv.environment, + builds: builds, + ); + + expect(plan.buildDart, BuildDart.prebuilt); + expect( + plan.toGnArgs(), + isNot(contains('--no-prebuilt-dart-sdk')), + ); + expect( + plan.toGnArgs(), + isNot(contains('--full-dart-sdk')), + ); + }); + + test('dart build can be set to from source', () { + final testEnv = TestEnvironment.withTestEngine( + withRbe: true, + ); + addTearDown(testEnv.cleanup); + + final testConfig = TestBuilderConfig(); + testConfig.addBuild( + name: 'linux/host_debug', + dimension: TestDroneDimension.linux, + ); + + final parser = ArgParser(); + final builds = BuildPlan.configureArgParser( + parser, + testEnv.environment, + configs: { + 'linux_test_config': testConfig.buildConfig( + path: 'ci/builders/linux_test_config.json', + ), + }, + help: false, + ); + + final plan = BuildPlan.fromArgResults( + parser.parse(['--build-dart']), + testEnv.environment, + builds: builds, + ); + + expect(plan.buildDart, BuildDart.build); + expect( + plan.toGnArgs(), + contains('--no-prebuilt-dart-sdk'), + ); + expect( + plan.toGnArgs(), + isNot(contains('--full-dart-sdk')), + ); + }); + + test('dart build can be set to full', () { + final testEnv = TestEnvironment.withTestEngine( + withRbe: true, + ); + addTearDown(testEnv.cleanup); + + final testConfig = TestBuilderConfig(); + testConfig.addBuild( + name: 'linux/host_debug', + dimension: TestDroneDimension.linux, + ); + + final parser = ArgParser(); + final builds = BuildPlan.configureArgParser( + parser, + testEnv.environment, + configs: { + 'linux_test_config': testConfig.buildConfig( + path: 'ci/builders/linux_test_config.json', + ), + }, + help: false, + ); + + final plan = BuildPlan.fromArgResults( + parser.parse(['--build-dart-full']), + testEnv.environment, + builds: builds, + ); + + expect(plan.buildDart, BuildDart.buildFull); + expect( + plan.toGnArgs(), + contains('--no-prebuilt-dart-sdk'), + ); + expect( + plan.toGnArgs(), + contains('--full-dart-sdk'), + ); + }); + test('build defaults to host_debug', () { final testEnv = TestEnvironment.withTestEngine( withRbe: true,