I’m still quite new to NixOS but enjoying it. Packaging my first go applications has worked fine so far but with sqlc I’m a bit stuck. I found out some build dependencies (e.g. libpq_queryand xxHash) and added them. This resolved previous errors but now I’m stuck with the following error:
# github.com/pganalyze/pg_query_go/v2/parser
In file included from pg_query.c:2:
pg_query_internal.h:4:10: fatal error: postgres.h: No such file or directory
4 | #include "postgres.h"
| ^~~~~~~~~~~~
compilation terminated.
I thought adding postgresql to the buildInputs should fix this but it does not. What am I missing?
<postgres.h> in turn would refer to an external one, but admittedly that depends on how broken the C project is…
Edit: Ah, it looks like the -Iinclude from the cgo pragma in parser.go is being ignored, or the include directory simply isn’t fetched with the rest of the repo. I don’t know enough about how nix does go builds to help debug that.
When integrating this library using Go modules, and using a vendor/ directory, you will need to explicitly copy over some of the C build files, since Go does not copy files in subfolders without .go files whilst vendoring.
The best way to do so is to use modvendor, and vendor your modules like this:
But I have no clue how to incorporate into the build process.
Looks to me like it was closed because go packages are broken as intended (by the go devs).
The suggested workaround is to create the go vendor directory manually (well, in a bespoke script that just downloads all the dependencies)… Ugly, but admittedly upstream’s problem. This module apparently shouldn’t be written the way it is.
Thanks for looking into it. That what I understood as well. That would mean keeping a local copy of the whole repo and a vendor folder as I cannot download additional resources during the build process, right? Seems a bit overkill to me.
go: github.com/antlr/antlr4/runtime/Go/antlr@v0.0.0-20211208212222-82c441726976: reading file:///nix/store/jqr2rqb2mwk0dln2b5ii10jplcy7m5fc–v1.12.0-go-modules/github.com/antlr/antlr4/runtime/%21go/antlr/@v/v0.0.0-20211208212222-82c441726976.mod: open /nix/store/jqr2rqb2mwk0dln2b5ii10jplcy7m5fc–v1.12.0-go-modules/github.com/antlr/antlr4/runtime/!go/antlr/@v/v0.0.0-20211208212222-82c441726976.mod: no such file or directory
That is what I’m currently doing (both trying to your great idea to work an ls-ing through the store. It seems that the downloaded source is not a zip after all. Right now I’m having trouble patching the vendor folder as it seems that go stores the source in a zip file and also hashes it. I will try some more though.
I stumbled here with the exact same issue (and it seems like trying to find examples of the use case for proxyVendor also ends up here), and wanted to share a pitfall that left me scratching my head.
proxyVendor should eliminate the need to go mode -replace the dependency to point to a local path. It does exactly what it’s documented to do (runs go mod download which populates the module cache with all the files needed for go proxy to work).
The gotcha that I kept running into was the same error that @eike saw around the zip files not being found. This non-obvious thing here is that vendorSha256 changes when you switch from proxyVendor = false (default) to proxyVendor = true (because of the additional files that make up the module cache), which means that if you don’t update the vendorSha256 it will be referencing the go module dependencies retrieved via go mod vendor instead of the go mod download, which do not conform to what go proxy expects.
The result is that the following snippet is all that needed:
sqlc = pkgs.buildGoModule {
name = "sqlc";
src = sqlc; # replacing this which however you are getting the source e.g. fetchFromGitHub, via flake inputs, etc.
subPackages = [ "cmd/sqlc" ];
doCheck = false;
vendorSha256 = "sha256-LX8C7098P940wdg8yig6h6azAsxdai+vEVhjdILIoMQ=";
proxyVendor = true;
buildInputs = [
pkgs.xxHash
pkgs.libpg_query
pkgs.postgresql_14
];
};