Cargo refused to build my project - A Rust debugging story!
Tags: rust, debug, cargo, programming
Published: 2018-05-09 11:05:01

---
title: Cargo refused to build my project - A Rust debugging story!
published: true
description: An afternoon of debugging!
tags: rust,debug,cargo,programming
---

### Background

Today, I resumed a `rust` project of mine after a long time. In order to check my last working code, I ran `cargo run`. But it refused to run with error message: 
```
...."-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "util"
= note: /usr/bin/ld: cannot find Scrt1.o: No such file or directory
          collect2: error: ld returned 1 exit status
```

### Linker Issues!

`ld` is used to link libraries. So, the error was not in the code but in the linking phase. I googled the error and the solution was to have `build-essential` package installed. But the package was already installed on my machine (it is one of the first packages I install on any development machine).

Some more googling revealed that `cargo` uses the system `cc` linker to link to the C runtime. Running `which cc` gave me `$HOME/anaconda3/bin/cc`. This `cc` is part of my Anaconda root environment. (Anaconda is a package manager for scientific computing packages. It is a convenient way for installing multiple versions of packages in different environments).

On Linux, the linker knows where to find the required libraries using the shared library cache. I ran `ldconfig -v` to refresh it and then try again. Same error!

It is possible to explicitly list directories to include using `LD_LIBRARY_PATH` environment variable. I tried setting the `LD_LIBRARY_PATH` to point to the required directory and then run cargo as `LD_LIBRARY_PATH=DIR cargo build -v`. But it gave the same error.

I thought that `cargo` must be setting the linker value somewhere, so instead let me try directly compiling with `rustc`. Even that gave the same error. With this, I eliminated the possibility of some environment variable only affecting `cargo`.


### More googling!

Further searching for the error with "rust" added showed me results of people having trouble cross-compiling. From this, I learned that cargo has different targets i.e different instruction sets (e,g x86-64, arm, x86, mips), different OSs (e.g linux, windows, freebsd) and different C runtimes (e.g glibc, musl, msvc). The Rust documentation on cargo mentioned that this is called a target triple. The [**Cargo book**](https://doc.rust-lang.org/cargo/reference/) mentioned that you can direct cargo to explicitly use a particular linker using RUSTFLAGS environment variable.

Since I am only building for my machine, I had to find out the exact value of the target. Rust gives an exhaustive list of all supported targets by running `rustc --print target-list`. My target was `x86_64-unknown-linux-gnu`.

It is possible to pass a linker to `cargo` explicitly as `RUSTFLAGS="-C linker=x86_64-unknown-linux-gnu" cargo build -v`. It worked!

### All-time fix!

I do not want to do this every time I run `cargo`. The Cargo book says that cargo uses a global config file in `$HOME/.cargo/config`.

I added the following to the file:
```toml
# Specify which linker to use for this target
[target.x86_64-unknown-linux-gnu]
linker = "x86_64-linux-gnu-gcc"
```
Now, `cargo build` works without issues.