Original address: medium.com/flutter-com…

The original author: atsigncompany.medium.com/

Published: May 10, 2021-4 minutes to read

Chris Swan is an engineer at The @Company

Last week, I wrote about the automation of building multi-architecture Docker images using GitHub Actions. Which brings me to another question — how do you create binaries for these builds? If I am making an Arm image, I need an Arm binary file to put in the image.

Currently, Dart Compile only compiles separate executables for the architecture it runs on. This is a shame, because the underlying tools are perfectly capable of cross-compiling, as J-P Nurmi explains in the cross-compiling Dart application.

Without cross-compilation, the only option is to run Dart Compile for the Dart SDK on each target platform. Google packaged the SDK as a Docker mirror Google/DART, but unfortunately this only works with X86_64 (aka AMD64). The Docker file for this image also uses the SDK APT package, but it also only works with X86_64.

So in order to run DART compilation on multiple schemas, I first needed a multi-schema build image.

FROM debian:stable
ARG DART_VERSION="2.12.4"
WORKDIR /tmp/
RUN \
  apt-get -q update && apt-get install --no-install-recommends -y -q \
    gnupg2 curl git ca-certificates unzip openssh-client && \
  case "$(uname -m)" in armv7l | armv7) ARCH="arm";; aarch64) ARCH="arm64";; *) ARCH="x64";; esac && \
  curl -O https://storage.googleapis.com/dart-archive/channels/stable/release/$DART_VERSION/sdk/dartsdk-linux-$ARCH-release.zip && \
  unzip dartsdk-linux-$ARCH-release.zip -d /usr/lib/ && \
  rm dartsdk-linux-$ARCH-release.zip && \
  mv /usr/lib/dart-sdk /usr/lib/dart
ENV DART_SDK /usr/lib/dart
ENV PATH $DART_SDK/bin:/root/.pub-cache/bin:$PATH
Copy the code

This is to install some key dependencies (the same as Google/DART), then download and install the DART SDK based on the output from uname -m to set up the underlying architecture. With a build image, you can create a lightweight running image based on the work of Google engineer Tony Pujals’ Subfuzion/Dart-Docker-Slim.

# Originally based on subfuzion/dart-docker-slim
# Using our buildimage as it supports x64|arm|arm64
FROM atsigncompany/buildimage AS dart
# Do all the copying to an output dir here first
# as the buildimage has a shell that can be used
# for multi-arch conditionals
RUN \
  mkdir -p /output/lib && mkdir -p /output/etc && \
  mkdir -p /output/etc/ssl/certs && \
  mkdir -p /output/usr/share/ca-certificates && \
  case "$(uname -m)" in \
   armv7l | armv7) ARCH="arm-linux-gnueabihf" ; \
    mkdir -p /output/lib/$ARCH ; \
    cp /lib/ld-linux-armhf.so.3 /output/lib/ld-linux-armhf.so.3 ; \
    cp /lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 \
       /output/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 ;; \
   aarch64) ARCH="aarch64-linux-gnu" ; \
    mkdir -p /output/lib/$ARCH ; \
    cp /lib/ld-linux-aarch64.so.1 /output/lib/ld-linux-aarch64.so.1 ; \
    cp /lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 \
       /output/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 ;; \
   *) ARCH="x86_64-linux-gnu" ; \
    mkdir -p /output/lib/$ARCH ; mkdir -p /output/lib64/ ; \
    cp /lib64/ld-linux-x86-64.so.2 /output/lib64/ld-linux-x86-64.so.2 ;; \
  esac && \
  cp /lib/$ARCH/libdl.so.2 /output/lib/$ARCH/libdl.so.2 && \
  cp /lib/$ARCH/libc.so.6 /output/lib/$ARCH/libc.so.6 && \
  cp /lib/$ARCH/libm.so.6 /output/lib/$ARCH/libm.so.6 && \
  cp /lib/$ARCH/librt.so.1 /output/lib/$ARCH/librt.so.1 && \
  cp /lib/$ARCH/libpthread.so.0 /output/lib/$ARCH/libpthread.so.0 && \
  cp /lib/$ARCH/libnss_dns.so.2 /output/lib/$ARCH/libnss_dns.so.2 && \
  cp /lib/$ARCH/libresolv.so.2 /output/lib/$ARCH/libresolv.so.2 && \ cp /etc/nsswitch.conf /output/etc/nsswitch.conf && \ cp /etc/resolv.conf /output/etc/resolv.conf &&  \ cp -R /usr/share/ca-certificates /output/usr/share/ca-certificates && \ cp -R /etc/ssl/certs /output/etc/ssl/certs
FROM scratch
COPY --from=dart /output /
# Is this even really needed, as Docker uses host hosts?
COPY ./at-runimage/etc-hosts /etc/hosts
Copy the code

This also uses the output of uname -m to determine the correct dependencies copied from the build image.

Then, building and running the image can be combined with the Dart application. I made a trivial dartshowplatform, printed publications and platform information.

$sudo docker run - it atsigncompany/dartshowplatform 2.12.4 (stable) (Thu Apr 15 12:26:53 2021 + 0200) on"linux_arm64"
Copy the code

Here is the Docker file.

FROM atsigncompany/buildimage
WORKDIR /app
COPY ./dartshowplatform/showplatform.dart .
RUN dart compile exe /app/showplatform.dart -o /app/dartshowplatform
FROM atsigncompany/runimage
COPY --from=0 /app/dartshowplatform /app/dartshowplatform
ENTRYPOINT ["/app/dartshowplatform"]
Copy the code

The build image is used to run the DART compilation and then copy the binaries it creates into the run image.

The full source code for the above content can be found at GitHub atsign-Company /at_dockerfiles.

If you’re wondering why we’re doing this, it’s because people are asking us to support Arm and Arm64 because, as mentioned above, the Arm footprint has grown tremendously. We can expect that before long we will also have to add support for RISC-V as the Instruction set Architecture (ISA) gains traction and wider adoption. The days of WinTel hegemony are over, and that means dealing with more heterogeneity, which requires more automation to avoid being overwhelmed by the complexity of it all.


The @Company is a tech startup dedicated to changing The way The modern Internet treats people’s data. To learn more about The @Company and their mission, check out their website.

Focus on Twitter on Flutter community: www.twitter.com/FlutterComm


Translation via www.DeepL.com/Translator (free version)