Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: overhaul #4

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ jobs:
"1.16.15",
"1.17.13",
"1.18.10",
"1.19.5",
"1.20.0",
"1.19.8",
"1.20.3",
]
fail-fast: true

Expand Down
69 changes: 69 additions & 0 deletions const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

const (
gobin = "go"
)

const (
flagNameRace = "race"
flagNameMSAN = "msan"
flagNameASAN = "asan"
flagNameCover = "cover"
flagNameCoverPKG = "coverpkg"
flagNameASMFlags = "asmflags"
flagNameBuildMode = "buildmode"
flagNameBuildVCS = "buildvcs"
flagNameCompiler = "compiler"
flagNameGcCGOFlags = "gccgoflags"
flagNameGcFlags = "gcflags"
flagNameInstallSuffix = "installsuffix"
flagNameLDFlags = "ldflags"
flagNameLinkShared = "linkshared"
flagNameMod = "mod"
flagNameModCacheRW = "modcacherw"
flagNameModFile = "modfile"
flagNameOverlay = "overlay"
flagNameProfileGuidedOptimization = "pgo"
flagNamePackageDir = "pkgdir"
flagNameTags = "tags"
flagNameTrimPath = "trimpath"
)

// Go Operating System values for GOOS.
const (
goosWindows = "windows"
goosLinux = "linux"
goosDarwin = "darwin"
goosIOS = "ios"
goosFreeBSD = "freebsd"
goosNetBSD = "netbsd"
goosOpenBSD = "openbsd"
goosAndroid = "android"
goosPlan9 = "plan9"
goosDragonfly = "dragonfly"
goosNACL = "nacl"
goosSolaris = "solaris"
goosJavaScript = "js"
goosAIX = "aix"
goosIllumos = "illumos"
goosWASIP1 = "wasip1"
)

// Go Architecture values for GOARCH.
const (
goarch386 = "386"
goarchAMD64 = "amd64"
goarchAMD64P32 = "amd64p32"
goarchARM = "arm"
goarchARM64 = "arm64"
goarchMIPS = "mips"
goarchMIPSLE = "mipsle"
goarchMIPS64 = "mips64"
goarchMIPS64LE = "mips64le"
goarchS390X = "s390x"
goarchPowerPC64 = "ppc64"
goarchPowerPC64LE = "ppc64le"
goarchRISCV64 = "riscv64"
goarchLoong64 = "loong64"
goarchWebAssembly = "wasm"
)
99 changes: 99 additions & 0 deletions constraints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import "github.com/hashicorp/go-version"

var (
flagConstraints map[string]version.Constraints
platformConstraints []PlatformConstraint
experimentConstraints map[string]version.Constraints
)

// Parse all of the constraints as efficiently as possible.
func init() {
var (
ok bool
constraint version.Constraints
err error
)

parsed := map[string]version.Constraints{}

flagConstraints = map[string]version.Constraints{}

flagConstraintsInputs := []struct {
name string
constraint string
}{
{"C", ">= 1.20"},
{flagNameASAN, ">= 1.18"},
{flagNameCover, ">= 1.20"},
{flagNameCoverPKG, ">= 1.20"},
{flagNameBuildVCS, ">= 1.18"},
{flagNameModCacheRW, ">= 1.14"},
{flagNameMod, ">= 1.11"},
{flagNameModFile, ">= 1.14"},
{flagNameOverlay, ">= 1.16"},
{flagNameProfileGuidedOptimization, ">= 1.20"},
{flagNameTrimPath, ">= 1.13"},
}

for _, input := range flagConstraintsInputs {
if constraint, ok = parsed[input.constraint]; ok {
flagConstraints[input.name] = constraint

continue
}

if constraint, err = version.NewConstraint(input.constraint); err != nil {
panic(err)
}

flagConstraints[input.name] = constraint
parsed[input.constraint] = constraint
}

platformConstraintsInputs := []struct {
constraint string
platforms []Platform
}{
{"<= 1.0", Platforms_1_0},
{">= 1.1, < 1.2", Platforms_1_1},
{">= 1.2, < 1.3", Platforms_1_2},
{">= 1.3, < 1.4", Platforms_1_3},
{">= 1.4, < 1.5", Platforms_1_4},
{">= 1.5, < 1.6", Platforms_1_5},
{">= 1.6, < 1.7", Platforms_1_6},
{">= 1.7, < 1.8", Platforms_1_7},
{">= 1.8, < 1.9", Platforms_1_8},
{">= 1.9, < 1.10", Platforms_1_9},
{">= 1.10, < 1.11", Platforms_1_10},
{">= 1.11, < 1.12", Platforms_1_11},
{">= 1.12, < 1.13", Platforms_1_12},
{">= 1.13, < 1.14", Platforms_1_13},
{">= 1.14, < 1.15", Platforms_1_14},
{">= 1.15, < 1.16", Platforms_1_15},
{">= 1.16, < 1.17", Platforms_1_16},
{">= 1.17, < 1.18", Platforms_1_17},
{">= 1.18, < 1.19", Platforms_1_18},
{">= 1.19, < 1.20", Platforms_1_19},
{">= 1.20, < 1.21", Platforms_1_20},
{">= 1.21, < 1.22", Platforms_1_21},
}

platformConstraints = make([]PlatformConstraint, len(platformConstraintsInputs))

for i, input := range platformConstraintsInputs {
if constraint, ok = parsed[input.constraint]; ok {
platformConstraints[i] = PlatformConstraint{Constraints: constraint, Platforms: input.platforms}

continue
}

if constraint, err = version.NewConstraint(input.constraint); err != nil {
panic(err)
}

platformConstraints[i] = PlatformConstraint{Constraints: constraint, Platforms: input.platforms}
parsed[input.constraint] = constraint
}
}
120 changes: 8 additions & 112 deletions go.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
Expand All @@ -20,68 +19,32 @@ type OutputTemplateData struct {
Arch string
}

type CompileOpts struct {
PackagePath string
Platform Platform
OutputTpl string
Ldflags string
Gcflags string
Cc string
Cxx string
Asmflags string
Tags string
ModMode string
Buildmode string
BuildVCS string
Cgo bool
Rebuild bool
TrimPath bool
GoCmd string
Race bool
}

// GoCrossCompile
func GoCrossCompile(opts *CompileOpts) error {
env := append(os.Environ(),
"GOOS="+opts.Platform.OS,
"GOARCH="+opts.Platform.Arch)

if opts.Cc != "" {
env = append(env, "CC="+opts.Cc)
}
if opts.Cxx != "" {
env = append(env, "CXX="+opts.Cxx)
}

// If we're building for our own platform, then enable cgo always. We
// respect the CGO_ENABLED flag if that is explicitly set on the platform.
if !opts.Cgo && os.Getenv("CGO_ENABLED") != "0" {
opts.Cgo = runtime.GOOS == opts.Platform.OS &&
runtime.GOARCH == opts.Platform.Arch
}

// If cgo is enabled then set that env var
if opts.Cgo {
env = append(env, "CGO_ENABLED=1")
} else {
env = append(env, "CGO_ENABLED=0")
}

var outputPath bytes.Buffer
tpl, err := template.New("output").Parse(opts.OutputTpl)
if err != nil {
return err
}

tplData := OutputTemplateData{
Dir: filepath.Base(opts.PackagePath),
OS: opts.Platform.OS,
Arch: opts.Platform.Arch,
}

if err := tpl.Execute(&outputPath, &tplData); err != nil {
return err
}

if opts.Platform.OS == "windows" {
if opts.Platform.OS == goosWindows {
outputPath.WriteString(".exe")
}

Expand All @@ -98,7 +61,7 @@ func GoCrossCompile(opts *CompileOpts) error {
// directory to build.
chdir := ""
if opts.PackagePath[0] == '_' {
if runtime.GOOS == "windows" {
if runtime.GOOS == goosWindows {
// We have to replace weird paths like this:
//
// _/c_/Users
Expand All @@ -117,51 +80,11 @@ func GoCrossCompile(opts *CompileOpts) error {
opts.PackagePath = ""
}

args := []string{"build"}

if opts.Rebuild {
args = append(args, "-a")
}

if opts.TrimPath {
args = append(args, "-trimpath")
}

if opts.ModMode != "" {
args = append(args, "-mod", opts.ModMode)
}

if opts.Buildmode != "" {
args = append(args, "-buildmode", opts.Buildmode)
}

if opts.BuildVCS != "" {
args = append(args, "-buildvcs", opts.BuildVCS)
}

if opts.Race {
args = append(args, "-race")
}

if opts.Gcflags != "" {
args = append(args, "-gcflags", opts.Gcflags)
}

if opts.Ldflags != "" {
args = append(args, "-ldflags", opts.Ldflags)
}

if opts.Asmflags != "" {
args = append(args, "-asmflags", opts.Asmflags)
}

if opts.Tags != "" {
args = append(args, "-tags", opts.Tags)
}
args := append([]string{"build"}, opts.Arguments()...)

args = append(args, "-o", outputPathReal, opts.PackagePath)

_, err = execGo(opts.GoCmd, env, chdir, args...)
_, err = execGo(opts.GoCmd, opts.Env(), chdir, args...)

return err
}
Expand Down Expand Up @@ -201,42 +124,14 @@ func GoMainDirs(packages []string, GoCmd string) ([]string, error) {

// GoRoot returns the GOROOT value for the compiled `go` binary.
func GoRoot() (string, error) {
output, err := execGo("go", nil, "", "env", "GOROOT")
output, err := execGo(gobin, nil, "", "env", "GOROOT")
if err != nil {
return "", err
}

return strings.TrimSpace(output), nil
}

// GoVersion reads the version of `go` that is on the PATH. This is done
// instead of `runtime.Version()` because it is possible to run gox against
// another Go version.
func GoVersion() (string, error) {
// NOTE: We use `go run` instead of `go version` because the output
// of `go version` might change whereas the source is guaranteed to run
// for some time thanks to Go's compatibility guarantee.

td, err := ioutil.TempDir("", "gox")
if err != nil {
return "", err
}
defer os.RemoveAll(td)

// Write the source code for the program that will generate the version
sourcePath := filepath.Join(td, "version.go")
if err := ioutil.WriteFile(sourcePath, []byte(versionSource), 0644); err != nil {
return "", err
}

// Execute and read the version, which will be the only thing on stdout.
version, err := execGo("go", nil, "", "run", sourcePath)

fmt.Printf("Detected Go Version: %s\n", version)

return version, err
}

// GoVersionParts parses the version numbers from the version itself
// into major and minor: 1.5, 1.4, etc.
func GoVersionParts() (result [2]int, err error) {
Expand All @@ -252,6 +147,7 @@ func GoVersionParts() (result [2]int, err error) {
func execGo(GoCmd string, env []string, dir string, args ...string) (string, error) {
var stderr, stdout bytes.Buffer
cmd := exec.Command(GoCmd, args...)

cmd.Stdout = &stdout
cmd.Stderr = &stderr
if env != nil {
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,11 @@ go 1.20
require (
github.com/hashicorp/go-version v1.6.0
github.com/mitchellh/iochan v1.0.0
github.com/stretchr/testify v1.8.2
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading