Self-contained, temporary, static rustc/cargo installation


#1

I’ve got an existing C codebase for a tool that can be built with ./configure && make. I’d like to use Rust for some parts of the tool, but I’d like to minimize hassle it creates for other people trying to compile the tool.

If I just rely on rustc or cargo being in PATH, I’ll have to add extra build instructions to the manual. When people don’t RTFM (and I don’t blame them) the build will fail, and I’ll have to display an error along lines of “Please install Rust”. It’s a drag. As awesome Rust is, I don’t expect all users to know about it and want to install it system-wide just to try my one tiny program.

So I have a (potentially terrible) idea to download and install a throw-away version of Rust compiler automatically during build, if it wasn’t available on the system.

Can it be done?

  • Is there a reasonably small self-contained Rust package that would work if dropped into some build/tmp directory?
  • Can everything Rust-specific (i.e. not libc) be linked statically, so that it won’t fail because build/tmp/rustsomelib.so is not found?
  • Can I ensure Rust won’t leave any files behind in system directories?

#2

Yes. Servo’s build system does something similar. Servo depends on unstable features, so it needs specific nightly builds of Rust and Cargo. It downloads tarballs from the official download archive and unpacks them within the Servo source directory. Then during the build, it adds their bin directories to $PATH and adds the Rust lib directory to $LD_LIBRARY_PATH (or $DYLD_LIBRARY_PATH on Mac). It also sets $CARGO_HOME to a location inside the directory.

You can see the code for the download steps and the environment variables.

Update: I’m not sure how small you are hoping for. The rust tarball is around 100MB, depending on the platform. (It includes the whole Rust standard library, and is statically linked to all its dependencies including LLVM and jemalloc.)

Can everything Rust-specific (i.e. not libc) be linked statically, so that it won’t fail because build/tmp/rustsomelib.so is not found?

Yes. Rustc links statically by default except to glibc and its dependencies.

Can I ensure Rust won’t leave any files behind in system directories?

By default, Cargo puts configuration and cache files in $HOME/.cargo, and build output in a directory named target inside the source directory. You can change these by setting $CARGO_HOME and $CARGO_TARGET_DIR, respectively. Cargo itself won’t leave any files behind outside of these directories.

However, Cargo packages may include build scripts that can run arbitrary code at build time. Well-behaved build scripts will only write within $CARGO_TARGET_DIR, but there’s no guarantee that all build scripts are well-behaved. If you are downloading and building crates written by someone else, you may want to check where they put their output. (Of course, if you’re not building as root, the build script won’t be able to write to system directories, but it could write to files in your home directory.)

If you’re just using rustc without Cargo, I don’t think it creates any files aside from the ones you tell it to build.


#3

Maybe you can use rustup with some configuration options in your make script. Not sure this will work but might be a good idea to give it a try:

curl -sf https://static.rust-lang.org/rustup.sh | sudo sh -- --prefix=my/install/dir --channel=nightly --date=2015-04-09 --no-modify-path

The options are:
–prefix=my/install/dir
–channel=nightly
–date=2015-04-09
–no-modify-path

and you need to tune up all these to your needs.