二年ぐらい前には、まだcgoしか無いようなドライバもそこそこ存在してましたが、cgo freeのドライバに変えてコンパイルをすっきりさせた方が良さそうです
cgo freeでは無いドライバが含まれるコードを普通にコンパイルしてラズパイzeroで実行させると、
$ ./rasp_zero
2025/01/12 17:17:17 "Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub":
create table foo (id integer not null primary key, name text);
delete from foo;
と言われるし、cgo対応のlinkerはいまいち不明だし、というわけで以下のリンクのサンプルコード(実は上のエラーメッセージはオリジナルのソースをコンパイルしてます)をcgo freeドライバに入れ替え
https://zenn.dev/teasy/articles/go-sqlite3-sample
github.com/mattn/go-sqlite3
を、
modernc.org/sqlite
に変更して、db openのコードを変更するだけでcgo freeとなって、
% GOOS=linux GOARCH=arm GOARM=6 go build -o rasp_zero
でコンパイルするとラズパイzeroで動くバイナリが出力されます
実はcgo free以外に、M1 Macの動作ではgo run ***では動作しても、./***では起動も終了もしないという不思議な現象が出てましたが、この件も一緒に解決、ただしこの現象ではIntel Macでは出ないという怪しげな現象でした
orm(例えばgormなど)もcgo freeにできるので、今後はcgoが必要なのはおそらくよほどな時になりそうです
<コードは>
sql.open()が変わっただけです
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "modernc.org/sqlite"
)
func main() {
os.Remove("./foo.db")
// original
// db, err := sql.Open("sqlite3", "./foo.db")
//
db, err := sql.Open("sqlite", "./foo.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
sqlStmt := `
create table foo (id integer not null primary key, name text);
delete from foo;
`
_, err = db.Exec(sqlStmt)
if err != nil {
log.Printf("%q: %s\n", err, sqlStmt)
return
}
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
for i := 0; i < 100; i++ {
_, err = stmt.Exec(i, fmt.Sprintf("こんにちわ世界%03d", i))
if err != nil {
log.Fatal(err)
}
}
tx.Commit()
rows, err := db.Query("select id, name from foo")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
fmt.Println(id, name)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
stmt, err = db.Prepare("select name from foo where id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
var name string
err = stmt.QueryRow("3").Scan(&name)
if err != nil {
log.Fatal(err)
}
fmt.Println(name)
_, err = db.Exec("delete from foo")
if err != nil {
log.Fatal(err)
}
_, err = db.Exec("insert into foo(id, name) values(1, 'foo'), (2, 'bar'), (3, 'baz')")
if err != nil {
log.Fatal(err)
}
rows, err = db.Query("select id, name from foo")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
fmt.Println(id, name)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
P.S. 2025/1/13
”実はcgo free以外に、M1 Macの動作ではgo run ***では動作しても、./***では起動も終了もしないという不思議な現象が出てました”
この件に関連して、DB(sqlite3)を使う別のコードではビルドもできず、やはりIntel Macでは問題なくビルドできて動作したので、おそらくVenturaのアップデートと関連ありますね
admin