如何在Alpine Docker容器内构建用于交叉编译的gcc+tools?

huangapple go评论75阅读模式
英文:

How to build gcc+tools for cross-compiling inside Alpine Docker container?

问题

为了我的一个Github项目,我正在发布适用于linux/amd64和linux/arm64的多架构容器镜像。其中一个阶段构建了一个完全独立的Go二进制文件,但它绝对需要CGO才能实现。目前,这个阶段不能始终作为Github上的"本地"阶段运行,比如在amd64上。相反,由于QEMU arm64模拟在amd64上,这变得非常慢,尽管部分原因是由于Github为公共项目提供的免费的runner。在我的个人10年老的i7上,事情进展得快得多。

通常情况下,搜索在alpine上安装具有musl支持的交叉编译工具链的第一个搜索引擎结果是 Cross-compiling with musl Toolchains (ariya.io) 或 musl.cc 本身。这个"solution"的一个大问题是,首先,musl.cc的软件包非常过时(11/2021),其次,也不是一个可固定版本的软件包源。至少在提供容器镜像的公共项目上,musl.cc是绝对不可接受的。(请不要讨论关于Alpine的固定问题。)

另一个排名很高的链接是 xentec/setup-cross-cc.sh,但我在Docker Alpine容器内无法使其正常工作,因为仍然存在未解决的错误。我看到了问题,解决方案据称是使用更新的Docker、runc和libseccomp -- 我的主机系统上都满足这些要求。所以显然这仍然没有正确修复或出现了回退。

我也知道 Golang cross compiling with CGO inside docker image -- 没有任何有用的答案。实际上,一些看似合法的答案在表面上看起来与所提出的问题并不完全相符。

我如何在(最新的)Alpine Docker容器内构建一个用于Alpine-musl的gcc + friends交叉编译工具链?请注意,我不想构建(交叉)apk Alpine软件包。我的最终目标是使用cgo构建Go二进制文件。

英文:

For one of my Github projects I'm releasing multi-arch container images for linux/amd64 and linux/arm64. One stage builds a Go fully standalone binary, but it absolutely needs CGO to do so. For the moment, this stage thus cannot be always running as a runner "native" stage, such as amd64 on Github. Instead, it is painfully slow due to the QEMU arm64 emulation on amd64 -- albeit part of the slowness is due to the free Github runners for public projects. On my personal 10yr-old i7 things go by much faster.

Typically, the first search engine result when searching for installing a cross-compiling tool chain on alpine with musl support is either Cross-compiling with musl Toolchains (ariya.io) or musl.cc itself. The big issue with this "solution" is that first, the packages from musl.cc are terribly outdated (11/2021), and second, are not a version pinnable package source either. Not least on a public project offering container images musl.cc is an absolute no-go. (Discussions about pinning issues with Alpine in general aside.)

Another high ranking hit is xentec/setup-cross-cc.sh, which I simply cannot get to work inside a Docker Alpine container, due to still unresolved does errors. I've seen the issues and the solution is allegedly a newer Docker, runc, and libseccomp -- which I all fulfill on my host system. So this obviously still isn't fixed correctly or has regressed.

I'm also aware of Golang cross compiling with CGO inside docker image -- without any helpful answer. In fact, some of the answers while on the surface looking legit are in their contents not really matching what has been questioned.

How can I build a cross-compiler toolchain of gcc + friends for Alpine-musl inside a (recent) Alpine Docker container?

Please note that I don't want to build (cross) apk Alpine packages. My ultimate Goal is to build Go binaries using cgo.

答案1

得分: 2

这里已经有一个整洁的解决方案:@tonistiigi/xx。然而,它不使用gcc,而是使用clang/llvm。事实证明,gcc和多架构并不是很兼容,因为gcc来自一个期望只有一个gcc用于构建其主机平台或精确交叉编译到另一个平台的时代。尽管这个答案不能解决我的原始问题,但它以不同但更简单的方式解决了我跨编译的基本需求。

xx的文档明确提到了Alpine,并提供了示例,特别是用于Go / Cgo。还请参考我在StackOverflow上的(标准)答案,所以我不会在这里重复所有内容。

主要思路如下:

FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx

FROM --platform=$BUILDPLATFORM golang:alpine
RUN apk add clang lld
COPY --from=xx / /
ARG TARGETPLATFORM
RUN xx-apk add musl-dev gcc
ENV CGO_ENABLED=1
RUN xx-go build -o hello ./hello.go && \
    xx-verify hello
英文:

Happens that there actually already is a neat and clean solution: @tonistiigi/xx. However, this doesn't use gcc but clang/llvm instead. As it turns out, gcc and multi-arch are somewhat not best friends, as gcc comes from a time where the expectation was to have a single gcc that either builds for its host platform, or cross-compiles to exactly one other platform. But while this answer doesn't solve my original question, it solves my underlying need for cross-compilation in a different, but much easier way.

xx's documentation explicitly mentions Alpine and shows examples, not least for using Go / Cgo. See also my (canonical) answer here on SO, so I'm not duplicating everything here.

The gist is as follows:

FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx

FROM --platform=$BUILDPLATFORM golang:alpine
RUN apk add clang lld
COPY --from=xx / /
ARG TARGETPLATFORM
RUN xx-apk add musl-dev gcc
ENV CGO_ENABLED=1
RUN xx-go build -o hello ./hello.go && \
    xx-verify hello

huangapple
  • 本文由 发表于 2023年6月9日 03:27:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76435120.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定