![使用 docker for alpine linux (musl) aarch64 与本机库交叉编译 go(lang) 应用程序,以便启用 CGO](https://linux22.com/image/194910/%E4%BD%BF%E7%94%A8%20docker%20for%20alpine%20linux%20(musl)%20aarch64%20%E4%B8%8E%E6%9C%AC%E6%9C%BA%E5%BA%93%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91%20go(lang)%20%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%EF%BC%8C%E4%BB%A5%E4%BE%BF%E5%90%AF%E7%94%A8%20CGO.png)
背景
我正在编写一个开源 GTK go 应用程序亚音速 API 客户端,其中:
- 目标是第一名移动友好的 Linux,例如上市后操作系统(阿尔卑斯Linux),莫边(德班)
- 未来还将扩展到桌面 Linux、Windows 和 Mac OS,但不会扩展到 Android 或 iOS,因为它们已经有了。
- 需要至少在
aarch64
和x86_64
- 取决于本机库,例如
portaudio
,,libasound
libopus
- 所以需要
CGO
启用它
我还没有发布应用程序,因为我自行托管我的 git,并且我必须做一些额外的配置。它要到 2021 年 10 月下旬才会上市。
应用程序成功编译(在主机上)并在我的主 PC(x86_64 fedora)上运行。
应用程序成功编译(在 docker 上)并在 aarch64 上运行glibc像 Mobian 这样的发行版
这是 Dockerfile:
FROM golang:1.17-bullseye
LABEL os=linux
LABEL arch=arm64
ENV GOOS=linux
ENV GOARCH=arm64
ENV CGO_ENABLED=1
ENV CC=aarch64-linux-gnu-gcc
ENV PATH="/go/bin/${GOOS}_${GOARCH}:${PATH}"
ENV PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig
# install build & runtime dependencies
RUN dpkg --add-architecture arm64
RUN apt update && apt upgrade -y
RUN apt install -y --no-install-recommends \
protobuf-compiler \
upx \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
pkg-config \
libasound2-dev:arm64 \
libgtk-3-dev:arm64 \
libcairo2-dev:arm64 \
libglib2.0-dev:arm64 \
libgdk-pixbuf2.0-dev:arm64 \
libsamplerate0:arm64 \
libsamplerate0-dev:arm64 \
libopusfile0:arm64 \
libopusfile-dev:arm64 \
libopus0:arm64 \
libopus-dev:arm64 \
libportaudio2:arm64 \
portaudio19-dev:arm64
# install build dependencies (code generators)
RUN go get github.com/hajimehoshi/oto \
&& go get github.com/faiface/beep \
&& go get github.com/faiface/beep/flac \
&& go get github.com/faiface/beep/speaker \
&& go get github.com/faiface/beep/mp3 \
&& go get github.com/faiface/beep/vorbis \
&& go get github.com/faiface/beep/wav\
&& go get github.com/gotk3/gotk3 \
&& go get github.com/delucks/go-subsonic \
&& go get github.com/hashicorp/go-retryablehttp \
&& go get github.com/zalando/go-keyring \
&& go get github.com/emirpasic/gods/lists/ \
&& go get github.com/emirpasic/gods/lists/arraylist \
问题
- 我无法在 postmarketOS 上运行 Mobian 工作二进制文件,因为 alpine linux 使用 musl 代替。
file
输出是:ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, (...) for GNU/Linux 3.7.0. not stripped
. - 我还没有在 docker debian 中使用 musl 工具链,因为它是 32 位二进制可执行文件,而镜像是 64 位。
- 我在 alpine 中找不到任何有关多架构的信息,所以我可能无法在 x86_64 上使用 docker image goalng:1.17-alpine (我还必须找到打包的本机库)
我希望这只是我的配置问题,如果可能的话,我希望使用 docker 来解决,因为我将来想使用 CI/CD。
资源、想法、解决方法
- 我有树莓派和 debian 安装了一些服务。我可以与本机 musl 工具链和 debian aarch64 docker 容器一起使用,但它在生产管道中并不方便。另外,我还没有尝试过这个。
好读
答案1
我遇到了类似的问题,我需要使用 cgo 构建一个静态 Go 二进制文件,该二进制文件最终会在高山容器与arm64架构,但必须建造在golang:高山容器与x86_64架构(我无法控制 CI/CD 运行程序架构)。
我通过下载交叉编译器 (CC) 并指定在 Go 构建期间使用它来使其工作。
以下是在容器用户的主目录中下载/解压 CC 并在基于 go 构建的过程中使用它的示例,/usr/src/example
该生成生成名为的可执行文件示例应用程序。
wget -P ~ https://musl.cc/aarch64-linux-musl-cross.tgz
tar -xvf ~/aarch64-linux-musl-cross.tgz -C ~
cd /usr/src/example
GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=~/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc go build -o exampleApp -a -ldflags=-extldflags=-static .
file
在输出上运行exe
验证它是针对 aarch64 静态链接的。然后我就可以在其他地方的 arm64 alpine 容器中运行它。