dhuseby / cargo-bootstrap

Bootstrapping script for Rust Cargo when cross-compilation is difficult or impossible.
BSD 2-Clause "Simplified" License
37 stars 9 forks source link

Build Status

About

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.

Dependencies

These can be installed via the pip tool:

sudo pip install pytoml dulwich requests

Command Line Options

--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.

Examples

To bootstrap Cargo on Bitrig I followed these steps:

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

Notes

FreeBSD

Make sure you do the following: