1 { go, govers, lib, fetchgit, fetchhg, fetchbzr, rsync
2 , fetchFromGitHub, stdenv }:
5 , nativeBuildInputs ? []
10 # We want parallel builds by default
11 , enableParallelBuilding ? true
13 # Go import path of the package
17 , goPackageAliases ? [ ]
19 # Extra sources to include in the gopath
22 # Extra gopaths containing src subfolder
23 # with sources to include in the gopath
26 # go2nix dependency file
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
44 # needed for buildFlags{,Array} warning
46 , buildFlagsArray ? ""
48 , meta ? {}, ... } @ args:
53 inherit (goDep) goPackagePath;
54 src = if goDep.fetch.type == "git" then
56 inherit (goDep.fetch) url rev sha256;
58 else if goDep.fetch.type == "hg" then
60 inherit (goDep.fetch) url rev sha256;
62 else if goDep.fetch.type == "bzr" then
64 inherit (goDep.fetch) url rev sha256;
66 else if goDep.fetch.type == "FromGitHub" then
68 inherit (goDep.fetch) owner repo rev sha256;
70 else abort "Unrecognized package fetch type: ${goDep.fetch.type}";
73 importGodeps = { depsFile }:
74 map dep2src (import depsFile);
76 goPath = if goDeps != null then importGodeps { depsFile = goDeps; } ++ 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;
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 (''
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"
114 rm -rf "go/src/$goPackagePath/vendor"
116 '' + lib.optionalString (goDeps != null) ''
117 if [ -d "go/src/$goPackagePath/vendor" ]; then
118 echo "vendor folder exists, 'goDeps' is not needed"
121 '' + lib.flip lib.concatMapStrings goPath ({ src, goPackagePath }: ''
123 (cd goPath; unpackFile "${src}")
124 mkdir -p "go/src/$(dirname "${goPackagePath}")"
125 chmod -R u+w goPath/*
126 mv goPath/* "go/src/${goPackagePath}"
129 '') + (lib.optionalString (extraSrcPaths != []) ''
130 ${rsync}/bin/rsync -a ${lib.concatMapStringsSep " " (p: "${p}/src") extraSrcPaths} go
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"
142 runHook postConfigure
145 renameImports = args.renameImports or (
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 (''
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"
168 local cmd="$1" dir="$2"
170 . $TMPDIR/buildFlagsArray
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
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
190 if [ -n "$OUT" ]; then
199 if [ -n "$subPackages" ]; then
200 echo "$subPackages" | sed "s,\(^\| \),\1$goPackagePath/,g"
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"
208 if (( "''${NIX_DEBUG:-0}" >= 1 )); then
209 buildFlagsArray+=(-x)
212 if [ ''${#buildFlagsArray[@]} -ne 0 ]; then
213 declare -p buildFlagsArray > $TMPDIR/buildFlagsArray
215 touch $TMPDIR/buildFlagsArray
217 if [ -z "$enableParallelBuilding" ]; then
218 export NIX_BUILD_CORES=1
220 for pkg in $(getGoDirs ""); do
221 echo "Building subPackage $pkg"
222 buildGoDir install "$pkg"
224 '' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
225 # normalize cross-compiled builds w.r.t. native builds
227 dir=$NIX_BUILD_TOP/go/bin/${go.GOOS}_${go.GOARCH}
228 if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then
231 if [[ -d $dir ]]; then
239 doCheck = args.doCheck or false;
240 checkPhase = args.checkPhase or ''
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"
252 installPhase = args.installPhase or ''
256 dir="$NIX_BUILD_TOP/go/bin"
257 [ -e "$dir" ] && cp -r $dir $out
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}"
271 export GOPATH=${lib.concatStringsSep ":" ( ["$d"] ++ ["$GOPATH"] ++ ["$PWD"] ++ extraSrcPaths)}
274 disallowedReferences = lib.optional (!allowGoReference) go
275 ++ lib.optional (!dontRenameImports) govers;
277 passthru = passthru //
279 lib.optionalAttrs (goPackageAliases != []) { inherit goPackageAliases; };
282 # Add default meta information
283 homepage = "https://${goPackagePath}";
284 platforms = go.meta.platforms or lib.platforms.all;
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.''