Static Linkage

Let's do the same thing, but statically linked. It's a lot easier.

This makes some UNIX people grumpy. Every binary has a copy of its dependencies when you statically link. So you're using more disk space, you can't update a single file and fix all the binaries that use it (useful for security). On the other hand, your binary is self-contained, no more LD_LIBRARY fights and it fits better with the Rust way. So be prepared to be flexible!

In your Cargo.toml, change the crate-type:

[lib]
crate-type = ["staticlib"] # Will create .a on Linux & Mac, .lib on Windows

Now when you build, you produce a .a file (or a .lib on Windows, which likes to be special).

Now you can simplify your build_linux.sh script:

#!/bin/bash
# Constrain the build location
CARGO_TARGET_DIR="tmp" cargo build
# You need the .a file now
cp tmp/debug/libex03a_rust_from_c_static.a .
# Cleaning up makes people happy
CARGO_TARGET_DIR="tmp" cargo clean
# Include the .a like any other C .a file in your build command
cc rust_from_c.c -o rust_from_c_static libex03a_rust_from_c_static.a
# Runs with no linkage magic
./rust_from_c_static

Size

Your statically linked rust_from_c_static binary is 4.5 Megabytes. Your dynamically linked rust_from_c is 16kb (with a 3.7 mb dynamic library in tow). We're not doing any sort of optimization, but that's why the UNIX people worry.

The original PDP-11 maxed out at 4Mb of RAM. The PDP-7 that ran a mini-UNIX had a maximum of 8kb!