This document describes how Windows support was implemented for gosseract and the key learnings from the development process.
gosseract is a Go wrapper for Tesseract OCR that uses CGO to interface with the C API. Supporting Windows required solving several challenges related to CGO compilation, library linking, and runtime DLL discovery.
Before this implementation, Windows support was blocked by issue #262. The main pain points were:
- No pre-built Tesseract libraries: Users had to compile Tesseract from source
- MSVC vs MinGW incompatibility: vcpkg builds Tesseract with MSVC, but Go's CGO on Windows uses MinGW (GCC)
- Complex build setup: Multiple environment variables and paths needed configuration
The original tessbridge.cpp used the C++ API which has name mangling issues between MSVC and MinGW. We rewrote it as tessbridge.c using the pure C API (tesseract/capi.h), which has stable ABI across compilers.
Key file: tessbridge.c
vcpkg installs MSVC-compiled DLLs (.dll) and import libraries (.lib). MinGW's linker needs .a import libraries. We use gendef and dlltool (included with MinGW) to create them:
# Generate .def file from DLL
gendef tesseract55.dll
# Create MinGW import library
dlltool -d tesseract55.def -l libtesseract55.a -D tesseract55.dllWindows doesn't have reliable pkg-config support. Instead of:
// #cgo pkg-config: tesseract leptWe use explicit flags in preprocessflags_windows.go:
// #cgo CFLAGS: -Wno-unused-result
// #cgo LDFLAGS: -ltesseract -lleptonicaThe actual include/library paths are provided via environment variables:
CGO_CFLAGS:-IC:/vcpkg/installed/x64-windows/includeCGO_LDFLAGS:-LC:/vcpkg/installed/x64-windows/lib
In GitHub Actions with bash shell on Windows, CGO_ENABLED defaults to 0 even though Go detects a C compiler. Always set it explicitly:
env:
CGO_ENABLED: "1"When using bash shell on Windows, the PATH environment variable in the YAML env: section doesn't work as expected for Go's CGO. The C compiler must be specified with full path:
env:
CC: C:/mingw64/bin/gcc.exe
CXX: C:/mingw64/bin/g++.exeEven after successful compilation, tests will fail with exit status 0xc0000135 (STATUS_DLL_NOT_FOUND) if DLLs aren't in PATH at runtime. Export PATH in the script:
export PATH="/c/mingw64/bin:/c/vcpkg/installed/x64-windows/bin:$PATH"When creating symlinks like libtesseract.a -> libtesseract55.a, be careful with glob patterns. If the symlink already exists, libtesseract*.a will match both files:
# BAD: matches libtesseract.a too
for f in libtesseract*.a; do ln -sf "$f" libtesseract.a; done
# GOOD: only matches versioned files
for f in libtesseract[0-9]*.a; do ln -sf "$f" libtesseract.a; doneTests require eng.traineddata. Download it and set TESSDATA_PREFIX:
- run: |
mkdir -p /c/tessdata
curl -sL -o /c/tessdata/eng.traineddata \
https://github.com/tesseract-ocr/tessdata/raw/main/eng.traineddata
- env:
TESSDATA_PREFIX: C:/tessdata- Without cache: ~22 minutes (compiles Tesseract and all dependencies)
- With cache: ~4 minutes
Cache these directories:
path: |
C:/vcpkg/installed
C:/vcpkg/packages
C:/vcpkg/buildtreesgosseract/
├── tessbridge.c # C API bridge (not C++)
├── tessbridge.h # Header file
├── preprocessflags_windows.go # Windows-specific CGO flags
├── preprocessflags_darwin.go # macOS-specific CGO flags
├── preprocessflags_x.go # Linux/other platforms
└── .github/workflows/
└── windows-ci.yml # Windows CI workflow
The Windows CI (windows-ci.yml) performs these steps:
- Checkout - Get the code
- Setup Go - Install Go 1.24+
- Cache vcpkg - Restore cached packages if available
- Install Tesseract -
vcpkg install tesseract:x64-windows - Create import libraries - Generate
.afiles from DLLs - Download tessdata - Get
eng.traineddata - Run tests - With proper environment variables
Users who want to build gosseract on Windows locally need:
-
MinGW-w64 (for GCC compiler)
-
vcpkg with Tesseract installed
-
Environment variables set:
export CGO_ENABLED=1 export CC=/c/mingw64/bin/gcc.exe export CGO_CFLAGS="-IC:/vcpkg/installed/x64-windows/include" export CGO_LDFLAGS="-LC:/vcpkg/installed/x64-windows/lib" export TESSDATA_PREFIX="C:/tessdata" export PATH="/c/mingw64/bin:/c/vcpkg/installed/x64-windows/bin:$PATH"
-
MinGW import libraries (
.afiles) created from vcpkg's DLLs
- Issue #262 - Original Windows support issue
- Tesseract C API
- vcpkg - C++ package manager
- MinGW-w64 - GCC for Windows
- 2026-01-16: Initial implementation completed
- Commits on
windows/cibranch document the iterative debugging process