Given that crate foo depends on crate bar which depends on crate baz,
I know baz's build.rs can get activated features of crate baz, by enumerating all environment variables in the form of CARGO_FEATURE_<name>.
But I don't know what to do in baz's build.rs to get foo's activated features , when building crate foo invoking e.g. cargo build --no-default-features --features "alpha".
In general, a crate deeper in the dependency tree can't get information about a crate higher in the dependency tree, except what the higher crate passes down (such as features).
What are you trying to do? There might be another way to accomplish it.
I'm writing crate clib to provide an easy way of generating bindings for C libs.
In version 0.2.0, at building stage, it will collect [package.metadata.clib] from downstream crates' Cargo.toml files. When build is done, it provides a global namespace clib:: for all the bindings of C libs.
In other words, downstream crates have dependency of clib, while clib has "build-dependencies" of downstream crates' Cargo.toml files.
I know this seems unusual and may have potential issue about incremental build to address. Just want to know how far it can go.
A thought that I had, maybe it's completely irrelevant: perhaps it is possible to insert the bindings via a proc-macro in the downstream crate, instead of writing a file? The downside is that you don't have the joint clib:: namespace anymore, but it is possible to have several packages under the same namespace in that crate, perhaps called mycrate::clib:: by convention, which might be good enough (assuming this is a wrapper crate, which will be the only one that actually needs access to the bindings). This could simplify your dependencies.
I don't know if this helps with the feature problem directly, for determining what to build; but at least which bindings are actually present can be determined by cfg attributes above the proc-macro invocation.
I wrote two crates to answer my own question: now it is feasible for upstream crate to retrieve feature set of the topmost crate, and collect metadata from downstream crates.
The pals crate dumps the process tree with the command line splitted into argv, to detect "--features", "--all-features" and "--no-default-features".
The inwelling crate collects metadata from downstream crates.