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  )