cross-rs / cross

“Zero setup” cross compilation and “cross testing” of Rust crates
Apache License 2.0
6.76k stars 378 forks source link

Building aarch64 image fails due to gfortran not being available #1518

Open astapleton opened 4 months ago

astapleton commented 4 months ago

Checklist

Describe your issue

Building the aarch64 Docker image on Mac M1/M2 fails due to a missing package error for gfortran. ie. running this:

docker build -f Dockerfile.aarch64-unknown-linux-gnu -t ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main https://github.com/cross-rs/cross.git#main:docker

results in this error:

Unable to locate package gfortran-aarch64-linux-gnu

which then fails the image creation.

It seems like this was introduced in this commit: https://github.com/cross-rs/cross/commit/6ab0e7cfc8fd45e6947b0c2768c041ad4ba0c528

I also reproduced this on an x86_64 Windows host when specifying --platform linux/arm64 during the build step.

What target(s) are you cross-compiling for?

No response

Which operating system is the host (e.g computer cross is on) running?

What architecture is the host?

What container engine is cross using?

cross version

cross 0.2.5

Example

docker build -f Dockerfile.aarch64-unknown-linux-gnu -t ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main https://github.com/cross-rs/cross.git#main:docker

Additional information / notes

Building with an older commit works:

docker build -f Dockerfile.aarch64-unknown-linux-gnu -t ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main https://github.com/cross-rs/cross.git#c87a52a60dbcde069714a8d2ed51570e7fc23cf9:docker
wenxb commented 2 months ago

Seems to be installing gfortran

astapleton commented 2 months ago

Still fails for me:

2.843 E: Unable to locate package gfortran-aarch64-linux-gnu
------
Dockerfile.aarch64-unknown-linux-gnu:15
--------------------
  14 |
  15 | >>> RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
  16 | >>>     g++-aarch64-linux-gnu \
  17 | >>>     gfortran-aarch64-linux-gnu \
  18 | >>>     libc6-dev-arm64-cross
  19 |
--------------------
ERROR: failed to solve: process "/bin/sh -c apt-get update && apt-get install --assume-yes --no-install-recommends     g++-aarch64-linux-gnu     gfortran-aarch64-linux-gnu     libc6-dev-arm64-cross" did not complete successfully: exit code: 100
wenxb commented 2 months ago

Still fails for me:

2.843 E: Unable to locate package gfortran-aarch64-linux-gnu
------
Dockerfile.aarch64-unknown-linux-gnu:15
--------------------
  14 |
  15 | >>> RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
  16 | >>>     g++-aarch64-linux-gnu \
  17 | >>>     gfortran-aarch64-linux-gnu \
  18 | >>>     libc6-dev-arm64-cross
  19 |
--------------------
ERROR: failed to solve: process "/bin/sh -c apt-get update && apt-get install --assume-yes --no-install-recommends     g++-aarch64-linux-gnu     gfortran-aarch64-linux-gnu     libc6-dev-arm64-cross" did not complete successfully: exit code: 100

I solved it by swapping 'gfortran-aarch64-linux-gnu' for 'gfortran'. You need to modify one of the sh files, which I can't remember, and then build a new custom image.

Emilgardis commented 2 months ago

Please use our tool for building the docker images, cargo build-docker-image, you should use Dockerfile.native, not Dockerfile.aarch64-unknown-linux-gnu

astapleton commented 2 months ago

Please use our tool for building the docker images, cargo build-docker-image, you should use Dockerfile.native, not Dockerfile.aarch64-unknown-linux-gnu

How does one use it? I don't see any documentation anywhere for it. When I invoke it without arguments it builds images for targets I don't want. And when I build with the aarch64-unknown-linux-gnu target, it starts building an image for x86_64-unknown-linux-gnu:

$ cargo build-docker-image aarch64-unknown-linux-gnu
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/xtask build-docker-image aarch64-unknown-linux-gnu`
[cross] note: Build aarch64-unknown-linux-gnu for x86_64-unknown-linux-gnu
Emilgardis commented 2 months ago

"aarch64-unknown-linux-gnu for x86_64-unknown-linux-gnu" means that we build a image for the aarch64-unknown-linux-gnu target with a platform of amd64, the current default. If you want to make the image for the arm64 platform you'll need to set the --platform parameter. The docs for that tool is in its --help output.

When the image platform=target we always use Dockerfile.native, this is because on aarch64 there are no cross tools to compile to aarch64, because its not a cross tool, its just the tool itself

astapleton commented 2 months ago

I tried building with cargo build-docker-image aarch64-unknown-linux-gnu --platform aarch64-unknown-linux-gnu but that errored out. I'm not sure if that platform argument is correct as the help documentation does not specify any details for the --platform argument:

      --build-arg <BUILD_ARG>
          Additional build arguments to pass to Docker

  -a, --platform <PLATFORM>

  -h, --help
          Print help (see a summary with '-h')

The build ends in these logs:

44.77 C compiler for the host machine: cc (gcc 9.4.0 "cc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0")
44.77 C linker for the host machine: cc ld.bfd 2.34
44.77 Host machine cpu family: aarch64
44.77 Host machine cpu: aarch64
44.77 Found pkg-config: /usr/bin/pkg-config (0.29.1)
44.77 Run-time dependency glib-2.0 found: YES 2.64.6
44.77 Configuring libslirp-version.h using configuration
44.77 Build targets in project: 1
44.77
44.77 Found ninja-1.10.0 at /usr/bin/ninja
44.78 ++ ninja -C build
44.78 ninja: Entering directory `build'
44.84 [1/32] Compiling C object 'slirp@sta/src_arp_table.c.o'.
44.84 [2/32] Compiling C object 'slirp@sta/src_if.c.o'.
44.84 [3/32] Compiling C object 'slirp@sta/src_ip_input.c.o'.
44.84 [4/32] Compiling C object 'slirp@sta/src_ip_output.c.o'.
44.84 [5/32] Compiling C object 'slirp@sta/src_cksum.c.o'.
44.85 [6/32] Compiling C object 'slirp@sta/src_dhcpv6.c.o'.
44.85 [7/32] Compiling C object 'slirp@sta/src_dnssearch.c.o'.
44.85 [8/32] Compiling C object 'slirp@sta/src_ip6_output.c.o'.
44.86 [9/32] Compiling C object 'slirp@sta/src_bootp.c.o'.
44.86 [10/32] Compiling C object 'slirp@sta/src_ip6_input.c.o'.
44.87 [11/32] Compiling C object 'slirp@sta/src_mbuf.c.o'.
44.87 [12/32] Compiling C object 'slirp@sta/src_ip_icmp.c.o'.
44.87 [13/32] Compiling C object 'slirp@sta/src_misc.c.o'.
44.89 [14/32] Compiling C object 'slirp@sta/src_ip6_icmp.c.o'.
44.89 [15/32] Compiling C object 'slirp@sta/src_ndp_table.c.o'.
44.90 [16/32] Compiling C object 'slirp@sta/src_sbuf.c.o'.
44.90 [17/32] Compiling C object 'slirp@sta/src_stream.c.o'.
44.91 [18/32] Compiling C object 'slirp@sta/src_state.c.o'.
44.92 [19/32] Compiling C object 'slirp@sta/src_slirp.c.o'.
44.93 [20/32] Compiling C object 'slirp@sta/src_ncsi.c.o'.
44.93 [21/32] Compiling C object 'slirp@sta/src_tftp.c.o'.
44.94 [22/32] Compiling C object 'slirp@sta/src_tcp_input.c.o'.
44.94 [23/32] Compiling C object 'slirp@sta/src_version.c.o'.
44.94 [24/32] Compiling C object 'slirp@sta/src_tcp_timer.c.o'.
44.95 [25/32] Compiling C object 'slirp@sta/src_socket.c.o'.
44.95 [26/32] Compiling C object 'slirp@sta/src_util.c.o'.
44.95 [27/32] Compiling C object 'slirp@sta/src_udp.c.o'.
44.95 [28/32] Compiling C object 'slirp@sta/src_tcp_output.c.o'.
44.95 [29/32] Compiling C object 'slirp@sta/src_udp6.c.o'.
44.96 [30/32] Compiling C object 'slirp@sta/src_vmstate.c.o'.
44.96 [31/32] Compiling C object 'slirp@sta/src_tcp_subr.c.o'.
44.97 [32/32] Linking static target libslirp.a.
44.97 ++ install -m 644 ./build/libslirp.a /usr/lib64/
44.97 install: target '/usr/lib64/' is not a directory: No such file or directory
------
Dockerfile.native:21
--------------------
  19 |
  20 |     COPY qemu.sh native-qemu.sh /
  21 | >>> RUN /native-qemu.sh
  22 |
  23 |     COPY dropbear.sh /
--------------------
ERROR: failed to solve: process "/bin/sh -c /native-qemu.sh" did not complete successfully: exit code: 1
Error:
   0: some error(s) encountered

Location:
   xtask/src/build_docker_image.rs:347

Error:

      0: `docker buildx build --platform linux/arm64 --build-arg 'CROSS_TARGET_TRIPLE=AARCH64_UNKNOWN_LINUX_GNU' --load --pull --cache-from 'type=registry,ref=ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main' --tag ghcr.io/cross-rs/aarch64-unknown-linux-gnu:local --label 'org.cross-rs.for-cross-target=aarch64-unknown-linux-gnu' --label 'org.cross-rs.runs-with=aarch64-unknown-linux-gnu' --file /Users/andrew/development/cross/docker/Dockerfile.native --progress auto .` failed with exit status: 1

   Location:
      xtask/src/build_docker_image.rs:310

   Warning: call to docker failed
   Suggestion: is `buildx` available for the container engine?
   Note: disable the `buildkit` dependency optionally with `CROSS_CONTAINER_ENGINE_NO_BUILDKIT=1`

I also tried following the suggestion here with CROSS_CONTAINER_ENGINE_NO_BUILDKIT=1 but that failed in the same way.

Emilgardis commented 2 months ago

That's annoying, the problem is this line (and others of similar nature): https://github.com/cross-rs/cross/blob/d8631fe4f4e8bb4c4b24417a35544857fb42ee22/docker/qemu.sh#L128 Which I guess should be another path on aarch64, I'll look into this eventually but if you can investigate it some more on your own I'd appreciate it.

I'm fairly sure this used to work though so I'm curious

The reason --platform doesn't have docs is because we accidentally made the doc comments into regular comments 😅 https://github.com/cross-rs/cross/blob/d8631fe4f4e8bb4c4b24417a35544857fb42ee22/xtask/src/build_docker_image.rs#L77