-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Obtain the Cargo compiler configuration for use in subcommands without building the package #8923
Comments
For reference, a sequence that demonstrations some of the complications in obtaining Cargo-modified compiler configuration:
|
Add --cfg and --rustc-cfg flags to output compiler configuration This PR is my attempt to address #8923. I have added the `--cfg` flag to the `cargo rustc` subcommand and the `--rustc-cfg` flag to the `cargo build`, `cargo check`, `cargo test`, and `cargo bench` subcommands, respectively. Both versions of the flag, `--cfg` and `--rustc-cfg`, do the same thing, but I thought it looked weird for the `cargo rustc` subcommand to be `cargo rustc --rustc-cfg`. The following example invocations are possible, once stabilized: - `cargo rustc --cfg` - `cargo build --rustc-cfg` - `cargo check --rustc-cfg` - `cargo test --rustc-cfg` - `cargo bench --rustc-cfg` In each case, compilation is aborted and only compiler configuration is emitted. All of the context creation and configuration is still executed, but execution of the compilation job is aborted. Similar to the `--unit-graph` implementation, the `--cfg/--rustc-cfg` flag is hidden, marked as a "unstable", and requires the `-Z unstable-options` flag at the moment. A complete example invocation with this PR would be: ```bash $ cargo +nightly rustc -Z unstable-options --cfg ``` I am open to alternatives for the flag name. I have thought of `--compiler-cfg`, `--compile-cfg`, and `--target-cfg`, but I went with `--rustc-cfg` because it is the Rust compiler (rustc) configuration (cfg). The `--target-cfg` could be confusing because there are Cargo targets and Compiler targets. A lone `--cfg` for the build, check, test, and bench subcommands would also be ambiguous and configuration that is being displayed. Originally, I was only going to add the `--cfg` flag to the `cargo rustc` subcommand, but build, check, test, and bench all have the `--unit-graph` flag, and I used that flag's implementation and existence as a template for this implementation. I am not opposed to having just the `--cfg` flag for the `cargo rustc` subcommand as originally proposed in #8923. I discovered during my initial investigation to implement the feature and familiarization with the Cargo codebase, that as part of the build context creation and compilation process, Cargo internally calls the `rustc --print cfg` command for all targets and stores the output in the `RustcTargetData` type. It does this for the host and any explicitly defined targets for cross-compilation. Compilation features, such as `+crt-static`, added to the compilation process through Cargo environment variables or TOML configuration directives are added to the internal `rustc --print cfg` command call. So, the `--cfg/--rustc-cfg` just emits the contents of the `RustcTagetData` type as JSON. There is no need to call the `rustc --print cfg` command again. The implementation then becomes nearly identical to the `--unit-graph` implementation. The output is only in JSON, similar to the `--unit-graph` feature, instead of the key-value and name style of the `rustc --print cfg` output because it easily resolves issues related to multi-targets, explicit target (`--target <TRIPLE>`) versus host configurations, and cross compilation. Subcommands and other projects can parse the JSON to recreate the key-value and name style if desired based on a specific target or the host. Here is an example of the JSON output (formatted for humans, the actual output is condensed), which is also available as a comment in the `cargo::core::compiler::rustc_cfg` module: ```javascript { "version": 1, "host": { "names": ["windows", "debug_assertions"], "arch":"x86_64", "endian":"little", "env":"msvc", "family":"windows", "features":["fxsr","sse","sse2"], "os":"windows", "pointer_width":"64", "vendor":"pc" }, "targets": { "x86_64-unknown-linux-gnu": { "names": ["debug_assertions", "unix"], "arch":"x86_64", "endian":"little", "env":"gnu", "family":"unix", "features": ["fxsr","sse","sse2"], "os":"linux", "pointer_width":"64", "vendor":"unknown" }, "i686-pc-windows-msvc": { "names": ["windows", "debug_assertions"], "arch":"x86", "endian":"little", "env":"msvc", "family":"windows", "features":["fxsr","sse","sse2"], "os":"windows", "pointer_width":"32", "vendor":"pc" } } } ``` I decided to remove the "target_" prefix from the relevant configurations to reduce "noise" in the output. Again, I am open to alternatives or suggestions on the JSON format.
This has been addressed with PR #9002. The Cargo-based compiler configuration can be obtained using the |
I opened tracking issue #9357 to track the new |
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 thecargo rustc -- --print cfg
command will be different from therustc --print cfg
command because Cargo will pass additional options based on Cargo environment variables and configuration files. For example, theRUSTFLAGS
environment variable is "managed" by Cargo and not recognized by rustc. So, the following could occur:Note the existence of the
target_feature="crt-static"
in the output from thecargo rustc -- --print cfg
command versus the output from therustc --print cfg
command, where thetarget_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 therustc --print cfg
command simply prints the configuration and does not compile. Ideally, thecargo 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, thecargo 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 thecargo 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 theplatform
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: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.
The text was updated successfully, but these errors were encountered: