Skip to content

Commit f5d21ff

Browse files
committed
cmd/go: decide whether to install .a based on number of CgoFiles
Instead of hardcoding the set of five packages that depend on cgo to decide whether a package should have an install target, make the decision based on whether the package has any CgoFiles. This means that in nocgo configurations, there will be no installed packages, and that if an GOOS/GOARCH combination doesn't have cgo files we don't unnecessarily install a .a. Because the determination of whether a file is a CgoFile is made later in the Import functions, the choice of whether to add a PkgObj for teh case there are CgoFiles is moved later. One concern here is that in some cases, PkgObj may be set differently in the case of the FindOnly mode, since the determination is moved across the boundary. We might want to always set PkgObj after the FindOnly boundary for consistency? cmd/go doesn't seem to use it when calling Import with FindOnly. Also remove internal/buildinternal/needs_install.go because we will be checking whether to install based on the number of cgo files and it might be overkill to make the NeedsInstalledDotA function be the equivalent of len(input) > 0. For #47257 Change-Id: I5f7f2137dc99aaeb2e2695c14e0222093a6b2407 Reviewed-on: https://go-review.googlesource.com/c/go/+/448803 Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Michael Matloob <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Michael Matloob <[email protected]>
1 parent 342751a commit f5d21ff

File tree

6 files changed

+27
-26
lines changed

6 files changed

+27
-26
lines changed

src/cmd/go/internal/modindex/read.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"go/build"
1313
"go/build/constraint"
1414
"go/token"
15-
"internal/buildinternal"
1615
"internal/godebug"
1716
"internal/goroot"
1817
"path"
@@ -396,6 +395,7 @@ func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *b
396395
inTestdata := func(sub string) bool {
397396
return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || str.HasPathPrefix(sub, "testdata")
398397
}
398+
var pkga string
399399
if !inTestdata(rp.dir) {
400400
// In build.go, p.Root should only be set in the non-local-import case, or in
401401
// GOROOT or GOPATH. Since module mode only calls Import with path set to "."
@@ -414,7 +414,6 @@ func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *b
414414
// The fields set below (SrcRoot, PkgRoot, BinDir, PkgTargetRoot, and PkgObj)
415415
// are only set in build.Import if p.Root != "".
416416
var pkgtargetroot string
417-
var pkga string
418417
suffix := ""
419418
if ctxt.InstallSuffix != "" {
420419
suffix = "_" + ctxt.InstallSuffix
@@ -437,8 +436,7 @@ func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *b
437436
p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
438437

439438
// Set the install target if applicable.
440-
if strings.ToLower(godebug.Get("installgoroot")) == "all" ||
441-
!p.Goroot || buildinternal.NeedsInstalledDotA(p.ImportPath) {
439+
if strings.ToLower(godebug.Get("installgoroot")) == "all" || !p.Goroot {
442440
p.PkgObj = ctxt.joinPath(p.Root, pkga)
443441
}
444442
}
@@ -629,6 +627,12 @@ func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *b
629627
}
630628
}
631629

630+
// Now that p.CgoFiles has been set, use it to determine whether
631+
// a package in GOROOT gets an install target:
632+
if len(p.CgoFiles) != 0 && p.Root != "" && p.Goroot && pkga != "" {
633+
p.PkgObj = ctxt.joinPath(p.Root, pkga)
634+
}
635+
632636
p.EmbedPatterns, p.EmbedPatternPos = cleanDecls(embedPos)
633637
p.TestEmbedPatterns, p.TestEmbedPatternPos = cleanDecls(testEmbedPos)
634638
p.XTestEmbedPatterns, p.XTestEmbedPatternPos = cleanDecls(xTestEmbedPos)

src/cmd/go/internal/work/build.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"flag"
1111
"fmt"
1212
"go/build"
13-
"internal/buildinternal"
1413
"os"
1514
"os/exec"
1615
"path/filepath"
@@ -740,11 +739,11 @@ func InstallPackages(ctx context.Context, patterns []string, pkgs []*load.Packag
740739
// or else something is wrong and worth reporting (like a ConflictDir).
741740
case p.Name != "main" && p.Module != nil:
742741
// Non-executables have no target (except the cache) when building with modules.
743-
case p.Name != "main" && p.Standard && !buildinternal.NeedsInstalledDotA(p.ImportPath):
742+
case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
744743
// Most packages in std do not need an installed .a, because they can be
745744
// rebuilt and used directly from the build cache.
746745
// A few targets (notably those using cgo) still do need to be installed
747-
// in case the user's environment lacks a C compiler. case p.Internal.GobinSubdir:
746+
// in case the user's environment lacks a C compiler.
748747
case p.Internal.GobinSubdir:
749748
base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
750749
case p.Internal.CmdlineFiles:

src/cmd/go/testdata/script/install_goroot_targets.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,12 @@ stdout cgo\.a
1919
env GODEBUG=installgoroot=all
2020
go list -f '{{.Target}}' fmt
2121
stdout fmt\.a
22+
23+
# With CGO_ENABLED=0, packages that would have
24+
# an install target with cgo on no longer do.
25+
env GODEBUG=
26+
env CGO_ENABLED=0
27+
go list -f '{{.Target}}' runtime/cgo
28+
! stdout .
29+
go list -export -f '{{.Export}}' runtime/cgo
30+
stdout $GOCACHE

src/go/build/build.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"go/doc"
1414
"go/token"
1515
"internal/buildcfg"
16-
"internal/buildinternal"
1716
"internal/godebug"
1817
"internal/goroot"
1918
"internal/goversion"
@@ -784,8 +783,7 @@ Found:
784783
p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
785784

786785
// Set the install target if applicable.
787-
if strings.ToLower(godebug.Get("installgoroot")) == "all" ||
788-
!p.Goroot || buildinternal.NeedsInstalledDotA(p.ImportPath) {
786+
if strings.ToLower(godebug.Get("installgoroot")) == "all" || !p.Goroot {
789787
p.PkgObj = ctxt.joinPath(p.Root, pkga)
790788
}
791789
}
@@ -1003,6 +1001,12 @@ Found:
10031001
}
10041002
}
10051003

1004+
// Now that p.CgoFiles has been set, use it to determine whether
1005+
// a package in GOROOT gets an install target:
1006+
if len(p.CgoFiles) != 0 && p.Root != "" && p.Goroot && pkga != "" {
1007+
p.PkgObj = ctxt.joinPath(p.Root, pkga)
1008+
}
1009+
10061010
for tag := range allTags {
10071011
p.AllTags = append(p.AllTags, tag)
10081012
}

src/go/build/deps_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ var depsRules = `
4040
# No dependencies allowed for any of these packages.
4141
NONE
4242
< constraints, container/list, container/ring,
43-
internal/buildinternal,
4443
internal/cfg, internal/coverage, internal/coverage/rtcov,
4544
internal/coverage/uleb128, internal/coverage/calloc,
4645
internal/cpu, internal/goarch,
@@ -286,7 +285,7 @@ var depsRules = `
286285
FMT, internal/goexperiment
287286
< internal/buildcfg;
288287
289-
go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion, internal/buildinternal
288+
go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion
290289
< go/build;
291290
292291
# databases

src/internal/buildinternal/needs_install.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)