Give precedence to html_root_url
over --extern-html-root-url
by default, but add a way to opt-in to the previous behavior by jyn514 · Pull Request #82776 · rust-lang/rust (original) (raw)
I'm not quite sure I understand - the snippet you pasted means you know at build time that serde is a third-party crate
Not quite. At build time (i.e. at the time that buck
is executed to perform the build), it's just a rustc invocation with an opaque set of command line arguments that are not meaningful to Buck. There is no concept of "third party" baked into Buck so there is no way it would reason about what is or is not a third party crate or what the implications of the distinction are. "Third party" is only emergent from how Buck is used within some individual monorepo and how the developers have chosen to organize the code in the repo.
At the time of authoring the build targets (i.e. when the developer runs reindeer
or cargo raze
to translate them from upstream's Cargo.toml), definitely we know what is a third party crate, because those tools only ever operate on third party crates, so by definition "third party" == the set of targets imported via those tools. They, too, do not reason about what is or is not third party code; simply everything they operate on is regarded as third party code. The tool's job is importing third party code from the crates.io/docs.rs ecosystem into the Buck based monorepo internal ecosystem.
Why is it harder to tell
serde
is a third-party crate when building crates that depend on it?
Think of each Buck target (one rust_library
invocation for example) as corresponding to a single invocation of a tool like rustc or rustdoc, with some arguments that possibly include output paths of the other targets it declares as dependencies, and produces one or more artifacts as outputs (like a linked executable, or an rlib, or a static lib). Sometimes the same target can be built in various "flavors" to control what the output is, for example #check to produce an rmeta only, #doc to produce rendered html documentation, and #default to produce rlib.
A small piece of Java logic in the Buck implementation of each rule (e.g. the implementation of rust_library
) is responsible for rearranging the human-readable arguments from the configuration language, like name = "serde"
, into command line args, like '--crate-name' 'serde'
, or deps = ["//path/to:serde", "//path/to:serde_json"]
into '--extern' 'serde=$(//path/to:serde)' '--extern' 'serde_json=$(//path/to:serde_json)'
, or features = ["std"]
into '--cfg' 'feature="std"'
. It's good when this is obvious and one-to-one, such that all the programmer is doing is writing down a straightforward rustc invocation in Buck syntax. They then get the ability to run that build in #check mode and #doc mode, build for various targets, build in ways that respect a global Buck configuration like what set of unstable features allowed, build at different optimization levels, etc.
Traversing the Buck targets of the dependencies to categorize which ones are third party is probably possible, but as you can tell is more involved than the above examples (going from features = ["std"]
to '--cfg' 'feature="std"'
). It involves looking at some other target's args, as opposed to its build outputs, which is suspicious.