44
55import 'dart:async' ;
66import 'dart:convert' ;
7- import 'dart:io' as io show Directory, Process;
7+ import 'dart:io' as io show Directory, Process, ProcessResult ;
88
99import 'package:path/path.dart' as p;
1010import 'package:platform/platform.dart' ;
@@ -41,7 +41,7 @@ final class RunnerProgress extends RunnerEvent {
4141 RunnerProgress (
4242 super .name, super .command, super .timestamp,
4343 this .what, this .completed, this .total, this .done,
44- ) : percent = (completed * 1000 ) / total;
44+ ) : percent = (completed * 100 ) / total;
4545
4646 /// What a command is currently working on, for example a build target or
4747 /// the name of a test.
@@ -263,7 +263,6 @@ final class GlobalBuildRunner extends Runner {
263263 gnArgs.remove (arg.$1);
264264 }
265265 }
266-
267266 return gnArgs;
268267 }();
269268
@@ -289,67 +288,157 @@ final class GlobalBuildRunner extends Runner {
289288 return result.ok;
290289 }
291290
292- // TODO(zanderso): This should start and stop RBE when it is an --rbe build.
293- Future <bool > _runNinja (RunnerEventHandler eventHandler) async {
294- final String ninjaPath = p.join (
295- engineSrcDir.path, 'flutter' , 'third_party' , 'ninja' , 'ninja' ,
291+ late final String _hostCpu = (){
292+ if (platform.isWindows) {
293+ return platform.environment['PROCESSOR_ARCHITECTURE' ] ?? 'x64' ;
294+ }
295+ final List <String > unameCommand = < String > ['uname' , '-m' ];
296+ final io.ProcessResult unameResult = processRunner.processManager.runSync (
297+ unameCommand,
296298 );
297- final String outDir = p.join (engineSrcDir.path, 'out' , build.ninja.config);
298- final List <String > command = < String > [
299- ninjaPath,
300- '-C' , outDir,
301- if (_isGomaOrRbe) ...< String > ['-j' , '200' ],
302- ...extraNinjaArgs,
303- ...build.ninja.targets,
304- ];
305- eventHandler (RunnerStart ('${build .name }: ninja' , command, DateTime .now ()));
299+ return unameResult.exitCode == 0 ? (unameResult.stdout as String ).trim () : 'x64' ;
300+ }();
306301
307- final ProcessRunnerResult processResult;
302+ late final String _buildtoolsPath = (){
303+ final String platformDir = switch (platform.operatingSystem) {
304+ Platform .linux => 'linux-$_hostCpu ' ,
305+ Platform .macOS => 'mac-$_hostCpu ' ,
306+ Platform .windows => 'windows-$_hostCpu ' ,
307+ _ => '<unknown>' ,
308+ };
309+ return p.join (engineSrcDir.path, 'buildtools' , platformDir);
310+ }();
311+
312+ Future <bool > _bootstrapRbe (
313+ RunnerEventHandler eventHandler, {
314+ bool shutdown = false ,
315+ }) async {
316+ final String reclientPath = p.join (_buildtoolsPath, 'reclient' );
317+ final String exe = platform.isWindows ? '.exe' : '' ;
318+ final String bootstrapPath = p.join (reclientPath, 'bootstrap$exe ' );
319+ final String reproxyPath = p.join (reclientPath, 'reproxy$exe ' );
320+ final String reclientConfigFile = switch (platform.operatingSystem) {
321+ Platform .linux => 'reclient-linux.cfg' ,
322+ Platform .macOS => 'reclient-mac.cfg' ,
323+ Platform .windows => 'reclient-win.cfg' ,
324+ _ => '<unknown>' ,
325+ };
326+ final String reclientConfigPath = p.join (
327+ engineSrcDir.path, 'flutter' , 'build' , 'rbe' , reclientConfigFile,
328+ );
329+ final List <String > bootstrapCommand = < String > [
330+ bootstrapPath,
331+ '--re_proxy=$reproxyPath ' ,
332+ '--automatic_auth=true' ,
333+ if (shutdown)
334+ '--shutdown'
335+ else ...< String > [
336+ '--cfg=$reclientConfigPath '
337+ ],
338+ ];
339+ if (! processRunner.processManager.canRun (bootstrapPath)) {
340+ eventHandler (RunnerError (
341+ build.name, < String > [], DateTime .now (), '"$bootstrapPath " not found.' ,
342+ ));
343+ return false ;
344+ }
345+ eventHandler (RunnerStart (
346+ '${build .name }: RBE ${shutdown ? 'shutdown' : 'startup' }' ,
347+ bootstrapCommand,
348+ DateTime .now (),
349+ ));
350+ final ProcessRunnerResult bootstrapResult;
308351 if (dryRun) {
309- processResult = _dryRunResult;
352+ bootstrapResult = _dryRunResult;
310353 } else {
311- final io.Process process = await processRunner.processManager.start (
312- command,
313- workingDirectory: engineSrcDir.path,
354+ bootstrapResult = await processRunner.runProcess (
355+ bootstrapCommand, failOk: true ,
314356 );
315- final List <int > stderrOutput = < int > [];
316- final Completer <void > stdoutComplete = Completer <void >();
317- final Completer <void > stderrComplete = Completer <void >();
318-
319- process.stdout
320- .transform <String >(const Utf8Decoder ())
321- .transform (const LineSplitter ())
322- .listen (
323- (String line) {
324- _ninjaProgress (eventHandler, command, line);
325- },
326- onDone: () async => stdoutComplete.complete (),
327- );
357+ }
358+ eventHandler (RunnerResult (
359+ '${build .name }: RBE ${shutdown ? 'shutdown' : 'startup' }' ,
360+ bootstrapCommand,
361+ DateTime .now (),
362+ bootstrapResult,
363+ ));
364+ return bootstrapResult.exitCode == 0 ;
365+ }
328366
329- process.stderr.listen (
330- stderrOutput.addAll,
331- onDone: () async => stderrComplete.complete (),
367+ Future <bool > _runNinja (RunnerEventHandler eventHandler) async {
368+ if (_isRbe) {
369+ if (! await _bootstrapRbe (eventHandler)) {
370+ return false ;
371+ }
372+ }
373+ bool success = false ;
374+ try {
375+ final String ninjaPath = p.join (
376+ engineSrcDir.path, 'flutter' , 'third_party' , 'ninja' , 'ninja' ,
332377 );
333-
334- await Future .wait <void >(< Future <void >> [
335- stdoutComplete.future, stderrComplete.future,
336- ]);
337- final int exitCode = await process.exitCode;
338-
339- processResult = ProcessRunnerResult (
340- exitCode,
341- < int > [], // stdout.
342- stderrOutput, // stderr.
343- stderrOutput, // combined,
344- pid: process.pid, // pid,
378+ final String outDir = p.join (
379+ engineSrcDir.path, 'out' , build.ninja.config,
345380 );
346- }
381+ final List <String > command = < String > [
382+ ninjaPath,
383+ '-C' , outDir,
384+ if (_isGomaOrRbe) ...< String > ['-j' , '200' ],
385+ ...extraNinjaArgs,
386+ ...build.ninja.targets,
387+ ];
388+ eventHandler (RunnerStart (
389+ '${build .name }: ninja' , command, DateTime .now ()),
390+ );
391+ final ProcessRunnerResult processResult;
392+ if (dryRun) {
393+ processResult = _dryRunResult;
394+ } else {
395+ final io.Process process = await processRunner.processManager.start (
396+ command,
397+ workingDirectory: engineSrcDir.path,
398+ );
399+ final List <int > stderrOutput = < int > [];
400+ final Completer <void > stdoutComplete = Completer <void >();
401+ final Completer <void > stderrComplete = Completer <void >();
402+
403+ process.stdout
404+ .transform <String >(const Utf8Decoder ())
405+ .transform (const LineSplitter ())
406+ .listen (
407+ (String line) {
408+ _ninjaProgress (eventHandler, command, line);
409+ },
410+ onDone: () async => stdoutComplete.complete (),
411+ );
412+
413+ process.stderr.listen (
414+ stderrOutput.addAll,
415+ onDone: () async => stderrComplete.complete (),
416+ );
347417
348- final RunnerResult result = RunnerResult (
349- '${build .name }: ninja' , command, DateTime .now (), processResult,
350- );
351- eventHandler (result);
352- return result.ok;
418+ await Future .wait <void >(< Future <void >> [
419+ stdoutComplete.future, stderrComplete.future,
420+ ]);
421+ final int exitCode = await process.exitCode;
422+
423+ processResult = ProcessRunnerResult (
424+ exitCode,
425+ < int > [], // stdout.
426+ stderrOutput, // stderr.
427+ stderrOutput, // combined,
428+ pid: process.pid, // pid,
429+ );
430+ }
431+ eventHandler (RunnerResult (
432+ '${build .name }: ninja' , command, DateTime .now (), processResult,
433+ ));
434+ success = processResult.exitCode == 0 ;
435+ } finally {
436+ if (_isRbe) {
437+ // Ignore failures to shutdown.
438+ await _bootstrapRbe (eventHandler, shutdown: true );
439+ }
440+ }
441+ return success;
353442 }
354443
355444 // Parse lines of the form '[6232/6269] LINK ./accessibility_unittests'.
@@ -389,10 +478,8 @@ final class GlobalBuildRunner extends Runner {
389478 ));
390479 }
391480
392- late final bool _isGoma = build.gn.contains ('--goma' ) ||
393- extraGnArgs.contains ('--goma' );
394- late final bool _isRbe = build.gn.contains ('--rbe' ) ||
395- extraGnArgs.contains ('--rbe' );
481+ late final bool _isGoma = _mergedGnArgs.contains ('--goma' );
482+ late final bool _isRbe = _mergedGnArgs.contains ('--rbe' );
396483 late final bool _isGomaOrRbe = _isGoma || _isRbe;
397484
398485 Future <bool > _runGenerators (RunnerEventHandler eventHandler) async {
0 commit comments