Hacker News new | past | comments | ask | show | jobs | submit login

What's your issue with SQLite+Go on Windows? I might be able to help



I just tried it now (a year later), same compiler error (using msys2):

    # github.com/mattn/go-sqlite3
    /usr/lib/gcc/x86_64-pc-msys/10.2.0/../../../../x86_64-pc-msys/bin/ld: cannot find -lmingwex
    /usr/lib/gcc/x86_64-pc-msys/10.2.0/../../../../x86_64-pc-msys/bin/ld: cannot find -lmingw32
    collect2: error: ld returned 1 exit status
The go-sqlite3 GitHub repo has tons of Windows-related issues, one just opened yesterday in fact. I'm not an experienced C programmer, I'm not well versed in compiler/linker toolchains, I know it's super tricky (especially on Windows) but I don't expect my clients to be experts either. I actually spent a few hours trying to solve this last time, time I could have spent coding.

It's not a problem with Go, per se, but it does create non-trivial requirements toolchain setup on Windows, which ruled out Go for me. The whole toolchain just feels a bit... flakey, setting up GOPATH and such (although, that seems to no longer be the case?). Rust's crates, just as an example, are amazing, I've never had a single problem with them (more than I can say for npm..) I know it's just one example, but sqlite3 is brilliant. This immediately ruled out Go for me for that project.


> It's not a problem with Go, per se, but it does create non-trivial requirements toolchain setup on Windows, which ruled out Go for me. The whole toolchain just feels a bit... flakey, setting up GOPATH and such (although, that seems to no longer be the case?). Rust's crates, just as an example, are amazing, I've never had a single problem with them (more than I can say for npm..) I know it's just one example, but sqlite3 is brilliant. This immediately ruled out Go for me for that project.

GOPATH is gone, thankfully, and with the introduction of modules. As with many things, crappy tutorials littered around the internet make things difficult. The toolchain itself is pretty damn easy to set up, it "just works" unless you want to use cgo (or one of your modules does), and in that case you're just left hanging. It's pretty clear that go despite _running_ cross platform doesn't particularly care about windows, e.g. the path package basically doesn't support windows natively, the cgo mess, etc.

> Rust's crates, just as an example, are amazing,

Rust has it's own set of problems that you're glossing over here. As an example, many popular crates required nightly last time I looked. Rust's compile times are incredibly painful too, and one of the worst offenders is the #1 json library for rust (serde).


The only popular crate that I can think of that still requires nigthly is Rocket[0], the 0.5 release does not but the lack of maintenance means that it has been three years since 0.4 and months since the last update. In that time Warp, Axum, Tide, Actix and many more frameworks that are all on stable has eaten its lunch. As for long compile times, I agree, it has gotten heaps better but is still far from Go (nor will it ever get that good), but for most my projects with incremental debug builds its in the ballpark of ~2 seconds, which is good enough for me and `cargo check` is close to instant. Release builds, yeah, they are slow.

[0]: https://github.com/SergioBenitez/Rocket


> Rust's compile times are incredibly painful too, and one of the worst offenders is the #1 json library for rust (serde).

Go and Rust sort of took opposite paths in terms of the compiler.

Rust spends the compilation time (for release compiles) to generate the fastest binaries the compiler can emit. The article talks about Go adding things like "A recent improvement was in version 1.17, which passes function arguments and results in registers" that's stuff that compilers like llvm have been doing pretty much at inception (20 years).

Go has optimized for compilation speed with the understanding that "Well, it's probably not CPU time that is REALLY making your software slow".

Go compiles faster and rust compiles faster results.


This is why I think Go could benefit with an LLVM target.


They are painful... Running the executable at the end with such a tiny footprint and outstanding predictable performance is very gratifying, however. It feels like the language and the compiler love you, they just have to work a little harder to deal with the complexity of macros and generics!


Yeah, if you use msys2 then you need mingw and such installed. But that's only an issue if you want to compile from a Windows host. You can compile from a POSIX host and target Windows just fine.

There are also pure Go implementations of sqlite3, should you wish to compile from a Windows host and do away with the msys2 dependency.

I'm curious what your clients are if they need to compile the code themselves (which suggests they're using your code as a package?) but which they don't need to use Go (which suggests you could just share them a compiled executable and thus they don't need to resolve this problem themselves). In either case, Go native code would fix that (albeit you don't get that for free -- you'd see a drop in query performance).

The GOPATH issue I never saw as flaky personally. It's one environmental variable, it was dead easy to set up and once it was set it worked fine. But my personal opinions aside, it was unpopular so yes, it no longer needs to be set. Ironically though, I personally think that's made things more complicated than less (or rather it's shifted the complexity elsewhere in the toolchain).

Rust crates are good but you'll find compiling against POSIX C code on Windows to be problematic regardless of the language. Rust just hides that problem because its developers are dogmatic enough that any C code is rewritten in Rust anyway. And Rust is performant enough that such rewrites are usually comparable, often even favorable, in speed to their C counterpart. That rarely seems the case with Go.

So it sounds like there isn't much point trying to solve your issue because you've already rewritten it in another language. However I assure you it is solvable in a number of different ways depending on what your underlying requirements were.


Thank you for your explanation and fair comparison. I'm sure that a seasoned C/Go programmer would skirt around those difficulties or be using POSIX in the first place, I prefer languages that do not impose any constraints on your choice of OS, even if I do prefer Linux for development, but it's not good enough to replace my daily driver.

I don't think there will be a Rust implementation of sqlite3 in the near future, it would be a monumental task. Having the C bindings just work with static compilation in Rust was a deal-maker for that particular personal project, even if it's just because some crate maintainer went to the extra effort to make a robust cross-platform build script and nothing to do with the language itself, it shows that they put in some effort and pride, but I also get tired of the hype and the Rewrite in Rust catchphrase.

I'm a university student, as part of my student job I had to develop a backend application. Someone has to be able to pick it up after me, hence simplicity and easy of use. In the end, I chose Node.js after strongly considering Go, Rust and Elixir that have more cohesive tooling (formatter, linter, better module system!), it was the easiest to justify. I couldn't trust myself to not find any issues/complications with Rust or Go and I just can't afford them running into these issues and explaining to them "oh, you need to set up a C compiler toolchain on Windows".


> I'm sure that a seasoned C/Go programmer would skirt around those difficulties or be using POSIX in the first place, I prefer languages that do not impose any constraints on your choice of OS, even if I do prefer Linux for development, but it's not good enough to replace my daily driver.

It's not Go that imposed that restraint. It was the C API used for sqlite3 that did. There's nothing stopping you using C in Go on Windows without requiring msys2.

> I don't think there will be a Rust implementation of sqlite3 in the near future, it would be a monumental task.

You say that but there's already a pure Go version and Rust ecosystem is famed for rewriting C/C++ stuff. So I wouldn't be so sure.

> I'm a university student, as part of my student job I had to develop a backend application. Someone has to be able to pick it up after me, hence simplicity and easy of use. In the end, I chose Node.js after strongly considering Go, Rust and Elixir that have more cohesive tooling (formatter, linter, better module system!), it was the easiest to justify. I couldn't trust myself to not find any issues/complications with Rust or Go and I just can't afford them running into these issues and explaining to them "oh, you need to set up a C compiler toolchain on Windows".

Sounds like you made a really smart choice there. I'm impressed too because mature judgements like these are a skill even a great many senior engineers lack so to have that kind of foresight while you're still at university is impressive.


You certainly have to set one up for Rust. I'm not sure about Go. Unless I need speed I generally reach for python, but even it sometimes needs a C compiler. I'm surprised the Node.js never needs one? Usually these "higher level" languages end up (on large projects) ultimately calling out to c/c++ libraries of some sort that aren't included in the "native libraries". Is that not true for node.js ?


Yes, Rust guides you though setting up tge MSVC toolchain, then everything Just Works™, I'm not sure which toolchain the Rust sqlite3 bindings crate uses, but it also just works.

Actually, a lot of Node.js is written in plain JS, even large parts of the runtime itself, I've never needed a C compiler. This was mostly to make it easier for contributers that don't want to learn C++.

It's extremely rare for libraries to require any system dependencies, such as a C toolchain. Sharp (libvips bindings) will try to download precompiled binaries from a bucket somewhere, this is all done in ad hoc postinstall scripts, for better or for worse... Other libraries use JS as a C compile target with asm.js, opinions aside, it actually works pretty well.


Why don't you try a pure-Go implementation? Should have enough features implemented for basic use

https://github.com/cvilsmeier/sqinn-go




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: