Mingw静态编译go-sqlite3包

最后都变了- 提交于 2020-03-17 02:11:48

某厂面试归来,发现自己落伍了!>>>

    在github.com/mattn/go-sqlite3上,作者说在windows下使用go-sqlite3要使用动态链接的方法[Go does not support static linking for external C library; sqlite3 should be built as a shared library. If it runs on Windows, it needs dll.],结合网上的资源,我整理出了如何使用静态编译的方法使用go-sqlite3。

    折腾的过程中发现使用go get命令的时候会把源码下载到go的安装目录\src\pkg\下,然后使用go install 的时候会编译包再安装的pkg目录下。src\pkg\github.com\mattn\go-sqlite3 这是go-sqlite3下载到本地后的目录结构。网上的资源是在Google groups找到的how to build "go-sqlite3" under windows with x64 ,内容如下:

Hi all. i got the solution. i hope it can help someone like me .

1. install tdm64-gcc

2. download the source code of sqlite3

3. go get https://github.com/mattn/go-sqlite3

4. unzip it and copy all files except shell.c to  github.com/mattn/go-sqlite3 directory

5. change sqlite3.go

    1) delete "#cgo pkg-config: sqlite3"

    2) change #include <sqlite3.h> to  #include "sqlite3.h"

    3) add

       #cgo windows LDFLAGS: -lmingwex -lmingw32

       #cgo windows CFLAGS: -fno-stack-check -fno-stack-protector -mno-stack-arg-probe

6. go install github.com/mattn/go-sqlite3  and test it 

the final sqlite3.go's beginning like this:

package sqlite

/*

#include "sqlite3.h"
#include <stdlib.h>
#include <string.h>

#cgo windows LDFLAGS: -lmingwex -lmingw32
#cgo windows CFLAGS: -fno-stack-check -fno-stack-protector -mno-stack-arg-probe

static int

_sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) {
  return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
}

static int
_sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
  return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
}

*/

import "C"

    按如上的步骤,没有下载安装tdm-gcc,其实tdm-gcc也就是mingw,执行go install github.com/mattn/go-sqlite3 之后能顺利的生成包go-sqilte3.a。然后就使用《Go web编程中》的例子使用SQLite数据库,进行测试,原始代码如下:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    db, err := sql.Open("sqlite3", "./foo.db")
    checkErr(err)

    //插入数据
    stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) values(?,?,?)")
    checkErr(err)

    res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
    checkErr(err)

    id, err := res.LastInsertId()
    checkErr(err)

    fmt.Println(id)
    //更新数据
    stmt, err = db.Prepare("update userinfo set username=? where uid=?")
    checkErr(err)

    res, err = stmt.Exec("astaxieupdate", id)
    checkErr(err)

    affect, err := res.RowsAffected()
    checkErr(err)

    fmt.Println(affect)

    //查询数据
    rows, err := db.Query("SELECT * FROM userinfo")
    checkErr(err)

    for rows.Next() {
        var uid int
        var username string
        var department string
        var created string
        err = rows.Scan(&uid, &username, &department, &created)
        checkErr(err)
        fmt.Println(uid)
        fmt.Println(username)
        fmt.Println(department)
        fmt.Println(created)
    }

    //删除数据
    stmt, err = db.Prepare("delete from userinfo where uid=?")
    checkErr(err)

    res, err = stmt.Exec(id)
    checkErr(err)

    affect, err = res.RowsAffected()
    checkErr(err)

    fmt.Println(affect)

}

func checkErr(err error) {
    if err != nil {
        panic(err)
    }
}

在Liteide中编译链接后报如下的错误:

D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__moddi3: not defined?

D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text): __divdi3: not defined?

D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text): __moddi3: not defined?

D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__divdi3: not defined?

D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text): __divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text): __divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text): __divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text): __moddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__moddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__moddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__divdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__moddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__moddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__umoddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__udivdi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__umoddi3: not defined?D:\go\go1.0.2.windows-386\go/pkg/windows_386/github.com/mattn/go-sqlite3.a(sqlite3.o)(.text):__udivdi3: not defined?

too many errors?exit code 2, process exited normally.

提示找不到这几个函数,再次搜索看这几个函数在那个库中的时候,找到如下的资源,链接地址是:

https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/VNP6Mwz_B6o

On Thu, Jul 21, 2011 at 5:09 PM, brainman  <alex.b...@gmail.com> wrote:
Hey. I know nothing about gcc but if I remove your line of


#cgo windows LDFLAGS: -lpthread -lgcc_s -lmingwex -lmsvcrt

I could build your package

make clean
make all

The test

make test

fails:

gotest

rm -f _test/camdev/sqlite.a
8g  -o _gotest_.8  _obj/vfs.cgo1.go _obj/sqlite.cgo1.go _obj/_cgo_gotypes.go sqlite_test.go
rm -f _test/camdev/sqlite.a
gopack grc _test/camdev/sqlite.a _gotest_.8  _cgo_defun.8 _cgo_import.8 sqlite3_obj.o vfs.o  vfs.cgo2.o sqlite.cgo2.o _cgo_export.o
_test/camdev/sqlite.a(sqlite3_obj.o)(.text): __divdi3: not defined
_test/camdev/sqlite.a(sqlite3_obj.o)(.text): __moddi3: not defined
_test/camdev/sqlite.a(sqlite3_obj.o)(.text): __moddi3: not defined
_test/camdev/sqlite.a(sqlite3_obj.o)(.text): __divdi3: not defined

Those are in -lgcc_s.
这样在sqlite3.go 修改成这样#cgo windows LDFLAGS: -lmingwex -lmingw32 -lgcc_s
再次执行go install github.com/mattn/go-sqlite3 报如下的错误,
# github.com/mattn/go-sqlite3
D:\mingw\bin/ld.exe: cannot find -lgcc_s
collect2.exe: error: ld returned 1 exit status
提示没有找到这个libgcc_s.a,经查找发现这是Mingw的一个基本库文件在如下的地址可以下载到:
http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/gcc-4.7.0-1/gcc-core-4.7.0-1-mingw32-bin.tar.lzma/download,是安装Mingw时没有安装完全导致的。后来也试了一下tdm-gcc,这个打包的mingw中比较完全,比Mingw 官网的那个安装工具安装的全面些。最后编译go-sqlite3通过,再次编译示例代码,正常通过,然后用sqlite的shell 工具建立表结构,运行后结果正确。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!