Go: Difference between revisions

From NixOS Wiki
imported>Milahu
link to implementation of buildGoModule
imported>Milahu
move buildGoPackage to separate section, add link to implementation
Line 2: Line 2:


== Packaging go modules ==
== Packaging go modules ==
There are helper tools such as [https://github.com/nix-community/vgo2nix vgo2nix] and [https://github.com/tweag/gomod2nix gomod2nix], however the nixpkgs library function '''buildGoModule''' ([https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/go-modules/generic/default.nix implementation]) does an absolutely fantastic job in packaging standard go modules.
The nixpkgs library function '''buildGoModule''' ([https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/go-modules/generic/default.nix implementation]) works in most cases of packaging go modules or applications.
See [https://nixos.org/manual/nixpkgs/stable/#sec-language-go nixpkgs manual '''Language: Go''']
See [https://nixos.org/manual/nixpkgs/stable/#sec-language-go nixpkgs manual '''Language: Go''']


=== go.mod file ===
=== buildGoModule ===
the <tt>go.mod</tt> file must be in the source root for <tt>buildGoModule</tt>.
the <tt>go.mod</tt> file must be in the source root for <tt>buildGoModule</tt>.
to change the source root, use
to change the source root, use
Line 16: Line 16:
   };
   };
</syntaxhighlight>
</syntaxhighlight>
=== buildGoPackage ===
If no <tt>go.mod</tt> file is available, '''buildGoPackage''' ([https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/go-packages/generic/default.nix implementation]) can be used.
Dependencies must be specified manually in a <tt>deps.nix</tt> file,
which is linked with
<syntaxhighlight lang=nix>
  some-package = buildGoPackage {
    # ...
    goDeps = ./deps.nix;
  };
</syntaxhighlight>
The <tt>deps.nix</tt> file can be generated with helper tools
such as [https://github.com/nix-community/vgo2nix vgo2nix]
and [https://github.com/tweag/gomod2nix gomod2nix].


==Install using Home Manger==
==Install using Home Manger==

Revision as of 19:24, 26 August 2021

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

The nixpkgs library function buildGoModule (implementation) works in most cases of packaging go modules or applications. See nixpkgs manual Language: Go

buildGoModule

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

buildGoPackage

If no go.mod file is available, buildGoPackage (implementation) can be used. Dependencies must be specified manually in a deps.nix file, which is linked with

  some-package = buildGoPackage {
    # ...
    goDeps = ./deps.nix;
  };


The deps.nix file can be generated with helper tools such as vgo2nix and gomod2nix.

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