go-sqlite3 icon indicating copy to clipboard operation
go-sqlite3 copied to clipboard

Proposal: sub-packages to enable optional features

Open emersion opened this issue 2 years ago • 8 comments

A common pain point when using go-sqlite3 is that enabling optional features requires adding a build tag to all go command invocations. For instance, when a program depends on FTS5, it's no longer possible to run go build, go test, etc as usual. End users need to explicitly add -tags sqlite_fts5 every time.

Here is a proposal to improve this. A new fts5 sub-package is introduce. Any program which depends on FTS5 can import it to turn on FTS5:

import _ "github.com/mattn/go-sqlite3/fts5"

What do you think?

emersion avatar Feb 09 '23 14:02 emersion

Have you tested this? AFAIK the #cgo directives are package-scoped. Consequently, specifying them in a sub-package like this won't have any effect.

rittneje avatar Feb 09 '23 15:02 rittneje

Yes, I have tested this and it works correctly.

AFAIU the cgo flags are not package-scoped, they are module-scoped. See: https://github.com/golang/go/issues/40041

emersion avatar Feb 09 '23 15:02 emersion

I just ran a simplified test case. From what I can tell, the #cgo directives are indeed package-scoped, not module-scoped.

cgotest/go.mod

module cgotest

go 1.18

cgotest/main.go

package main

import _ "cgotest/subpackage"

/*
#include <sqlite3.h>
*/
import "C"

func main() {
	C.sqlite3_open_v2(nil, nil, 0, nil)
}

cgotest/subpackage/c.go

package subpackage

/*
#cgo LDFLAGS: -lsqlite3
*/
import "C"
$ go run main.go 
# command-line-arguments
Undefined symbols for architecture x86_64:
  "_sqlite3_open_v2", referenced from:
      __cgo_6884829902c1_Cfunc_sqlite3_open_v2 in _x002.o
     (maybe you meant: __cgo_6884829902c1_Cfunc_sqlite3_open_v2)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

rittneje avatar Feb 09 '23 16:02 rittneje

On my system this builds just fine (and fails at runtime because of the nil parameters):

> go version
go version go1.20 linux/amd64
> go run main.go
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f21b6f2da2d]

emersion avatar Feb 09 '23 16:02 emersion

Okay, based on further testing, it seems this behavior changed in Go 1.19. However, it was not mentioned in the release notes. And I'm not sure if it was intentional, since the cgo docs make no mention of modules or sub-packages. I'm going to file an issue with the Go authors for this.

In the meantime, I don't think we can accept this change, since this module intends to support Go 1.18.

rittneje avatar Feb 09 '23 17:02 rittneje

Note, the result of this discussion is at https://github.com/golang/go/issues/58438#issuecomment-1424957107.

emersion avatar Feb 17 '23 09:02 emersion

In the end I opted to bundle FTS5 in a separate Go package: https://git.sr.ht/~emersion/go-sqlite3-fts5

emersion avatar Feb 17 '23 12:02 emersion

Now that this package depends on Go 1.19, would you be open to considering this PR for inclusion?

emersion avatar Jul 06 '25 11:07 emersion