This python script is designed to do the bare minimum to compile and link the Cargo binary for the purposes of bootstrapping itself on a new platform for which cross-compiling isn't possible. I wrote this specifically to bootstrap Cargo on Bitrig. Bitrig is a fork of OpenBSD that uses clang/clang++ and other BSD licensed tools instead of GNU licensed software. Cross compiling from another platform is extremely difficult because of the alternative toolchain Bitrig uses.
With this script, all that should be necessary to run this is a working Rust toolchain, Python, and Git.
This script will not set up a full cargo cache or anything. It works by cloning the cargo index and then starting with the cargo dependencies, it recursively builds the dependency tree. Once it has the dependency tree, it starts with the leaves of the tree, doing a breadth first traversal and for each dependency, it clones the repo, sets the repo's head to the correct revision and then executes the build command specified in the cargo config.
This bootstrap script uses a temporary directory to store the built dependency libraries and uses that as a link path when linking dependencies and the cargo binary. The goal is to create a statically linked cargo binary that is capable of being used as a "local cargo" when running the main cargo Makefiles.
pytoml -- used for parsing toml files. https://github.com/avakar/pytoml
dulwich -- used for working with git repos. https://git.samba.org/?p=jelmer/dulwich.git;a=summary
requests -- used to download crates. http://python-requests.org
These can be installed via the pip tool:
sudo pip install pytoml dulwich requests
--cargo-root <path> specify the path to the cargo repo root.
--target-dir <path> specify the location to store build results.
--crate-index <path> path to where crates.io index shoudl be cloned
--target <triple> build target: e.g. x86_64-unknown-bitrig
--host <triple> host machine: e.g. x86_64-unknown-linux-gnu
--no-clone don't clone crates.io index, --crate-index must point to existing clone.
--no-git don't assume that the crates index and cargo root are git repos; implies --no-clone
--no-clean don't remove the folders created during bootstrapping.
--download only download the crates needed to bootstrap cargo.
--no-download don't download any crates (fail if any do not exist)
--graph output dot format graph of dependencies.
--urls-file <file> file to write crate URLs to
--blacklist <crates> list of blacklisted crates to skip
--patchdir <dir> directory containing patches to apply to crates after fetching them
The --cargo-root
option defaults to the current directory if unspecified. The
target directory defaults to Python equivilent of mktemp -d
if unspecified.
The --crate-index
option specifies where the crates.io index will be cloned. Or,
if you already have a clone of the index, the crates index should point there
and you should also specify --no-clone
. The --target
option is used to
specify which platform you are bootstrapping for. The --host
option defaults
to the value of the --target
option when not specified.
To bootstrap Cargo on Bitrig I followed these steps:
/tmp/bootstrap
./tmp/index
./tmp/out
, for the output./tmp/cargo
../bootstrap.py --crate-index /tmp/index --target-dir /tmp/out --no-clone --no-clean --target x86_64-unknown-bitrig
After the script completes, there is a Cargo executable named cargo-0_5_0
in
/tmp/out
. That executable can then be used to bootstrap Cargo from source by
specifying it as the --local-cargo
option to Cargo's ./configure
script.
./configure --local-cargo=/tmp/out/cargo-0_5_0
Make sure you do the following: