目前小菜刀的项目中需要用到SQLite数据库,https://github.com/mattn/go-sqlite3支持database/sql接口,采用Go的标准接口有利于项目后续扩展,因此选择了该驱动。但是,它是基于CGO实现的,所以跨平台编译会比较麻烦,小菜刀总结了一些经验,特分享给读者朋友们。
什么是跨平台编译?
简单地说, 就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是,所谓平台,实际上包含两个概念:体系架构(Architecture)、操作系统 (Operating System)。同一个体系架构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系架构上运行。
我们知道Go语言是支持跨平台编译的,在之前的文章《Go交叉编译》中有详细介绍过怎么操作。Go实现跨平台编译的思想其实很简单:通过保存可以生成最终机器码的多份翻译代码,在编译时根据 GOARCH=xxx
和GOOS=xxx
参数(对应体系架构和操作系统)进行初始化设置,最终调用对应平台编写的特定方法来生成机器码,从而实现跨平台编译。
CGO编译存在的问题
有一点需要注意:Go所谓的跨平台编译只是针对Go代码部分,它是Go的交叉编译器(cross-compiler toolchains)。当我们使用了CGO时,要想实现跨平台编译,同时需要让C/C++代码也支持跨平台。
package main
/*
#include <stdio.h>
void printint(int v) {
printf("printint: %d\n", v);
}
*/
import "C"
func main() {
v := 42
C.printint(C.int(v))
}
小菜刀的开发机器:amd64架构,darwin系统。目标编译平台:amd64架构,linux系统。现想将上述含有CGO的代码编译为目标平台的可执行文件。
$ GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -o main main.go
通过以上命令,得到编译错