build: better error messages

This commit is contained in:
xushiwei
2024-04-29 01:34:21 +08:00
parent 769b93a277
commit 286b520d83
2 changed files with 41 additions and 16 deletions

View File

@@ -20,7 +20,6 @@ import (
"fmt" "fmt"
"go/token" "go/token"
"go/types" "go/types"
"log"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@@ -99,6 +98,20 @@ func Do(args []string, conf *Config) {
initial, err := packages.Load(cfg, patterns...) initial, err := packages.Load(cfg, patterns...)
check(err) check(err)
mode := conf.Mode
if len(initial) == 1 && len(initial[0].CompiledGoFiles) > 0 {
if mode == ModeBuild {
mode = ModeInstall
}
} else if mode == ModeRun {
if len(initial) > 1 {
fmt.Fprintln(os.Stderr, "cannot run multiple packages")
} else {
fmt.Fprintln(os.Stderr, "no Go files in matched packages")
}
return
}
llssa.Initialize(llssa.InitAll) llssa.Initialize(llssa.InitAll)
if verbose { if verbose {
llssa.SetDebug(llssa.DbgFlagAll) llssa.SetDebug(llssa.DbgFlagAll)
@@ -113,10 +126,6 @@ func Do(args []string, conf *Config) {
return rt[0].Types return rt[0].Types
}) })
mode := conf.Mode
if mode == ModeBuild && len(initial) == 1 {
mode = ModeInstall
}
buildAllPkgs(prog, initial, mode, verbose) buildAllPkgs(prog, initial, mode, verbose)
var runtimeFiles []string var runtimeFiles []string
@@ -124,20 +133,25 @@ func Do(args []string, conf *Config) {
runtimeFiles = allLinkFiles(rt) runtimeFiles = allLinkFiles(rt)
} }
if mode != ModeBuild { if mode != ModeBuild {
nErr := 0
for _, pkg := range initial { for _, pkg := range initial {
if pkg.Name == "main" { if pkg.Name == "main" {
linkMainPkg(pkg, runtimeFiles, conf, mode, verbose) nErr += linkMainPkg(pkg, runtimeFiles, conf, mode, verbose)
} }
} }
if nErr > 0 {
fmt.Fprintf(os.Stderr, "%d errors occurred\n", nErr)
os.Exit(1)
}
} }
} }
func setNeedRuntime(pkg *packages.Package) { func setNeedRuntime(pkg *packages.Package) {
pkg.Module = nil // just use pkg.Module to mark it needs runtime pkg.ID = "" // just use pkg.Module to mark it needs runtime
} }
func isNeedRuntime(pkg *packages.Package) bool { func isNeedRuntime(pkg *packages.Package) bool {
return pkg.Module == nil return pkg.ID == ""
} }
func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) { func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) {
@@ -145,7 +159,7 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
ssaProg, pkgs, errPkgs := allPkgs(initial, ssa.SanityCheckFunctions) ssaProg, pkgs, errPkgs := allPkgs(initial, ssa.SanityCheckFunctions)
ssaProg.Build() ssaProg.Build()
for _, errPkg := range errPkgs { for _, errPkg := range errPkgs {
log.Println("cannot build SSA for package", errPkg) fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg)
} }
for _, pkg := range pkgs { for _, pkg := range pkgs {
buildPkg(prog, pkg, mode, verbose) buildPkg(prog, pkg, mode, verbose)
@@ -155,7 +169,7 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
} }
} }
func linkMainPkg(pkg *packages.Package, runtimeFiles []string, conf *Config, mode Mode, verbose bool) { func linkMainPkg(pkg *packages.Package, runtimeFiles []string, conf *Config, mode Mode, verbose bool) (nErr int) {
pkgPath := pkg.PkgPath pkgPath := pkg.PkgPath
name := path.Base(pkgPath) name := path.Base(pkgPath)
app := conf.OutFile app := conf.OutFile
@@ -180,11 +194,17 @@ func linkMainPkg(pkg *packages.Package, runtimeFiles []string, conf *Config, mod
args = append(args, runtimeFiles...) args = append(args, runtimeFiles...)
} }
// TODO(xsw): show work if verbose || mode != ModeRun {
// fmt.Fprintln(os.Stderr, "clang", args)
if verbose {
fmt.Fprintln(os.Stderr, "#", pkgPath) fmt.Fprintln(os.Stderr, "#", pkgPath)
} }
defer func() {
if e := recover(); e != nil {
nErr = 1
}
}()
// TODO(xsw): show work
// fmt.Fprintln(os.Stderr, "clang", args)
err := clang.New("").Exec(args...) err := clang.New("").Exec(args...)
check(err) check(err)
@@ -195,6 +215,7 @@ func linkMainPkg(pkg *packages.Package, runtimeFiles []string, conf *Config, mod
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Run() cmd.Run()
} }
return
} }
func buildPkg(prog llssa.Program, aPkg aPackage, mode Mode, verbose bool) { func buildPkg(prog llssa.Program, aPkg aPackage, mode Mode, verbose bool) {

View File

@@ -17,6 +17,7 @@
package clang package clang
import ( import (
"io"
"os" "os"
"os/exec" "os/exec"
) )
@@ -26,6 +27,9 @@ import (
// Cmd represents a nm command. // Cmd represents a nm command.
type Cmd struct { type Cmd struct {
app string app string
Stdout io.Writer
Stderr io.Writer
} }
// New creates a new nm command. // New creates a new nm command.
@@ -33,13 +37,13 @@ func New(app string) *Cmd {
if app == "" { if app == "" {
app = "clang" app = "clang"
} }
return &Cmd{app} return &Cmd{app, os.Stdout, os.Stderr}
} }
func (p *Cmd) Exec(args ...string) error { func (p *Cmd) Exec(args ...string) error {
cmd := exec.Command(p.app, args...) cmd := exec.Command(p.app, args...)
cmd.Stdout = os.Stdout cmd.Stdout = p.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = p.Stderr
return cmd.Run() return cmd.Run()
} }