Rust is a multi-paradigm, high-level, general-purpose programming language designed for performance and safety, especially safe concurrency. In today’s post we are using Rust nightly
. You can also add more targets like stable
or beta
, but we are going to show you the power or utilizing caching when it comes to building in Rust on Travis.
Rust builds are notoriously slow, especially when compiling from a clean slate. This is less true than it once was, but it’s still slow enough to be a significant problem for CI systems. So I thought why not write something that will help future Rust builders using Travis?
Actually, you’re doing just fine. The good news is, is that we can use cache: cargo
, and a few other things up our builders sleeves to help the speed of builds in Rust. For example, take a look at this .travis.yml
I wrote:
---
cache: cargo
dist: xenial
language: rust
matrix:
allow_failures:
- rust: nightly
before_cache:
- rm -rf ~/.cargo/registry/index/ # Remove cache files
- rm -f ./target/.rustc_info.json # Remove more cache files that are recursively brought back upon a triggered build
- find ./target/debug -maxdepth 1 -type f -delete # Delete loose files
fast_finish: true
os: linux
rust:
- stable
- beta
- nightly
script:
- "cargo build --verbose --all"
- "cargo test --verbose --all"
We are testing against 3 Rust channels here, on occassion nightly
will fail due to the compiler, but since this post is about speeding up your builds, you’ll notice I put in a conditional, that is, allowing failures from only one Rust channel, and that is nightly
:
matrix:
allow_failures:
- rust: nightly
You’ll notice stable
and beta
are not listed along with nightly
. Now since speed is the center of this post, you may want to disable Cargo’s incremental compilation, as it doesn’t really give any more verbosity to the build, so let’s try removing it for even faster builds. In order to do this, you’ll need to set the CARGO_INCREMENTAL
env var
to 0
.
Now, let’s make a test file, here’s some Rust code, you’re free to name it whatever you like, in this case you can see we named our file test_run
:
extern crate test_run;
use logic_gates::{and, xor};
pub type Sum = u8;
pub type Carry = u8;
pub fn half_adder_input_output() -> Vec<((u8, u8), (Sum, Carry))> {
vec![
((0, 0), (0, 0)),
((0, 1), (1, 0)),
((1, 0), (1, 0)),
((1, 1), (0, 1)),
]
}
fn half_adder(a: u8, b: u8) -> (Sum, Carry) {
(xor(a, b), and(a, b))
}
#[test]
fn one_bit_adder() {
for (inn, out) in half_adder_input_output() {
let (a, b) = inn;
assert_eq!(half_adder(a, b), out);
}
}
Looks good builders, now let’s go over what we have:
.travis.yml
fileenv var
to 0
matrix
build (multiple platforms and Rust versions) to test both stable Rust versions and nightly builds of their respective rust compiler on different platforms. I stated earlier, you’ll find nightly builds can fail, since those compilers aren’t final and may have bugs, so don’t mark these build fails as an overall failure of the build if that’s solely what went wrongAs the official Travis documentation states, Travis currently checks ~/.cargo
and target/
for any changes from the current cache after a build. You must note, there will always be changes in target/
if the source has changed, which it usually does when a Travis build runs. This means new incremental object files, fingerprints, and build script compilation files are being added to the cache every build, and the more you build – the more clutter! You’ll notice there’s a before_cache
section I added, in this section I added:
before_cache:
- rm -rf ~/.cargo/registry/index/
- rm -f ./target/.rustc_info.json
- find ./target/debug -maxdepth 1 -type f -delete
This will help with that subroutine, and speed your builds up whilst using Rust, and now you should have a working build! You can carry over some of the methods you read here today and apply them to larger scale projects, this is just a small sample of implementing various ways of speeding up Rust builds on Travis.
If you have any questions please email me at montana@travis-ci.org and I’ll answer any and all questions!
Happy building!