当我写作此文时,可能理解并不深刻。今日重读 Crates.io 文档,发现它理论上还是可以做到“既换皮又换身的”:
A minimal registry can be implemented by having a git repository that contains an index, and a server that contains the compressed .crate files created by cargo package.
A full-featured registry that supports publishing will additionally need to have a web API service that conforms to the API used by Cargo.
换了国内源,构建时该卡还会卡。因为它所谓的换源,只是更换crates.io“索引”的源,而不是package“内容”的源。换了国内源后,在国内编译时访问 crates.io-index 自然会快很多,可是crates.io-index里面的信息含量本身就不多,主要是package名称/版本/依赖/特性等,Cargo还要去crates.io网站查询指定package的下载地址,而下载地址也是指向crates.io网站的。最终网络访问瓶颈还是境外的crates.io网站。
https://mirrors.tuna.tsinghua.edu.cn/help/crates.io-index.git/
清华大学开源软件镜像站,Rust crates.io 索引镜像使用帮助:
编辑 $CARGO_HOME/config 文件,添加以下内容:
[source.crates-io] replace-with = 'mirror' [source.mirror] registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
https://mirrors.gitcode.host/zzy/rust-crate-guide/4-cargo/4.1-source-replacement.html
创建 $HOME/.cargo/config 文件(各操作系统及版本均大致相同),然后在 config 文件内写入下述配置内容:
[source.crates-io] registry = "https://github.com/rust-lang/crates.io-index" # 指定镜像 replace-with = '镜像源名' # 如:tuna、sjtu、ustc,或者 rustcc # 注:以下源配置一个即可,无需全部 # 中国科学技术大学 [source.ustc] registry = "git://mirrors.ustc.edu.cn/crates.io-index" # 上海交通大学 [source.sjtu] registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index" # 清华大学 [source.tuna] registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git" # rustcc社区 [source.rustcc] registry = "https://code.aliyun.com/rustcc/crates.io-index.git"
https://github.com/rust-lang/crates.io-index/blob/master/to/ki/tokio
// ingore old vertions ... {"name":"tokio","vers":"1.30.0","deps":[{"name":"async-stream","req":"^0.3","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"backtrace","req":"^0.3.58","features":[],"optional":false,"default_features":true,"target":"cfg(tokio_taskdump)","kind":"normal"},{"name":"bytes","req":"^1.0.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"futures","req":"^0.3.0","features":["async-await"],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"libc","req":"^0.2.145","features":[],"optional":true,"default_features":true,"target":"cfg(unix)","kind":"normal"},{"name":"libc","req":"^0.2.145","features":[],"optional":false,"default_features":true,"target":"cfg(unix)","kind":"dev"},{"name":"loom","req":"^0.7","features":["futures","checkpoint"],"optional":false,"default_features":true,"target":"cfg(loom)","kind":"dev"},{"name":"mio","req":"^0.8.6","features":[],"optional":true,"default_features":false,"target":null,"kind":"normal"},{"name":"mio-aio","req":"^0.7.0","features":["tokio"],"optional":false,"default_features":true,"target":"cfg(target_os = \"freebsd\")","kind":"dev"},{"name":"mockall","req":"^0.11.1","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"nix","req":"^0.26","features":["fs","socket"],"optional":false,"default_features":false,"target":"cfg(unix)","kind":"dev"},{"name":"num_cpus","req":"^1.8.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"parking_lot","req":"^0.12.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"pin-project-lite","req":"^0.2.11","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"rand","req":"^0.8.0","features":[],"optional":false,"default_features":true,"target":"cfg(not(all(target_family = \"wasm\", target_os = \"unknown\")))","kind":"dev"},{"name":"signal-hook-registry","req":"^1.1.1","features":[],"optional":true,"default_features":true,"target":"cfg(unix)","kind":"normal"},{"name":"socket2","req":"^0.5.3","features":["all"],"optional":true,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"normal"},{"name":"socket2","req":"^0.5.3","features":[],"optional":false,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"dev"},{"name":"tempfile","req":"^3.1.0","features":[],"optional":false,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"dev"},{"name":"tokio-macros","req":"~2.1.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"tokio-stream","req":"^0.1","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"tokio-test","req":"^0.4.0","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"tracing","req":"^0.1.25","features":["std"],"optional":true,"default_features":false,"target":"cfg(tokio_unstable)","kind":"normal"},{"name":"wasm-bindgen-test","req":"^0.3.0","features":[],"optional":false,"default_features":true,"target":"cfg(all(target_family = \"wasm\", not(target_os = \"wasi\")))","kind":"dev"},{"name":"windows-sys","req":"^0.48","features":[],"optional":true,"default_features":true,"target":"cfg(windows)","kind":"normal"},{"name":"windows-sys","req":"^0.48","features":["Win32_Foundation","Win32_Security_Authorization"],"optional":false,"default_features":true,"target":"cfg(windows)","kind":"dev"}],"cksum":"2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd","features":{"default":[],"fs":[],"full":["fs","io-util","io-std","macros","net","parking_lot","process","rt","rt-multi-thread","signal","sync","time"],"io-std":[],"io-util":["bytes"],"macros":["tokio-macros"],"net":["libc","mio/os-poll","mio/os-ext","mio/net","socket2","windows-sys/Win32_Foundation","windows-sys/Win32_Security","windows-sys/Win32_Storage_FileSystem","windows-sys/Win32_System_Pipes","windows-sys/Win32_System_SystemServices"],"process":["bytes","libc","mio/os-poll","mio/os-ext","mio/net","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Threading","windows-sys/Win32_System_WindowsProgramming"],"rt":[],"rt-multi-thread":["num_cpus","rt"],"signal":["libc","mio/os-poll","mio/net","mio/os-ext","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Console"],"stats":[],"sync":[],"test-util":["rt","sync","time"],"time":[]},"yanked":false,"rust_version":"1.63"} {"name":"tokio","vers":"1.31.0","deps":[{"name":"async-stream","req":"^0.3","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"backtrace","req":"^0.3.58","features":[],"optional":false,"default_features":true,"target":"cfg(tokio_taskdump)","kind":"normal"},{"name":"bytes","req":"^1.0.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"futures","req":"^0.3.0","features":["async-await"],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"libc","req":"^0.2.145","features":[],"optional":true,"default_features":true,"target":"cfg(unix)","kind":"normal"},{"name":"libc","req":"^0.2.145","features":[],"optional":false,"default_features":true,"target":"cfg(unix)","kind":"dev"},{"name":"loom","req":"^0.7","features":["futures","checkpoint"],"optional":false,"default_features":true,"target":"cfg(loom)","kind":"dev"},{"name":"mio","req":"^0.8.6","features":[],"optional":true,"default_features":false,"target":null,"kind":"normal"},{"name":"mio-aio","req":"^0.7.0","features":["tokio"],"optional":false,"default_features":true,"target":"cfg(target_os = \"freebsd\")","kind":"dev"},{"name":"mockall","req":"^0.11.1","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"nix","req":"^0.26","features":["fs","socket"],"optional":false,"default_features":false,"target":"cfg(unix)","kind":"dev"},{"name":"num_cpus","req":"^1.8.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"parking_lot","req":"^0.12.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"pin-project-lite","req":"^0.2.11","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"rand","req":"^0.8.0","features":[],"optional":false,"default_features":true,"target":"cfg(not(all(target_family = \"wasm\", target_os = \"unknown\")))","kind":"dev"},{"name":"signal-hook-registry","req":"^1.1.1","features":[],"optional":true,"default_features":true,"target":"cfg(unix)","kind":"normal"},{"name":"socket2","req":"^0.5.3","features":["all"],"optional":true,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"normal"},{"name":"socket2","req":"^0.5.3","features":[],"optional":false,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"dev"},{"name":"tempfile","req":"^3.1.0","features":[],"optional":false,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"dev"},{"name":"tokio-macros","req":"~2.1.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"tokio-stream","req":"^0.1","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"tokio-test","req":"^0.4.0","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"tracing","req":"^0.1.25","features":["std"],"optional":true,"default_features":false,"target":"cfg(tokio_unstable)","kind":"normal"},{"name":"wasm-bindgen-test","req":"^0.3.0","features":[],"optional":false,"default_features":true,"target":"cfg(all(target_family = \"wasm\", not(target_os = \"wasi\")))","kind":"dev"},{"name":"windows-sys","req":"^0.48","features":[],"optional":true,"default_features":true,"target":"cfg(windows)","kind":"normal"},{"name":"windows-sys","req":"^0.48","features":["Win32_Foundation","Win32_Security_Authorization"],"optional":false,"default_features":true,"target":"cfg(windows)","kind":"dev"}],"cksum":"40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920","features":{"default":[],"fs":[],"full":["fs","io-util","io-std","macros","net","parking_lot","process","rt","rt-multi-thread","signal","sync","time"],"io-std":[],"io-util":["bytes"],"macros":["tokio-macros"],"net":["libc","mio/os-poll","mio/os-ext","mio/net","socket2","windows-sys/Win32_Foundation","windows-sys/Win32_Security","windows-sys/Win32_Storage_FileSystem","windows-sys/Win32_System_Pipes","windows-sys/Win32_System_SystemServices"],"process":["bytes","libc","mio/os-poll","mio/os-ext","mio/net","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Threading","windows-sys/Win32_System_WindowsProgramming"],"rt":[],"rt-multi-thread":["num_cpus","rt"],"signal":["libc","mio/os-poll","mio/net","mio/os-ext","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Console"],"stats":[],"sync":[],"test-util":["rt","sync","time"],"time":[]},"yanked":false,"rust_version":"1.63"} {"name":"tokio","vers":"1.32.0","deps":[{"name":"async-stream","req":"^0.3","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"backtrace","req":"^0.3.58","features":[],"optional":false,"default_features":true,"target":"cfg(tokio_taskdump)","kind":"normal"},{"name":"bytes","req":"^1.0.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"futures","req":"^0.3.0","features":["async-await"],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"libc","req":"^0.2.145","features":[],"optional":true,"default_features":true,"target":"cfg(unix)","kind":"normal"},{"name":"libc","req":"^0.2.145","features":[],"optional":false,"default_features":true,"target":"cfg(unix)","kind":"dev"},{"name":"loom","req":"^0.7","features":["futures","checkpoint"],"optional":false,"default_features":true,"target":"cfg(loom)","kind":"dev"},{"name":"mio","req":"^0.8.6","features":[],"optional":true,"default_features":false,"target":null,"kind":"normal"},{"name":"mio-aio","req":"^0.7.0","features":["tokio"],"optional":false,"default_features":true,"target":"cfg(target_os = \"freebsd\")","kind":"dev"},{"name":"mockall","req":"^0.11.1","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"nix","req":"^0.26","features":["fs","socket"],"optional":false,"default_features":false,"target":"cfg(unix)","kind":"dev"},{"name":"num_cpus","req":"^1.8.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"parking_lot","req":"^0.12.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"pin-project-lite","req":"^0.2.11","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal"},{"name":"rand","req":"^0.8.0","features":[],"optional":false,"default_features":true,"target":"cfg(not(all(target_family = \"wasm\", target_os = \"unknown\")))","kind":"dev"},{"name":"signal-hook-registry","req":"^1.1.1","features":[],"optional":true,"default_features":true,"target":"cfg(unix)","kind":"normal"},{"name":"socket2","req":"^0.5.3","features":["all"],"optional":true,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"normal"},{"name":"socket2","req":"^0.5.3","features":[],"optional":false,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"dev"},{"name":"tempfile","req":"^3.1.0","features":[],"optional":false,"default_features":true,"target":"cfg(not(target_family = \"wasm\"))","kind":"dev"},{"name":"tokio-macros","req":"~2.1.0","features":[],"optional":true,"default_features":true,"target":null,"kind":"normal"},{"name":"tokio-stream","req":"^0.1","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"tokio-test","req":"^0.4.0","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev"},{"name":"tracing","req":"^0.1.25","features":["std"],"optional":true,"default_features":false,"target":"cfg(tokio_unstable)","kind":"normal"},{"name":"wasm-bindgen-test","req":"^0.3.0","features":[],"optional":false,"default_features":true,"target":"cfg(all(target_family = \"wasm\", not(target_os = \"wasi\")))","kind":"dev"},{"name":"windows-sys","req":"^0.48","features":[],"optional":true,"default_features":true,"target":"cfg(windows)","kind":"normal"},{"name":"windows-sys","req":"^0.48","features":["Win32_Foundation","Win32_Security_Authorization"],"optional":false,"default_features":true,"target":"cfg(windows)","kind":"dev"}],"cksum":"17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9","features":{"default":[],"fs":[],"full":["fs","io-util","io-std","macros","net","parking_lot","process","rt","rt-multi-thread","signal","sync","time"],"io-std":[],"io-util":["bytes"],"macros":["tokio-macros"],"net":["libc","mio/os-poll","mio/os-ext","mio/net","socket2","windows-sys/Win32_Foundation","windows-sys/Win32_Security","windows-sys/Win32_Storage_FileSystem","windows-sys/Win32_System_Pipes","windows-sys/Win32_System_SystemServices"],"process":["bytes","libc","mio/os-poll","mio/os-ext","mio/net","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Threading","windows-sys/Win32_System_WindowsProgramming"],"rt":[],"rt-multi-thread":["num_cpus","rt"],"signal":["libc","mio/os-poll","mio/net","mio/os-ext","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Console"],"stats":[],"sync":[],"test-util":["rt","sync","time"],"time":[]},"yanked":false,"rust_version":"1.63"}
Cargo从这里可以拿到历史版本号,依赖项(deps),特性(features)等信息。
https://crates.io/api/v1/crates/tokio/1.32.0
{"version":{"audit_actions":[{"action":"publish","time":"2023-08-16T21:11:49.973478+00:00","user":{"avatar":"https://avatars.githubusercontent.com/u/6180?v=4","id":10,"login":"carllerche","name":"Carl Lerche","url":"https://github.com/carllerche"}}],"checksum":"17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9","crate":"tokio","crate_size":725004,"created_at":"2023-08-16T21:11:49.973478+00:00","dl_path":"/api/v1/crates/tokio/1.32.0/download","downloads":1848459,"features":{"default":[],"fs":[],"full":["fs","io-util","io-std","macros","net","parking_lot","process","rt","rt-multi-thread","signal","sync","time"],"io-std":[],"io-util":["bytes"],"macros":["tokio-macros"],"net":["libc","mio/os-poll","mio/os-ext","mio/net","socket2","windows-sys/Win32_Foundation","windows-sys/Win32_Security","windows-sys/Win32_Storage_FileSystem","windows-sys/Win32_System_Pipes","windows-sys/Win32_System_SystemServices"],"process":["bytes","libc","mio/os-poll","mio/os-ext","mio/net","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Threading","windows-sys/Win32_System_WindowsProgramming"],"rt":[],"rt-multi-thread":["num_cpus","rt"],"signal":["libc","mio/os-poll","mio/net","mio/os-ext","signal-hook-registry","windows-sys/Win32_Foundation","windows-sys/Win32_System_Console"],"stats":[],"sync":[],"test-util":["rt","sync","time"],"time":[]},"id":873708,"license":"MIT","links":{"authors":"/api/v1/crates/tokio/1.32.0/authors","dependencies":"/api/v1/crates/tokio/1.32.0/dependencies","version_downloads":"/api/v1/crates/tokio/1.32.0/downloads"},"num":"1.32.0","published_by":{"avatar":"https://avatars.githubusercontent.com/u/6180?v=4","id":10,"login":"carllerche","name":"Carl Lerche","url":"https://github.com/carllerche"},"readme_path":"/api/v1/crates/tokio/1.32.0/readme","rust_version":"1.63","updated_at":"2023-08-16T21:11:49.973478+00:00","yanked":false}}
Cargo从这里可以拿到package下载地址:"dl_path":"/api/v1/crates/tokio/1.32.0/download"。这是一个相对地址,前面需要加上crates.io的origin,最终获得完整下载地址:https://crates.io/api/v1/crates/tokio/1.32.0/download。
https://crates.io/api/v1/crates/tokio/1.32.0/download
自动重定向到 https://static.crates.io/crates/tokio/tokio-1.32.0.crate,下载得到的是.crate文件,实际是一个压缩包,解压后就是tokio项目源代码目录树。
现有方案不解决主要问题。我想今后Rust还是需要提供crates.io内package下载镜像源的。
20231031 LIIGO补记:参见文首补记,Registry设计本身或许并没有问题。我想今后国内的Rust镜像源会内置下载功能,不用再去境外网站下载。