Search code examples
mysqlrustrust-diesel

Why rustc did not include libmariadb into release binary?


I thought rust compiler uses static binding and includes all the dependent libraries at compile time (hence executable size).

But when I've tried to use compiled binary in a docker scratch image with actix, mysql client and diesel with mysql feature enabled this error pops up:

error while loading shared libraries: libmariadb.so.3: cannot open shared object file: No such file or director

My dockerfile:

FROM rust:1.43 as builder
WORKDIR /var/app

RUN apt-get update && apt-get install -y libclang-dev clang libmariadb-dev-compat libmariadb-dev

COPY Cargo.toml Cargo.lock diesel.toml ./
COPY src src

RUN cargo install diesel_cli --no-default-features --features mysql
RUN cp /usr/local/cargo/bin/diesel diesel
RUN cargo build --release

FROM ubuntu
USER 1000
WORKDIR /var/app

COPY --from=builder --chown=1000:1000 /var/app/target/release/sniper_api app
COPY --from=builder --chown=1000:1000 /var/app/diesel diesel

CMD ["./app"]

My cargo:

[dependencies]
actix-rt = "1.0.0"
actix-web = "2.0.0"
actix-http = "1.0.1"
serde = { version = "1.0.112", features=["derive"] }
dotenv = "0.15.0"
config = "0.10.1"
diesel = { version = "1.4.2", features = ["mysql","r2d2"]}
futures = "0.3.5"
r2d2 = "0.8.8"
r2d2_mysql = "18.0.0"
env_logger = "0.7.1"

But if I use ubuntu/debian/etc. image as runtime and install libmariadb-dev-compat libmariadb-dev everything is fine. Is there a way to get true single binary with mysql connector in Rust?


Solution

  • I thought rust compiler uses static binding and includes all the dependent libraries at compile time (hence executable size).

    This only applies for Rust libraries. For other languages, there is generally little rustc can do.

    In particular in this case, diesel provides mysql/mariadb support via the mysqlclient-sys crate for which there currently is an issue and an accompanying PR open to support static linking for this library. But they haven't been merged yet.