mirror of
https://github.com/caddyserver/xcaddy.git
synced 2025-01-22 08:36:28 +01:00
Improved cross-platform support
This commit is contained in:
parent
5a59fd84d5
commit
6f998dab69
2 changed files with 122 additions and 10 deletions
59
builder.go
59
builder.go
|
@ -34,6 +34,7 @@ import (
|
|||
// Builder can produce a custom Caddy build with the
|
||||
// configuration it represents.
|
||||
type Builder struct {
|
||||
Compile
|
||||
CaddyVersion string `json:"caddy_version,omitempty"`
|
||||
Plugins []Dependency `json:"plugins,omitempty"`
|
||||
Replacements []Replace `json:"replacements,omitempty"`
|
||||
|
@ -54,21 +55,42 @@ func (b Builder) Build(ctx context.Context, outputFile string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
env, err := b.newEnvironment(ctx)
|
||||
// set some defaults from the environment, if applicable
|
||||
if b.OS == "" {
|
||||
b.OS = os.Getenv("GOOS")
|
||||
}
|
||||
if b.Arch == "" {
|
||||
b.Arch = os.Getenv("GOARCH")
|
||||
}
|
||||
if b.ARM == "" {
|
||||
b.ARM = os.Getenv("GOARM")
|
||||
}
|
||||
|
||||
// prepare the build environment
|
||||
buildEnv, err := b.newEnvironment(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer env.Close()
|
||||
defer buildEnv.Close()
|
||||
|
||||
// prepare the environmen for the go command; for
|
||||
// the most part we want it to inherit our current
|
||||
// environment, with a few customizations
|
||||
env := os.Environ()
|
||||
env = setEnv(env, "GOOS="+b.OS)
|
||||
env = setEnv(env, "GOARCH="+b.Arch)
|
||||
env = setEnv(env, "GOARM="+b.ARM)
|
||||
env = setEnv(env, fmt.Sprintf("CGO_ENABLED=%t", b.Cgo))
|
||||
|
||||
log.Println("[INFO] Building Caddy")
|
||||
|
||||
cmd := env.newCommand("go", "build",
|
||||
// compile
|
||||
cmd := buildEnv.newCommand("go", "build",
|
||||
"-o", absOutputFile,
|
||||
"-ldflags", "-w -s", // trim debug symbols
|
||||
"-trimpath",
|
||||
)
|
||||
cmd.Env = append(os.Environ(), "CGO_ENABLED=0")
|
||||
err = env.runCommand(ctx, cmd, 5*time.Minute)
|
||||
err = buildEnv.runCommand(ctx, cmd, 5*time.Minute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -78,24 +100,41 @@ func (b Builder) Build(ctx context.Context, outputFile string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// setEnv sets an environment variable-value pair in
|
||||
// env, overriding an existing variable if it already
|
||||
// exists. The env slice is one such as is returned
|
||||
// by os.Environ(), and set must also have the form
|
||||
// of key=value.
|
||||
func setEnv(env []string, set string) []string {
|
||||
parts := strings.SplitN(set, "=", 2)
|
||||
key := parts[0]
|
||||
for i := 0; i < len(env); i++ {
|
||||
if strings.HasPrefix(env[i], key+"=") {
|
||||
env[i] = set
|
||||
return env
|
||||
}
|
||||
}
|
||||
return append(env, set)
|
||||
}
|
||||
|
||||
// Dependency pairs a Go module path with a version.
|
||||
type Dependency struct {
|
||||
// The name (path) of the Go module. If at a version > 1, it
|
||||
// should contain semantic import version suffix (i.e. "/v2").
|
||||
// Used with `go get`
|
||||
ModulePath string
|
||||
ModulePath string `json:"module_path,omitempty"`
|
||||
|
||||
// The version of the Go module, like used with `go get`.
|
||||
Version string
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// Replace represents a Go module replacement.
|
||||
type Replace struct {
|
||||
// The import path of the module being replaced.
|
||||
Old string
|
||||
Old string `json:"old,omitempty"`
|
||||
|
||||
// The path to the replacement module.
|
||||
New string
|
||||
New string `json:"new,omitempty"`
|
||||
}
|
||||
|
||||
// newTempFolder creates a new folder in a temporary location.
|
||||
|
@ -148,7 +187,7 @@ func versionedModulePath(modulePath, moduleVersion string) (string, error) {
|
|||
// only return the error if we know they were trying to use a semantic version
|
||||
// (could have been a commit SHA or something)
|
||||
if strings.HasPrefix(moduleVersion, "v") {
|
||||
return "", err
|
||||
return "", fmt.Errorf("%s: %v", moduleVersion, err)
|
||||
}
|
||||
return modulePath, nil
|
||||
}
|
||||
|
|
73
platforms.go
Normal file
73
platforms.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
package xcaddy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Compile contains parameters for compilation.
|
||||
type Compile struct {
|
||||
Platform
|
||||
Cgo bool `json:"cgo,omitempty"`
|
||||
}
|
||||
|
||||
// Platform represents a build target.
|
||||
type Platform struct {
|
||||
OS string `json:"os,omitempty"`
|
||||
Arch string `json:"arch,omitempty"`
|
||||
ARM string `json:"arm,omitempty"`
|
||||
}
|
||||
|
||||
// SupportedPlatforms runs `go tool dist list` to make
|
||||
// a list of possible build targets.
|
||||
func SupportedPlatforms() ([]Compile, error) {
|
||||
out, err := exec.Command("go", "tool", "dist", "list", "-json").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var dists []dist
|
||||
err = json.Unmarshal(out, &dists)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// translate from the go command's output structure
|
||||
// to our own user-facing structure
|
||||
var compiles []Compile
|
||||
for _, d := range dists {
|
||||
comp := d.toCompile()
|
||||
if d.GOARCH == "arm" {
|
||||
if d.GOOS == "linux" {
|
||||
// only linux supports ARMv5; see https://github.com/golang/go/issues/18418
|
||||
comp.ARM = "5"
|
||||
compiles = append(compiles, comp)
|
||||
}
|
||||
comp.ARM = "6"
|
||||
compiles = append(compiles, comp)
|
||||
comp.ARM = "7"
|
||||
compiles = append(compiles, comp)
|
||||
} else {
|
||||
compiles = append(compiles, comp)
|
||||
}
|
||||
}
|
||||
|
||||
return compiles, nil
|
||||
}
|
||||
|
||||
// dist is the structure that fits the output
|
||||
// of the `go tool dist list -json` command.
|
||||
type dist struct {
|
||||
GOOS string `json:"GOOS"`
|
||||
GOARCH string `json:"GOARCH"`
|
||||
CgoSupported bool `json:"CgoSupported"`
|
||||
}
|
||||
|
||||
func (d dist) toCompile() Compile {
|
||||
return Compile{
|
||||
Platform: Platform{
|
||||
OS: d.GOOS,
|
||||
Arch: d.GOARCH,
|
||||
},
|
||||
Cgo: d.CgoSupported,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue