@@ -153,8 +153,10 @@ func (b *Builder) Do(ctx context.Context, root *Action) {
153
153
defer b .exec .Unlock ()
154
154
155
155
if err != nil {
156
- if err == errPrintedOutput {
157
- base .SetExitStatus (2 )
156
+ if b .AllowErrors {
157
+ if a .Package .Error == nil {
158
+ a .Package .Error = & load.PackageError {Err : err }
159
+ }
158
160
} else {
159
161
base .Errorf ("%s" , err )
160
162
}
@@ -512,7 +514,7 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
512
514
}
513
515
514
516
defer func () {
515
- if err != nil && err != errPrintedOutput {
517
+ if err != nil {
516
518
err = fmt .Errorf ("go build %s: %v" , p .ImportPath , err )
517
519
}
518
520
if err != nil && b .IsCmdList && b .NeedError && p .Error == nil {
@@ -861,9 +863,11 @@ OverlayLoop:
861
863
if p .Module != nil && ! allowedVersion (p .Module .GoVersion ) {
862
864
output += "note: module requires Go " + p .Module .GoVersion + "\n "
863
865
}
864
- b . showOutput ( a , p . Dir , p . Desc (), output )
866
+
865
867
if err != nil {
866
- return errPrintedOutput
868
+ return errors .New (fmt .Sprint (formatOutput (b .WorkDir , p .Dir , p .Desc (), output )))
869
+ } else {
870
+ b .showOutput (a , p .Dir , p .Desc (), output )
867
871
}
868
872
}
869
873
if err != nil {
@@ -1542,9 +1546,8 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string,
1542
1546
var out []byte
1543
1547
out , err = b .runOut (nil , p .Dir , nil , b .PkgconfigCmd (), "--cflags" , pcflags , "--" , pkgs )
1544
1548
if err != nil {
1545
- b .showOutput (nil , p .Dir , b .PkgconfigCmd ()+ " --cflags " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1546
- b .Print (err .Error () + "\n " )
1547
- return nil , nil , errPrintedOutput
1549
+ prefix , suffix := formatOutput (b .WorkDir , p .Dir , b .PkgconfigCmd ()+ " --cflags " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1550
+ return nil , nil , errors .New (fmt .Sprint (prefix , suffix + err .Error ()))
1548
1551
}
1549
1552
if len (out ) > 0 {
1550
1553
cflags , err = splitPkgConfigOutput (out )
@@ -1557,9 +1560,8 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string,
1557
1560
}
1558
1561
out , err = b .runOut (nil , p .Dir , nil , b .PkgconfigCmd (), "--libs" , pcflags , "--" , pkgs )
1559
1562
if err != nil {
1560
- b .showOutput (nil , p .Dir , b .PkgconfigCmd ()+ " --libs " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1561
- b .Print (err .Error () + "\n " )
1562
- return nil , nil , errPrintedOutput
1563
+ prefix , suffix := formatOutput (b .WorkDir , p .Dir , b .PkgconfigCmd ()+ " --libs " + strings .Join (pcflags , " " )+ " -- " + strings .Join (pkgs , " " ), string (out ))
1564
+ return nil , nil , errors .New (fmt .Sprint (prefix , suffix + err .Error ()))
1563
1565
}
1564
1566
if len (out ) > 0 {
1565
1567
// NOTE: we don't attempt to parse quotes and unescapes here. pkg-config
@@ -1651,7 +1653,7 @@ func (b *Builder) linkShared(ctx context.Context, a *Action) (err error) {
1651
1653
// BuildInstallFunc is the action for installing a single package or executable.
1652
1654
func BuildInstallFunc (b * Builder , ctx context.Context , a * Action ) (err error ) {
1653
1655
defer func () {
1654
- if err != nil && err != errPrintedOutput {
1656
+ if err != nil {
1655
1657
// a.Package == nil is possible for the go install -buildmode=shared
1656
1658
// action that installs libmangledname.so, which corresponds to
1657
1659
// a list of packages, not just one.
@@ -2103,15 +2105,7 @@ func (b *Builder) Showcmd(dir string, format string, args ...any) {
2103
2105
// If a is not nil and a.output is not nil, showOutput appends to that slice instead of
2104
2106
// printing to b.Print.
2105
2107
func (b * Builder ) showOutput (a * Action , dir , desc , out string ) {
2106
- prefix := "# " + desc
2107
- suffix := "\n " + out
2108
- if reldir := base .ShortPath (dir ); reldir != dir {
2109
- suffix = strings .ReplaceAll (suffix , " " + dir , " " + reldir )
2110
- suffix = strings .ReplaceAll (suffix , "\n " + dir , "\n " + reldir )
2111
- suffix = strings .ReplaceAll (suffix , "\n \t " + dir , "\n \t " + reldir )
2112
- }
2113
- suffix = strings .ReplaceAll (suffix , " " + b .WorkDir , " $WORK" )
2114
-
2108
+ prefix , suffix := formatOutput (b .WorkDir , dir , desc , out )
2115
2109
if a != nil && a .output != nil {
2116
2110
a .output = append (a .output , prefix ... )
2117
2111
a .output = append (a .output , suffix ... )
@@ -2123,12 +2117,41 @@ func (b *Builder) showOutput(a *Action, dir, desc, out string) {
2123
2117
b .Print (prefix , suffix )
2124
2118
}
2125
2119
2126
- // errPrintedOutput is a special error indicating that a command failed
2127
- // but that it generated output as well, and that output has already
2128
- // been printed, so there's no point showing 'exit status 1' or whatever
2129
- // the wait status was. The main executor, builder.do, knows not to
2130
- // print this error.
2131
- var errPrintedOutput = errors .New ("already printed output - no need to show error" )
2120
+ // formatOutput prints "# desc" followed by the given output.
2121
+ // The output is expected to contain references to 'dir', usually
2122
+ // the source directory for the package that has failed to build.
2123
+ // formatOutput rewrites mentions of dir with a relative path to dir
2124
+ // when the relative path is shorter. This is usually more pleasant.
2125
+ // For example, if fmt doesn't compile and we are in src/html,
2126
+ // the output is
2127
+ //
2128
+ // $ go build
2129
+ // # fmt
2130
+ // ../fmt/print.go:1090: undefined: asdf
2131
+ // $
2132
+ //
2133
+ // instead of
2134
+ //
2135
+ // $ go build
2136
+ // # fmt
2137
+ // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
2138
+ // $
2139
+ //
2140
+ // formatOutput also replaces references to the work directory with $WORK.
2141
+ // formatOutput returns the output in a prefix with the description and a
2142
+ // suffix with the actual output.
2143
+ func formatOutput (workDir , dir , desc , out string ) (prefix , suffix string ) {
2144
+ prefix = "# " + desc
2145
+ suffix = "\n " + out
2146
+ if reldir := base .ShortPath (dir ); reldir != dir {
2147
+ suffix = strings .ReplaceAll (suffix , " " + dir , " " + reldir )
2148
+ suffix = strings .ReplaceAll (suffix , "\n " + dir , "\n " + reldir )
2149
+ suffix = strings .ReplaceAll (suffix , "\n \t " + dir , "\n \t " + reldir )
2150
+ }
2151
+ suffix = strings .ReplaceAll (suffix , " " + workDir , " $WORK" )
2152
+
2153
+ return prefix , suffix
2154
+ }
2132
2155
2133
2156
var cgoLine = lazyregexp .New (`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]` )
2134
2157
var cgoTypeSigRe = lazyregexp .New (`\b_C2?(type|func|var|macro)_\B` )
@@ -2142,9 +2165,10 @@ func (b *Builder) run(a *Action, dir string, desc string, env []string, cmdargs
2142
2165
if desc == "" {
2143
2166
desc = b .fmtcmd (dir , "%s" , strings .Join (str .StringList (cmdargs ... ), " " ))
2144
2167
}
2145
- b .showOutput (a , dir , desc , b .processOutput (out ))
2146
2168
if err != nil {
2147
- err = errPrintedOutput
2169
+ err = errors .New (fmt .Sprint (formatOutput (b .WorkDir , dir , desc , b .processOutput (out ))))
2170
+ } else {
2171
+ b .showOutput (a , dir , desc , b .processOutput (out ))
2148
2172
}
2149
2173
}
2150
2174
return err
@@ -2488,11 +2512,10 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s
2488
2512
}
2489
2513
}
2490
2514
2491
- b .showOutput (a , p .Dir , desc , b .processOutput (output ))
2492
- if err != nil {
2493
- err = errPrintedOutput
2494
- } else if os .Getenv ("GO_BUILDER_NAME" ) != "" {
2495
- return errors .New ("C compiler warning promoted to error on Go builders" )
2515
+ if err != nil || os .Getenv ("GO_BUILDER_NAME" ) != "" {
2516
+ err = errors .New (fmt .Sprintf (formatOutput (b .WorkDir , p .Dir , desc , b .processOutput (output ))))
2517
+ } else {
2518
+ b .showOutput (a , p .Dir , desc , b .processOutput (output ))
2496
2519
}
2497
2520
}
2498
2521
return err
@@ -3410,8 +3433,8 @@ func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFL
3410
3433
if bytes .Contains (out , []byte ("-intgosize" )) || bytes .Contains (out , []byte ("-cgo" )) {
3411
3434
return "" , "" , errors .New ("must have SWIG version >= 3.0.6" )
3412
3435
}
3413
- b . showOutput ( a , p . Dir , p . Desc (), b . processOutput ( out )) // swig error
3414
- return "" , "" , errPrintedOutput
3436
+ // swig error
3437
+ return "" , "" , errors . New ( fmt . Sprint ( formatOutput ( b . WorkDir , p . Dir , p . Desc (), b . processOutput ( out ))))
3415
3438
}
3416
3439
return "" , "" , err
3417
3440
}
0 commit comments