diff --git a/.github/buildkit.toml b/.github/buildkit.toml new file mode 100644 index 00000000..ff6039f1 --- /dev/null +++ b/.github/buildkit.toml @@ -0,0 +1,2 @@ +[worker.oci] + max-parallelism = 4 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9f83464..d45bfcd7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,6 +74,8 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 + with: + config: .github/buildkit.toml - name: Test if: matrix.target == 'buildkit' diff --git a/Dockerfile b/Dockerfile index cfebc56a..2394b941 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,85 +1,52 @@ # syntax=docker/dockerfile:1.2 +ARG ALPINE_BASE=alpine:3.14 + ARG QEMU_VERSION ARG QEMU_REPO=https://github.com/qemu/qemu -FROM --platform=$BUILDPLATFORM debian:buster AS src -RUN apt-get update && apt-get install -y git +# xx is a helper for cross-compilation +FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:56b19a5fb89b99195ec494d59ad34370d14540858c1f56c560ec1e7f2d1c177f AS xx + +FROM --platform=$BUILDPLATFORM ${ALPINE_BASE} AS src +RUN apk add --no-cache git patch ARG QEMU_VERSION ARG QEMU_REPO WORKDIR /src RUN git clone $QEMU_REPO && \ + git clone --depth 1 -b 3.14-stable https://github.com/alpinelinux/aports.git && \ cd qemu && \ git checkout $QEMU_VERSION && \ + for f in ../aports/community/qemu/*.patch; do patch -p1 < $f; done && \ scripts/git-submodule.sh update \ ui/keycodemapdb \ tests/fp/berkeley-testfloat-3 \ tests/fp/berkeley-softfloat-3 \ dtc slirp -FROM --platform=$BUILDPLATFORM debian:buster AS qemu - -RUN apt-get update && \ - apt-get install -y \ - dpkg-dev \ - git \ - ninja-build \ - pkg-config \ - python3 \ - python3-setuptools - -WORKDIR /qemu - -ARG TARGETPLATFORM - -ENV PATH=/qemu/install-scripts:$PATH -RUN --mount=target=./install-scripts,src=scripts \ - TARGETPLATFORM=${TARGETPLATFORM} cross.sh install gcc libglib2.0-dev | sh - -FROM qemu AS base-amd64 -FROM qemu AS base-arm64 -FROM qemu AS base-ppc64le -FROM qemu AS base-s390x -FROM qemu AS base-armv7 -FROM qemu AS base-armv6 -FROM qemu AS base-386 -FROM qemu AS base-mips64le - -FROM tonistiigi/debian:riscv AS riscv-libglibc -RUN apt-get update && apt-get install -y libglib2.0-dev - -RUN for f in $(dpkg-query -L zlib1g-dev libglib2.0-dev libpcre3-dev libglib2.0-0 libpcre3); do [ ! -d $f ] && echo $f; done > /tmp/list -RUN mkdir -p /out && tar cvf /out/libglibc.tar -T /tmp/list - -FROM tonistiigi/xx:riscv-toolchain AS base-riscv64 -RUN apt-get update && \ - apt-get install -y \ - dpkg-dev \ - git \ - ninja-build \ - pkg-config \ - python3 \ - python3-setuptools +FROM --platform=$BUILDPLATFORM ${ALPINE_BASE} AS base +RUN apk add --no-cache git clang lld python3 llvm make ninja pkgconfig glib-dev gcc musl-dev perl bash +COPY --from=xx / / ENV PATH=/qemu/install-scripts:$PATH WORKDIR /qemu -RUN --mount=from=riscv-libglibc,target=/riscv-libglibc,src=out \ - mkdir -p /tmp/out && tar xvf /riscv-libglibc/libglibc.tar -C /tmp/out && \ - cp -a /tmp/out/usr/include/* /usr/riscv64-linux-gnu/include/ && \ - cp -a /tmp/out/usr/lib/riscv64-linux-gnu/* /usr/riscv64-linux-gnu/lib/ && \ - cp -a /tmp/out/usr/lib/* /usr/riscv64-linux-gnu/lib/ && \ - ln -s /usr/riscv64-linux-gnu /usr/riscv64-buildroot-linux-gnu -ENV CROSS_PREFIX=riscv64-buildroot-linux-gnu +ARG TARGETPLATFORM +RUN xx-apk add musl-dev gcc glib-dev glib-static linux-headers zlib-static +RUN set -e; \ + [ "$(xx-info arch)" = "ppc64le" ] && XX_CC_PREFER_LINKER=ld xx-clang --setup-target-triple; \ + [ "$(xx-info arch)" = "386" ] && XX_CC_PREFER_LINKER=ld xx-clang --setup-target-triple; \ + true -FROM base-$TARGETARCH$TARGETVARIANT AS base FROM base AS build ARG TARGETPLATFORM -ARG QEMU_VERSION +ARG QEMU_VERSION QEMU_TARGETS +ENV AR=llvm-ar STRIP=llvm-strip RUN --mount=target=.,from=src,src=/src/qemu,rw --mount=target=./install-scripts,src=scripts \ TARGETPLATFORM=${TARGETPLATFORM} configure_qemu.sh && \ make -j "$(getconf _NPROCESSORS_ONLN)" && \ - make install + make install && \ + cd /usr/bin && for f in $(ls qemu-*); do xx-verify $f; done ARG BINARY_PREFIX RUN cd /usr/bin; [ -z "$BINARY_PREFIX" ] || for f in $(ls qemu-*); do ln -s $f $BINARY_PREFIX$f; done @@ -88,18 +55,18 @@ FROM build AS build-archive RUN cd /usr/bin && mkdir -p /archive && \ tar czvfh "/archive/${BINARY_PREFIX}qemu_${QEMU_VERSION}_$(echo $TARGETPLATFORM | sed 's/\//-/g').tar.gz" ${BINARY_PREFIX}qemu* -FROM --platform=$BUILDPLATFORM tonistiigi/xx:golang@sha256:6f7d999551dd471b58f70716754290495690efa8421e0a1fcf18eb11d0c0a537 AS xgo FROM --platform=$BUILDPLATFORM golang:1.16-alpine AS binfmt -COPY --from=xgo / / +COPY --from=xx / / ENV CGO_ENABLED=0 ARG TARGETPLATFORM ARG QEMU_VERSION WORKDIR /src RUN apk add --no-cache git RUN --mount=target=. \ - TARGETPLATFORM=$TARGETPLATFORM go build \ + TARGETPLATFORM=$TARGETPLATFORM xx-go build \ -ldflags "-X main.revision=$(git rev-parse --short HEAD) -X main.qemuVersion=${QEMU_VERSION}" \ - -o /go/bin/binfmt ./cmd/binfmt + -o /go/bin/binfmt ./cmd/binfmt && \ + xx-verify /go/bin/binfmt FROM scratch AS binaries ARG BINARY_PREFIX @@ -110,7 +77,7 @@ COPY --from=build-archive /archive/* / FROM --platform=$BUILDPLATFORM tonistiigi/bats-assert AS assert -FROM golang:alpine AS buildkit-test +FROM golang:1.16-alpine AS buildkit-test RUN apk add --no-cache bash bats WORKDIR /work COPY --from=assert . . diff --git a/docker-bake.hcl b/docker-bake.hcl index a44ff8d8..ce800a46 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -39,7 +39,6 @@ target "all-arch" { "linux/s390x", "linux/riscv64", "linux/386", - "linux/mips64le" ] } diff --git a/scripts/configure_qemu.sh b/scripts/configure_qemu.sh index 489c0359..39a8e609 100755 --- a/scripts/configure_qemu.sh +++ b/scripts/configure_qemu.sh @@ -3,17 +3,18 @@ set -e : ${QEMU_TARGETS=} -: ${FLAG_CROSS_PREFIX=} -arch="$(cross.sh arch)" -if [ "$arch" != "x86_64" ]; then +arch="$(xx-info arch)" + +if [ -z "$QEMU_TARGETS" ]; then +if [ "$arch" != "amd64" ]; then QEMU_TARGETS="$QEMU_TARGETS x86_64-linux-user" fi -if [ "$arch" != "aarch64" ]; then +if [ "$arch" != "arm64" ]; then QEMU_TARGETS="$QEMU_TARGETS aarch64-linux-user" fi -if [ "$arch" != "armv7l" ] && [ "$arch" != "armv6l" ] ; then +if [ "$arch" != "arm" ]; then QEMU_TARGETS="$QEMU_TARGETS arm-linux-user" fi if [ "$arch" != "riscv64" ]; then @@ -22,10 +23,10 @@ fi if [ "$arch" != "ppc64le" ]; then QEMU_TARGETS="$QEMU_TARGETS ppc64le-linux-user" fi -if [ "$arch" != "s390x" ] && [ "$arch" != "riscv64" ] ; then +if [ "$arch" != "s390x" ]; then QEMU_TARGETS="$QEMU_TARGETS s390x-linux-user" fi -if [ "$arch" != "i386" ] ; then +if [ "$arch" != "386" ] ; then QEMU_TARGETS="$QEMU_TARGETS i386-linux-user" fi if [ "$arch" != "mips64le" ] ; then @@ -34,9 +35,6 @@ fi if [ "$arch" != "mips64" ] ; then QEMU_TARGETS="$QEMU_TARGETS mips64-linux-user" fi - -if cross.sh is_cross; then - FLAG_CROSS_PREFIX="--cross-prefix=$(cross.sh cross-prefix)-" fi set -x @@ -67,4 +65,14 @@ set -x --disable-sdl \ --disable-spice \ --disable-tools \ - --disable-vte $FLAG_CROSS_PREFIX --target-list="$QEMU_TARGETS" + --disable-vte \ + --disable-werror \ + --disable-debug-info \ + --disable-glusterfs \ + --cross-prefix=$(xx-info)- \ + --host-cc=$(xx-clang --print-target-triple)-clang \ + --host=$(xx-clang --print-target-triple) \ + --build=$(TARGETPLATFORM= TARGETPAIR= xx-clang --print-target-triple) \ + --cc=$(xx-clang --print-target-triple)-clang \ + --extra-ldflags=-latomic \ + --target-list="$QEMU_TARGETS" diff --git a/scripts/cross.sh b/scripts/cross.sh deleted file mode 100755 index e470ef83..00000000 --- a/scripts/cross.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env sh - -: ${TARGETPLATFORM=} -: ${TARGETOS=} -: ${TARGETARCH=} -: ${TARGETVARIANT=} - -: ${OUT_ARCH=} -: ${DPKG_ARCH=} -: ${PKG_PREFIX=} -: ${CROSS_PREFIX=} - -if [ -n "$TARGETPLATFORM" ]; then - os="$(echo $TARGETPLATFORM | cut -d"/" -f1)" - arch="$(echo $TARGETPLATFORM | cut -d"/" -f2)" - if [ ! -z "$os" ] && [ ! -z "$arch" ]; then - export TARGETOS="$os" - export TARGETARCH="$arch" - if [ "$arch" = "arm" ]; then - case "$(echo $TARGETPLATFORM | cut -d"/" -f3)" in - "v5") - export TARGETVARIANT="5" - ;; - "v6") - export TARGETVARIANT="6" - ;; - *) - export TARGETVARIANT="7" - ;; - esac - fi - fi -fi - -case "$TARGETARCH" in -"amd64") - OUT_ARCH="x86_64" - DPKG_ARCH="amd64" - PKG_PREFIX="x86_64-linux-gnu" - ;; -"arm64") - OUT_ARCH="aarch64" - DPKG_ARCH="arm64" - PKG_PREFIX="aarch64-linux-gnu" - ;; -"arm") - OUT_ARCH="armv7l" - DPKG_ARCH="armhf" - PKG_PREFIX="arm-linux-gnueabihf" - if [ "$TARGETVARIANT" = "6" ]; then - OUT_ARCH="armv6l" - DPKG_ARCH="armel" - PKG_PREFIX="arm-linux-gnueabi" - fi - ;; -"riscv64") - OUT_ARCH="riscv64" - DPKG_ARCH="riscv64" - PKG_PREFIX="riscv64-linux-gnu" - ;; -"ppc64le") - OUT_ARCH="ppc64le" - DPKG_ARCH="ppc64el" - PKG_PREFIX="powerpc64le-linux-gnu" - ;; -"s390x") - OUT_ARCH="s390x" - DPKG_ARCH="s390x" - PKG_PREFIX="s390x-linux-gnu" - ;; -"386") - OUT_ARCH="i386" - DPKG_ARCH="i386" - PKG_PREFIX="i686-linux-gnu" - ;; -"mips64le") - OUT_ARCH="mips64le" - DPKG_ARCH="mips64el" - PKG_PREFIX="mips64el-linux-gnuabi64" - ;; -*) - OUT_ARCH="$(uname -m)" - DPKG_ARCH="$(dpkg --print-architecture)" -esac - -if [ -n "$CROSS_PREFIX" ]; then - PKG_PREFIX="$CROSS_PREFIX" -fi - -case "$1" in -"is_cross") - if [ "$OUT_ARCH" = "$(uname -m)" ]; then - exit 1 - else - exit 0 - fi - ;; -"arch") - echo $OUT_ARCH; - ;; -"dpkg-arch") - echo $DPKG_ARCH; - ;; -"cross-prefix") - echo $PKG_PREFIX; - ;; -"install") - if [ "$OUT_ARCH" != "$(uname -m)" ] && ! dpkg --print-foreign-architectures | grep "$DPKG_ARCH" >/dev/null ; then - echo dpkg --add-architecture "$DPKG_ARCH" - echo apt-get update - fi - shift - pkgs="" - for name in $@; do - if [ "$OUT_ARCH" != "$(uname -m)" ] && [ "$name" = "gcc" ] || [ "$name" = "g++" ]; then - pfx="$PKG_PREFIX" - if [ "$pfx" = "x86_64-linux-gnu" ]; then - pfx="x86-64-linux-gnu" - fi - pkgs="$pkgs $name-$pfx " - else - pkgs="$pkgs $name:$DPKG_ARCH " - fi - done - echo apt-get install -y $pkgs - ;; -*) - echo "unknown command $1" - exit 1 - ;; -esac diff --git a/scripts/riscv64-buildroot-linux-gnu-pkg-config b/scripts/riscv64-buildroot-linux-gnu-pkg-config deleted file mode 100755 index 24e3c89c..00000000 --- a/scripts/riscv64-buildroot-linux-gnu-pkg-config +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -basename=`basename $0` -prefix=/usr/`echo $basename|sed s/-pkg-config//` -PKG_CONFIG_LIBDIR=/usr/riscv64-linux-gnu/lib/pkgconfig -export PKG_CONFIG_LIBDIR -pkg-config --define-variable=prefix=$prefix $@ \ No newline at end of file