Compare commits

...

7 Commits
v1.0.3 ... main

Author SHA1 Message Date
Timon Ringwald 20f84c6bf1 print go install command by default 2022-08-30 00:42:47 +02:00
Timon Ringwald c964a85673 show build info 2022-08-29 10:50:38 +02:00
Timon Ringwald f91780d6ce insert buildinfo at compile time 2022-08-29 10:42:18 +02:00
Timon Ringwald 402b269bf4 removed commented code 2022-08-29 00:41:27 +02:00
Timon Ringwald 8ec8d32a5b remove debug flags by default 2022-08-29 00:03:56 +02:00
Timon Ringwald bd0ed87f70 updated README 2022-08-18 15:06:39 +02:00
Timon Ringwald 9569739605 new chowcase for v1.0.3 added 2022-08-18 00:01:01 +02:00
8 changed files with 232 additions and 41 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -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
View File

@ -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
}

165
metadata.go Normal file
View File

@ -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()
}