rust-lang / docker-rust

The official Docker images for Rust
436 stars 88 forks source link

Add musl-dev to alpine images #68

Closed mamins1376 closed 3 years ago

mamins1376 commented 3 years ago

Currently when building something that involves compiling C (bat as an example), at the linking stage the following happens, due to missing /usr/lib/crti.o:

   ...
   Compiling clap v2.33.3
   Compiling chrono v0.4.19
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" ...  "-Wl,-Bdynamic" "-lgcc_s" "-lc"
  = note: /usr/lib/gcc/x86_64-alpine-linux-musl/9.3.0/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find crti.o: No such file or directory
          collect2: error: ld returned 1 exit status

error: aborting due to previous error

This can be eliminated simply by adding musl-dev after RUN apk add ....

sfackler commented 3 years ago

The official alpine images tend to be as small as possible - take go's for example: https://hub.docker.com/_/golang which doesn't even include gcc.

mamins1376 commented 3 years ago

What's the point of including gcc when there are not even std headers? Is it a common scenario to compile no_std-equivalent C/C++ code?

sfackler commented 3 years ago

rustc uses gcc as its linker.

mamins1376 commented 3 years ago

Ok, got it. I guess RUN apk add --no-cache musl-dev should always be the first line of some Dockerfiles. Not a big deal though, the trade-off seems appropriate. Thanks for your response.

wrenix commented 1 year ago

Why is that not default in the rust-alpine container preinstalled?

polarathene commented 9 months ago

Given the discussion at https://github.com/rust-lang/compiler-team/issues/422

Should that change land, the user will fail to build a simple "hello world" program when dynamic linking becomes default with musl targets.

They'd either need to know to specify -C link-self-contained=yes as a rust flag for cargo (additionally with -C target-feature=+crt-static if they want to get static builds back), or to install musl-dev in the container.

Documenting that on DockerHub would be the better route if the alpine image is meant to prioritize size over UX (less of an issue until the image toolchain defaults to dynamic linking), but only if the size increase was notable..


musl-dev adds 11MB uncompressed to the existing 825MB image (1.33% image weight increase)

FROM rust:alpine
RUN apk add --no-cache musl-dev
$ docker build -t rust-musl-dev .

# Barely an increase:
$ docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
rust-musl-dev         latest    0ae623d62975   7 seconds ago   836MB
rust                  alpine    5d20fa327476   2 days ago      825MB
rust                  latest    890a6b209e1c   2 weeks ago     1.5GB
golang                alpine    bb520cee46ae   11 days ago     222MB
golang                latest    4c88d2e04e7d   11 days ago     815MB

$ docker image history rust-musl-dev
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
0ae623d62975   2 minutes ago   RUN /bin/sh -c apk add --no-cache musl-dev #…   10.3MB    buildkit.dockerfile.v0
<missing>      2 days ago      /bin/sh -c set -eux;     apkArch="$(apk --pr…   680MB
<missing>      2 days ago      /bin/sh -c #(nop)  ENV RUSTUP_HOME=/usr/loca…   0B
<missing>      4 weeks ago     /bin/sh -c apk add --no-cache         ca-cer…   138MB
<missing>      7 weeks ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      7 weeks ago     /bin/sh -c #(nop) ADD file:756183bba9c7f4593…   7.34MB

Here are those two layers 680MB + 138MB (via dive):

image

image

The small addition of musl-dev for improved UX:

image

We're looking at a modest 1.33% increase in image weight, not a deal breaker.