Skip to content

Commit

Permalink
[et] Lookup output filesystem path, not label
Browse files Browse the repository at this point in the history
Sets BuildTarget.executable to the `root_out_dir`-relative path of the
executable (e.g. `displaylist_unittests`) instead of its label (e.g.
`//out/host_debug/displaylist_unittests`). This is required since, in
the lines following the output lookup, we assume it to be a path
relative to the build output directory.

Also breaks out functions for:
* `_gnDesc`: returns the JSON output of `gn desc buildDir target`
* `_gnOutputs`:  returns the output files listed by `gn outputs buildDir target`

Noticed while working on: flutter/flutter#147071
  • Loading branch information
cbracken committed Apr 20, 2024
1 parent 40110ec commit f5fde03
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 33 deletions.
76 changes: 52 additions & 24 deletions tools/engine_tool/lib/src/gn_utils.dart
Expand Up @@ -77,30 +77,9 @@ final class BuildTarget {
Future<Map<String, BuildTarget>> findTargets(
Environment environment, Directory buildDir) async {
final Map<String, BuildTarget> r = <String, BuildTarget>{};
final List<String> getBuildInfoCommandLine = <String>[
gnBinPath(environment),
'desc',
buildDir.path,
'*',
'--format=json',
];

final ProcessRunnerResult result = await environment.processRunner.runProcess(
getBuildInfoCommandLine,
workingDirectory: environment.engine.srcDir,
failOk: true);

// Handle any process failures.
fatalIfFailed(environment, getBuildInfoCommandLine, result);

late final Map<String, Object?> jsonResult;
try {
jsonResult = jsonDecode(result.stdout) as Map<String, Object?>;
} catch (e) {
environment.logger.fatal(
'gn desc output could not be parsed:\nE=$e\nIN=${result.stdout}\n');
}

final Map<String, Object?> jsonResult =
await _runGnDesc(buildDir.path, '*', environment);
for (final MapEntry<String, Object?> targetEntry in jsonResult.entries) {
final String label = targetEntry.key;
if (targetEntry.value == null) {
Expand All @@ -120,7 +99,7 @@ Future<Map<String, BuildTarget>> findTargets(
}
final bool testOnly = getBool(properties, 'testonly');
final List<String> outputs =
getListOfString(properties, 'outputs') ?? <String>[];
await _runGnOutputs(buildDir.path, label, environment);
File? executable;
if (type == BuildTargetType.executable) {
if (outputs.isEmpty) {
Expand All @@ -135,6 +114,55 @@ Future<Map<String, BuildTarget>> findTargets(
return r;
}

/// Returns the JSON output of running `gn desc buildDir label`.
Future<Map<String, Object?>> _runGnDesc(
String buildDir, String label, Environment environment) async {
final List<String> commandline = <String>[
gnBinPath(environment),
'desc',
buildDir,
label,
'--format=json',
];

final ProcessRunnerResult result = await environment.processRunner.runProcess(
commandline,
workingDirectory: environment.engine.srcDir,
failOk: true);

// Handle any process failures.
fatalIfFailed(environment, commandline, result);

late final Map<String, Object?> jsonResult;
try {
jsonResult = jsonDecode(result.stdout) as Map<String, Object?>;
} catch (e) {
environment.logger.fatal(
'gn desc output could not be parsed:\nE=$e\nIN=${result.stdout}\n');
}
return jsonResult;
}

/// Returns the output paths returned by `gn outputs buildDir label`.
Future<List<String>> _runGnOutputs(
String buildDir, String label, Environment environment) async {
final List<String> commandline = <String>[
gnBinPath(environment),
'outputs',
buildDir,
label,
];
final ProcessRunnerResult result = await environment.processRunner.runProcess(
commandline,
workingDirectory: environment.engine.srcDir,
failOk: true);

// Handle any process failures.
fatalIfFailed(environment, commandline, result);

return result.stdout.split('\n');
}

/// Process selectors and filter allTargets for matches.
///
/// We support:
Expand Down
16 changes: 8 additions & 8 deletions tools/engine_tool/test/build_command_test.dart
Expand Up @@ -361,10 +361,10 @@ void main() {
]);
expect(result, equals(0));
expect(testEnv.processHistory.length, greaterThanOrEqualTo(2));
expect(testEnv.processHistory[3].command[0], contains('ninja'));
expect(testEnv.processHistory[3].command[2], endsWith('/host_debug'));
expect(testEnv.processHistory[6].command[0], contains('ninja'));
expect(testEnv.processHistory[6].command[2], endsWith('/host_debug'));
expect(
testEnv.processHistory[3].command[5],
testEnv.processHistory[6].command[5],
equals('flutter/fml:fml_arc_unittests'),
);
} finally {
Expand All @@ -390,18 +390,18 @@ void main() {
]);
expect(result, equals(0));
expect(testEnv.processHistory.length, greaterThanOrEqualTo(2));
expect(testEnv.processHistory[3].command[0], contains('ninja'));
expect(testEnv.processHistory[3].command[2], endsWith('/host_debug'));
expect(testEnv.processHistory[6].command[0], contains('ninja'));
expect(testEnv.processHistory[6].command[2], endsWith('/host_debug'));
expect(
testEnv.processHistory[3].command[5],
testEnv.processHistory[6].command[5],
equals('flutter/display_list:display_list_unittests'),
);
expect(
testEnv.processHistory[3].command[6],
testEnv.processHistory[6].command[6],
equals('flutter/flow:flow_unittests'),
);
expect(
testEnv.processHistory[3].command[7],
testEnv.processHistory[6].command[7],
equals('flutter/fml:fml_arc_unittests'),
);
} finally {
Expand Down
2 changes: 2 additions & 0 deletions tools/engine_tool/test/gn_utils_test.dart
Expand Up @@ -39,6 +39,8 @@ void main() {
final List<CannedProcess> cannedProcesses = <CannedProcess>[
CannedProcess((List<String> command) => command.contains('desc'),
stdout: fixtures.gnDescOutput()),
CannedProcess((List<String> command) => command.contains('outputs'),
stdout: 'display_list_unittests'),
];

test('find test targets', () async {
Expand Down
4 changes: 3 additions & 1 deletion tools/engine_tool/test/test_command_test.dart
Expand Up @@ -42,6 +42,8 @@ void main() {
final List<CannedProcess> cannedProcesses = <CannedProcess>[
CannedProcess((List<String> command) => command.contains('desc'),
stdout: fixtures.gnDescOutput()),
CannedProcess((List<String> command) => command.contains('outputs'),
stdout: 'display_list_unittests'),
];

test('test command executes test', () async {
Expand Down Expand Up @@ -83,7 +85,7 @@ void main() {
'//third_party/protobuf:protoc',
]);
expect(result, equals(1));
expect(testEnvironment.processHistory.length, lessThan(3));
expect(testEnvironment.processHistory.length, lessThan(6));
expect(testEnvironment.processHistory.where((ExecutedProcess process) {
return process.command[0].contains('protoc');
}), isEmpty);
Expand Down

0 comments on commit f5fde03

Please sign in to comment.