英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论