3

qemu-user-static 下 cgo go build 卡住的一次解决

 1 year ago
source link: https://zhangguanzhang.github.io/2023/08/08/qemu-cgo-build-hang/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

qemu-user-static 下 cgo go build 卡住的一次解决



字数统计: 550阅读时长: 2 min
 2023/08/08  103  Share

记录 qemu-user-static 下 cgo go build 卡住的一次解决

内部构建机器都是 amd64 架构,项目大多数都没用 cgo,用了的几个都是 sqlite 这种长期稳定的,编译 arm64 的是下面的步骤:

FROM xxx/golang:xxx 带 gcc-aarch64-linux-gnu 的 amd64 golang 镜像

COPY ...
RUN CC=aarch64-linux-gnu-gcc GOARCH=arm64 CGO_ENABLED=1 \
go build xxxx

前不久有个 odbc 的 cgo 项目,这样报错:

/usr/lib/gcc-cross/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/bin/ld.gold: error: cannot find -lodbc

上面报错是因为 amd64 的镜像里安装 unixodbc-dev 的是 amd64 架构的,sqlite 没问题应该是它单元测试覆盖率很高了,而且安卓是 arm64 ,头文件里很多差异性估计用 #define 做 if else 了所以没问题。

qemu go build hangs

FROM --platform=linux/arm64 xxx/golang:xxx
RUN apt install -y unixodbc-dev
COPY ...
RUN GOARCH=arm64 CGO_ENABLED=1 \
go build xxxx

arm64 机器上编译是没问题的,但是我们构建机器都是 amd64 架构(centos 7,内核 419 版本)使用的 利用 qemu user 模式和 binfmt_misc 构建其他架构的 docker 镜像 ,时不时卡在 go build 上

升级了 qemu 版本和 docker 版本,还是卡住,后面打算升级内核。

安装 arm64 lib

但是升级内核之前想了下,能不能在 amd64 里安装 arm64 的 odbc lib,然后传递 CGO_CFLAGSCGO_LDFLAGS 指定 arm64 的 odbc path,最终搞出来了:

FROM --platform=linux/arm64 debian:buster-slim as deb
RUN set -eux; \
if [ -e /etc/apt/sources.list ];then sed -ri 's/[a-zA-Z0-9.]+(debian.org|ubuntu.com)/mirrors.aliyun.com/g' /etc/apt/sources.list; fi; \
apt update; \
cd /tmp; \
apt download libodbc1 unixodbc-dev; \
mkdir -p /test/usr/local/lib_arm64 /test/usr/local/include_arm64; \
ls *.deb | while read deb;do dpkg-deb -x $deb /opt/; done; \
find /opt; \
find /opt/usr/lib/ -not -type d -exec cp -a {} /test/usr/local/lib_arm64 \; ; \
find /opt/usr/include/ -not -type d -exec cp -a {} /test/usr/local/include_arm64 \; ; \
ls -l /test/usr/local/lib_arm64 /test/usr/local/include_arm64

FROM scratch
COPY --from=deb /test /odbc

上面镜像构建成 xxxxx/file/odbc:v1

FROM xxxxx/file/odbc:v1 as odbc
FROM xxx/golang:xxx # apt install -y gcc-aarch64-linux-gnu 的 amd64 golang 镜像
COPY --from=odbc /odbc /

RUN CC=aarch64-linux-gnu-gcc GOARCH=arm64 CGO_ENABLED=1 \
CGO_CFLAGS='-g -O2 -I/usr/local/include_arm64' \
CGO_LDFLAGS='-g -O2 -L/usr/local/lib_arm64 -lodbc' \
go build xxx

-g -O2 是默认的值,主要是后面的参数


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK