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