Go
Go is a statically-typed language with syntax loosely derived from that of C, adding garbage collected memory management, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library.
Packaging go modules
There are helper tools such as vgo2nix and gomod2nix, however the nixpkgs library function buildGoModule (implementation) does an absolutely fantastic job in packaging standard go modules. See nixpkgs manual Language: Go
go.mod file
the go.mod file must be in the source root for buildGoModule. to change the source root, use
some-package = buildGoModule {
src = fetchFromGitHub {
# ...
} + "/path/to/module";
# ...
};
Install using Home Manger
Enable go in home manager config `home.nix` in `~/.config/nixpkgs`.
programs.go.enable = true;
Using cgo on NixOS
On NixOS, include files and libraries aren't kept in a system-wide search path. If a Go program uses cgo and attempts to include C header files, or link against libraries, compilation is likely to fail.
In order to expose header files and libraries in environment variable search paths, nix-shell can be used to enter an environment which provides the requested development dependencies.
For example, suppose a Go program includes <sys/capability.h> (provided by libcap), and links against libcap. To obtain an environment in which the program can be compiled, run:
$ nix-shell -p libcap go gcc
You can verify the presence of the necessary environment variables via the following command:
$ export | egrep 'NIX_.*(LDFLAGS|COMPILE|LINK)'
If you intend to compile against glibc statically (such as via go build -ldflags "-s -w -linkmode external -extldflags -static"), add glibc.static to the list of packages passed to nix-shell.
Compile go program with static compile flag
If go build -ldflags "-s -w -linkmode external -extldflags -static"
fails on NixOS, with the error message cannot find `-lpthread
and cannot find -lc
- it is because the linker cannot find static glibc to link with. You need to have glibc.static in your environment (and have CFLAGS/LDFLAGS adjusted accordingly).
One way to achieve this is to have something like the following as shell.nix
and run the compilation in a nix-shell:
with import <nixpkgs> {}; {
devEnv = stdenv.mkDerivation {
name = "dev";
buildInputs = [ stdenv go glibc.static ];
CFLAGS="-I${pkgs.glibc.dev}/include";
LDFLAGS="-L${pkgs.glibc}/lib";
};
}