[Go] Gorm + SQLite – cgo freie Version
Hi,
in einem meiner letzten Entwicklungen in Golang bin ich auf das Problem gestoßen, dass die Binary für Windows nicht funktionierte da diese mit der Option CGO_ENABLED=0 kompiliert wurde.
Was ist CGO?
Cgo ist eine Schnittstelle für Go, die es ermöglicht, C-Code direkt aus einem Go-Programm aufzurufen. Mit cgo kann man C-Funktionen schreiben, die von Go-Code aus aufrufbar sind und umgekehrt. Um cgo zu verwenden, muss man normales Go-Code schreiben, das ein Pseudo-Paket “C” importiert. Der Go-Code kann dann auf Typen wie C.size_t, Variablen wie C.stdout oder Funktionen wie C.putchar verweisen. Wenn der Import von “C” unmittelbar von einem Kommentar vorangestellt wird, wird dieser Kommentar, der als Präambel bezeichnet wird, als Header beim Kompilieren der C-Teile des Pakets verwendet.
CGO_ENABLED=1 ?
Ich versuchte also CGO zu aktivieren und das Binary erneut zu kompilieren. Ich setzte also die Option CGO_ENABLED=1 und kurze Zeit später blickte ich in die nächste Fehlermeldung.
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -o bin/tool.exe cmd/main.go
# runtime/cgo
gcc: error: unrecognized command-line option ‘-mthreads’; did you mean ‘-pthread’?
Ich fügte danach das Flag -pthreads hinzu und bekam die nächstee Fehlermeldung. Ok dachte ich mir, dass Probblem muss doch bereits jemand gelöst haben. Und siehe da, es war auch so.
Gorm cgo
Das in Go geschriebene ORM Gorm hatte in Ihrem Github Repo dazu bereits einige offene Issues. Einmal hier https://github.com/go-gorm/gorm/issues/4173 und einmal hier https://github.com/go-gorm/gorm/issues/4922. Im zweiten Issue findet man beim scrollen aber eine Lösung, es wurde eine cgo Freie SQLite Version erstellt.
glebarez/sqlite
Es gibt einen funktionierenden cgo freien Fork https://github.com/glebarez/sqlite welcher kompatiblem mit Gorm ist. Dazu zieht ihr euch die Abhängigkeit in euer Go Projekt mitttels:
go get https://github.com/glebarez/sqlite
Anschließend tauscht Ihr die Gorm implementierung aus und ersetzt Sie mit der neuen Version. Das sieht dann ungefähr so aus.
import (
"github.com/glebarez/sqlite"
"gorm.io/gorm"
)
db, err := gorm.Open(sqlite.Open("sqlite.db"), &gorm.Config{})
Nun sollte eure Anwendung wieder wie gewohnt funktionieren und Ihr könnt eure Windows Binary CGO frei kompilieren. Die Umsetzung ist ein klein wenig langsamer aber hat dafür einen riesigen Vorteil, der es mir persönlich definitiv Wert die Implementierung auszutauschen. Einen Benchmark zu dem Pkg in Vergleich zur CGO Version findet Ihr hier.
Ich hoffe diese Info hilft dem ein oder anderen.