Skip to content

fix(build): add CGO build tags to fix Docker static builds#138

Merged
hrygo merged 1 commit into
mainfrom
fix/135-docker-build-load-extension
Feb 10, 2026
Merged

fix(build): add CGO build tags to fix Docker static builds#138
hrygo merged 1 commit into
mainfrom
fix/135-docker-build-load-extension

Conversation

@yangxb2010000

Copy link
Copy Markdown
Collaborator

🐛 Problem

Docker 静态构建失败,错误信息:

store/db/sqlite/sqlite_extension.go:35:21: sqliteConn.LoadExtension undefined 
(type *sqlite3.SQLiteConn has no field or method LoadExtension)

CI Failure: https://github.com/hrygo/divinesense/actions/runs/21849819582/job/63053719047

🔍 Root Cause

PR #131 添加的 sqlite_extension.gosqlite_vec_loader.go 使用了 CGO 专属的 API:

  • sqlite3.SQLiteConn 类型(仅在 CGO 模式下可用)
  • LoadExtension() 方法(仅在 CGO 模式下可用)

但 Dockerfile 使用 CGO_ENABLED=0 进行静态编译:

CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build ...

✅ Solution

使用 build tags 分离 CGO 和非 CGO 实现:

修改文件

  1. sqlite_extension.go: //go:build !sqlite_vec && cgo

    • CGO 环境:从动态库加载扩展(.so/.dylib)
    • 非 CGO:跳过此文件
  2. sqlite_vec_loader.go: //go:build !sqlite_vec && cgo

    • CGO 环境:尝试多个扩展路径
    • 非 CGO:跳过此文件
  3. sqlite_extension_stub.go (NEW): //go:build !sqlite_vec && !cgo

    • 非 CGO 环境:返回错误(使用 Go fallback)
    • CGO:跳过此文件

Build Matrix

sqlite_vec CGO Implementation
false true Dynamic loader
false false Stub (Go fallback)
true N/A Static linking

✅ Verification

  • CGO_ENABLED=0 编译成功(Docker 静态构建)
  • CGO_ENABLED=1 编译成功(标准构建)
  • ✅ sqlite-vec 扩展正常加载(18 个函数)
  • ✅ 本地测试通过
  • ✅ 无功能回归

📊 Impact

  • ✅ Docker 镜像可以成功构建
  • ✅ 非构建使用 Go fallback 进行向量搜索
  • ✅ CGO 构建保持完整的 sqlite-vec 支持

🔗 Related


Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com

Fixes #135

Root cause:
- sqlite_extension.go and sqlite_vec_loader.go use CGO-only APIs
  (sqlite3.SQLiteConn.LoadExtension)
- Docker builds use CGO_ENABLED=0 for static compilation
- These files were being compiled in non-CGO environment, causing:
  "LoadExtension undefined (type *sqlite3.SQLiteConn has no field or method)"

Solution:
Use build tags to separate CGO and non-CGO implementations:

1. sqlite_extension.go: !sqlite_vec && cgo
   - CGO environment: Load extension from dynamic library (.so/.dylib)
   - Non-CGO: Skip this file

2. sqlite_vec_loader.go: !sqlite_vec && cgo
   - CGO environment: Try multiple extension paths
   - Non-CGO: Skip this file

3. sqlite_extension_stub.go: !sqlite_vec && !cgo (NEW)
   - Non-CGO environment: Return error (use Go fallback)
   - CGO: Skip this file

Build matrix:
+------------+------------+----------------------+
| sqlite_vec | CGO       | Implementation        |
+------------+------------+----------------------+
| false      | true      | Dynamic loader       |
| false      | false     | Stub (Go fallback)   |
| true       | N/A       | Static linking       |
+------------+------------+----------------------+

Verification:
- ✅ CGO_ENABLED=0 build successful (Docker static build)
- ✅ CGO_ENABLED=1 build successful (standard build)
- ✅ sqlite-vec extension loads correctly (18 functions)
- ✅ Local testing passed
- ✅ No regression in existing functionality

Impact:
- Docker images can now build successfully
- Non-CGO builds use Go fallback for vector search
- CGO builds maintain full sqlite-vec support

Refs #135
Refs #131

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@hrygo hrygo merged commit 8f51b36 into main Feb 10, 2026
13 checks passed
@hrygo hrygo deleted the fix/135-docker-build-load-extension branch February 10, 2026 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[fix] Docker build fails with "LoadExtension undefined" after PR #131

2 participants