Surface Windows build errors in non-verbose mode (#63707)
This commit is contained in:
parent
89f004e0d3
commit
6f0cfc9524
@ -257,6 +257,9 @@ abstract class ProcessUtils {
|
|||||||
/// If [filter] is non-null, all lines that do not match it are removed. If
|
/// If [filter] is non-null, all lines that do not match it are removed. If
|
||||||
/// [mapFunction] is present, all lines that match [filter] are also forwarded
|
/// [mapFunction] is present, all lines that match [filter] are also forwarded
|
||||||
/// to [mapFunction] for further processing.
|
/// to [mapFunction] for further processing.
|
||||||
|
///
|
||||||
|
/// If [stdoutErrorMatcher] is non-null, matching lines from stdout will be
|
||||||
|
/// treated as errors, just as if they had been logged to stderr instead.
|
||||||
Future<int> stream(
|
Future<int> stream(
|
||||||
List<String> cmd, {
|
List<String> cmd, {
|
||||||
String workingDirectory,
|
String workingDirectory,
|
||||||
@ -264,6 +267,7 @@ abstract class ProcessUtils {
|
|||||||
String prefix = '',
|
String prefix = '',
|
||||||
bool trace = false,
|
bool trace = false,
|
||||||
RegExp filter,
|
RegExp filter,
|
||||||
|
RegExp stdoutErrorMatcher,
|
||||||
StringConverter mapFunction,
|
StringConverter mapFunction,
|
||||||
Map<String, String> environment,
|
Map<String, String> environment,
|
||||||
});
|
});
|
||||||
@ -485,6 +489,7 @@ class _DefaultProcessUtils implements ProcessUtils {
|
|||||||
String prefix = '',
|
String prefix = '',
|
||||||
bool trace = false,
|
bool trace = false,
|
||||||
RegExp filter,
|
RegExp filter,
|
||||||
|
RegExp stdoutErrorMatcher,
|
||||||
StringConverter mapFunction,
|
StringConverter mapFunction,
|
||||||
Map<String, String> environment,
|
Map<String, String> environment,
|
||||||
}) async {
|
}) async {
|
||||||
@ -504,7 +509,9 @@ class _DefaultProcessUtils implements ProcessUtils {
|
|||||||
}
|
}
|
||||||
if (line != null) {
|
if (line != null) {
|
||||||
final String message = '$prefix$line';
|
final String message = '$prefix$line';
|
||||||
if (trace) {
|
if (stdoutErrorMatcher?.hasMatch(line) == true) {
|
||||||
|
_logger.printError(message, wrap: false);
|
||||||
|
} else if (trace) {
|
||||||
_logger.printTrace(message);
|
_logger.printTrace(message);
|
||||||
} else {
|
} else {
|
||||||
_logger.printStatus(message, wrap: false);
|
_logger.printStatus(message, wrap: false);
|
||||||
|
@ -107,6 +107,10 @@ Future<void> _runCmakeGeneration(String cmakePath, Directory buildDir, Directory
|
|||||||
Future<void> _runBuild(String cmakePath, Directory buildDir, String buildModeName) async {
|
Future<void> _runBuild(String cmakePath, Directory buildDir, String buildModeName) async {
|
||||||
final Stopwatch sw = Stopwatch()..start();
|
final Stopwatch sw = Stopwatch()..start();
|
||||||
|
|
||||||
|
// MSBuild sends all output to stdout, including build errors. This surfaces
|
||||||
|
// known error patterns.
|
||||||
|
final RegExp errorMatcher = RegExp(r':\s*(?:warning|(?:fatal )?error).*?:');
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
try {
|
try {
|
||||||
result = await processUtils.stream(
|
result = await processUtils.stream(
|
||||||
@ -126,13 +130,13 @@ Future<void> _runBuild(String cmakePath, Directory buildDir, String buildModeNam
|
|||||||
'VERBOSE_SCRIPT_LOGGING': 'true'
|
'VERBOSE_SCRIPT_LOGGING': 'true'
|
||||||
},
|
},
|
||||||
trace: true,
|
trace: true,
|
||||||
|
stdoutErrorMatcher: errorMatcher,
|
||||||
);
|
);
|
||||||
} on ArgumentError {
|
} on ArgumentError {
|
||||||
throwToolExit("cmake not found. Run 'flutter doctor' for more information.");
|
throwToolExit("cmake not found. Run 'flutter doctor' for more information.");
|
||||||
}
|
}
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
final String verboseInstructions = globals.logger.isVerbose ? '' : ' To view the stack trace, please run `flutter run -d windows -v`.';
|
throwToolExit('Build process failed.');
|
||||||
throwToolExit('Build process failed.$verboseInstructions');
|
|
||||||
}
|
}
|
||||||
globals.flutterUsage.sendTiming('build', 'windows-cmake-build', Duration(milliseconds: sw.elapsedMilliseconds));
|
globals.flutterUsage.sendTiming('build', 'windows-cmake-build', Duration(milliseconds: sw.elapsedMilliseconds));
|
||||||
}
|
}
|
||||||
|
@ -80,11 +80,13 @@ add_dependencies(flutter_wrapper_app flutter_assemble)
|
|||||||
# _phony_ is a non-existent file to force this command to run every time,
|
# _phony_ is a non-existent file to force this command to run every time,
|
||||||
# since currently there's no way to get a full input/output list from the
|
# since currently there's no way to get a full input/output list from the
|
||||||
# flutter tool.
|
# flutter tool.
|
||||||
|
set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
|
||||||
|
set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
||||||
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
|
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
${CPP_WRAPPER_SOURCES_APP}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/_phony_
|
${PHONY_OUTPUT}
|
||||||
COMMAND ${CMAKE_COMMAND} -E env
|
COMMAND ${CMAKE_COMMAND} -E env
|
||||||
${FLUTTER_TOOL_ENVIRONMENT}
|
${FLUTTER_TOOL_ENVIRONMENT}
|
||||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
||||||
|
@ -239,6 +239,63 @@ void main() {
|
|||||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('Windows build extracts errors from stdout', () async {
|
||||||
|
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||||
|
..visualStudioOverride = mockVisualStudio;
|
||||||
|
applyMocksToCommand(command);
|
||||||
|
setUpMockProjectFilesForBuild();
|
||||||
|
when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
|
||||||
|
|
||||||
|
// This contains a mix of routine build output and various types of errors
|
||||||
|
// (compile error, link error, warning treated as an error) from MSBuild,
|
||||||
|
// edited down for compactness. For instance, where similar lines are
|
||||||
|
// repeated in actual output, one or two representative lines are chosen
|
||||||
|
// to be included here.
|
||||||
|
const String stdout = r'''Microsoft (R) Build Engine version 16.6.0+5ff7b0c9e for .NET Framework
|
||||||
|
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||||
|
|
||||||
|
Checking Build System
|
||||||
|
Generating C:/foo/windows/flutter/ephemeral/flutter_windows.dll, [etc], _phony_
|
||||||
|
Building Custom Rule C:/foo/windows/flutter/CMakeLists.txt
|
||||||
|
standard_codec.cc
|
||||||
|
Generating Code...
|
||||||
|
flutter_wrapper_plugin.vcxproj -> C:\foo\build\windows\flutter\Debug\flutter_wrapper_plugin.lib
|
||||||
|
C:\foo\windows\runner\main.cpp(18): error C2220: the following warning is treated as an error [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
C:\foo\windows\runner\main.cpp(18): warning C4706: assignment within conditional expression [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
main.obj : error LNK2019: unresolved external symbol "void __cdecl Bar(void)" (?Bar@@YAXXZ) referenced in function wWinMain [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
C:\foo\build\windows\runner\Debug\test.exe : fatal error LNK1120: 1 unresolved externals [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
Building Custom Rule C:/foo/windows/runner/CMakeLists.txt
|
||||||
|
flutter_window.cpp
|
||||||
|
main.cpp
|
||||||
|
C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
-- Install configuration: "Debug"
|
||||||
|
-- Installing: C:/foo/build/windows/runner/Debug/data/icudtl.dat
|
||||||
|
''';
|
||||||
|
|
||||||
|
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||||
|
cmakeGenerationCommand(),
|
||||||
|
buildCommand('Release',
|
||||||
|
stdout: stdout,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await createTestCommandRunner(command).run(
|
||||||
|
const <String>['windows', '--no-pub']
|
||||||
|
);
|
||||||
|
// Just the warnings and errors should be surfaced.
|
||||||
|
expect(testLogger.errorText, r'''C:\foo\windows\runner\main.cpp(18): error C2220: the following warning is treated as an error [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
C:\foo\windows\runner\main.cpp(18): warning C4706: assignment within conditional expression [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
main.obj : error LNK2019: unresolved external symbol "void __cdecl Bar(void)" (?Bar@@YAXXZ) referenced in function wWinMain [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
C:\foo\build\windows\runner\Debug\test.exe : fatal error LNK1120: 1 unresolved externals [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier [C:\foo\build\windows\runner\test.vcxproj]
|
||||||
|
''');
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
|
ProcessManager: () => processManager,
|
||||||
|
Platform: () => windowsPlatform,
|
||||||
|
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('Windows verbose build sets VERBOSE_SCRIPT_LOGGING', () async {
|
testUsingContext('Windows verbose build sets VERBOSE_SCRIPT_LOGGING', () async {
|
||||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||||
..visualStudioOverride = mockVisualStudio;
|
..visualStudioOverride = mockVisualStudio;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user