Description
Describe the problem you are trying to solve
I would like to obtain the Rust compiler (rustc) configuration, i.e. the output from the cargo rustc -- --print cfg
, within cargo subcommands. The output from the cargo rustc -- --print cfg
command will be different from the rustc --print cfg
command because Cargo will pass additional options based on Cargo environment variables and configuration files. For example, the RUSTFLAGS
environment variable is "managed" by Cargo and not recognized by rustc. So, the following could occur:
PS C:\> $env:RUSTFLAGS="-C target-feature=+crt-static";
PS C:\> cargo rustc -- --print cfg
Compiling <PACKAGE> vX.X.X (<PACKAGE_PATH>)
debug_assertions
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="crt-static"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows
Finished dev [unoptimized + debuginfo] target(s) in 0.10s
PS C:\> rustc --print cfg
debug_assertions
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows
Note the existence of the target_feature="crt-static"
in the output from the cargo rustc -- --print cfg
command versus the output from the rustc --print cfg
command, where the target_feature="crt-static
line is missing.
There are also a couple of other issues with the above example. One, the cargo rustc -- --print cfg
actually builds the package. It does not skip building the package, whereas the rustc --print cfg
command simply prints the configuration and does not compile. Ideally, the cargo rustc -- --print cfg
command would also not compile the entire package. Second, the format is human-readable, but it would also be nice to have more machine/subcommand readable format, such as JSON that also omits the "Compiling...." and "Finished..." lines. Third, the cargo rustc -- --print cfg
command only works if a single Cargo target is defined for the package; otherwise, an error message appears indicating that passing arguments to the compiler requires a specific Cargo target, e.g. --lib
or --bin <NAME>
.
Much of this came about from developing the cargo-rustc-cfg crate for use in the cargo-wix subcommand, where we ultimately want to know if a user's project is statically linking the Windows C Runtime (CRT), provide information to WiX templates for conditional builds of Windows installers, and working on supporting cross-compilation, mostly between x86_64, i686, MSVC, and GNU rustc targets on Windows; hence, the Windows-centric examples.
I recognize this is closely related to the discussion around --build-plan
flag, the cargo-metadata crate, and the --unit-graph
flag. It is possible that I have missed some field or output in these that would yield similar information to the cargo rustc -- --print cfg
command, but in my review the metadata output appears to be too high level and does not contain compiler configuration information and the --unit-graph
output only has the platform
field, which is the target triple (Side note, this will be useful for the cargo-wix subcommand once it is stabilized but won't get us everything we would like to have). I understand there is some hesitation to expose too much Cargo build internals and the multi-targets feature could be a complication.
Describe the solution you'd like
I currently see multiple solutions:
-
Add a
--cfg
flag to thecargo rustc
subcommand, so that the following would be possible:PS C:\> cargo rustc --cfg debug_assertions target_arch="x86_64" target_endian="little" target_env="msvc" target_family="windows" target_feature="fxsr" target_feature="sse" target_feature="sse2" target_os="windows" target_pointer_width="64" target_vendor="pc" windows
This would not build the project but any compiler arguments from Cargo-related environment variables and/or configuration files (
.cargo/config.toml
) would be applied. I think having the flag instead of inspecting the<args> Rustc args
values for a--print cfg
would be easier to implement. I am open to alternative names for the flags as well, i.e.--print-cfg
,--config
,--print-config
, etc. However, I do know that Cargo looks for the--target
option in the<args> Rustc args
and warns about targets being defined in two places, so some inspection already exists. -
If 1 is implemented, then possibly add an option to change the format of the output, i.e.
--cfg-format=JSON
or--cfg-json
. I would actually be fine with defaulting the output to JSON and not having key-value line-based output format. I think this would require some parsing of therustc <ADDITIONAL_CARGO_COMPILER_ARGS> --print cfg
output from within Cargo as opposed to just "forwarding" the output to stdout. I could easily add the conversion to JSON to the cargo-rustc-cfg crate if "forwarding" is quicker and easier. -
Add the compiler configuration to the
--unit-graph
output. This seems appropriate but I am not sure how this fits in with the larger discussion, desires, and goals of the--unit-graph
feature. -
Add the compiler configuration to the cargo-metadata output. This does not seem appropriate as the metadata appears to be more about the package configuration than the compiler configuration.
-
A combination of 1, 2, and 3.
Notes
I am willing to help implement any of these items or new ones, but I wanted to gauge interest and check if I missed something in obtaining the compiler configuration from within a cargo subcommand.