记录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

<h2>解决过程</h2>
上面报错是因为 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_CFLAGS、CGO_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 是默认的值,主要是后面的参数

声明:本网站刊载的所有内容,包括文字、图片、音频、视频、软件、程序、以及网页版式设计等如无特殊说明或标注,均在网上搜集。仅供访问者个人学习、研究或欣赏,禁止商业性或盈利性用途,访问者应遵守著作权法的规定,在使用时征得本站和原著作权人的同意并支付许可使用费。本网站刊登内容,如有侵权请权利人予以告知,本站将立即予以删除。
(0)
保哥保哥黄金会员
上一篇 2023年8月24日
下一篇 2023年8月29日

相关推荐

发表回复

登录后才能评论