-
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
Allow cfg(...)ing targets in Cargo.toml #5367
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @matklad (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
I feed a bit uneasy about |
My goal is for |
Yeah, I think |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much @fitzgen, this is looking pretty good! I definitely feel like this is on the right track. I think that this is also highly related to #5335 (as a heads up).
@matklad I don't think this'll affect the index/crates.io b/c there's nothing that affects dependency resolution but rather just how crates are compiled, right?
src/cargo/util/toml/mod.rs
Outdated
@@ -556,6 +556,9 @@ impl TomlManifest { | |||
.or_else(|| v.build_dependencies2.as_ref()), | |||
)?, | |||
build_dependencies2: None, | |||
lib: v.lib.clone(), | |||
bin: v.bin.clone(), | |||
example: v.example.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could test
also be included here? And bench
?
Hm, probably. I was thinking that maybe this should affect dependency resolution, so that you get error "crate foo is unsupported for $host_triple" earlier, during lockfile generation, but looks like this is not possible because you know $host_triple only when you are actually compiling. I think this clears my doubts, so removing the nomination. |
☔ The latest upstream changes (presumably #5335) made this pull request unmergeable. Please resolve the merge conflicts. |
a20c633
to
f8d27ce
Compare
I think this is ready for another look: r? @alexcrichton |
☔ The latest upstream changes (presumably #5384) made this pull request unmergeable. Please resolve the merge conflicts. |
src/cargo/util/toml/targets.rs
Outdated
.flat_map(|benches| { | ||
benches.iter() | ||
.cloned() | ||
.filter_map(|bench| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a particularly gnarly super-nested loop duplicated (it looks like) in a few places, could these be tightened up?
tests/testsuite/cfg.rs
Outdated
assert_that( | ||
p.cargo("build").arg("-v"), | ||
execs().with_status(0) | ||
// TODO FITZGEN: I don't know why this assertion fails... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll want to write down autobins = true
in the manifest above to get this working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Could some tests also be added exhibiting "layering" configuration where a unit test or something like that is configured in multiple [[test]]
blocks (some platform-specific).
Additionally could a test be added to ensure that you can't define more than one [lib]
target?
Apologies if this should be brought up in another issue, but I'm curious if this PR would this allow you to do something like this? # Cargo.toml
[lib]
[target.'cfg(target_os = "ios")']
crate-type = ["staticlib"]
[target.'cfg(target_os = "android")']
crate-type = ["cdylib"] I'm trying to make a "universal" lib crate that has feature gates for two platform specific sub-crates. For example: [workspace]
members = ["Source/Rust/generic", "Source/Rust/apple", "Source/Rust/java"]
[package]
name = "example-universal"
version = "0.1.0"
authors = ["Chris Ballinger <chrisballinger@gmail.com>"]
[lib]
name = "example"
path = "Source/Rust/universal/lib.rs"
crate-type = ["staticlib", "cdylib"]
[features]
apple = ["example-apple"]
java = ["example-java"]
[profile.release]
debug = true
[dependencies]
example-generic = { path = "Source/Rust/generic" }
example-apple = { path = "Source/Rust/apple", optional = true }
example-java = { path = "Source/Rust/java", optional = true } [package]
name = "example-generic"
version = "0.1.0"
authors = ["Chris Ballinger <chrisballinger@gmail.com>"]
[lib]
name = "example_generic"
[dependencies]
libc = "0.2" [package]
name = "example-apple"
version = "0.1.0"
authors = ["Chris Ballinger <chrisballinger@gmail.com>"]
[lib]
name = "example_apple"
crate-type = ["staticlib"]
[dependencies]
dispatch = "0.1"
objc-foundation = "0.1"
example-generic = { path = "../generic" } [package]
name = "example-java"
version = "0.1.0"
authors = ["Chris Ballinger <chrisballinger@gmail.com>"]
[lib]
name = "example_java"
crate-type = ["cdylib"]
[dependencies]
jni = "0.10"
example-generic = { path = "../generic" } The issue here is that in my "universal" parent crate, cdylib isn't a valid crate-type for ios, and staticlib isn't valid for android. When compiling for iOS with cargo-lipo, cargo gives warnings about unsupported cdylib:
|
@chrisballinger, with this PR, you will be able to do [target.'cfg(not(target = "x86_64-apple-ios"))'.lib]
name = "example"
path = "Source/Rust/universal/lib.rs"
crate-type = ["staticlib", "cdylib"]
[target.'cfg(target = "x86_64-apple-ios")'.lib]
name = "example"
path = "Source/Rust/universal/lib.rs"
crate-type = ["staticlib"] |
29c37b6
to
19787f5
Compare
Ok, rebased. Will address review feedback now. |
Enforcing only a single
Does anyone have any suggestions on how to move forward? |
Aha! I just figured out a way to pass a package id through! |
Ok, so in the latest commit I am ensuring that there is only one Does anyone have any suggestions? |
}) | ||
.collect::<Vec<_>>(); | ||
|
||
// Ensure that there is only one [lib] activated per crate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where the unique [lib]
checking happens, fwiw.
src/cargo/ops/cargo_compile.rs
Outdated
let mut pkg_libs: HashMap<(&PackageId, &str), Vec<&Unit>> = Default::default(); | ||
|
||
for unit in &units { | ||
if let TargetKind::Lib(ref pkgid, _) = *unit.target.kind() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, if I understand correctly, you don't have to add pkgid
to TargetKind
, because you can use unit.pkg.package_id()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I didn't see that.
|
||
[target.'cfg(not(target_pointer_width = "1"))'.lib] | ||
name = "always" | ||
path = "src/always.rs" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel uneasy about the fact that you specify different names depending on the platform.... Should we make this case an error perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned below, if they both activate, then it will be an error. No merging is done.
The updates are looking pretty good with @matklad's thoughts as well, but it may be good to discuss the overall interface we'd like here as well. I believe we don't want this to enable multiple For example let's take something like: [target.foo.lib]
name = 'bar' This already implies there may be two targets in the manifest. If The next question would be how do these targets interact? For example if don't automatically infer a target then it means the library is not workable by default on non- Or do we want a sort of "merging" of targets? For example what about: [target.'cfg(target_arch = "wasm32")'.lib]
crate-type = ["cdylib"] Does this "merge" with the main I feel like merging is probably what one might expect, but it's something we'll want to think through as well as consider what it means for other targets as well? (can you "merge" two test targets?) Perhaps we can just say that any targets with the same |
@fitzgen Awesome, thank you! |
I was assuming that we would not do merging, and that if we ever ended up in a situation where two |
@fitzgen hm so if we don't do any merging, how's this supposed to be used? That means if I have something like: [lib]
test = false
[target.'cfg(target_arch = "wasm32")'.lib]
crate-type = ["cdylib"]
test = false that won't work on wasm, right? (because on wasm there's two lib targets) |
In that case the check for a unique lib would trigger and there would be an error. You would have to have a cfg for wasm and a cfg for not wasm. I agree that this isn't super ergonomic, but it seems that we can always loosen the restrictions and start merging later. I just want to get the minimum thing working for now. |
Ok that makes sense yeah, I agree that this is the conservative route and we can always soup it up later! That reminds me though, can you be sure this functionality is behind a Cargo feature? |
☔ The latest upstream changes (presumably #5358) made this pull request unmergeable. Please resolve the merge conflicts. |
Like a normal feature in Cargo.toml? Are you intending for this to be available only to folks who build their own cargo? Is there someway we can automatically make it nightly-only? |
ef093d7
to
6ecd1df
Compare
@fitzgen oh there's a |
Fix rust-lang#4900 Sort of addresses rust-lang#4881 as well.
The original motivation behind this PR was to allow
Tests work:
Benches work:
And compiling to wasm still works:
Given all that, my mission here is done, and I am going to close this PR. |
This is a WORK IN PROGRESS!
Currently,
[[bin]]
s do the Right Thing (I think) and maybe[lib]
too but I haven't tested. Mostly posting this to acquire some early feedback. cc @alexcrichtonFix #4900
Sort of fix #4881 (it seems like maybe cfg'ing the
[lib]
is good enough that we don't need to be able to cfg the individualcrate-type
s?)