Go: Difference between revisions
Tags: Undo Mobile edit Mobile web edit |
m use monospace formatting where applicable, add more links, update link to the Go homepage |
||
| (2 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
[https:// | [https://go.dev/ 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. | ||
== buildGoModule == | == buildGoModule == | ||
nixpkgs includes a library function called '''buildGoModule''' ([https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/go/module.nix implementation]) See [https://nixos.org/manual/nixpkgs/stable/#sec-language-go nixpkgs manual '''Language: Go'''] | nixpkgs includes a library function called '''buildGoModule''' ([https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/go/module.nix implementation]) See [https://nixos.org/manual/nixpkgs/stable/#sec-language-go nixpkgs manual '''Language: Go'''] | ||
<code>buildGoModule</code> uses the version of Go that's included in <code>nixpkgs</code> to build the software. | |||
==== Using a specific version of Go ==== | ==== Using a specific version of Go ==== | ||
To build for a specific version of Go, you may need to find the appropriate | To build for a specific version of Go, you may need to find the appropriate <code>pkgs.buildGoXXXModule</code> function to use. | ||
This function may not be present in the version of nixpkgs that you're using, for example, | This function may not be present in the version of nixpkgs that you're using, for example, <code>buildGo122Module</code> is not available in <code>github:NixOS/nixpkgs/nixos-23.05</code>, but is available in <code>github:NixOS/nixpkgs/nixos-unstable</code>. | ||
==== Subpackages ==== | ==== Subpackages ==== | ||
By default, | By default, <code>buildGoModule</code> will attempt to build the <code>main</code> package that's in the root of the source code location. | ||
However, it's a common pattern in Go applications to have binaries within the | However, it's a common pattern in Go applications to have binaries within the <code>./cmd/binary-name</code> directory instead. | ||
Setting the | Setting the <code>subPackages</code> attribute to be a list of the packages to build supports this pattern. | ||
==== Example (downloading source code from Github) ==== | ==== Example (downloading source code from Github) ==== | ||
The following | The following <code>flake.nix</code> demonstrates how to build a Go module, where the source code is located in Github. To use it, copy this file as <code>flake.nix</code> into an empty directory on your computer, and run <code>nix build</code>. Nix will download the source code, including dependencies, and produce a <code>./result</code> folder containing a <code>ziti</code> binary. | ||
Running | Running <code>nix shell</code> will create a shell, where you can execute the <code>ziti</code> binary.<syntaxhighlight lang="nix"> | ||
{ | { | ||
description = "OpenZiti"; | description = "OpenZiti"; | ||
| Line 62: | Line 62: | ||
==== Example (local source) ==== | ==== Example (local source) ==== | ||
If you want to build a local project with Nix, replace the | If you want to build a local project with Nix, replace the <code>src</code> attribute to be the local directory, e.g.:<syntaxhighlight lang="nix"> | ||
some-package = buildGoModule { | some-package = buildGoModule { | ||
src = ./. | src = ./. | ||
| Line 92: | Line 92: | ||
== Using cgo on NixOS == | == 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. | On NixOS, include files and libraries aren't kept in a system-wide search path. If a Go program uses [https://go.dev/wiki/cgo 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, <tt>nix-shell</tt> can be used to enter an environment which provides the requested development dependencies. | In order to expose header files and libraries in environment variable search paths, <tt>nix-shell</tt> can be used to enter an environment which provides the requested development dependencies. | ||
For example, suppose a Go program includes <tt><sys/capability.h></tt> (provided by <tt>libcap</tt>), and links against <tt>libcap</tt>. To obtain an environment in which the program can be compiled, run: | For example, suppose a Go program includes <code><tt><sys/capability.h></tt></code> (provided by <tt>libcap</tt>), and links against <tt>libcap</tt>. To obtain an environment in which the program can be compiled, run: | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
| Line 109: | Line 109: | ||
If you intend to compile against glibc statically (such as via <tt>go build -ldflags "-s -w -linkmode external -extldflags -static"</tt>), add <tt>glibc.static</tt> to the list of packages passed to <tt>nix-shell</tt>. | If you intend to compile against glibc statically (such as via <tt>go build -ldflags "-s -w -linkmode external -extldflags -static"</tt>), add <tt>glibc.static</tt> to the list of packages passed to <tt>nix-shell</tt>. | ||
If you encounter [https://github.com/go-delve/delve/issues/3085 this issue] and receive an error about _FORTIFY_SOURCE when running delve (for example in VSCode), put <tt>hardeningDisable = [ "fortify" ];</tt> inside shell.nix or in the <tt>mkShell</tt> invocation argument like this: | If you encounter [https://github.com/go-delve/delve/issues/3085 this issue] and receive an error about <code>_FORTIFY_SOURCE</code> when running delve (for example in [[Visual Studio Code|VSCode]]), put <tt>hardeningDisable = [ "fortify" ];</tt> inside <code>shell.nix</code> or in the <tt>mkShell</tt> invocation argument like this: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
pkgs.mkShell { | pkgs.mkShell { | ||
| Line 118: | Line 118: | ||
== Compile go program with static compile flag == | == Compile go program with static compile flag == | ||
If <code>go build -ldflags "-s -w -linkmode external -extldflags -static"</code> fails on NixOS, with the error message <code>cannot find `-lpthread</code> and <code>cannot find -lc</code> - 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). | If <code>go build -ldflags "-s -w -linkmode external -extldflags -static"</code> fails on NixOS, with the error message <code>cannot find `-lpthread</code> and <code>cannot find -lc</code> - it is because the linker cannot find static glibc to link with. You need to have <tt>glibc.static</tt> in your environment (and have <code>CFLAGS</code>/<code>LDFLAGS</code> adjusted accordingly). | ||
One way to achieve this is to have something like the following as <code>shell.nix</code> and run the compilation in a nix-shell: | One way to achieve this is to have something like the following as <code>shell.nix</code> and run the compilation in a <tt>nix-shell</tt>: | ||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
| Line 134: | Line 134: | ||
== Compile go program with static compile flag (take 2) == | == Compile go program with static compile flag (take 2) == | ||
Linking against glibc.static does not really work because glibc does not really like static linking. You get a warning like <code>warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking</code>. To really create a static build, use musl. Example based on buildGoModule example from documentation: | Linking against <tt>glibc.static</tt> does not really work because glibc does not really like static linking. You get a warning like <code>warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking</code>. To really create a static build, use musl. Example based on <code>buildGoModule</code> example from documentation: | ||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
| Line 173: | Line 173: | ||
[[Category:Languages]] | [[Category:Languages]] | ||
[[Category: | [[Category:Go]] | ||