CentOS7中_帶sqlite3_CGO的golang程序_交叉編譯到arm中


CentOS7中_帶sqlite3_CGO的golang程序_交叉編譯到arm中

轉載注明來源: 本文鏈接 來自osnosn的博客,寫於 2019-10-28.

編寫了個golang程序,用到了這個CGO庫github.com/mattn/go-sqlite3,用來支持sqlite3。
在x86_64機器中編譯運行都ok。另有一台arm機器,裝了armbian。
想在x86_64機器中交叉編譯到arm64,碰到了一些問題。

經過摸索,似乎解決了。寫下筆記給后來人參考。


環境:

  • x86_64機器,裝的是centos7,64位的。
  • arm機器,aarch64-Linux-5.0.2-aml-s905, little_endian,裝的armbian,64位的。

嘗試用go直接交叉編譯

  • CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 go build -ldflags "-w -s" -o arm-mygofile mygofile.go 交叉編譯失敗。
  • CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -ldflags "-w -s" -o arm-mygofile mygofile.go 交叉編譯成功,但執行時發現sqlite3庫沒有加載。

golang在沒有CGO時,直接可以交叉編譯。有CGO就不行了。

嘗試用arm的gcc

  • 在centos7中安裝,yum install gcc-arm-linux-gnu
  • CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 CC=arm-linux-gnu-gcc go build -ldflags "-w -s" -o arm-mygofile mygofile.go 交叉編譯失敗。說stdlib.h找不到。

arm-linux-gnu-gcc -v 中看到 sysroot目錄 /usr/arm-linux-gnu/sys-root/ 為空。
從 yum search 中,也沒找到對應的包。看來只能手工去下載編譯用的head文件和庫文件。

嘗試交叉編譯 arm 執行文件(32bit)

  • 之前已經安裝 yum install gcc-arm-linux-gnu
  • https://releases.linaro.org/components/toolchain/binaries/latest-7
  • 下載 arm-linux-gnueabi/sysroot-glibc-linaro-2.25-2019.02-arm-linux-gnueabi.tar.xz
  • 解壓 tar Jxvf sysroot-glibc-linaro-2.25-2019.02-arm-linux-gnueabi.tar.xz

build時,指定 sysroot 的位置。

  • CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 CC=arm-linux-gnu-gcc CGO_CFLAGS="-g -O2 --sysroot=/..../sysroot-glibc-linaro-2.25-2019.02-arm-linux-gnueabi/" CGO_LDFLAGS="-g -O2 --sysroot=/..../sysroot-glibc-linaro-2.25-2019.02-arm-linux-gnueabi/" go build -ldflags "-w -s" -o arm-mygofile mygofile.go 編譯成功。

但copy到armbian后,無法執行(動態庫ld-linux.so找不到)。似乎是32位的動態庫沒找到。

嘗試加上 -static 參數。使用靜態鏈接。

  • CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 CC=arm-linux-gnu-gcc CGO_CFLAGS="-g -O2 --sysroot=/..../sysroot-glibc-linaro-2.25-2019.02-arm-linux-gnueabi/" CGO_LDFLAGS="-g -O2 --sysroot=/..../sysroot-glibc-linaro-2.25-2019.02-arm-linux-gnueabi/ -static" go build -ldflags "-w -s" -o arm-mygofile mygofile.go 編譯成功(有錯誤警告,說sqlite3使用了glibc動態庫)。

copy到armbian后,執行正常。執行文件是32位靜態鏈接的。
---似乎成功了---

armeb-linux-gnueabihf 中的 sysroot-glibc-linaro....-armlinux-gnueabihf.tar.xz文件 應該也可以。聽說64位的arm,默認就是帶hf的。
我沒有嘗試。
s905,好像是armv8的。估計用 armv8l-linux-gnueabihf 也行。我也沒嘗試。

交叉編譯 aarch64 執行文件(64bit)

  • 在centos7中安裝,yum install gcc-aarch64-linux-gnu
  • https://releases.linaro.org/components/toolchain/binaries/latest-7
  • 下載 aarch64-linux-gnu/sysroot-glibc-linaro-2.25-2019.02-aarch64-linux-gnu.tar.xz
  • 解壓 tar Jxvf sysroot-glibc-linaro-2.25-2019.02-aarch64-linux-gnu.tar.xz

build時,指定 sysroot 的位置。

  • CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC="aarch64-linux-gnu-gcc" CGO_CFLAGS="-g -O2 --sysroot=/..../sysroot-glibc-linaro-2.25-2019.02-aarch64-linux-gnu/" CGO_LDFLAGS="-g -O2 --sysroot=/..../sysroot-glibc-linaro-2.25-2019.02-aarch64-linux-gnu/" go build -ldflags "-w -s" -o arm-mygofile mygofile.go 編譯成功。

copy到armbian后,執行正常。執行文件是64位動態鏈接的。
---成功了---

直接在armbian中用arm的golang build得到的執行文件,也是64位動態鏈接的。但體積要小些。比交叉編譯的小幾百KB。不知道為什么。


轉載注明來源: 本文鏈接 來自osnosn的博客.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM