Go

From NixOS Wiki
Revision as of 19:10, 13 September 2020 by Makefu (talk | contribs)
Jump to: navigation, search

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 go2nix, however the nixpkgs library function buildGoModule does an absolutely fantastic job in packaging standard go modules. See nixpkgs manual Language: Go

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";
  };
}