Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
Timon Ringwald | 20f84c6bf1 | |
Timon Ringwald | c964a85673 | |
Timon Ringwald | f91780d6ce | |
Timon Ringwald | 402b269bf4 | |
Timon Ringwald | 8ec8d32a5b | |
Timon Ringwald | bd0ed87f70 | |
Timon Ringwald | 9569739605 |
16
README.md
16
README.md
|
@ -18,7 +18,7 @@ Distributed under the MIT License. See [LICENSE.md](https://git.milar.in/milarin
|
|||
|
||||
## Demo
|
||||
|
||||
[![asciicast](https://asciinema.org/a/zNs6qELnxFc14SVAVvqox1Hq4.svg)](https://asciinema.org/a/zNs6qELnxFc14SVAVvqox1Hq4)
|
||||
[![asciicast](https://asciinema.org/a/YOFZE4hskODO5TkNedyIBa4V8.svg)](https://asciinema.org/a/YOFZE4hskODO5TkNedyIBa4V8)
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -59,24 +59,28 @@ Usage of ./gocc:
|
|||
By default, `gocc` compiles the module in the current working directory.
|
||||
You can provide a custom module path after all other arguments.
|
||||
|
||||
For example: `gocc -t 4 -ignoreconfig path/to/go/module`
|
||||
Example: `gocc -t 4 -ignoreconfig path/to/go/module`
|
||||
|
||||
#### Choosing Operating systems
|
||||
|
||||
You can decide, for which operating systems `gocc` should compile for via `-os`.
|
||||
Provide the operating systems as a comma-separated list.
|
||||
|
||||
For example: `gocc -os "windows,linux"`
|
||||
Example: `gocc -os "windows,linux"`
|
||||
|
||||
For a list of supported operating systems, run `go tool dist list`
|
||||
For a list of supported operating systems, run `go tool dist list`.
|
||||
|
||||
Providing no `-os` flag will compile for all available systems (without config file)
|
||||
|
||||
#### Choosing architectures
|
||||
|
||||
Analogous to operating systems, you can provide architectures via `-arch`.
|
||||
|
||||
For example: `gocc -arch "amd64,386"`
|
||||
Example: `gocc -arch "amd64,386"`
|
||||
|
||||
For a list of supported architectures, run `go tool dist list`
|
||||
For a list of supported architectures, run `go tool dist list`.
|
||||
|
||||
Providing no `-arch` flag will compile for all available architectures (without config file)
|
||||
|
||||
#### Output path
|
||||
|
||||
|
|
11
compile.go
11
compile.go
|
@ -35,7 +35,9 @@ func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
|||
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompiling}
|
||||
|
||||
compileCmd := exec.Command("go", "build", "-o", filePath)
|
||||
args := []string{"build", "-o", filePath, "-ldflags=" + BuildLdFlags(cfg.OS, cfg.Arch)}
|
||||
|
||||
compileCmd := exec.Command("go", args...)
|
||||
compileCmd.Dir = ModulePath
|
||||
|
||||
if err := compileCmd.Start(); err != nil {
|
||||
|
@ -50,13 +52,6 @@ func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
|||
}
|
||||
|
||||
Compress(filePath, start, cfg, ch, wg)
|
||||
|
||||
// uncomment for independent compile and compress tasks
|
||||
// (slightly slower in tests, most likely because of more context switches)
|
||||
/*
|
||||
ch <- &CompileReport{Config: cfg, State: StateWaiting}
|
||||
go Runner.Run(func() { Compress(filePath, cfg, ch, wg) })
|
||||
*/
|
||||
}
|
||||
|
||||
func Compress(filePath string, start time.Time, cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
||||
|
|
23
config.go
23
config.go
|
@ -18,9 +18,10 @@ type Config struct {
|
|||
OS []string `json:"os"`
|
||||
Arch []string `json:"arch"`
|
||||
|
||||
Silent bool `json:"silent"`
|
||||
NoCompress bool `json:"no_compress"`
|
||||
NumThreads int `json:"num_threads"`
|
||||
Silent bool `json:"silent"`
|
||||
NoCompress bool `json:"no_compress"`
|
||||
NumThreads int `json:"num_threads"`
|
||||
KeepDebugFlags bool `json:"debug_flags"`
|
||||
}
|
||||
|
||||
func SetFlagIfDefault[T comparable](flag *T, newValue T, defaultValue T) {
|
||||
|
@ -56,6 +57,7 @@ func LoadConfig() error {
|
|||
SetFlagIfDefault(Silent, cfg.Silent, DefaultSilent)
|
||||
SetFlagIfDefault(NoCompress, cfg.NoCompress, DefaultNoCompress)
|
||||
SetFlagIfDefault(NumThreads, cfg.NumThreads, DefaultNumThreads)
|
||||
SetFlagIfDefault(KeepDebugFlags, cfg.KeepDebugFlags, DefaultKeepDebugFlags)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -80,13 +82,14 @@ func SaveConfig() (string, error) {
|
|||
enc.SetIndent("", "\t")
|
||||
|
||||
cfg := &Config{
|
||||
OutputDir: *OutputDir,
|
||||
OutputFile: *OutputFile,
|
||||
OS: strings.Split(*OS, ","),
|
||||
Arch: strings.Split(*Arch, ","),
|
||||
Silent: *Silent,
|
||||
NoCompress: *NoCompress,
|
||||
NumThreads: *NumThreads,
|
||||
OutputDir: *OutputDir,
|
||||
OutputFile: *OutputFile,
|
||||
OS: strings.Split(*OS, ","),
|
||||
Arch: strings.Split(*Arch, ","),
|
||||
Silent: *Silent,
|
||||
NoCompress: *NoCompress,
|
||||
NumThreads: *NumThreads,
|
||||
KeepDebugFlags: *KeepDebugFlags,
|
||||
}
|
||||
|
||||
if err := enc.Encode(cfg); err != nil {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module git.milar.in/milarin/gocc
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
git.milar.in/milarin/buildinfo v1.0.0
|
||||
git.milar.in/milarin/channel v0.0.7
|
||||
git.milar.in/milarin/configfile v1.0.2
|
||||
git.milar.in/milarin/gmath v0.0.1
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1,3 +1,5 @@
|
|||
git.milar.in/milarin/buildinfo v1.0.0 h1:tw98GupUYl/0a/3aPGuezhE4wseycOSsbcLp70hy60U=
|
||||
git.milar.in/milarin/buildinfo v1.0.0/go.mod h1:arI9ZoENOgcZcanv25k9y4dKDUhPp0buJrlVerGruas=
|
||||
git.milar.in/milarin/channel v0.0.7 h1:cVKtwgH/EE7U+XTHcoFCClJ4LR349KanzjX9xKwRcNg=
|
||||
git.milar.in/milarin/channel v0.0.7/go.mod h1:We83LTI8S7u7II3pD+A2ChCDWJfCkcBUCUqii9HjTtM=
|
||||
git.milar.in/milarin/configfile v1.0.2 h1:QgZVSVDsFm3HK7PEg6a2ANeZxqo0JlIooyyJv8VaCNI=
|
||||
|
|
3
init.go
3
init.go
|
@ -8,6 +8,7 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"git.milar.in/milarin/buildinfo"
|
||||
"git.milar.in/milarin/configfile"
|
||||
)
|
||||
|
||||
|
@ -16,7 +17,7 @@ func Init() {
|
|||
var err error
|
||||
|
||||
if *ShowVersion {
|
||||
fmt.Printf("gocc %s\n", VERSION)
|
||||
buildinfo.Print(buildinfo.Options{})
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
|
52
main.go
52
main.go
|
@ -16,28 +16,35 @@ import (
|
|||
"git.milar.in/milarin/channel"
|
||||
)
|
||||
|
||||
var VERSION = "v1.0.3"
|
||||
|
||||
// globals
|
||||
var (
|
||||
OutputFileTmpl = template.New("output-file")
|
||||
|
||||
ModulePath string
|
||||
ModulePath string
|
||||
|
||||
ProjectPath string
|
||||
ProjectName string
|
||||
Runner channel.Runner
|
||||
|
||||
// meta data for executables
|
||||
VersionTag string
|
||||
CommitHash string
|
||||
BuildTime string
|
||||
|
||||
Runner channel.Runner
|
||||
|
||||
MaxConfigStringLength int
|
||||
)
|
||||
|
||||
// command line arguments default values
|
||||
var (
|
||||
DefaultOutputDir = "output"
|
||||
DefaultOutputFile = "{{.Name}}-{{.OS}}-{{.Arch}}{{.Ext}}"
|
||||
DefaultOS = ""
|
||||
DefaultArch = ""
|
||||
DefaultSilent = false
|
||||
DefaultNoCompress = false
|
||||
DefaultNumThreads = runtime.NumCPU()
|
||||
DefaultOutputDir = "output"
|
||||
DefaultOutputFile = "{{.Name}}-{{.OS}}-{{.Arch}}{{.Ext}}"
|
||||
DefaultOS = ""
|
||||
DefaultArch = ""
|
||||
DefaultSilent = false
|
||||
DefaultNoCompress = false
|
||||
DefaultNumThreads = runtime.NumCPU()
|
||||
DefaultKeepDebugFlags = false
|
||||
)
|
||||
|
||||
// command line arguments
|
||||
|
@ -48,19 +55,32 @@ var (
|
|||
OS = flag.String("os", DefaultOS, "comma-separated list of operating systems to compile for (empty for all)")
|
||||
Arch = flag.String("arch", DefaultArch, "comma-separated list of architectures to compile for (empty for all)")
|
||||
|
||||
Silent = flag.Bool("s", DefaultSilent, "silent mode (no output)")
|
||||
NoCompress = flag.Bool("c", DefaultNoCompress, "dont compress any executables")
|
||||
NumThreads = flag.Int("t", DefaultNumThreads, "amount of threads (0 = infinite)")
|
||||
Silent = flag.Bool("s", DefaultSilent, "silent mode (no output)")
|
||||
NoCompress = flag.Bool("c", DefaultNoCompress, "dont compress any executables")
|
||||
NumThreads = flag.Int("t", DefaultNumThreads, "amount of threads (0 = infinite)")
|
||||
KeepDebugFlags = flag.Bool("d", DefaultKeepDebugFlags, "keep debug flags")
|
||||
|
||||
SaveConfigFile = flag.Bool("saveconfig", false, "save config file with current configuration and exit")
|
||||
IgnoreConfigFile = flag.Bool("ignoreconfig", false, "dont read any config file")
|
||||
FindConfigFile = flag.Bool("findconfig", false, "print config file path and exit")
|
||||
|
||||
DontPrintInstallCmd = flag.Bool("p", false, "print 'go install' command")
|
||||
|
||||
ShowVersion = flag.Bool("v", false, "show version and exit")
|
||||
)
|
||||
|
||||
func main() {
|
||||
Init()
|
||||
GatherMetaData()
|
||||
|
||||
if !*Silent && !*DontPrintInstallCmd {
|
||||
tag := VersionTag
|
||||
if tag == "" || strings.HasPrefix(tag, "(devel") {
|
||||
tag = "latest"
|
||||
}
|
||||
Println(ColorDone.Sprintf("go install -ldflags=\"%s\" %s@%s", BuildLdFlags("", ""), ProjectPath, tag))
|
||||
Println()
|
||||
}
|
||||
|
||||
ch := make(chan *CompileReport, len(CompileConfigs))
|
||||
wg := new(sync.WaitGroup)
|
||||
|
@ -98,8 +118,8 @@ func DetermineProjectName() error {
|
|||
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
if strings.HasPrefix(line, "module ") {
|
||||
fullName := strings.TrimPrefix(line, "module ")
|
||||
parts := strings.Split(fullName, "/")
|
||||
ProjectPath = strings.TrimPrefix(line, "module ")
|
||||
parts := strings.Split(ProjectPath, "/")
|
||||
ProjectName = parts[len(parts)-1]
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetCommitHash(hashfmt string) (string, error) {
|
||||
gitCmd := exec.Command("git", "log", "-n", "1", "--pretty=format:"+hashfmt)
|
||||
gitCmd.Dir = ModulePath
|
||||
|
||||
stdout, err := gitCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := gitCmd.Start(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hashData, err := io.ReadAll(stdout)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := gitCmd.Wait(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
trimmedHash := strings.TrimSpace(string(hashData))
|
||||
if trimmedHash == "" {
|
||||
return "", errors.New("no valid hash found")
|
||||
}
|
||||
|
||||
return trimmedHash, nil
|
||||
}
|
||||
|
||||
func GetVersionTag() (string, error) {
|
||||
gitCmd := exec.Command("git", "log", "-n", "1", "--pretty=format:%(describe:tags)")
|
||||
gitCmd.Dir = ModulePath
|
||||
|
||||
stdout, err := gitCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := gitCmd.Start(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tagData, err := io.ReadAll(stdout)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := gitCmd.Wait(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
trimmedTag := strings.TrimSpace(string(tagData))
|
||||
if trimmedTag == "" {
|
||||
return "", errors.New("no valid version tag found")
|
||||
}
|
||||
|
||||
return trimmedTag, nil
|
||||
}
|
||||
|
||||
func WorkTreeChanged() bool {
|
||||
gitCmd := exec.Command("git", "status", "--porcelain")
|
||||
gitCmd.Dir = ModulePath
|
||||
|
||||
stdout, err := gitCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if err := gitCmd.Start(); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(stdout)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if err := gitCmd.Wait(); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return len(data) != 0
|
||||
}
|
||||
|
||||
func GatherMetaData() {
|
||||
BuildTime = time.Now().Format(time.RFC3339)
|
||||
|
||||
if !WorkTreeChanged() {
|
||||
VersionTag, _ = GetVersionTag()
|
||||
CommitHash, _ = GetCommitHash("%H")
|
||||
} else {
|
||||
hash, _ := GetCommitHash("%h")
|
||||
VersionTag = fmt.Sprintf("(devel-%s)", hash)
|
||||
}
|
||||
|
||||
if !*Silent {
|
||||
ColorDone.Println("build info:")
|
||||
fmt.Printf("version: %s\n", VersionTag)
|
||||
fmt.Printf("build time: %s\n", BuildTime)
|
||||
if CommitHash != "" {
|
||||
fmt.Printf("commit hash: %s\n", CommitHash)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
func BuildLdFlags(os, arch string) string {
|
||||
b := &strings.Builder{}
|
||||
|
||||
if !*KeepDebugFlags {
|
||||
b.WriteString("-s -w")
|
||||
}
|
||||
|
||||
if CommitHash != "" {
|
||||
b.WriteString(" -X ")
|
||||
b.WriteString("git.milar.in/milarin/buildinfo.Commit")
|
||||
b.WriteString("=")
|
||||
b.WriteString(CommitHash)
|
||||
}
|
||||
|
||||
if VersionTag != "" {
|
||||
b.WriteString(" -X ")
|
||||
b.WriteString("git.milar.in/milarin/buildinfo.Version")
|
||||
b.WriteString("=")
|
||||
b.WriteString(VersionTag)
|
||||
}
|
||||
|
||||
b.WriteString(" -X ")
|
||||
b.WriteString("git.milar.in/milarin/buildinfo.Name")
|
||||
b.WriteString("=")
|
||||
b.WriteString(ProjectName)
|
||||
|
||||
b.WriteString(" -X ")
|
||||
b.WriteString("git.milar.in/milarin/buildinfo.BuildTime")
|
||||
b.WriteString("=")
|
||||
b.WriteString(BuildTime)
|
||||
|
||||
if os != "" {
|
||||
b.WriteString(" -X ")
|
||||
b.WriteString("git.milar.in/milarin/buildinfo.OS")
|
||||
b.WriteString("=")
|
||||
b.WriteString(os)
|
||||
}
|
||||
|
||||
if arch != "" {
|
||||
b.WriteString(" -X ")
|
||||
b.WriteString("git.milar.in/milarin/buildinfo.Arch")
|
||||
b.WriteString("=")
|
||||
b.WriteString(arch)
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
Loading…
Reference in New Issue