gf框架使用sqlite3数据库后交叉编译cgo适配arm64-linux

gf框架使用sqlite3数据库后交叉编译cgo适配arm64-linux


1. 前言

之前已经说过我们将使用openwrt+nginx+go+sqlite3的方式在openwrt上开发适配业务的web,而框架使用的go-frame,目前go语言操作sqlite3的相关库都使用了cgo,因此我们不得不面对交叉编译cgo的问题。

2. 解决方案

我们考虑了两个解决方案:1、openwrt下安装openwrt-go,然后在openwrt下编译工程;2、安装arm-linux交叉编译工具链,然后交叉编译基于cgo程序。

虽然我们的openwrt为19.07.1是支持go语言的,但是编译固件时没有添加openwrt-go,因此为了避免重新编译固件以及升级固件,暂时没有选择这种方案,其实添加一个go环境还是蛮不错的(https://openwrt.org/packages/pkgdata/golang-src)。

确实直接使用交叉编译工具链来编译cgo工程更合理一些,毕竟openwrt大多情况下还是嵌入式环境,尽量还是考虑这种交叉编译方案好一些,其实也没有那么复杂,安装交叉编译工具链,然后编译时指定对应环境变量即可。

3. wsl+Windows交叉编译cgo工程

3.1 简述cgo程序交叉编译

Windows安装相关交叉编译工具链很少,基本上都是在Ubuntu等类似的宿主机上搭建交叉编译环境,然后交叉编译适合目标机的程序,对于cgo也是如此,你可以简单理解cgo就是c程序套壳一层go接口,所以交叉编译cgo程序可以说就是交叉编译c/c++程序,因此我们搭建交叉编译环境,然后指定编译的CC、CXX环境变量即可,由于目前wsl已经足够成熟(wsl2和vmware强制而二选一,你能明白操作系统的重要性了吧),因此目前使用wsl+Windows的模式编译项目,项目在Windows下,但是交叉编译环境安装在wsl中,然后利用wsl中的交叉编译环境编译Windows下的项目。

3.2 安装交叉编译工具链

由于我们是交叉编译适配aar64+linux的程序,因此相对简单一些,直接安装现成的交叉编译工具链即可(如果是其它的系统和cpu架构,需要根据具体情况而定,但是思路都是安装相关系统和cpu架构的gcc和g++及对应依赖库,方便后续编译时使用):

sudo apt-get update
sudo apt install -y cpp-aarch64-linux-gnu g++-aarch64-linux-gnu

3.3 交叉编译包含cgo依赖的go项目

之后在wsl中编译时指定对应的环境变量即可(注意结合go的特性进行静态链接,这样虽然会导致程序大一些,但是避免了动态库的依赖,更方便移植):

CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ GOOS=linux GOARCH=arm64 go build -o ./bin/server main.go -ldflags '-s -w --extldflags "-static -fpic"'

-ldflags '-s -w’可以去掉一些符号表,这样不但可以减少程序的体积,实际发布后在一定程序上也可以避免程序被二进制逆向破解。static那部分则是静态链接方式,将相关库都静态链接,这样生成的程序就不必依赖可能的动态库了。

3.4 交叉编译依赖sqlite3的gf工程

交叉编译时使用gf建议只设置config.toml中的extra,当成go build命令来使用:

config.toml:

[gfcli]
    # 自定义DAO生成配置(默认是读取database配置)
    [[gfcli.gen.dao]]
        link   = "sqlite:./gateway.db"
        tables = "user, login_log, oper_log"
        descriptionTag = true
        noModelComment = true
    [gfcli.build]
        cgo      = 1
        extra    = "-ldflags '-s -w --extldflags \"-static -fpic\"'"

编译时:

CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ GOOS=linux GOARCH=arm64 gf build main.go -o ./bin/TSL-G10-SW-GATEWAY-WEB --pack public --swagger -v 1.0.0

至于gf框架如何使用sqlite3可以看这里:https://goframe.org/pages/viewpage.action?pageId=17203966

4. 最后

cgo的使用还是不错的,尽量根据go的特性使用静态库,这也是go使用起来体验不错的原因之一,太多的动态库依赖往往让编译过程变得比较麻烦,找依赖错误往往占编译的很大一部分。

参考:https://github.com/eyasliu/blog/issues/27

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值