github.com/goreleaser/goreleaser@v1.25.1/internal/builders/buildtarget/targets.go (about) 1 // Package buildtarget can generate a list of targets based on a matrix of 2 // goos, goarch, goarm, goamd64, gomips and go version. 3 package buildtarget 4 5 import ( 6 "fmt" 7 "strings" 8 9 "github.com/caarlos0/log" 10 "github.com/goreleaser/goreleaser/pkg/config" 11 ) 12 13 type target struct { 14 os, arch, arm, mips, amd64 string 15 } 16 17 func (t target) String() string { 18 if extra := t.arm + t.mips + t.amd64; extra != "" { 19 return fmt.Sprintf("%s_%s_%s", t.os, t.arch, extra) 20 } 21 return fmt.Sprintf("%s_%s", t.os, t.arch) 22 } 23 24 // List compiles the list of targets for the given builds. 25 func List(build config.Build) ([]string, error) { 26 // nolint:prealloc 27 var targets []target 28 // nolint:prealloc 29 var result []string 30 for _, target := range allBuildTargets(build) { 31 if !contains(target.os, validGoos) { 32 return result, fmt.Errorf("invalid goos: %s", target.os) 33 } 34 if !contains(target.arch, validGoarch) { 35 return result, fmt.Errorf("invalid goarch: %s", target.arch) 36 } 37 if target.arm != "" && !contains(target.arm, validGoarm) { 38 return result, fmt.Errorf("invalid goarm: %s", target.arm) 39 } 40 if target.mips != "" && !contains(target.mips, validGomips) { 41 return result, fmt.Errorf("invalid gomips: %s", target.mips) 42 } 43 if target.amd64 != "" && !contains(target.amd64, validGoamd64) { 44 return result, fmt.Errorf("invalid goamd64: %s", target.amd64) 45 } 46 if !valid(target) { 47 log.WithField("target", target).Debug("skipped invalid build") 48 continue 49 } 50 if ignored(build, target) { 51 log.WithField("target", target).Debug("skipped ignored build") 52 continue 53 } 54 targets = append(targets, target) 55 } 56 for _, target := range targets { 57 result = append(result, target.String()) 58 } 59 return result, nil 60 } 61 62 func allBuildTargets(build config.Build) (targets []target) { 63 for _, goos := range build.Goos { 64 for _, goarch := range build.Goarch { 65 if goarch == "arm" { 66 for _, goarm := range build.Goarm { 67 targets = append(targets, target{ 68 os: goos, 69 arch: goarch, 70 arm: goarm, 71 }) 72 } 73 continue 74 } 75 if strings.HasPrefix(goarch, "amd64") { 76 for _, goamd := range build.Goamd64 { 77 targets = append(targets, target{ 78 os: goos, 79 arch: goarch, 80 amd64: goamd, 81 }) 82 } 83 continue 84 } 85 if strings.HasPrefix(goarch, "mips") { 86 for _, gomips := range build.Gomips { 87 targets = append(targets, target{ 88 os: goos, 89 arch: goarch, 90 mips: gomips, 91 }) 92 } 93 continue 94 } 95 targets = append(targets, target{ 96 os: goos, 97 arch: goarch, 98 }) 99 } 100 } 101 return 102 } 103 104 // TODO: this could be improved by using a map. 105 // https://github.com/goreleaser/goreleaser/pull/522#discussion_r164245014 106 func ignored(build config.Build, target target) bool { 107 for _, ig := range build.Ignore { 108 if ig.Goos != "" && ig.Goos != target.os { 109 continue 110 } 111 if ig.Goarch != "" && ig.Goarch != target.arch { 112 continue 113 } 114 if ig.Goarm != "" && ig.Goarm != target.arm { 115 continue 116 } 117 if ig.Gomips != "" && ig.Gomips != target.mips { 118 continue 119 } 120 if ig.Goamd64 != "" && ig.Goamd64 != target.amd64 { 121 continue 122 } 123 return true 124 } 125 return false 126 } 127 128 func valid(target target) bool { 129 return contains(target.os+target.arch, validTargets) 130 } 131 132 func contains(s string, ss []string) bool { 133 for _, z := range ss { 134 if z == s { 135 return true 136 } 137 } 138 return false 139 } 140 141 // lists from https://golang.org/doc/install/source#environment 142 // nolint: gochecknoglobals 143 var ( 144 validTargets = []string{ 145 "aixppc64", 146 "android386", 147 "androidamd64", 148 "androidarm", 149 "androidarm64", 150 "darwinamd64", 151 "darwinarm64", 152 "dragonflyamd64", 153 "freebsd386", 154 "freebsdamd64", 155 "freebsdarm", 156 "freebsdarm64", // not on the official list for some reason, yet its supported on go 1.14+ 157 "illumosamd64", 158 "iosarm64", 159 "jswasm", 160 "wasip1wasm", 161 "linux386", 162 "linuxamd64", 163 "linuxarm", 164 "linuxarm64", 165 "linuxppc64", 166 "linuxppc64le", 167 "linuxmips", 168 "linuxmipsle", 169 "linuxmips64", 170 "linuxmips64le", 171 "linuxs390x", 172 "linuxriscv64", 173 "linuxloong64", 174 "netbsd386", 175 "netbsdamd64", 176 "netbsdarm", 177 "netbsdarm64", // not on the official list for some reason, yet its supported on go 1.13+ 178 "openbsd386", 179 "openbsdamd64", 180 "openbsdarm", 181 "openbsdarm64", 182 "plan9386", 183 "plan9amd64", 184 "plan9arm", 185 "solarisamd64", 186 "windowsarm", 187 "windowsarm64", 188 "windows386", 189 "windowsamd64", 190 } 191 192 validGoos = []string{ 193 "aix", 194 "android", 195 "darwin", 196 "dragonfly", 197 "freebsd", 198 "illumos", 199 "ios", 200 "js", 201 "linux", 202 "netbsd", 203 "openbsd", 204 "plan9", 205 "solaris", 206 "windows", 207 "wasip1", 208 } 209 210 validGoarch = []string{ 211 "386", 212 "amd64", 213 "arm", 214 "arm64", 215 "mips", 216 "mips64", 217 "mips64le", 218 "mipsle", 219 "ppc64", 220 "ppc64le", 221 "s390x", 222 "wasm", 223 "riscv64", 224 "loong64", 225 } 226 227 validGoarm = []string{"5", "6", "7"} 228 validGomips = []string{"hardfloat", "softfloat"} 229 validGoamd64 = []string{"v1", "v2", "v3", "v4"} 230 )