Skip to content

Commit a3ebc6a

Browse files
authored
Add windows arm64 crossbuild support (#652)
1 parent ff1e49c commit a3ebc6a

File tree

8 files changed

+225
-1
lines changed

8 files changed

+225
-1
lines changed

.github/release-drafter.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ template: |
6666
- `docker.elastic.co/beats-dev/golang-crossbuild:$RESOLVED_VERSION-mips-debian12(-fips)?` - linux/mips64, linux/mips64el
6767
- `docker.elastic.co/beats-dev/golang-crossbuild:$RESOLVED_VERSION-ppc-debian12(-fips)?` - linux/ppc64, linux/ppc64le
6868
- `docker.elastic.co/beats-dev/golang-crossbuild:$RESOLVED_VERSION-s390x-debian12(-fips)?` - linux/s390x
69+
- `docker.elastic.co/beats-dev/golang-crossbuild:$RESOLVED_VERSION-windows-arm64-debian12(-fips)?` - linux/arm64, windows/arm64
6970
7071
### Changes
7172

go/Makefile.debian12

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
IMAGES := base main darwin armhf armel mips ppc s390x npcap
2-
ARM_IMAGES := base-arm darwin-arm64
2+
ARM_IMAGES := base-arm darwin-arm64 windows-arm64
33
DEBIAN_VERSION := 12
44
TAG_EXTENSION := -debian12
55

go/windows-arm64/Dockerfile.tmpl

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
ARG REPOSITORY
2+
ARG VERSION
3+
ARG TAG_EXTENSION=''
4+
5+
FROM ${REPOSITORY}/golang-crossbuild:${VERSION}-base-arm${TAG_EXTENSION}
6+
7+
#ARG LLVM_MINGW64_VER=20250826
8+
ARG LLVM_MINGW64_VER=20250910
9+
ARG LLVM_MINGW_UBUNTU_REL='22.04'
10+
ARG LLVM_MINGW64_SRC="https://github.com/mstorsjo/llvm-mingw/releases/download"
11+
ENV LLVM_MINGW64_VER="${LLVM_MINGW64_VER}"
12+
ENV LLVM_MINGW64_SRC="$LLVM_MINGW64_SRC"
13+
14+
{{- if ne .DEBIAN_VERSION "12"}}
15+
RUN echo "This Docker image will work only with Debian >12" && exit 1
16+
{{- end }}
17+
18+
RUN \
19+
apt-get -o Acquire::Check-Valid-Until=false update \
20+
&& apt-get install -qq -y --no-install-recommends --allow-unauthenticated \
21+
cmake \
22+
patch \
23+
libssl-dev \
24+
libxml2-dev \
25+
lzma-dev \
26+
uuid-dev \
27+
make \
28+
bash \
29+
wget \
30+
&& rm -rf /var/lib/apt/lists/*
31+
32+
WORKDIR /tmp
33+
COPY --chmod=0755 scripts/setup-llvm-mingw64.sh /tmp/
34+
RUN /tmp/setup-llvm-mingw64.sh
35+
36+
COPY --chmod=0755 scripts/install-llvm-mingw64.sh /tmp/install-llvm-mingw64.sh
37+
RUN /tmp/install-llvm-mingw64.sh /tmp/llvm-mingw64 && rm -rf /tmp/*
38+
39+
COPY rootfs /
40+
41+
# Basic test
42+
RUN which aarch64-w64-mingw32-gcc
43+
44+
RUN cd / \
45+
&& aarch64-w64-mingw32-gcc helloWorld.c -o helloWorld.arm64 \
46+
&& file helloWorld.arm64 \
47+
&& file helloWorld.arm64 | grep -c 'PE32+ executable (console) Aarch64, for MS Windows'
48+
49+
RUN cd / \
50+
&& aarch64-w64-mingw32uwp-gcc helloWorld.c -o helloWorld.arm64e \
51+
&& file helloWorld.arm64e \
52+
&& file helloWorld.arm64e | grep -c 'PE32+ executable (console) Aarch64, for MS Windows'
53+
54+
ENV CGO_ENABLED 1
55+
#ENV CC aarch64-w64-mingw32-gcc
56+
#ENV CXX aarch64-w64-mingw32-g++
57+
ENV CGO_FLAGS="$CGO_FLAGS -I/usr/generic-w64-mingw32/include"
58+
ENV CGO_CFLAGS="-fno-addrsig"
59+
RUN go env
60+
61+
RUN aarch64-w64-mingw32-gcc --version
62+
63+
RUN go clean -cache -modcache -i -r
64+
65+
# Build-time metadata as defined at http://label-schema.org.
66+
ARG BUILD_DATE
67+
ARG IMAGE
68+
ARG VCS_REF
69+
ARG VCS_URL
70+
LABEL org.label-schema.build-date=$BUILD_DATE \
71+
org.label-schema.name=$IMAGE \
72+
org.label-schema.vcs-ref=$VCS_REF \
73+
org.label-schema.vcs-url=$VCS_URL \
74+
org.label-schema.schema-version="1.0"

go/windows-arm64/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include ../Makefile.common
2+
3+
ifeq ($(DOCKER_MULTIARCH),1)
4+
DOCKER_CMD := $(SELF_DIR)/../.buildkite/scripts/buildx.sh
5+
6+
push:
7+
@echo "Already done by buildx (.buildkite/scripts/buildx.sh)."
8+
atomic-push:
9+
@echo "Already done by buildx (.buildkite/scripts/buildx.sh)."
10+
endif
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
3+
windows:
4+
arm64:
5+
CC: aarch64-w64-mingw32-gcc
6+
CXX: aarch64-w64-mingw32-g++
7+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <stdio.h>
2+
int main() {
3+
printf("Hello, World!");
4+
return 0;
5+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copied from: https://github.com/x1unix/docker-go-mingw/tree/20dfaff6efe8fe3a4ff588a58ccb31646cd2fd60
4+
#
5+
set -e
6+
set -o pipefail
7+
8+
trap 'echo "$0: Error on line $LINENO" >&2' ERR
9+
10+
src="$1"
11+
if [ -z "$src" ]; then
12+
echo "Error: missing source dir"
13+
exit 1
14+
fi
15+
16+
base_dir='/usr'
17+
18+
echo ":: Installing llvm-mingw64..."
19+
echo "Source dir: $src"
20+
21+
cd "$src" || exit 1
22+
find . -mindepth 1 -maxdepth 1 -type d ! -name . | while read -r subdir; do
23+
dst_dir="$(basename "$subdir")"
24+
25+
case "$dst_dir" in
26+
bin)
27+
perm=755
28+
;;
29+
*)
30+
perm=644
31+
;;
32+
esac
33+
34+
find "$subdir" -type f | while read -r file; do
35+
dst="$base_dir/${file/.\//}"
36+
mkdir -p "$(dirname "$dst")"
37+
install -m $perm "$file" "$dst"
38+
done
39+
done
40+
41+
echo ":: Restoring symlinks..."
42+
while IFS= read -r line; do
43+
src=$(echo "$line" | awk '{print $1}')
44+
src="$base_dir/$src"
45+
46+
dest=$(echo "$line" | awk '{print $2}')
47+
dest="$(realpath "$base_dir/$dest")"
48+
ln -s "$dest" "$src"
49+
done <symlinks.txt
50+
51+
echo ":: Cleanup"
52+
cd ..
53+
rm -rf "$src"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copied from: https://github.com/x1unix/docker-go-mingw/tree/20dfaff6efe8fe3a4ff588a58ccb31646cd2fd60
4+
#
5+
set -e
6+
set -o pipefail
7+
8+
trap 'echo "$0: Error on line $LINENO" >&2' ERR
9+
10+
if [ -z "$LLVM_MINGW64_SRC" ]; then
11+
echo "Error: LLVM_MINGW64_SRC is undefined"
12+
env
13+
exit 1
14+
fi
15+
16+
if [ -z "$LLVM_MINGW_UBUNTU_REL" ]; then
17+
echo "Error: LLVM_MINGW_UBUNTU_REL is undefined"
18+
env
19+
exit 1
20+
fi
21+
22+
if [ -z "$LLVM_MINGW64_VER" ]; then
23+
echo "Error: LLVM_MINGW64_VER is undefined"
24+
env
25+
exit 1
26+
fi
27+
28+
apt update && apt install xz-utils --yes
29+
30+
case "$(uname -m)" in
31+
aarch64 | arm64)
32+
m_arch="aarch64"
33+
;;
34+
x86_64 | amd64)
35+
m_arch="x86_64"
36+
;;
37+
*)
38+
echo "Error: unsupported architecture $(uname -m)"
39+
exit 1
40+
;;
41+
esac
42+
43+
pkg_dir="llvm-mingw-$LLVM_MINGW64_VER-ucrt-ubuntu-$LLVM_MINGW_UBUNTU_REL-$m_arch"
44+
pkg_file="$pkg_dir.tar.xz"
45+
src_url="$LLVM_MINGW64_SRC/$LLVM_MINGW64_VER/$pkg_file"
46+
echo ":: Downloading $src_url ..."
47+
wget "$src_url"
48+
# wget -q --spider "$src_url"
49+
50+
if [ ! -f "$pkg_file" ]; then
51+
echo "Error: can't find downloaded file $pkg_file"
52+
ls -la
53+
exit 1
54+
fi
55+
56+
echo ":: Extracting file..."
57+
tar -xf "$pkg_file"
58+
rm "$pkg_file"
59+
60+
echo ":: Preparing file list..."
61+
mv "$pkg_dir" llvm-mingw64
62+
cd llvm-mingw64
63+
64+
# Keep llvm-mingw64 only for arm target to avoid conflict with gcc-mingw64
65+
rm bin/x86_64* bin/i686*
66+
rm -rf i686-w64-mingw32 x86_64-w64-mingw32
67+
68+
# Backup symlinks
69+
find . -type l | while read -r symlink; do
70+
src="${symlink/.\//}"
71+
dst="$(dirname "$src")/$(readlink "$symlink")"
72+
echo "$src $dst" >>symlinks.txt
73+
rm "$symlink"
74+
done

0 commit comments

Comments
 (0)