mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
2dca50dee8
Easier parallelism and more control over platforms we build for, but more importantly, we can do parallel builds using the build script which properly embeds version information into the binaries. We also produce the archive files ourselves and in parallel rather than using external tar and zip commands.
164 lines
4.1 KiB
Go
164 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"sync"
|
|
|
|
"github.com/mholt/archiver"
|
|
)
|
|
|
|
var buildScript, pkgDir, distDir, buildDir, releaseDir string
|
|
|
|
func init() {
|
|
pkgDir = filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "mholt", "caddy")
|
|
buildScript = filepath.Join(pkgDir, "build.bash")
|
|
distDir = filepath.Join(pkgDir, "dist")
|
|
buildDir = filepath.Join(distDir, "builds")
|
|
releaseDir = filepath.Join(distDir, "release")
|
|
}
|
|
|
|
func main() {
|
|
// First, clean up
|
|
err := os.RemoveAll(buildDir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = os.RemoveAll(releaseDir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Then set up
|
|
err = os.MkdirAll(buildDir, 0755)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = os.MkdirAll(releaseDir, 0755)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Perform builds and make archives in parallel; only as many
|
|
// goroutines as we have processors.
|
|
var wg sync.WaitGroup
|
|
var throttle = make(chan struct{}, numProcs())
|
|
for _, p := range platforms {
|
|
wg.Add(1)
|
|
throttle <- struct{}{}
|
|
|
|
if p.os == "" || p.arch == "" || p.archive == "" {
|
|
log.Fatalf("Platform OS, architecture, and archive format is required: %+v", p)
|
|
}
|
|
|
|
go func(p platform) {
|
|
defer wg.Done()
|
|
defer func() { <-throttle }()
|
|
|
|
fmt.Printf("== Building %s\n", p)
|
|
|
|
var baseFilename, binFilename string
|
|
baseFilename = fmt.Sprintf("caddy_%s_%s", p.os, p.arch)
|
|
if p.arch == "arm" {
|
|
baseFilename += p.arm
|
|
}
|
|
binFilename = baseFilename
|
|
if p.os == "windows" {
|
|
binFilename += ".exe"
|
|
}
|
|
|
|
binPath := filepath.Join(buildDir, binFilename)
|
|
archive := filepath.Join(releaseDir, fmt.Sprintf("%s.%s", baseFilename, p.archive))
|
|
archiveContents := append(distContents, binPath)
|
|
|
|
err := build(p, binPath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Printf("== Compressing %s\n", baseFilename)
|
|
|
|
if p.archive == "zip" {
|
|
err := archiver.Zip(archive, archiveContents)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
} else if p.archive == "tar.gz" {
|
|
err := archiver.TarGz(archive, archiveContents)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}(p)
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
func build(p platform, out string) error {
|
|
cmd := exec.Command(buildScript, out)
|
|
cmd.Dir = pkgDir
|
|
cmd.Env = os.Environ()
|
|
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
|
|
cmd.Env = append(cmd.Env, "GOOS="+p.os)
|
|
cmd.Env = append(cmd.Env, "GOARCH="+p.arch)
|
|
cmd.Env = append(cmd.Env, "GOARM="+p.arm)
|
|
cmd.Stderr = os.Stderr
|
|
return cmd.Run()
|
|
}
|
|
|
|
type platform struct {
|
|
os, arch, arm, binExt, archive string
|
|
}
|
|
|
|
func (p platform) String() string {
|
|
outStr := fmt.Sprintf("%s/%s", p.os, p.arch)
|
|
if p.arch == "arm" {
|
|
outStr += fmt.Sprintf(" (ARM v%s)", p.arm)
|
|
}
|
|
return outStr
|
|
}
|
|
|
|
func numProcs() int {
|
|
n := runtime.GOMAXPROCS(0)
|
|
if n == runtime.NumCPU() && n > 1 {
|
|
n -= 1
|
|
}
|
|
return n
|
|
}
|
|
|
|
// See: https://golang.org/doc/install/source#environment
|
|
// Not all supported platforms are listed since some are
|
|
// problematic and we only build the most common ones.
|
|
// These are just the pre-made, readily-available static
|
|
// builds, and we can add more upon request if there is
|
|
// enough demand.
|
|
var platforms = []platform{
|
|
{os: "darwin", arch: "386", archive: "zip"},
|
|
{os: "darwin", arch: "amd64", archive: "zip"},
|
|
{os: "freebsd", arch: "386", archive: "tar.gz"},
|
|
{os: "freebsd", arch: "amd64", archive: "tar.gz"},
|
|
{os: "freebsd", arch: "arm", arm: "7", archive: "tar.gz"},
|
|
{os: "linux", arch: "386", archive: "tar.gz"},
|
|
{os: "linux", arch: "amd64", archive: "tar.gz"},
|
|
{os: "linux", arch: "arm", arm: "7", archive: "tar.gz"},
|
|
{os: "linux", arch: "arm64", archive: "tar.gz"},
|
|
{os: "netbsd", arch: "386", archive: "tar.gz"},
|
|
{os: "netbsd", arch: "amd64", archive: "tar.gz"},
|
|
{os: "openbsd", arch: "386", archive: "tar.gz"},
|
|
{os: "openbsd", arch: "amd64", archive: "tar.gz"},
|
|
{os: "solaris", arch: "amd64", archive: "tar.gz"},
|
|
{os: "windows", arch: "386", archive: "zip"},
|
|
{os: "windows", arch: "amd64", archive: "zip"},
|
|
}
|
|
|
|
var distContents = []string{
|
|
filepath.Join(distDir, "init"),
|
|
filepath.Join(distDir, "CHANGES.txt"),
|
|
filepath.Join(distDir, "LICENSES.txt"),
|
|
filepath.Join(distDir, "README.txt"),
|
|
}
|