-
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
Metabuild (RFC 2196) #5628
Metabuild (RFC 2196) #5628
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
There is a major hack/problem with the current implementation and I wanted to see if anyone had ideas on how to fix it. It currently puts the generated metabuild script into the "target" directory (
The only other idea I had was to try to rewrite the Target list in the Manifest after the "target" directory is known, but I think that will be difficult due to mutability. Other notes/questions:
|
@@ -584,7 +626,8 @@ pub fn build_map<'b, 'cfg>(cx: &mut Context<'b, 'cfg>, units: &[Unit<'b>]) -> Ca | |||
} | |||
|
|||
{ | |||
let key = unit.pkg | |||
let key = unit | |||
.pkg |
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 seems like an unrelated formatting change that shouldn't appear in the same commit.
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.
Yea, I prefer to use rustfmt to format, but master has diverged quite a bit from the canonical format. I'll try to remove the unrelated changes.
I was thinking I might post a separate PR running rustfmt, but that touches 123 files which I think probably can't be reviewed properly. I'm not sure how you guys want to handle that moving forward. Each rust release brings more changes to rustfmt. It makes things more difficult the more the master branch diverges.
src/cargo/util/toml/targets.rs
Outdated
use std::collections::HashSet; | ||
use std::fs::{self, DirEntry}; | ||
use std::path::{Path, PathBuf}; |
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 seems like an unrelated formatting change. (It's a good change, but unrelated to this commit.)
src/cargo/util/toml/targets.rs
Outdated
use core::{compiler, Edition, Target}; | ||
use util::errors::CargoResult; | ||
use super::{LibKind, PathValue, StringOrBool, TomlBenchTarget, TomlBinTarget, TomlExampleTarget, | ||
TomlLibTarget, TomlManifest, TomlTarget, TomlTestTarget}; |
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.
Likewise, unrelated format change.
src/cargo/util/toml/targets.rs
Outdated
package_root, | ||
edition, | ||
legacy_path, | ||
); |
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.
Unrelated format change.
.find(|u| u.pkg.name().as_str() == name.as_str()) | ||
.map(|dep| dep.target.crate_name()) | ||
}) | ||
.collect(); |
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 a minor nit that I'm not sure needs fixing: this is O(n^2), because it searches all of available_deps
for every entry in meta_deps
. If some readily available data structure provides an O(1) mapping from name to dep, I'd suggest using that. If one doesn't exist, though, I don't know that it's worth creating one just for this, given that the common case will have relatively few metabuild entries.
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'm unaware of any other way to get the necessary information. As you mention, I would expect these lists to usually be very small.
for dep in &meta_deps { | ||
output.push(format!(" {}::metabuild();\n", dep)); | ||
} | ||
output.push("}".to_string()); |
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.
Minor nit: please include a newline at the end of the file.
}; | ||
if changed { | ||
fs::write(&path, output)?; | ||
} |
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.
For clarity and potential future reuse, please extract this logic into a "write if changed" function.
Thank you for working on this, @ehuss! |
Other than the issue you mentioned with the target directory, this looks good to me now. |
☔ The latest upstream changes (presumably #5716) made this pull request unmergeable. Please resolve the merge conflicts. |
Egad I had missed this until now! @ehuss is this ready to go after a once over or were there still any remaining design questions we wanted to answer before landing? |
There's one major problem left. The |
Ok sure yeah makes sense. I think though that the |
Would it be OK if Example: {"packages": [
{"name": "foo",
"targets": [
{"kind": ["custom-build"],
"crate_types": ["bin"],
"name": "foo",
"src_path": ["/path/to/foo/target/.metabuild/metabuild-foo-e8a1568fc72dd376.rs"]
},
...
],
...
}
]} |
Hm perhaps yeah, I was thinking "no" but I'm also thinking more of build plans. It probably wouldn't be the end of the world for sure! In any case this is all unstable so as long as it's mentioned on the tracking issue it's fine to implement whatever for now I think |
☔ The latest upstream changes (presumably #5710) made this pull request unmergeable. Please resolve the merge conflicts. |
I hacked together an alternate solution that mutates the The only other approach I've thought of is to change Let me know which approach sounds the most palatable, or if you have some other idea. This new one works a little better (and is a little simpler), so I'm inclined towards that. |
Thanks! I think though for me at least my preference would be to reflect this in |
Hmm, I'm not sure. At least for build-plan, you'd want it to be there, otherwise you wouldn't be able to use this feature with external build systems, right? As for |
I'm not sure actually that this would necessarily be compatible with a build plan! In some contexts you may move around where execution happens and the original generation of the plan may happen in a somewhat isolated environment which isn't guaranteed to have changes reflected into others per se. I sort of see this as the responsibility of the build planner to figure out how to assemble this file to compile it, although it's true that the source is always generated by cargo so maybe it is better to include it then? I think in general I'm just worried about build plans and In any case this is all unstable so I'm fine landing whatever here for now! Just want to make sure we keep tabs on this in the tracking issue |
I've been trying to figure out how to do this. I'm not sure I understood this suggestion. |
It's a breaking change I think yeah in the sense that consumers who aren't ready for this type of package won't work, but that's also somewhat expected when we add new features to Cargo in that older clients aren't always compatible with newer features. It doesn't break any existing build, though, which I believe is the most important part. |
Sorry for letting this languish. I would prefer not to break the JSON output, as it would break a lot of tools. I agree it is not perfect to expose the path to a mostly internal file/implementation detail. However, exposing it seems to be less harmful than changing the output. The only concern I can think of is if someone runs Also, for the build-plan portion, I'm not convinced hiding it is a good idea. I don't see how an external build tool would be able to construct the build script and build it properly without the metabuild included in the build-plan output. I think it would essentially make this unusable with external build tools. |
I basically have no opinion on how this should be implemented, I'm totally fine with basically anything because it's unstable. Just need to be sure to note it down to discuss before stabilization! |
- Add newline at end of file. - Remove unnecessary rustfmt changes. - Move file writing code to `write_if_changed`.
- Use new enum `TargertSourcePath` for Target::src_path to make it explicit that metabuild has a special path. - `cargo metadata` now skips the metabuild Target. - JSON artifacts include the true path to the metabuild source file. This may not be the best solution, but it's unclear what it should be, and I would prefer to avoid breaking the output. Alternatively it could just not emit anything? I'm not completely familiar with the use case of these artifact messages. - Place the file in `target/.metabuild/metabuild-pkgname-HASH.rs` instead of in the debug/release directory. Its contents do not depend on the profile. - Fix bug in write_if_changed. - More tests.
I have updated with a new approach of using a custom enum for
I think this is now ready for review, I'm not aware of any remaining issues. |
@bors: r+ |
📌 Commit ecc87b1 has been approved by |
Thanks! |
☀️ Test successful - status-appveyor, status-travis |
No description provided.