Repository navigation
feat: add Build::message_logger for structured access to cc's messages - #1967
Merged
Merged
Conversation
…iter The writer gets the lines cc prints as `cargo:warning=`: the compiler's stderr and cc's own warnings. They are still printed as warnings unless `cargo_warnings(false)` is set; other `cargo:` lines always go to stdout. Clones and the flag check's inner `Build` share the writer, and a failed write is reported once as a warning instead of failing the build.
NobodyXu
requested changes
Sep 30, 2026
NobodyXu
left a comment
Contributor
There was a problem hiding this comment.
Thank you!
How about we make the capture more structured?
Build::message_output to also write cc's messages to a writerBuild::message_logger for structured access to cc's messages
NobodyXu
requested changes
Sep 30, 2026
NobodyXu
left a comment
Contributor
There was a problem hiding this comment.
Thank you!
I think we can elaborate the doc here by copying the related PR
…er docs `CommandFailed` is now a struct variant with `is_detection_cmd` and `exit_status`. `is_detection_cmd` is true for commands whose failure cc recovers from: `--print-search-dirs`, `xcrun --show-sdk-version` and compiler family detection. Family detection's `-E` failure now goes through the shared helper too, so it reaches the logger with `cargo_debug`, like its other commands.
Contributor
Author
|
The |
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1769.
Adds
Build::message_logger, following the structure suggested in review. A logger implementsBuildMessageLoggerand gets each message with aBuildMessageKind, the text as aBuildMessage, and extra data as&dyn Any:GeneralWarning: every warning cc prints itself.extrais().StderrForwarding: each line a command cc runs writes to stderr, such as the compiler or the archiver.extrais theCommand.CommandFailed { is_detection_cmd, exit_status }: a command cc runs exits unsuccessfully. The text is the error cc returns, andextrais theCommand. cc recovers from some of these, such as a failed--print-search-dirsquery, so the build can still succeed.is_detection_cmdis true for those:--print-search-dirs,xcrun --show-sdk-versionand compiler family detection. Checks whose failure cc expects, such as flag support probes and thearcall withDthat cc retries without it, are not reported.Following the discussion in the issue:
cargo_warnings(false)they only go to the logger.cargo:lines (rustc-link-lib,rustc-link-search,rerun-if-env-changed) stay on stdout.logreturns nothing, so the logger can't fail the build unless it panics. It gets&self, and synchronisation is up to it.Details:
CargoOutput, as HuzaifaAbdulRehman suggested in the issue, so it reaches every command cc runs. Clones of aBuildshare it.BuildMessageKind, itsCommandFailedvariant andBuildMessageare#[non_exhaustive].BuildMessageonly hasStrfor now and implementsDisplay.BuildstaysClone,Send,Sync,Unpin,UnwindSafeandRefUnwindSafe. A private wrapper keeps the last two, sincedyn BuildMessageLoggerhas neither.cargo_warnings(false)with a logger still captures it.StderrForwardergets theCargoOutputand theCommand, so the serial path, theparallelpath and therun_outputhelpers all forward through one function.wait_on_child,run_output, theparallelrunner and family detection's-Echeck now build the "command did not execute successfully" error with one helper, which also passes it to the logger. The detection commands get a copy ofCargoOutputthat setsis_detection_cmd.run_silent_on_errorkeeps its own error, so the failures it expects stay silent.parallel, a failed compile's error is still printed as a warning, but the logger gets it once, asCommandFailed.cargo_debugis on stays hidden from the logger too, and so do its failures, apart from the zig--versioncheck.Buildthat the flag support probe creates now shares the logger and thecargo_warningssetting. So withcargo_warnings(false), the probe's own warnings no longer reach stdout, like the main build's. Before, they were printed even with warnings off. This probe also runs for cc's own checks, such as inherited rustflags.\rfrom Windows compilers, and are converted to UTF-8 lossily.cargo_debugoutput isn't passed to it either.Without a logger, a build's stdout is the same as on main, apart from the flag probe change above. Checked by comparing stdout on main and on this branch for successful, failing and MSVC builds, with and without
parallel.The
message_loggertest runs builds in a subprocess and checks:cargo:warning=lines on stdout, including both compiles' stderr with theccandarcommands asextra, and the flag probe's warningscargo_warnings(false)stdout has no warnings, the logger has them, and therustc-link-*lines are still on stdoutcpp_set_stdlibwarning on MSVC arrives asGeneralWarningwith()CommandFailedwith exit code 1,is_detection_cmdfalse and the command, and withparallelthe error isn't passed again as a warningexpand: stderr that cc collects instead of streaming reaches the logger, followed byCommandFailedwithis_detection_cmdfalse--print-search-dirsquery forwasm32arrives asCommandFailedwithis_detection_cmdtrue, and cc still finds an archivercargo_debug, family detection's failed-Earrives asCommandFailedwithis_detection_cmdtruexcrun --show-sdk-versionarrives withis_detection_cmdtrue and cc goes on, and a failedxcrun --show-sdk-patharrives with false and failsNoneremoves itBuild's auto traitsRemoving any single routing point (each kind,
run_output's stderr, the\rstrip, the stderr pipe, the probe's logger or warnings setting, removal withNone, the unwind impls, the detection flag for--print-search-dirs,xcrun --show-sdk-versionand family detection, or family detection's-Erouting) makes the test fail. Not covered: a last stderr line without a newline, since the shim always ends its lines, and family detection that succeeds, which the shim can't do.Tested on Windows with and without
--features parallel: whole suite, clippy with-D warnings, fmt, rustdoc with-D warnings, and a library check on Rust 1.88. Not run here: Linux, macOS, the MSRV check anddev-tools/cc-test.This touches
is_flag_supported_innerlike #1965, which is merged now. The branch merges with main without conflicts, and the suite passes on the merged result.