Adding or Updating Go Projects - informalsystems/cosmos.nix Wiki

Many of the projects in the cosmos ecosystem use go. Cosmos.nix has chosen to use gomod2nix to manage go dependencies based off of go.mod and go.sum files. We have created a haskell script for automatically syncing go dependencies, which are locked in a go-modules.toml file.

Adding a go project.

Updating a go project.

Common issues

CGO_ENABLED

If you find yourself faced with an error like this:

vendor/gopkg.in/olebedev/go-duktape.v3/dbgsockettransport.go:14:16: undefined: Context
vendor/gopkg.in/olebedev/go-duktape.v3/dbgsockettransport.go:16:15: undefined: DebugRequestFunc
vendor/gopkg.in/olebedev/go-duktape.v3/dbgsockettransport.go:17:15: undefined: DebugDetachedFunc
vendor/gopkg.in/olebedev/go-duktape.v3/dbgsockettransport.go:31:30: undefined: Context
vendor/gopkg.in/olebedev/go-duktape.v3/dbgsockettransport.go:33:14: undefined: DebugRequestFunc
vendor/gopkg.in/olebedev/go-duktape.v3/dbgsockettransport.go:34:15: undefined: DebugDetachedFunc
vendor/gopkg.in/olebedev/go-duktape.v3/timers.go:11:10: undefined: Context
vendor/gopkg.in/olebedev/go-duktape.v3/timers.go:30:10: undefined: Context
vendor/gopkg.in/olebedev/go-duktape.v3/timers.go:37:20: undefined: Context
vendor/gopkg.in/olebedev/go-duktape.v3/timers.go:63:22: undefined: Context
vendor/gopkg.in/olebedev/go-duktape.v3/timers.go:63:22: too many errors

or another common one is:

github.com/CosmWasm/wasmvm/api
# github.com/CosmWasm/wasmvm/api
vendor/github.com/CosmWasm/wasmvm/api/mock_failure.go:15:27: undefined: GoAPI
vendor/github.com/CosmWasm/wasmvm/api/mocks.go:192:2: undefined: GasMeter
vendor/github.com/CosmWasm/wasmvm/api/mocks.go:193:20: undefined: Gas

You might need to add CGO_ENABLED = "1"; to the default.nix for your go project

example

Tests failing in check phase

If you get an error message from the check phase while building, that mentions the homeless-shelter, a message like this:

    cmd_test.go:27:
                Error Trace:    cmd_test.go:27
                Error:          Received unexpected error:
                                couldn't make client config: mkdir /homeless-shelter: permission denied
                Test:           TestInitCmd

You probably need to add the code below to the default.nix for your project.

example

  preCheck = ''
    export HOME="$(mktemp -d)"
  '';

Nix usually aliases $HOME to a directory called /homeless-shelter with no permissions enabled, so that your code is forced to avoid impure environment variables. In this case we want to allow a temporary directory for testing purposes.

If the above solution doesn't work, or you get an error message that suggests some impure action failed (this is usually calling out to the network), then you might have to disable tests altogether. This shouldn't be an issue since the project should run its own tests in CI, but it is a bit unfortunate. The solution is to add doCheck = false; to the default.nix for your project.

example

Multiple go applications in the same repo

Sometimes there are multiple go modules in a repo, and gomod2nix will get confused. If you get an error like this:

Building subPackage ./cosmovisor
main module (github.com/cosmos/cosmos-sdk) does not contain package github.com/cosmos/cosmos-sdk/cosmovisor

You might have to manually remove that separate module. The easiest way to do this is use the post configure phase to remove that directory. You can do this by adding the code below to your default.nix.

  postConfigure = ''
    rm -rf ./cosmovisor
  '';

example

Relative path directives in go.mod

I created an issue in the upstream repository about this, but I think gomod2nix does not handle relative path directives in go.mod, therefore I added the ability to provide customVendorSrc so that you can manually add the project to the vendors/ directory. You might be having this issue if you come across this error, however you will get a similar error if you have not synced your go modules, so try entering a nix shell (nix develop) and running syncGoModules first.

app/app.go:10:2: cannot find package "." in:
        /build/source/vendor/github.com/regen-network/regen-ledger/types/module
app/app.go:95:2: cannot find package "." in:
        /build/source/vendor/github.com/regen-network/regen-ledger/types/module/server
app/app.go:96:2: cannot find package "." in:
        /build/source/vendor/github.com/regen-network/regen-ledger/x/ecocredit
app/app.go:11:2: cannot find package "." in:
        /build/source/vendor/github.com/regen-network/regen-ledger/x/ecocredit/module

If this is indeed your error, you can resolve it by removing the directories that are referenced in the relative path directive, and adding them directly to the vendor/ bundle with the customVendorSrc attr in your default.nix. This is a pretty nasty issue, and I am hoping to find a better solution.

example

Dynamically linked libraries

This is probably your problem if you see a message like this:

> checking for references to /build/ in /nix/store/acyirvqpq99n71mdfm3jwv0xl6sv5rl0-juno...
> RPATH of binary /nix/store/acyirvqpq99n71mdfm3jwv0xl6sv5rl0-juno/bin/junod contains a forbidden reference to /build/
  For full logs, run 'nix log /nix/store/7c9gqkw39gmwa3hp0mjqkv1z76bx9i8v-juno.drv'.

Right now I don't have a solution for this, I need to figure out how to statically link a c library via nix.