Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ go, cacert, git, lib, stdenv }: 2 3{ name ? "${args'.pname}-${args'.version}" 4, src 5, nativeBuildInputs ? [ ] 6, passthru ? { } 7, patches ? [ ] 8 9 # Go tags, passed to go via -tag 10, tags ? [ ] 11 12 # A function to override the go-modules derivation 13, overrideModAttrs ? (_oldAttrs: { }) 14 15 # path to go.mod and go.sum directory 16, modRoot ? "./" 17 18 # vendorHash is the SRI hash of the vendored dependencies 19 # 20 # if vendorHash is null, then we won't fetch any dependencies and 21 # rely on the vendor folder within the source. 22, vendorHash ? args'.vendorSha256 or (throw "buildGoModule: vendorHash is missing") 23 # Whether to delete the vendor folder supplied with the source. 24, deleteVendor ? false 25 # Whether to fetch (go mod download) and proxy the vendor directory. 26 # This is useful if your code depends on c code and go mod tidy does not 27 # include the needed sources to build or if any dependency has case-insensitive 28 # conflicts which will produce platform dependant `vendorHash` checksums. 29, proxyVendor ? false 30 31 # We want parallel builds by default 32, enableParallelBuilding ? true 33 34 # Do not enable this without good reason 35 # IE: programs coupled with the compiler 36, allowGoReference ? false 37 38, CGO_ENABLED ? go.CGO_ENABLED 39 40, meta ? { } 41 42 # Not needed with buildGoModule 43, goPackagePath ? "" 44 45 # needed for buildFlags{,Array} warning 46, buildFlags ? "" 47, buildFlagsArray ? "" 48 49, ... 50}@args': 51 52assert goPackagePath != "" -> throw "`goPackagePath` is not needed with `buildGoModule`"; 53assert (args' ? vendorHash && args' ? vendorSha256) -> throw "both `vendorHash` and `vendorSha256` set. only one can be set."; 54 55let 56 args = removeAttrs args' [ "overrideModAttrs" "vendorSha256" "vendorHash" ]; 57 58 go-modules = if (vendorHash == null) then "" else 59 (stdenv.mkDerivation { 60 name = "${name}-go-modules"; 61 62 nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ go git cacert ]; 63 64 inherit (args) src; 65 inherit (go) GOOS GOARCH; 66 67 # The following inheritence behavior is not trivial to expect, and some may 68 # argue it's not ideal. Changing it may break vendor hashes in Nixpkgs and 69 # out in the wild. In anycase, it's documented in: 70 # doc/languages-frameworks/go.section.md 71 prePatch = args.prePatch or ""; 72 patches = args.patches or [ ]; 73 patchFlags = args.patchFlags or [ ]; 74 postPatch = args.postPatch or ""; 75 preBuild = args.preBuild or ""; 76 postBuild = args.modPostBuild or ""; 77 sourceRoot = args.sourceRoot or ""; 78 79 GO111MODULE = "on"; 80 81 impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ 82 "GIT_PROXY_COMMAND" 83 "SOCKS_SERVER" 84 "GOPROXY" 85 ]; 86 87 configurePhase = args.modConfigurePhase or '' 88 runHook preConfigure 89 export GOCACHE=$TMPDIR/go-cache 90 export GOPATH="$TMPDIR/go" 91 cd "${modRoot}" 92 runHook postConfigure 93 ''; 94 95 buildPhase = args.modBuildPhase or ('' 96 runHook preBuild 97 '' + lib.optionalString deleteVendor '' 98 if [ ! -d vendor ]; then 99 echo "vendor folder does not exist, 'deleteVendor' is not needed" 100 exit 10 101 else 102 rm -rf vendor 103 fi 104 '' + '' 105 if [ -d vendor ]; then 106 echo "vendor folder exists, please set 'vendorHash = null;' in your expression" 107 exit 10 108 fi 109 110 ${if proxyVendor then '' 111 mkdir -p "''${GOPATH}/pkg/mod/cache/download" 112 go mod download 113 '' else '' 114 if (( "''${NIX_DEBUG:-0}" >= 1 )); then 115 goModVendorFlags+=(-v) 116 fi 117 go mod vendor "''${goModVendorFlags[@]}" 118 ''} 119 120 mkdir -p vendor 121 122 runHook postBuild 123 ''); 124 125 installPhase = args.modInstallPhase or '' 126 runHook preInstall 127 128 ${if proxyVendor then '' 129 rm -rf "''${GOPATH}/pkg/mod/cache/download/sumdb" 130 cp -r --reflink=auto "''${GOPATH}/pkg/mod/cache/download" $out 131 '' else '' 132 cp -r --reflink=auto vendor $out 133 ''} 134 135 if ! [ "$(ls -A $out)" ]; then 136 echo "vendor folder is empty, please set 'vendorHash = null;' in your expression" 137 exit 10 138 fi 139 140 runHook postInstall 141 ''; 142 143 dontFixup = true; 144 145 outputHashMode = "recursive"; 146 outputHash = vendorHash; 147 outputHashAlgo = if args' ? vendorSha256 || vendorHash == "" then "sha256" else null; 148 }).overrideAttrs overrideModAttrs; 149 150 package = stdenv.mkDerivation (args // { 151 nativeBuildInputs = [ go ] ++ nativeBuildInputs; 152 153 inherit (go) GOOS GOARCH; 154 155 GO111MODULE = "on"; 156 GOFLAGS = lib.optionals (!proxyVendor) [ "-mod=vendor" ] ++ lib.optionals (!allowGoReference) [ "-trimpath" ]; 157 inherit CGO_ENABLED enableParallelBuilding; 158 159 configurePhase = args.configurePhase or ('' 160 runHook preConfigure 161 162 export GOCACHE=$TMPDIR/go-cache 163 export GOPATH="$TMPDIR/go" 164 export GOPROXY=off 165 export GOSUMDB=off 166 cd "$modRoot" 167 '' + lib.optionalString (vendorHash != null) '' 168 ${if proxyVendor then '' 169 export GOPROXY=file://${go-modules} 170 '' else '' 171 rm -rf vendor 172 cp -r --reflink=auto ${go-modules} vendor 173 ''} 174 '' + '' 175 176 # currently pie is only enabled by default in pkgsMusl 177 # this will respect the `hardening{Disable,Enable}` flags if set 178 if [[ $NIX_HARDENING_ENABLE =~ "pie" ]]; then 179 export GOFLAGS="-buildmode=pie $GOFLAGS" 180 fi 181 182 runHook postConfigure 183 ''); 184 185 buildPhase = args.buildPhase or ('' 186 runHook preBuild 187 188 exclude='\(/_\|examples\|Godeps\|testdata' 189 if [[ -n "$excludedPackages" ]]; then 190 IFS=' ' read -r -a excludedArr <<<$excludedPackages 191 printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}" 192 excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf 193 exclude+='\|'"$excludedAlternates" 194 fi 195 exclude+='\)' 196 197 buildGoDir() { 198 local cmd="$1" dir="$2" 199 200 . $TMPDIR/buildFlagsArray 201 202 declare -a flags 203 flags+=($buildFlags "''${buildFlagsArray[@]}") 204 flags+=(''${tags:+-tags=${lib.concatStringsSep "," tags}}) 205 flags+=(''${ldflags:+-ldflags="$ldflags"}) 206 flags+=("-p" "$NIX_BUILD_CORES") 207 208 if [ "$cmd" = "test" ]; then 209 flags+=(-vet=off) 210 flags+=($checkFlags) 211 fi 212 213 local OUT 214 if ! OUT="$(go $cmd "''${flags[@]}" $dir 2>&1)"; then 215 if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then 216 echo "$OUT" >&2 217 return 1 218 fi 219 fi 220 if [ -n "$OUT" ]; then 221 echo "$OUT" >&2 222 fi 223 return 0 224 } 225 226 getGoDirs() { 227 local type; 228 type="$1" 229 if [ -n "$subPackages" ]; then 230 echo "$subPackages" | sed "s,\(^\| \),\1./,g" 231 else 232 find . -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort --unique | grep -v "$exclude" 233 fi 234 } 235 236 if (( "''${NIX_DEBUG:-0}" >= 1 )); then 237 buildFlagsArray+=(-x) 238 fi 239 240 if [ ''${#buildFlagsArray[@]} -ne 0 ]; then 241 declare -p buildFlagsArray > $TMPDIR/buildFlagsArray 242 else 243 touch $TMPDIR/buildFlagsArray 244 fi 245 if [ -z "$enableParallelBuilding" ]; then 246 export NIX_BUILD_CORES=1 247 fi 248 for pkg in $(getGoDirs ""); do 249 echo "Building subPackage $pkg" 250 buildGoDir install "$pkg" 251 done 252 '' + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' 253 # normalize cross-compiled builds w.r.t. native builds 254 ( 255 dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH} 256 if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then 257 mv $dir/* $dir/.. 258 fi 259 if [[ -d $dir ]]; then 260 rmdir $dir 261 fi 262 ) 263 '' + '' 264 runHook postBuild 265 ''); 266 267 doCheck = args.doCheck or true; 268 checkPhase = args.checkPhase or '' 269 runHook preCheck 270 # We do not set trimpath for tests, in case they reference test assets 271 export GOFLAGS=''${GOFLAGS//-trimpath/} 272 273 for pkg in $(getGoDirs test); do 274 buildGoDir test "$pkg" 275 done 276 277 runHook postCheck 278 ''; 279 280 installPhase = args.installPhase or '' 281 runHook preInstall 282 283 mkdir -p $out 284 dir="$GOPATH/bin" 285 [ -e "$dir" ] && cp -r $dir $out 286 287 runHook postInstall 288 ''; 289 290 strictDeps = true; 291 292 disallowedReferences = lib.optional (!allowGoReference) go; 293 294 passthru = passthru // { inherit go go-modules vendorHash; } // { inherit (args') vendorSha256; }; 295 296 meta = { 297 # Add default meta information 298 platforms = go.meta.platforms or lib.platforms.all; 299 } // meta; 300 }); 301in 302lib.warnIf (buildFlags != "" || buildFlagsArray != "") 303 "Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`" 304 package