Skip to content
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

Implement new sdist feature to download rust toolchain #2177

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

Owen-CH-Leung
Copy link
Contributor

@Owen-CH-Leung Owen-CH-Leung commented Aug 8, 2024

Solves #2120

This PR implements feature to download rust toolchain when trying to pip install a python package built by maturin. Specifically, when maturin execute WriteDistInfo, when compiling with the rustls feature, it will try to check if toolchain is installed, and proceed to install the rustup installer and download the stable toolchain if toolchain is absent

Initial draft to implement downloading rust toolchain during sdist
Copy link

netlify bot commented Aug 8, 2024

Deploy Preview for maturin-guide ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 908bec0
🔍 Latest deploy log https://app.netlify.com/sites/maturin-guide/deploys/66bb2365438ee80008aef3dc
😎 Deploy Preview https://deploy-preview-2177--maturin-guide.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@Owen-CH-Leung
Copy link
Contributor Author

@messense Can you review this PR ? I'm not sure if I'm heading to the right direction so I'd like to get some feedback before proceeding to polish it

@@ -1132,6 +1148,19 @@ impl BuildContext {
}
Ok(wheels)
}
/// Check if user requires to install rust toolchain
///
/// Loop over `build-system.requires` defined in pyproject.toml and see if `rust-toolchain` is provided
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't going to work because pip will try to install rust-toolchain package from pypi.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't have rust-toolchain on pypi yet, we can try to use rust-toolchain.toml / legacy rust-toolchain file or rust-version in Cargo.toml of the binding crate, then fallback to Rust stable.

Copy link
Contributor Author

@Owen-CH-Leung Owen-CH-Leung Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@messense Thanks. So it means like if user provides a rust-toolchain.toml file in the project directory, that would be indicating that user wants to install rust-toolchain ?

Copy link

@padix-key padix-key Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To put my two cents in, I think that the rust toolchain should be present for the build, even if rust-toolchain.tomlis missing in which case a default toolchain would be used. Bonus points if [toolchain] can be specified directly in the pyproject.toml as e.g [tool.maturin.toolchain].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about an additional command line flag such as maturin sdist --install-rust-toolchain ? (Or maybe when env variable MATURIN_INSTALL_RUST is set to true? ). This will be backward-compatible while keeping maturin flexible for users .

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only be suitable in the case the user of the package knows what Maturin, Rust etc. is. However, the reason I brought up issue #2120, is that a typical user just wants to use a package and would probably do not like to think about the build backend of this package.

In other words, it would be nice in my opinion, if a user can install a source distribution of a package that uses maturin as build-system simply via pip install without knowing such internals

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@messense @padix-key I've modified prepare_metadata_for_build_wheel to remove the check for rust-toolchain, and add logic in maturin pep517 write-dist-info command to check for toolchain from there ( and install from rustup if not present). Let me know what you think

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have actually barely insight into the maturin internals, I only know the user side 😃.

Copy link
Contributor

@mbway mbway Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think automatically downloading an installation script and running it for the user and installing to non-standard locations is undesirable. I would not be happy if this took place on my system without any confirmation at least. I could also see it causing problems for CI systems which may accidentally install rustup each build if misconfigured.
An opt-in command line flag or environment variable seems like a good approach to me. If not passed it could print

rust toolchain (cargo) not found.
Please install it manually or pass `maturin sdist --auto-install-toolchain`

so discoverability wouldn't be an issue for the 'typical user' described as not being aware of what they need to have installed

@@ -382,7 +382,7 @@ fn http_agent() -> Result<ureq::Agent, UploadError> {

#[cfg(feature = "rustls")]
#[allow(clippy::result_large_err)]
fn http_agent() -> Result<ureq::Agent, UploadError> {
pub fn http_agent() -> Result<ureq::Agent, UploadError> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a http_agent below that also need to be made public.

.to_str()
.context("Fail to construct target path for installing rust toolchain")?;

download_and_execute_rustup(target_path_str, target_path_str)
Copy link
Member

@messense messense Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skip download if there is already a working rust toolchain (probably need to validate version with rust-version in Cargo.toml and Cargo.toml of every crate dependencies, I think we can get that from cargo metadata output).

@messense messense requested a review from konstin August 9, 2024 01:36
@messense
Copy link
Member

messense commented Aug 9, 2024

cc @padix-key since you requested this feature.

@konstin konstin force-pushed the impl_sdist_feature_to_install_rust_toolchain branch from 908bec0 to e06953f Compare October 17, 2024 12:57
@konstin
Copy link
Member

konstin commented Oct 20, 2024

(sorry for the further delay, i was on this but got thrown off again by #2268)

@Owen-CH-Leung
Copy link
Contributor Author

Owen-CH-Leung commented Oct 21, 2024

I was trying to create a CI test to verify that pip install will work even without toolchain but no luck :(

@mbway
Copy link
Contributor

mbway commented Oct 21, 2024

Why are rustup and cargo being installed to non-standard locations? the code seems to be using home_dir() as CARGO_HOME. On unix the default is $HOME/.cargo (source).

@padix-key
Copy link

Would it be sensible to install cargo and rustup in a temporary location and clean it after finishing the build, or do you think the size of them would be too large for repeated install/uninstall?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants