在VSCode中用Golang调用sqlite3连接器遇ld链接错误求助
问题
我在VSCode中使用Golang编写了一段仅实现SQLite3数据库连接及基础SQL操作的代码:
package main import ( "database/sql" "fmt" "log" "os" _ "github.com/mattn/go-sqlite3" ) type Users struct { UserId, intUname string } func main() { os.Remove("foo.db") db, err := sql.Open("sqlite3", "foo.db") if err != nil { log.Fatal(err) } defer db.Close() sql := `create table users (userId integer, uname text);` db.Exec(sql) sql = `insert into users(userId,uname) values(1,'Mike');` db.Exec(sql) sql = `insert into users(userId,uname) values(2,'John');` db.Exec(sql) rows, err := db.Query("select * from users") if err != nil { log.Fatal(err) } defer rows.Close() var users []Users = make([]Users, 0) for rows.Next() { var u Users rows.Scan(&u.UserId, &u.intUname) users = append(users, u) } fmt.Println(users) }
执行go run .时出现链接错误,报错信息如下:
csccl25013> go run . # github.com/goproject/sqlite3 /nfs/site/disks/simcloud_zhoudo1x_002/go/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1 /nfs/site/itools/em64t_SLES12SP5/pkgs/gcc/4.7.2/.bin/../lib64/gcc/x86_64-suse-linux/4.7.2/../../../../x86_64-suse-linux/bin/ld: /tmp/go-link-322571714/000015.o(.text+0x63): unresolvable AWAVAUATUSH��h�*H�T$(���� relocation against symbol `stderr@@GLIBC_2.2.5' /nfs/site/itools/em64t_SLES12SP5/pkgs/gcc/4.7.2/.bin/../lib64/gcc/x86_64-suse-linux/4.7.2/../../../../x86_64-suse-linux/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status
需要解决该错误,让代码正常执行并连接SQLite3。
解决方案
1. 修复代码中的字段类型/名称错误
你的Users结构体存在两处问题,会导致数据扫描失败:
- 数据库中
userId是integer类型,但结构体定义为string,类型不匹配 - 结构体字段
intUname与数据库列名uname不对应
修正后的代码片段:
type Users struct { UserId int Uname string } // 循环内的扫描语句同步修改 rows.Scan(&u.UserId, &u.Uname)
2. 解决链接错误(核心问题)
该链接错误源于GCC版本过低(4.7.2),github.com/mattn/go-sqlite3是依赖Cgo的包,旧版GCC无法兼容其编译后的链接需求,提供三种解决思路:
方案一:升级GCC版本
将GCC升级到5.4及以上版本(推荐GCC 8.x或更高):
- 如果服务器使用模块管理系统(如module),执行类似命令加载新版本:
module load gcc/8.3.0 - 若无法全局升级,可手动编译安装GCC到个人目录,然后将其bin路径加入
PATH环境变量
方案二:替换为纯Go实现的SQLite驱动
使用modernc.org/sqlite(完全基于Go实现,无需Cgo):
- 替换导入的驱动包:
import ( // 其他包不变 _ "modernc.org/sqlite" )
- 修改数据库打开语句的驱动名:
db, err := sql.Open("sqlite", "foo.db")
此方案无需依赖C编译器,兼容性更强,适合无法升级GCC的环境。
方案三:强制使用旧版C++ ABI编译
若必须保留当前GCC版本,可通过Cgo参数强制使用旧版ABI,解决符号链接问题:
CGO_CFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0" go run .
完成上述步骤后,重新执行go run .,代码应正常输出[{1 Mike} {2 John}]。
内容的提问来源于stack exchange,提问作者marks
相关产品推荐
相关产品推荐

