emk / rust-musl-builder

Docker images for compiling static Rust binaries using musl-libc and musl-gcc, with static versions of useful C libraries. Supports openssl and diesel crates.
Apache License 2.0
1.54k stars 193 forks source link

How do you statically link libraries? #51

Closed Gisleburt closed 6 years ago

Gisleburt commented 6 years ago

I'm using a multi build docker file to try to create a docker image with nothing but the binary in it. Unfortunately I'm left with a large number of dynamic links.

Dockerfile:

#########
# Build #
#########
FROM ekidd/rust-musl-builder AS builder

RUN sudo apt-get update \
 && sudo apt-get install -y \
    libmysqlclient-dev

WORKDIR /build

RUN sudo chown rust:rust .

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

RUN cargo build --release

##############
# Executable #
##############
FROM scratch

WORKDIR /app

COPY --from=builder /build/target/x86_64-unknown-linux-musl/release/webserver webserver

EXPOSE 8080

CMD ["/app/webserver"]

However, if I test the binary after building:

$ ldd target/x86_64-unknown-linux-musl/release/webserver
        linux-vdso.so.1 =>  (0x00007fff33df6000)
        libmysqlclient.so.20 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 (0x00007f41a7252000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f41a7038000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f41a6e34000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f41a6c17000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f41a6895000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f41a658c000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f41a6376000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f41a5fac000)
        /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f41a7861000)

I feel like others must have gone through this but I can't find any sort of guide written down anywhere (my google foo is bad though so 🤷🏻‍♂️).

I feel esspecially silly as I think I was able to do this about nine months ago (with very basic apps at least). 😊

Is there a process I can go through to manage static linking? Perhaps a step by step guide?

Gisleburt commented 6 years ago

My current work around for this is to build an image with dynamic links. I'm lead to believe that there are no repo'd versions of the static links and I'd have to compile them by hand.

It would still be good to know where one can learn a bit more about this process, how to find static libraries, how to build them when they don't exist, if anyone has some thoughts on it to share.

emk commented 6 years ago

Please see my response at https://github.com/emk/rust-musl-builder/issues/52, which links to the section of the README explaining how to do this.

Getting C libraries to link statically almost always requires a bit of experimentation. I already supply several major C libraries in the existing image, and every one of them required a fair bit of work. :-/ I wish I had a better answer.

Gisleburt commented 6 years ago

I think the main problem (unless I'm missing something) is that Oracle don't seem to provide the mysql-connector-c static libraries. I've found C++ source and can build it but that doesn't seem to want to link. They also provide a blob of everything but I don't know how to build it 🙄. I'm going to give up for now, if I ever work it out, I'll come back and let you know.