-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
cargo: Add global features options #14663
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
base: master
Are you sure you want to change the base?
Conversation
So, I thought more about this, and I think there are multiple parts:
This pull request is that it conflates use 1 and use 2. It is not possible to set the cargo features based on options of the superproject, which has two problems:
So these two uses should be separated. This is the direction I went with my own proposals at #14639 and #14660, though admittedly that was more of a gut design than something well-thought: for use 1, define options in This leaves use 3, i.e. consulting the result of global feature resolution from the So in the end I'm not sure that this PR is a good step, but maybe I'm overlooking something. |
I think the problem here is we can't rely on traditional Meson options for Cargo features. Cargo features are global and additive by nature. Let's assume the main project has a cargo subproject named
If cargo features were a traditional per-subproject Meson option, user could do This PR only covers the user side, but I agree we still need a way for main project to also be able to add features.
That's an easy one, when generating the AST we know the final list of features enabled on that crate. It in fact already write it at the end: dep = declare_dependency(
link_with : lib,
variables : {'features' : 'f1'}
) We can just declare that list before calling subdir: enabled_features = ['f1']
...
subdir('meson')
...
dep = declare_dependency(
link_with : lib,
variables : {'features' : enabled_features}
)
...
|
3033ccf
to
e59aa4a
Compare
Updated this PR to add |
Also define @bonzini I think this should cover all your cases? |
- Add rust.add_cargo_features() method to add features from meson.build. It is similar to add_global_arguments(), we can add global cargo features until it is first used. - Add rust.cargo_features and rust.cargo_no_default_features CLI options to allow the user to add extra features.
567fa5f
to
d6a2c1f
Compare
Defining |
What do you mean by non-subproject Cargo.toml? |
I mean building pure-Rust targets (i.e. those that don't link directly to any C dependencies) from a Cargo.toml file, even if they are not from a subproject. I described it a bit more in the |
You mean if the main project has a |
Or more than one. In practice for the use cases where people will use Meson there will be mixed C/Rust code and some kind of Meson declarations will be needed. But most likely you will have some leaf crates that don't need any Meson-specific code, only perhaps some override_dependency. And even for those that have mixed C and Rust it's useful to have them participate in global feature resolution. |
Is that a rustc or a cargo limitation? How does the rust ecosystem handle multiple crates that use the same word for a build option with different semantic meanings? English is a limited namespace unless you start adding the crate name as a prefix to all build options, which, well, "works" but also lol... |
It's a Cargo limitation. They live with it because most crates will not have any, or will only have "std" and "alloc". If a "feature" can be implemented through a separate compilation unit without running into language limitations, thet do that because the crate acts as both compilation and distribution unit. |
If it's only a limitation of cargo when building a cargo dependency graph then maybe we just don't need to implement its flaws, and instead we can just treat cfgs as independently toggleable per-project settings even if the cfg names happen to coincide? |
This reads a bit like a misunderstanding. There is no global set of all feature names that would cause collisions if two crates happen to use the same name for one of their features. Both on the command line and in the If a crate wants to expose a feature of one of it's dependencies to its dependents, it has to define its own feature (potentially with the same name) and then enable the dependency's feature based on that. Let's say two crates, |
Ok. Then it sounds like meson project options are a good mapping to cargo features. And the problem is "just" resolving the issue where, to put it in "regular" C/C++ terms, multiple subprojects each have a dependency on a third subproject with different It's not cargo-specific for a subproject libfoobar to require Just, usually if you don't explicitly set both enabled in the superproject, the first call to dependency() is the only one that passes default_options to the subproject invocation. And then building fails because, idk, subp-b tries to build against libfoobar.so's optional dbus support but libfoobar.so got configured instead with the optional libmicrohttpd embedded server. Or, libfoobar.so is actually Gtk-3 and subp-b tries to build unconditionally against the gdk X11 backend (because everyone knows that only X11 exists), but the first call to dependency() was in subp-a which made sure to toggle on the Wayland gdk backend (because of how incredibly modern it is). And some bright fellow figured that it makes sense to not default to X11 since "nobody should be using that anymore" (look, I have to deal with Gentoo users, this is a sore point). |
Which basically leaves me wondering why it's impossible to observe any discussion about rust without the claim being made that rust is "leaving behind traditional approaches, and the old assumptions don't work anymore", when that is manifestly untrue... |
Yes, it is possible and it's how it worked until 1.7.0. It's just a pain in the neck. It's not that Rust leaves behind traditional approaches, in fact I hate it when it does. It's more that Rust already has a declarative build syntax which is enough in most cases, and there's a lot of tooling built around that syntax (sometimes it's easy to replicate it in Meson, see |
Perhaps what we really need here (?) is per subproject options but also build the full Cargo.toml dependency graph at once and "smartly" toggle the defaults during project synthesis? |
Yes, that is the direction that both @xclaesse and myself agree on. He has this simpler solution which leaves most of the work to |
Hmm, I indeed misunderstood cargo's --features cli. I thought those features were enabled on all packages, but it's only on the main project. Thanks for pointing that! I think in that case this PR doesn't make much sense, I need to rethink this. |
The way per subproject option was working before had some issues:
|
Huh? That would be news to me.
Optional dependencies create an implicit feature of the same name, which then wouldn't be listed in the
Yes, features can be enabled but not disabled. |
It is similar to add_global_arguments(), we can add global cargo
features until it is first used.
to allow the user to add extra features.