package main import ( "os/exec" "path/filepath" "strings" "sync" ) func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) { b := new(strings.Builder) data := &OutputFileTmplData{ Name: ProjectName, OS: cfg.OS, Arch: cfg.Arch, Ext: cfg.FileExt, } if err := OutputFileTmpl.Execute(b, data); err != nil { ch <- &CompileReport{Config: cfg, State: StateCompileError} wg.Done() return } filePath := filepath.Join(*OutputDir, b.String()) filePath, err := filepath.Abs(filePath) if err != nil { ch <- &CompileReport{Config: cfg, State: StateCompileError} wg.Done() return } ch <- &CompileReport{Config: cfg, State: StateCompiling} compileCmd := exec.Command("go", "build", "-o", filePath) compileCmd.Dir = ModulePath if err := compileCmd.Start(); err != nil { ch <- &CompileReport{Config: cfg, State: StateCompileError} wg.Done() return } if err := compileCmd.Wait(); err != nil { ch <- &CompileReport{Config: cfg, State: StateCompileError} wg.Done() return } Compress(filePath, 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, cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) { defer wg.Done() ch <- &CompileReport{Config: cfg, State: StateCompressing} if !*NoCompress && cfg.Compress { compressCmd := exec.Command("upx", "--best", filePath) compressCmd.Dir = ModulePath if err := compressCmd.Start(); err != nil { ch <- &CompileReport{Config: cfg, State: StateCompressError} return } if err := compressCmd.Wait(); err != nil { ch <- &CompileReport{Config: cfg, State: StateCompressError} return } } ch <- &CompileReport{Config: cfg, State: StateDone} }