Skip to content

Commit 73b32c4

Browse files
authored
[native_toolchain_c] Include missing errors output when running CL (#2811)
CL outputs error-related messages to the standard output. This patch allows outputting these errors to the user while preserving the current level of logging for other toolchains. Include `createCapturingRecordLogger` utility to check the level of a `LogRecord`, otherwise the test would always succeed. Closes #2809
1 parent 224d93e commit 73b32c4

File tree

8 files changed

+101
-11
lines changed

8 files changed

+101
-11
lines changed

pkgs/native_toolchain_c/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.17.4
2+
3+
- For Windows, include errors from the standard output of `cl` in the logger's
4+
output of CBuilder.
5+
([#2809](https://github.com/dart-lang/native/issues/2809))
6+
17
## 0.17.3
28

39
- Bump `package:hooks` and `package:code_assets`to 1.0.0.

pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ class RunCBuilder {
399399
environment: environment,
400400
logger: logger,
401401
captureOutput: false,
402+
stdoutLogLevel: Level.INFO,
402403
throwOnUnexpectedExitCode: true,
403404
);
404405

@@ -410,6 +411,7 @@ class RunCBuilder {
410411
environment: environment,
411412
logger: logger,
412413
captureOutput: false,
414+
stdoutLogLevel: Level.INFO,
413415
throwOnUnexpectedExitCode: true,
414416
);
415417
}

pkgs/native_toolchain_c/lib/src/utils/run_process.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Future<RunProcessResult> runProcess({
1919
Map<String, String>? environment,
2020
required Logger? logger,
2121
bool captureOutput = true,
22+
Level stdoutLogLevel = Level.FINE,
2223
int expectedExitCode = 0,
2324
bool throwOnUnexpectedExitCode = false,
2425
}) async {
@@ -46,7 +47,7 @@ Future<RunProcessResult> runProcess({
4647
final stdoutSub = process.stdout.listen((List<int> data) {
4748
try {
4849
final decoded = systemEncoding.decode(data);
49-
logger?.fine(decoded);
50+
logger?.log(stdoutLogLevel, decoded);
5051
if (captureOutput) {
5152
stdoutBuffer.write(decoded);
5253
}

pkgs/native_toolchain_c/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: native_toolchain_c
22
description: >-
33
A library to invoke the native C compiler installed on the host machine.
4-
version: 0.17.3
4+
version: 0.17.4
55
repository: https://github.com/dart-lang/native/tree/main/pkgs/native_toolchain_c
66

77
topics:

pkgs/native_toolchain_c/test/cbuilder/cbuilder_build_failure_test.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ library;
88
import 'dart:io';
99

1010
import 'package:code_assets/code_assets.dart';
11+
import 'package:collection/collection.dart';
1112
import 'package:hooks/hooks.dart';
13+
import 'package:logging/logging.dart';
1214
import 'package:native_toolchain_c/native_toolchain_c.dart';
1315
import 'package:test/test.dart';
1416

@@ -68,4 +70,60 @@ void main() {
6870
throwsException,
6971
);
7072
});
73+
74+
test('CL build failure include error output', () async {
75+
if (!Platform.isWindows) {
76+
// Avoid needing status files on Dart SDK CI.
77+
return;
78+
}
79+
80+
final tempUri = await tempDirForTest();
81+
final tempUri2 = await tempDirForTest();
82+
final source = packageUri.resolve(
83+
'test/cbuilder/testfiles/build_failure/cl.c',
84+
);
85+
const name = 'cl';
86+
87+
final buildInputBuilder = BuildInputBuilder()
88+
..setupShared(
89+
packageName: name,
90+
packageRoot: tempUri,
91+
outputFile: tempUri.resolve('output.json'),
92+
outputDirectoryShared: tempUri2,
93+
)
94+
..config.setupBuild(linkingEnabled: false)
95+
..addExtension(
96+
CodeAssetExtension(
97+
targetOS: OS.windows,
98+
targetArchitecture: Architecture.current,
99+
linkModePreference: LinkModePreference.dynamic,
100+
cCompiler: cCompiler,
101+
),
102+
);
103+
104+
final buildInput = buildInputBuilder.build();
105+
final buildOutput = BuildOutputBuilder();
106+
107+
final logs = <LogRecord>[];
108+
final logger = createCapturingRecordLogger(logs);
109+
final cbuilder = CBuilder.library(
110+
sources: [source.toFilePath()],
111+
name: name,
112+
assetName: name,
113+
includes: [],
114+
buildMode: BuildMode.release,
115+
);
116+
await expectLater(
117+
cbuilder.run(input: buildInput, output: buildOutput, logger: logger),
118+
throwsException,
119+
);
120+
121+
// Note: don't check the entire message as CL output is based on user
122+
// locale.
123+
final line = logs.firstWhereOrNull(
124+
(log) =>
125+
log.level == Level.INFO && log.message.contains('fatal error C1070'),
126+
);
127+
expect(line != null, true);
128+
});
71129
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#include "cl.h"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#ifndef BUILD_FAILURE_CL_H
6+
#define BUILD_FAILURE_CL_H
7+
8+
#ifdef _WIN32
9+
#define INCLUDE_EXPORT __declspec(dllexport)
10+
#else
11+
#define INCLUDE_EXPORT
12+
//#endif
13+
14+
#endif

pkgs/native_toolchain_c/test/helpers.dart

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,19 @@ Logger? _logger;
7171
Logger createCapturingLogger(List<String> capturedMessages) =>
7272
_createTestLogger(capturedMessages: capturedMessages);
7373

74-
Logger _createTestLogger({List<String>? capturedMessages}) =>
75-
Logger.detached('')
76-
..level = Level.ALL
77-
..onRecord.listen((record) {
78-
printOnFailure(
79-
'${record.level.name}: ${record.time}: ${record.message}',
80-
);
81-
capturedMessages?.add(record.message);
82-
});
74+
Logger createCapturingRecordLogger(List<LogRecord> capturedLogs) =>
75+
_createTestLogger(capturedLogs: capturedLogs);
76+
77+
Logger _createTestLogger({
78+
List<String>? capturedMessages,
79+
List<LogRecord>? capturedLogs,
80+
}) => Logger.detached('')
81+
..level = Level.ALL
82+
..onRecord.listen((record) {
83+
printOnFailure('${record.level.name}: ${record.time}: ${record.message}');
84+
capturedMessages?.add(record.message);
85+
capturedLogs?.add(record);
86+
});
8387

8488
Uri packageUri = findPackageRoot('native_toolchain_c');
8589

0 commit comments

Comments
 (0)