@@ -149,8 +149,10 @@ func (b *Builder) Do(ctx context.Context, root *Action) {
149
149
defer b .exec .Unlock ()
150
150
151
151
if err != nil {
152
- if err == errPrintedOutput {
153
- base .SetExitStatus (2 )
152
+ if b .AllowErrors {
153
+ if a .Package .Error == nil {
154
+ a .Package .Error = & load.PackageError {Err : err }
155
+ }
154
156
} else {
155
157
base .Errorf ("%s" , err )
156
158
}
@@ -508,8 +510,8 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
508
510
}
509
511
510
512
defer func () {
511
- if err != nil && err != errPrintedOutput {
512
- err = fmt .Errorf ("go build %s: %v" , a . Package .ImportPath , err )
513
+ if err != nil {
514
+ err = fmt .Errorf ("go build %s: %v" , p .ImportPath , err )
513
515
}
514
516
if err != nil && b .IsCmdList && b .NeedError && p .Error == nil {
515
517
p .Error = & load.PackageError {Err : err }
@@ -821,9 +823,11 @@ OverlayLoop:
821
823
if p .Module != nil && ! allowedVersion (p .Module .GoVersion ) {
822
824
output += "note: module requires Go " + p .Module .GoVersion + "\n "
823
825
}
824
- b . showOutput ( a , a . Package . Dir , a . Package . Desc (), output )
826
+
825
827
if err != nil {
826
- return errPrintedOutput
828
+ return errors .New (fmt .Sprint (formatOutput (b .WorkDir , p .Dir , p .Desc (), output )))
829
+ } else {
830
+ b .showOutput (a , p .Dir , p .Desc (), output )
827
831
}
828
832
}
829
833
if err != nil {
@@ -1502,9 +1506,8 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string,
1502
1506
var out []byte
1503
1507
out , err = b .runOut (nil , p .Dir , nil , b .PkgconfigCmd (), "--cflags" , pcflags , "--" , pkgs )
1504
1508
if err != nil {
1505
- b .showOutput (nil , p .Dir , b .PkgconfigCmd ()+ " --cflags " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1506
- b .Print (err .Error () + "\n " )
1507
- return nil , nil , errPrintedOutput
1509
+ prefix , suffix := formatOutput (b .WorkDir , p .Dir , b .PkgconfigCmd ()+ " --cflags " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1510
+ return nil , nil , errors .New (fmt .Sprint (prefix , suffix + err .Error ()))
1508
1511
}
1509
1512
if len (out ) > 0 {
1510
1513
cflags , err = splitPkgConfigOutput (out )
@@ -1517,9 +1520,8 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string,
1517
1520
}
1518
1521
out , err = b .runOut (nil , p .Dir , nil , b .PkgconfigCmd (), "--libs" , pcflags , "--" , pkgs )
1519
1522
if err != nil {
1520
- b .showOutput (nil , p .Dir , b .PkgconfigCmd ()+ " --libs " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1521
- b .Print (err .Error () + "\n " )
1522
- return nil , nil , errPrintedOutput
1523
+ prefix , suffix := formatOutput (b .WorkDir , p .Dir , b .PkgconfigCmd ()+ " --libs " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1524
+ return nil , nil , errors .New (fmt .Sprint (prefix , suffix + err .Error ()))
1523
1525
}
1524
1526
if len (out ) > 0 {
1525
1527
// NOTE: we don't attempt to parse quotes and unescapes here. pkg-config
@@ -1611,7 +1613,7 @@ func (b *Builder) linkShared(ctx context.Context, a *Action) (err error) {
1611
1613
// BuildInstallFunc is the action for installing a single package or executable.
1612
1614
func BuildInstallFunc (b * Builder , ctx context.Context , a * Action ) (err error ) {
1613
1615
defer func () {
1614
- if err != nil && err != errPrintedOutput {
1616
+ if err != nil {
1615
1617
// a.Package == nil is possible for the go install -buildmode=shared
1616
1618
// action that installs libmangledname.so, which corresponds to
1617
1619
// a list of packages, not just one.
@@ -2015,15 +2017,7 @@ func (b *Builder) Showcmd(dir string, format string, args ...any) {
2015
2017
// If a is not nil and a.output is not nil, showOutput appends to that slice instead of
2016
2018
// printing to b.Print.
2017
2019
func (b * Builder ) showOutput (a * Action , dir , desc , out string ) {
2018
- prefix := "# " + desc
2019
- suffix := "\n " + out
2020
- if reldir := base .ShortPath (dir ); reldir != dir {
2021
- suffix = strings .ReplaceAll (suffix , " " + dir , " " + reldir )
2022
- suffix = strings .ReplaceAll (suffix , "\n " + dir , "\n " + reldir )
2023
- suffix = strings .ReplaceAll (suffix , "\n \t " + dir , "\n \t " + reldir )
2024
- }
2025
- suffix = strings .ReplaceAll (suffix , " " + b .WorkDir , " $WORK" )
2026
-
2020
+ prefix , suffix := formatOutput (b .WorkDir , dir , desc , out )
2027
2021
if a != nil && a .output != nil {
2028
2022
a .output = append (a .output , prefix ... )
2029
2023
a .output = append (a .output , suffix ... )
@@ -2035,12 +2029,41 @@ func (b *Builder) showOutput(a *Action, dir, desc, out string) {
2035
2029
b .Print (prefix , suffix )
2036
2030
}
2037
2031
2038
- // errPrintedOutput is a special error indicating that a command failed
2039
- // but that it generated output as well, and that output has already
2040
- // been printed, so there's no point showing 'exit status 1' or whatever
2041
- // the wait status was. The main executor, builder.do, knows not to
2042
- // print this error.
2043
- var errPrintedOutput = errors .New ("already printed output - no need to show error" )
2032
+ // formatOutput prints "# desc" followed by the given output.
2033
+ // The output is expected to contain references to 'dir', usually
2034
+ // the source directory for the package that has failed to build.
2035
+ // formatOutput rewrites mentions of dir with a relative path to dir
2036
+ // when the relative path is shorter. This is usually more pleasant.
2037
+ // For example, if fmt doesn't compile and we are in src/html,
2038
+ // the output is
2039
+ //
2040
+ // $ go build
2041
+ // # fmt
2042
+ // ../fmt/print.go:1090: undefined: asdf
2043
+ // $
2044
+ //
2045
+ // instead of
2046
+ //
2047
+ // $ go build
2048
+ // # fmt
2049
+ // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
2050
+ // $
2051
+ //
2052
+ // formatOutput also replaces references to the work directory with $WORK.
2053
+ // formatOutput returns the output in a prefix with the description and a
2054
+ // suffix with the actual output.
2055
+ func formatOutput (workDir , dir , desc , out string ) (prefix , suffix string ) {
2056
+ prefix = "# " + desc
2057
+ suffix = "\n " + out
2058
+ if reldir := base .ShortPath (dir ); reldir != dir {
2059
+ suffix = strings .ReplaceAll (suffix , " " + dir , " " + reldir )
2060
+ suffix = strings .ReplaceAll (suffix , "\n " + dir , "\n " + reldir )
2061
+ suffix = strings .ReplaceAll (suffix , "\n \t " + dir , "\n \t " + reldir )
2062
+ }
2063
+ suffix = strings .ReplaceAll (suffix , " " + workDir , " $WORK" )
2064
+
2065
+ return prefix , suffix
2066
+ }
2044
2067
2045
2068
var cgoLine = lazyregexp .New (`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]` )
2046
2069
var cgoTypeSigRe = lazyregexp .New (`\b_C2?(type|func|var|macro)_\B` )
@@ -2054,9 +2077,10 @@ func (b *Builder) run(a *Action, dir string, desc string, env []string, cmdargs
2054
2077
if desc == "" {
2055
2078
desc = b .fmtcmd (dir , "%s" , strings .Join (str .StringList (cmdargs ... ), " " ))
2056
2079
}
2057
- b .showOutput (a , dir , desc , b .processOutput (out ))
2058
2080
if err != nil {
2059
- err = errPrintedOutput
2081
+ err = errors .New (fmt .Sprint (formatOutput (b .WorkDir , dir , desc , b .processOutput (out ))))
2082
+ } else {
2083
+ b .showOutput (a , dir , desc , b .processOutput (out ))
2060
2084
}
2061
2085
}
2062
2086
return err
@@ -2400,11 +2424,10 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s
2400
2424
}
2401
2425
}
2402
2426
2403
- b .showOutput (a , p .Dir , desc , b .processOutput (output ))
2404
- if err != nil {
2405
- err = errPrintedOutput
2406
- } else if os .Getenv ("GO_BUILDER_NAME" ) != "" {
2407
- return errors .New ("C compiler warning promoted to error on Go builders" )
2427
+ if err != nil || os .Getenv ("GO_BUILDER_NAME" ) != "" {
2428
+ err = errors .New (fmt .Sprintf (formatOutput (b .WorkDir , p .Dir , desc , b .processOutput (output ))))
2429
+ } else {
2430
+ b .showOutput (a , p .Dir , desc , b .processOutput (output ))
2408
2431
}
2409
2432
}
2410
2433
return err
@@ -3358,8 +3381,8 @@ func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFL
3358
3381
if bytes .Contains (out , []byte ("-intgosize" )) || bytes .Contains (out , []byte ("-cgo" )) {
3359
3382
return "" , "" , errors .New ("must have SWIG version >= 3.0.6" )
3360
3383
}
3361
- b . showOutput ( a , p . Dir , p . Desc (), b . processOutput ( out )) // swig error
3362
- return "" , "" , errPrintedOutput
3384
+ // swig error
3385
+ return "" , "" , errors . New ( fmt . Sprint ( formatOutput ( b . WorkDir , p . Dir , p . Desc (), b . processOutput ( out ))))
3363
3386
}
3364
3387
return "" , "" , err
3365
3388
}
0 commit comments