biome: 1.9.2 -> 1.9.3 (#349335)
[NixPkgs.git] / pkgs / build-support / go / package.nix
blob754736dfbe6ef2ccccdadd5b755f32eb12ab1ee8
1 { go, govers, lib, fetchgit, fetchhg, fetchbzr, rsync
2 , fetchFromGitHub, stdenv }:
4 { buildInputs ? []
5 , nativeBuildInputs ? []
6 , passthru ? {}
7 , preFixup ? ""
8 , shellHook ? ""
10 # We want parallel builds by default
11 , enableParallelBuilding ? true
13 # Go import path of the package
14 , goPackagePath
16 # Go package aliases
17 , goPackageAliases ? [ ]
19 # Extra sources to include in the gopath
20 , extraSrcs ? [ ]
22 # Extra gopaths containing src subfolder
23 # with sources to include in the gopath
24 , extraSrcPaths ? [ ]
26 # go2nix dependency file
27 , goDeps ? null
29 # Whether to delete the vendor folder supplied with the source.
30 , deleteVendor ? false
32 , dontRenameImports ? false
34 # Do not enable this without good reason
35 # IE: programs coupled with the compiler
36 , allowGoReference ? false
38 , CGO_ENABLED ? go.CGO_ENABLED
40 , ldflags ? [ ]
42 , GOFLAGS ? [ ]
44 # needed for buildFlags{,Array} warning
45 , buildFlags ? ""
46 , buildFlagsArray ? ""
48 , meta ? {}, ... } @ args:
50 let
51   dep2src = goDep:
52     {
53       inherit (goDep) goPackagePath;
54       src = if goDep.fetch.type == "git" then
55         fetchgit {
56           inherit (goDep.fetch) url rev sha256;
57         }
58       else if goDep.fetch.type == "hg" then
59         fetchhg {
60           inherit (goDep.fetch) url rev sha256;
61         }
62       else if goDep.fetch.type == "bzr" then
63         fetchbzr {
64           inherit (goDep.fetch) url rev sha256;
65         }
66       else if goDep.fetch.type == "FromGitHub" then
67         fetchFromGitHub {
68           inherit (goDep.fetch) owner repo rev sha256;
69         }
70       else abort "Unrecognized package fetch type: ${goDep.fetch.type}";
71     };
73   importGodeps = { depsFile }:
74     map dep2src (import depsFile);
76   goPath = if goDeps != null then importGodeps { depsFile = goDeps; } ++ extraSrcs
77                              else extraSrcs;
78   package = stdenv.mkDerivation (
79     (builtins.removeAttrs args [ "goPackageAliases" "disabled" "extraSrcs"]) // {
81     nativeBuildInputs = [ go ]
82       ++ (lib.optional (!dontRenameImports) govers) ++ nativeBuildInputs;
83     buildInputs = buildInputs;
85     inherit (go) GOOS GOARCH GO386;
87     GOHOSTARCH = go.GOHOSTARCH or null;
88     GOHOSTOS = go.GOHOSTOS or null;
90     inherit CGO_ENABLED enableParallelBuilding;
92     GO111MODULE = "off";
93     GOTOOLCHAIN = "local";
94     GOFLAGS = GOFLAGS ++ lib.optional (!allowGoReference)  "-trimpath" ;
96     GOARM = toString (lib.intersectLists [(stdenv.hostPlatform.parsed.cpu.version or "")] ["5" "6" "7"]);
98     # If not set to an explicit value, set the buildid empty for reproducibility.
99     ldflags = ldflags ++ lib.optional (!lib.any (lib.hasPrefix "-buildid=") ldflags) "-buildid=";
101     configurePhase = args.configurePhase or (''
102       runHook preConfigure
104       # Extract the source
105       cd "$NIX_BUILD_TOP"
106       mkdir -p "go/src/$(dirname "$goPackagePath")"
107       mv "$sourceRoot" "go/src/$goPackagePath"
109     '' + lib.optionalString deleteVendor ''
110       if [ ! -d "go/src/$goPackagePath/vendor" ]; then
111         echo "vendor folder does not exist, 'deleteVendor' is not needed"
112         exit 10
113       else
114         rm -rf "go/src/$goPackagePath/vendor"
115       fi
116     '' + lib.optionalString (goDeps != null) ''
117       if [ -d "go/src/$goPackagePath/vendor" ]; then
118         echo "vendor folder exists, 'goDeps' is not needed"
119         exit 10
120       fi
121     '' + lib.flip lib.concatMapStrings goPath ({ src, goPackagePath }: ''
122       mkdir goPath
123       (cd goPath; unpackFile "${src}")
124       mkdir -p "go/src/$(dirname "${goPackagePath}")"
125       chmod -R u+w goPath/*
126       mv goPath/* "go/src/${goPackagePath}"
127       rmdir goPath
129     '') + (lib.optionalString (extraSrcPaths != []) ''
130       ${rsync}/bin/rsync -a ${lib.concatMapStringsSep " " (p: "${p}/src") extraSrcPaths} go
132     '') + ''
133       export GOPATH=$NIX_BUILD_TOP/go:$GOPATH
134       export GOCACHE=$TMPDIR/go-cache
136       # currently pie is only enabled by default in pkgsMusl
137       # this will respect the `hardening{Disable,Enable}` flags if set
138       if [[ $NIX_HARDENING_ENABLE =~ "pie" ]]; then
139         export GOFLAGS="-buildmode=pie $GOFLAGS"
140       fi
142       runHook postConfigure
143     '');
145     renameImports = args.renameImports or (
146       let
147         inputsWithAliases = lib.filter (x: x ? goPackageAliases)
148           (buildInputs ++ (args.propagatedBuildInputs or [ ]));
149         rename = to: from: "echo Renaming '${from}' to '${to}'; govers -d -m ${from} ${to}";
150         renames = p: lib.concatMapStringsSep "\n" (rename p.goPackagePath) p.goPackageAliases;
151       in lib.concatMapStringsSep "\n" renames inputsWithAliases);
153     buildPhase = args.buildPhase or (''
154       runHook preBuild
156       runHook renameImports
158       exclude='\(/_\|examples\|Godeps\|testdata'
159       if [[ -n "$excludedPackages" ]]; then
160         IFS=' ' read -r -a excludedArr <<<$excludedPackages
161         printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}"
162         excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf
163         exclude+='\|'"$excludedAlternates"
164       fi
165       exclude+='\)'
167       buildGoDir() {
168         local cmd="$1" dir="$2"
170         . $TMPDIR/buildFlagsArray
172         declare -a flags
173         flags+=($buildFlags "''${buildFlagsArray[@]}")
174         flags+=(''${tags:+-tags=''${tags// /,}})
175         flags+=(''${ldflags:+-ldflags="$ldflags"})
176         flags+=("-p" "$NIX_BUILD_CORES")
178         if [ "$cmd" = "test" ]; then
179           flags+=(-vet=off)
180           flags+=($checkFlags)
181         fi
183         local OUT
184         if ! OUT="$(go $cmd "''${flags[@]}" $dir 2>&1)"; then
185           if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then
186             echo "$OUT" >&2
187             return 1
188           fi
189         fi
190         if [ -n "$OUT" ]; then
191           echo "$OUT" >&2
192         fi
193         return 0
194       }
196       getGoDirs() {
197         local type;
198         type="$1"
199         if [ -n "$subPackages" ]; then
200           echo "$subPackages" | sed "s,\(^\| \),\1$goPackagePath/,g"
201         else
202           pushd "$NIX_BUILD_TOP/go/src" >/dev/null
203           find "$goPackagePath" -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort | uniq | grep -v "$exclude"
204           popd >/dev/null
205         fi
206       }
208       if (( "''${NIX_DEBUG:-0}" >= 1 )); then
209         buildFlagsArray+=(-x)
210       fi
212       if [ ''${#buildFlagsArray[@]} -ne 0 ]; then
213         declare -p buildFlagsArray > $TMPDIR/buildFlagsArray
214       else
215         touch $TMPDIR/buildFlagsArray
216       fi
217       if [ -z "$enableParallelBuilding" ]; then
218           export NIX_BUILD_CORES=1
219       fi
220       for pkg in $(getGoDirs ""); do
221         echo "Building subPackage $pkg"
222         buildGoDir install "$pkg"
223       done
224     '' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
225       # normalize cross-compiled builds w.r.t. native builds
226       (
227         dir=$NIX_BUILD_TOP/go/bin/${go.GOOS}_${go.GOARCH}
228         if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then
229           mv $dir/* $dir/..
230         fi
231         if [[ -d $dir ]]; then
232           rmdir $dir
233         fi
234       )
235     '' + ''
236       runHook postBuild
237     '');
239     doCheck = args.doCheck or false;
240     checkPhase = args.checkPhase or ''
241       runHook preCheck
242       # We do not set trimpath for tests, in case they reference test assets
243       export GOFLAGS=''${GOFLAGS//-trimpath/}
245       for pkg in $(getGoDirs test); do
246         buildGoDir test "$pkg"
247       done
249       runHook postCheck
250     '';
252     installPhase = args.installPhase or ''
253       runHook preInstall
255       mkdir -p $out
256       dir="$NIX_BUILD_TOP/go/bin"
257       [ -e "$dir" ] && cp -r $dir $out
259       runHook postInstall
260     '';
262     strictDeps = true;
264     shellHook = ''
265       d=$(mktemp -d "--suffix=-$name")
266     '' + toString (map (dep: ''
267        mkdir -p "$d/src/$(dirname "${dep.goPackagePath}")"
268        ln -s "${dep.src}" "$d/src/${dep.goPackagePath}"
269     ''
270     ) goPath) + ''
271       export GOPATH=${lib.concatStringsSep ":" ( ["$d"] ++ ["$GOPATH"] ++ ["$PWD"] ++ extraSrcPaths)}
272     '' + shellHook;
274     disallowedReferences = lib.optional (!allowGoReference) go
275       ++ lib.optional (!dontRenameImports) govers;
277     passthru = passthru //
278       { inherit go; } //
279       lib.optionalAttrs (goPackageAliases != []) { inherit goPackageAliases; };
281     meta = {
282       # Add default meta information
283       homepage = "https://${goPackagePath}";
284       platforms = go.meta.platforms or lib.platforms.all;
285     } // meta;
286   });
288 lib.warnIf (buildFlags != "" || buildFlagsArray != "")
289   "`buildFlags`/`buildFlagsArray` are deprecated and will be removed in the 24.11 release. Use the `ldflags` and/or `tags` attributes instead"
290 lib.warnIf (builtins.elem "-buildid=" ldflags) "`-buildid=` is set by default as ldflag by buildGoModule"
291 lib.warnIf (builtins.elem "-trimpath" GOFLAGS) "`-trimpath` is added by default to GOFLAGS by buildGoModule when allowGoReference isn't set to true"
292 lib.warn '''buildGoPackage' is deprecated and will be removed for the 25.05 release.
293 Please use 'buildGoModule' instead. Tips for migration can be found in the Go section of the nixpkgs manual.''
294   package