使用 docker for alpine linux (musl) aarch64 与本机库交叉编译 go(lang) 应用程序,以便启用 CGO

使用 docker for alpine linux (musl) aarch64 与本机库交叉编译 go(lang) 应用程序,以便启用 CGO

背景

我正在编写一个开源 GTK go 应用程序亚音速 API 客户端,其中:

  • 目标是第一名移动友好的 Linux,例如上市后操作系统(阿尔卑斯Linux),莫边(德班)
  • 未来还将扩展到桌面 Linux、Windows 和 Mac OS,但不会扩展到 Android 或 iOS,因为它们已经有了。
  • 需要至少在aarch64x86_64
  • 取决于本机库,例如portaudio,,libasoundlibopus
  • 所以需要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 \

问题

  1. 我无法在 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.
  2. 我还没有在 docker debian 中使用 musl 工具链,因为它是 32 位二进制可执行文件,而镜像是 64 位。
  3. 我在 alpine 中找不到任何有关多架构的信息,所以我可能无法在 x86_64 上使用 docker image goalng:1.17-alpine (我还必须找到打包的本机库)

我希望这只是我的配置问题,如果可能的话,我希望使用 docker 来解决,因为我将来想使用 CI/CD。

资源、想法、解决方法

  • 我有树莓派和 debian 安装了一些服务。我可以与本机 musl 工具链和 debian aarch64 docker 容器一起使用,但它在生产管道中并不方便。另外,我还没有尝试过这个。

好读

  1. 交叉编译 CGO 项目(也使用 docker)
  2. 使用跨平台 musl 工具链进行交叉编译
  3. 有关 alpine linux 和 go 二进制文件的相关 stackoverflow 线程

答案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 容器中运行它。

相关内容