-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an initial 'build' command to engine_tool #50681
Conversation
Thanks for starting on this =) I hadn't thought this command all the way through, but my vague thought was that it would leverage the library here as much as makes sense, similar to the example code here. There are kind of two paths for the build command. Down one path it uses the pre-canned builds from the json files, possibly with some options/targets overridden/added. Down the second path, it ignores the pre-canned builds, and you specify everything, falling back on defaults. The second path can still use the |
// Some wrinkles I'd like to iron out: | ||
// - There can be multiple GlobalBuild objects with the same name. How | ||
// should we deal with these conflicts? "mac_clang_tidy" and | ||
// "mac_host_engine" both define "host_debug". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as the CI recipes are concerned, the names don't matter. We can go through the json files and make them unique, and then enforce it in the script here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
// - There can be multiple GlobalBuild objects with the same name. How | ||
// should we deal with these conflicts? "mac_clang_tidy" and | ||
// "mac_host_engine" both define "host_debug". | ||
// - Naming: Should BuildConfig be BuilderConfig and GlobalBuild be BuildConfig? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense to me. I'm not married to any of the names, and happy if we can find better ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 names
// "mac_host_engine" both define "host_debug". | ||
// - Naming: Should BuildConfig be BuilderConfig and GlobalBuild be BuildConfig? | ||
// - The BuildConfig database seems to be lacking things I expected: | ||
// - There is no "android_debug_*" GlobalBuild in any of the builders that run on mac? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the configurations built on CI are a subset of what's useful to build locally. I have some thoughts about that. One is to provide an option to ignore the platform that the build config is asking for. Another is to create some new json files that we only run locally and not on CI. Open to suggestions about what to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could also be a sign that we have too many configurations (or too few on CI)
That being said, the easiest suggestion I think is to have local JSON files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another is to create some new json files that we only run locally and not on CI. Open to suggestions about what to do.
I lean strongly towards introducing new builders for local development. The CI builders run targets/tests that aren't necessary for local development, resulting in a slower inner loop. For example: producing engine .zip archives is rarely necessary when developing.
Crank's builders are a fork of the CI builders targeted for local development scenarios: https://github.com/loic-sharma/crank/blob/4b114fed1668a383e1540b2bf4d29dc0b1dc1148/lib/builders.dart#L5-L359
// - Naming: Should BuildConfig be BuilderConfig and GlobalBuild be BuildConfig? | ||
// - The BuildConfig database seems to be lacking things I expected: | ||
// - There is no "android_debug_*" GlobalBuild in any of the builders that run on mac? | ||
// - The gn flags specified in the GlobalBuilds don't reference rbe or goma? Should this be a local configuration that the user selects? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gn
script and CI try to enable Goma implicitly, so the flag doesn't show up too much in the CI configs.
The migration to RBE is in-progress, but there are a few builds that have it. It has to be requested explicitly both locally and in CI.
// TODO(johnmccutchan): List all available build targets and allow the user | ||
// to specify which one(s) we should build on the cli. | ||
|
||
// TODO(johnmccutchan): Can we show a progress indicator like 'running gn...'? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think we can copy some code from flutter_tool for this.
/// returns false. | ||
Map<String, BuildConfig> filterBuildConfigs( | ||
Map<String, BuildConfig> input, ConfigFilter test) { | ||
final Map<String, BuildConfig> r = <String, BuildConfig>{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great place for the inline-for, imo:
return {
for (final entry in input.entries)
if (test(entry.name, entry.value))
entry.name: entry.value
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
List<GlobalBuild> filterBuilds( | ||
Map<String, BuildConfig> input, BuildFilter test) { | ||
final List<GlobalBuild> r = <GlobalBuild>[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here, I'd just use the inline-for:
https://dart.dev/language/collections#control-flow-operators
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
/// A function that returns true or false when given a [BuildConfig] and its | ||
/// name. | ||
typedef ConfigFilter = bool Function(String name, BuildConfig config); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally (here and below) I'd just inline the function definition.
That avoids having to explain these generically "returns true or false" and you can just document how it's used in the (single?) function below.
// Some wrinkles I'd like to iron out: | ||
// - There can be multiple GlobalBuild objects with the same name. How | ||
// should we deal with these conflicts? "mac_clang_tidy" and | ||
// "mac_host_engine" both define "host_debug". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
// - There can be multiple GlobalBuild objects with the same name. How | ||
// should we deal with these conflicts? "mac_clang_tidy" and | ||
// "mac_host_engine" both define "host_debug". | ||
// - Naming: Should BuildConfig be BuilderConfig and GlobalBuild be BuildConfig? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 names
// "mac_host_engine" both define "host_debug". | ||
// - Naming: Should BuildConfig be BuilderConfig and GlobalBuild be BuildConfig? | ||
// - The BuildConfig database seems to be lacking things I expected: | ||
// - There is no "android_debug_*" GlobalBuild in any of the builders that run on mac? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could also be a sign that we have too many configurations (or too few on CI)
That being said, the easiest suggestion I think is to have local JSON files.
argParser.addOption( | ||
_configFlag, | ||
abbr: 'c', | ||
defaultsTo: 'host_debug', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely a TODO (unless you feel inspired) but I have the perfect default for you here:
https://github.com/flutter/engine/tree/main/tools/pkg/engine_repo_tools
Specifically:
engine/tools/pkg/engine_repo_tools/lib/engine_repo_tools.dart
Lines 156 to 169 in df0dc1f
/// Returns the most recently modified output target in [outDir]. | |
/// | |
/// If there are no output targets, returns `null`. | |
Output? latestOutput() { | |
final List<Output> outputs = this.outputs(); | |
if (outputs.isEmpty) { | |
return null; | |
} | |
outputs.sort((Output a, Output b) { | |
return b.path.statSync().modified.compareTo(a.path.statSync().modified); | |
}); | |
return outputs.first; | |
} | |
} |
You can see a recent example of this being used here (not exactly the same, but close):
engine/testing/scenario_app/bin/android_integration_tests.dart
Lines 44 to 49 in df0dc1f
defaultsTo: | |
engine?. | |
outputs(). | |
where((Output o) => basename(o.path.path).startsWith('android_')). | |
firstOrNull?. | |
path.path, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I'd rather have a deterministic default.
For Crank, you can set your default builder in a ~/.config/crank/config.json
config file.
This config file also lets you add your own custom builders, which is useful if the CI builders don't support your desired scenario like Android from a macOS host. See: https://github.com/loic-sharma/crank#custom-builders
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoding a default for now sgtm. I suspect we'll want a config file with defaults at some point, but that's big enough for a separate PR.
.runProcess(commandLine, workingDirectory: environment.engine.outDir); | ||
if (r.exitCode != 0) { | ||
// TODO(johnmccutchan): We probably want to stream the ninja output | ||
// so we can see build progress and compilation failures immediately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also loses output colors, which are really helpful. You probably want something like:
Future<int> runProcess(String executable, List<String> arguments) async {
var process = await Process.start(
executable,
arguments,
runInShell: true,
mode: ProcessStartMode.inheritStdio,
);
return await process.exitCode;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code has been deleted.
@johnmccutchan If you haven't already, consider playing with Crank to see what its UX is like: https://github.com/loic-sharma/crank#crank- If you'd like, I'd be happy to do a quick call to demo it! |
fb87ec8
to
95630e9
Compare
I've updated the PR to use GlobalBuildRunner. |
argParser.addOption( | ||
_configFlag, | ||
abbr: 'c', | ||
defaultsTo: 'host_debug', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoding a default for now sgtm. I suspect we'll want a config file with defaults at some point, but that's big enough for a separate PR.
7bcee93
to
551edbd
Compare
551edbd
to
49caed0
Compare
@johnmccutchan Do you still need help with I admit that class sucks, I'd be willing to either (a) work with you to improve it or (b) help you with the specific test(s). Ping me tomorrow! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! I'll make some improvements to the logger after this lands that will help with clearing the progress log messages. (Even when disabling newlines and appending '\r', if a message goes over a single line, then the terminal scrolls...)
…144041) flutter/engine@b5bebfe...fbc9b88 2024-02-23 [email protected] Roll Skia from 037e08e92598 to 49dd7ed24bec (3 revisions) (flutter/engine#50916) 2024-02-23 [email protected] Add an initial 'build' command to engine_tool (flutter/engine#50681) 2024-02-23 [email protected] Roll Dart SDK from 7f6eccd65255 to 9849ca5fcaec (1 revision) (flutter/engine#50915) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
et
.query builds
toquery builders
because that seemed to be more precise(?)Some extra requests during review:
build_command.dart
I suspect @zanderso and @loic-sharma can give me (some?) answers.build_command_test.dart
. Pointers to good examples are appreciated.