How to build a 32bit static binary with Rust? - rust

Using Creating a basic webservice in Rust and Taking Rust everywhere with rustup as documentation, I have managed to successfully compile a 64 bit static binary with Rust:
rustup target add x86_64-unknown-linux-musl
cargo build --target=x86_64-unknown-linux-musl
But I can't seem to find out how to build a 32bit static binary.
I did find a i686-unknown-linux-musl target when running rustc --print target-list, only to find out it is not available when running rustup target list.
Am I missing something something or it is not possible yet?

The std binaries for i686-unknown-linux-musl is only available on Rust 1.10 or newer. You can create a static binary for i686 with the following commands:
$ rustup default stable # stable must at least 1.10
$ rustup target add i686-unknown-linux-musl
$ cargo build --target i686-unknown-linux-musl
The generated binaries can be found on target/i686-unknown-linux-musl/debug/ or target/i686-unknown-linux-musl/release/.
We can check that the generated binary is static linked with ldd:
$ ldd target/i686-unknown-linux-musl/debug/main
not a dynamic executable

Related

Default cargo output directory for binaries

I downloaded a Rust project and built it with cargo build. I have not configured Rust beforehand. Where can I find the output binaries?
They'll be under target/debug or target/release depending on which configuration you built - if the command was just cargo build, then target/debug.

How is it possible to use a nightly rustc compiler in buildroot

rustc and cargo are supported in buildroot. But even the latest buildroot master uses rust version 1.33.0 stable I think.
How can I use the a nightly version of rust in buildroot?
Update: This patch http://lists.busybox.net/pipermail/buildroot/2016-April/159523.html introduces rust in buildroot. And this buildroot repo https://github.com/elebihan/buildroot/tree/feature/rust-1.33.0 has some latest rustc version.
This is for a QEMU ARM Vexpress, but I think it will get you where you are going:
Using Rust with Buildroot (full build)
You can skip up to the pushd command to the downloaded nightly rust source. Instead of doing all that, just use the location of the code you got when you run rustup install nightly (or however else you're installing the nightly snapshot`).
I hope that helps.
If the build commands don't need to be changed, you can just download the source to some directory and add RUST_OVERRIDE_SRCDIR=<path to rust source> in your local.mk. See the Buildroot manual.

What is the difference between binaries in ~/.rustup vs ~/.cargo?

I just installed Rust with rustup on MacOS and noticed that there are two rustc and two cargo binaries:
~/.cargo/bin/rustc (cargo)
~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/rustc (cargo)
Their versions are exactly the same, but diff shows there exists some difference. So why are there two different rustc (cargo) binaries and which one should I use?
The reason there are two files named rustc is because rustup is a toolchain multiplexer. It lets you install many versions of Rust and easily switch between them.
The binary installed at ~/.cargo/bin/rustc proxies to the current toolchain that you have selected. Each installed compiler is kept under the toolchains directory.
Although the compiler in the toolchains directory appears to be a smaller file, that's only because it's dynamically linked instead of statically linked.
More information can be found on rustup's README.

How to solve librustdoc.so missing when using rustbook tool?

I've used
cargo install --git https://github.com/steveklabnik/rustbook.git
to install rustbook successfully, but when I run rustbook I get an error:
rustbook: error while loading shared libraries: librustdoc-c0dcaea09a16c7ec.so: cannot open shared object file: No such file or directory
But I can find out this .so file.
./.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustdoc-c0dcaea09a16c7ec.so
./.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustdoc-c0dcaea09a16c7ec.so
How can I let rustbook know the path to librustdoc-c0dcaea09a16c7ec.so?
rustc 1.16.0-nightly (4ecc85beb 2016-12-28)
rustdoc 1.16.0-nightly (4ecc85beb 2016-12-28)
rustup show:
Default host: x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.16.0-nightly (4ecc85beb 2016-12-28)
This appears to be a known issue with rustup (#350, #765), specifically around cargo-installed binaries that were compiled against the nightly toolchain. If your application requires nightly to even compile, there's not much you can do other than rustup run nightly myprogram. This will start the program with the appropriate environment.
If the application doesn't require nightly Rust, then install it using the stable toolchain.
List the directory containing your shared library into /etc/ld.so.conf, or make a symlink from a path already listed there, or from /usr/lib (/usr/local/lib would be preferable, but maybe you have to add it to the list in ld.so.conf, so this would be again case 1).

Adding codegen flags to a Cargo build

On Macintosh, to allow some symbols to go unlinked, it is necessary to pass -C link-args='-Wl,-undefined,dynamic_lookup' to the Rust compiler. One needs to do this when building Postgres plugins, because some of the Postgres intrinsics are only compiled into the Postgres server, and not available for linking from shared libs.
At present, the project's process is as follows:
Build is run with cargo build -v.
Failing call to rustc is copied and -C link-args='-Wl,-undefined,dynamic_lookup' added to it.
Success!
This seems like a hard sell for automation. What options are available for adding codegen flags to Rust builds through cargo?
cargo provides rustc command which allows one to pass arbitrary compiler flags. The following should do it:
% cargo rustc -- -C link-args='-Wl,-undefined,dynamic_lookup'

Resources