cmd/go: refactor injection of modload.LoaderState

This change refactors the injection of the global
`modload.LoaderState` variable such that the injection can occur later
in the chain of function calls.  This allows us to keep the behavior
of the global PerPackageFlags (e.g. BuildGcFlags, etc) consistent and
avoid introducing a dependency on the module loader state there.

This commit is part of the overall effort to eliminate global
modloader state.

Change-Id: I1a0cc07173a1804426392581ba8de4ae1e30cdef
Reviewed-on: https://go-review.googlesource.com/c/go/+/711115
Reviewed-by: Michael Matloob <matloob@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@google.com>
This commit is contained in:
Ian Alexander
2025-10-07 12:57:12 -04:00
parent c18fa69e52
commit 29046398bb
7 changed files with 85 additions and 81 deletions

View File

@@ -30,7 +30,7 @@ type PerPackageFlag struct {
// A ppfValue is a single <pattern>=<flags> per-package flag value.
type ppfValue struct {
match func(*Package) bool // compiled pattern
match func(*modload.State, *Package) bool // compiled pattern
flags []string
}
@@ -43,7 +43,7 @@ func (f *PerPackageFlag) Set(v string) error {
func (f *PerPackageFlag) set(v, cwd string) error {
f.raw = v
f.present = true
match := func(p *Package) bool { return p.Internal.CmdlinePkg || p.Internal.CmdlineFiles } // default predicate with no pattern
match := func(_ *modload.State, p *Package) bool { return p.Internal.CmdlinePkg || p.Internal.CmdlineFiles } // default predicate with no pattern
// For backwards compatibility with earlier flag splitting, ignore spaces around flags.
v = strings.TrimSpace(v)
if v == "" {
@@ -64,7 +64,7 @@ func (f *PerPackageFlag) set(v, cwd string) error {
return fmt.Errorf("parameter may not start with quote character %c", v[0])
}
pattern := strings.TrimSpace(v[:i])
match = MatchPackage(modload.LoaderState, pattern, cwd)
match = MatchPackage(pattern, cwd)
v = v[i+1:]
}
flags, err := quoted.Split(v)
@@ -86,10 +86,13 @@ func (f *PerPackageFlag) Present() bool {
}
// For returns the flags to use for the given package.
func (f *PerPackageFlag) For(p *Package) []string {
//
// The module loader state is used by the matcher to know if certain
// patterns match packages within the state's MainModules.
func (f *PerPackageFlag) For(s *modload.State, p *Package) []string {
flags := []string{}
for _, v := range f.values {
if v.match(p) {
if v.match(s, p) {
flags = v.flags
}
}

View File

@@ -5,6 +5,7 @@
package load
import (
"cmd/go/internal/modload"
"fmt"
"path/filepath"
"reflect"
@@ -125,7 +126,7 @@ func TestPerPackageFlag(t *testing.T) {
}
for _, p := range tt.pkgs {
dir := nativeDir(p.dir)
flags := ppFlags.For(&Package{PackagePublic: PackagePublic{ImportPath: p.path, Dir: dir}, Internal: PackageInternal{CmdlinePkg: p.cmdline}})
flags := ppFlags.For(modload.NewState(), &Package{PackagePublic: PackagePublic{ImportPath: p.path, Dir: dir}, Internal: PackageInternal{CmdlinePkg: p.cmdline}})
if !reflect.DeepEqual(flags, p.flags) {
t.Errorf("For(%v, %v, %v) = %v, want %v", p.path, dir, p.cmdline, flags, p.flags)
}

View File

@@ -355,14 +355,14 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
// can produce better error messages if it starts with the original paths.
// The initial load of p loads all the non-test imports and rewrites
// the vendored paths, so nothing should ever call p.vendored(p.Imports).
func (p *Package) Resolve(loaderstate *modload.State, imports []string) []string {
func (p *Package) Resolve(s *modload.State, imports []string) []string {
if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
panic("internal error: p.Resolve(p.Imports) called")
}
seen := make(map[string]bool)
var all []string
for _, path := range imports {
path = ResolveImportPath(loaderstate, p, path)
path = ResolveImportPath(s, p, path)
if !seen[path] {
seen[path] = true
all = append(all, path)
@@ -1151,7 +1151,7 @@ func isDir(path string) bool {
// First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
// If vendor expansion doesn't trigger, then the path is also subject to
// Go 1.11 module legacy conversion (golang.org/issue/25069).
func ResolveImportPath(loaderstate *modload.State, parent *Package, path string) (found string) {
func ResolveImportPath(s *modload.State, parent *Package, path string) (found string) {
var parentPath, parentDir, parentRoot string
parentIsStd := false
if parent != nil {
@@ -1160,12 +1160,12 @@ func ResolveImportPath(loaderstate *modload.State, parent *Package, path string)
parentRoot = parent.Root
parentIsStd = parent.Standard
}
return resolveImportPath(loaderstate, path, parentPath, parentDir, parentRoot, parentIsStd)
return resolveImportPath(s, path, parentPath, parentDir, parentRoot, parentIsStd)
}
func resolveImportPath(loaderstate *modload.State, path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
func resolveImportPath(s *modload.State, path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
if cfg.ModulesEnabled {
if _, p, e := modload.Lookup(loaderstate, parentPath, parentIsStd, path); e == nil {
if _, p, e := modload.Lookup(s, parentPath, parentIsStd, path); e == nil {
return p
}
return path
@@ -1935,7 +1935,7 @@ func (p *Package) load(loaderstate *modload.State, ctx context.Context, opts Pac
// The linker loads implicit dependencies.
if p.Name == "main" && !p.Internal.ForceLibrary {
ldDeps, err := LinkerDeps(p)
ldDeps, err := LinkerDeps(loaderstate, p)
if err != nil {
setError(err)
return
@@ -2635,12 +2635,12 @@ func SafeArg(name string) bool {
}
// LinkerDeps returns the list of linker-induced dependencies for main package p.
func LinkerDeps(p *Package) ([]string, error) {
func LinkerDeps(s *modload.State, p *Package) ([]string, error) {
// Everything links runtime.
deps := []string{"runtime"}
// External linking mode forces an import of runtime/cgo.
if what := externalLinkingReason(p); what != "" && cfg.BuildContext.Compiler != "gccgo" {
if what := externalLinkingReason(s, p); what != "" && cfg.BuildContext.Compiler != "gccgo" {
if !cfg.BuildContext.CgoEnabled {
return nil, fmt.Errorf("%s requires external (cgo) linking, but cgo is not enabled", what)
}
@@ -2673,7 +2673,7 @@ func LinkerDeps(p *Package) ([]string, error) {
// externalLinkingReason reports the reason external linking is required
// even for programs that do not use cgo, or the empty string if external
// linking is not required.
func externalLinkingReason(p *Package) (what string) {
func externalLinkingReason(s *modload.State, p *Package) (what string) {
// Some targets must use external linking even inside GOROOT.
if platform.MustLinkExternal(cfg.Goos, cfg.Goarch, false) {
return cfg.Goos + "/" + cfg.Goarch
@@ -2716,7 +2716,7 @@ func externalLinkingReason(p *Package) (what string) {
// Using -ldflags=-linkmode=external forces external linking.
// If there are multiple -linkmode options, the last one wins.
if p != nil {
ldflags := BuildLdflags.For(p)
ldflags := BuildLdflags.For(s, p)
for i := len(ldflags) - 1; i >= 0; i-- {
a := ldflags[i]
if a == "-linkmode=external" ||
@@ -2842,7 +2842,7 @@ func TestPackageList(loaderstate *modload.State, ctx context.Context, opts Packa
// in LoadImport instead.
func LoadImportWithFlags(loaderstate *modload.State, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
p, err := loadImport(loaderstate, context.TODO(), PackageOpts{}, nil, path, srcDir, parent, stk, importPos, mode)
setToolFlags(p)
setToolFlags(loaderstate, p)
return p, err
}
@@ -2850,7 +2850,7 @@ func LoadImportWithFlags(loaderstate *modload.State, path, srcDir string, parent
// It's then guaranteed to not return an error
func LoadPackageWithFlags(loaderstate *modload.State, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
p := LoadPackage(loaderstate, context.TODO(), PackageOpts{}, path, srcDir, stk, importPos, mode)
setToolFlags(p)
setToolFlags(loaderstate, p)
return p
}
@@ -2992,7 +2992,7 @@ func PackagesAndErrors(loaderstate *modload.State, ctx context.Context, opts Pac
// compute the effective flags for all loaded packages
// (not just the ones matching the patterns but also
// their dependencies).
setToolFlags(pkgs...)
setToolFlags(loaderstate, pkgs...)
setPGOProfilePath(pkgs)
@@ -3231,12 +3231,12 @@ func (e *mainPackageError) ImportPath() string {
return e.importPath
}
func setToolFlags(pkgs ...*Package) {
func setToolFlags(loaderstate *modload.State, pkgs ...*Package) {
for _, p := range PackageList(pkgs) {
p.Internal.Asmflags = BuildAsmflags.For(p)
p.Internal.Gcflags = BuildGcflags.For(p)
p.Internal.Ldflags = BuildLdflags.For(p)
p.Internal.Gccgoflags = BuildGccgoflags.For(p)
p.Internal.Asmflags = BuildAsmflags.For(loaderstate, p)
p.Internal.Gcflags = BuildGcflags.For(loaderstate, p)
p.Internal.Ldflags = BuildLdflags.For(loaderstate, p)
p.Internal.Gccgoflags = BuildGccgoflags.For(loaderstate, p)
}
}
@@ -3327,7 +3327,7 @@ func GoFilesPackage(loaderstate *modload.State, ctx context.Context, opts Packag
pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
pkg.Incomplete = true
}
setToolFlags(pkg)
setToolFlags(loaderstate, pkg)
return pkg
}
@@ -3471,14 +3471,14 @@ func PackagesAndErrorsOutsideModule(loaderstate *modload.State, ctx context.Cont
}
// EnsureImport ensures that package p imports the named package.
func EnsureImport(loaderstate *modload.State, p *Package, pkg string) {
func EnsureImport(s *modload.State, p *Package, pkg string) {
for _, d := range p.Internal.Imports {
if d.Name == pkg {
return
}
}
p1, err := LoadImportWithFlags(loaderstate, pkg, p.Dir, p, &ImportStack{}, nil, 0)
p1, err := LoadImportWithFlags(s, pkg, p.Dir, p, &ImportStack{}, nil, 0)
if err != nil {
base.Fatalf("load %s: %v", pkg, err)
}
@@ -3494,10 +3494,10 @@ func EnsureImport(loaderstate *modload.State, p *Package, pkg string) {
// "go test -cover"). It walks through the packages being built (and
// dependencies) and marks them for coverage instrumentation when
// appropriate, and possibly adding additional deps where needed.
func PrepareForCoverageBuild(loaderstate *modload.State, pkgs []*Package) {
var match []func(*Package) bool
func PrepareForCoverageBuild(s *modload.State, pkgs []*Package) {
var match []func(*modload.State, *Package) bool
matchMainModAndCommandLine := func(p *Package) bool {
matchMainModAndCommandLine := func(_ *modload.State, p *Package) bool {
// note that p.Standard implies p.Module == nil below.
return p.Internal.CmdlineFiles || p.Internal.CmdlinePkg || (p.Module != nil && p.Module.Main)
}
@@ -3505,24 +3505,24 @@ func PrepareForCoverageBuild(loaderstate *modload.State, pkgs []*Package) {
if len(cfg.BuildCoverPkg) != 0 {
// If -coverpkg has been specified, then we instrument only
// the specific packages selected by the user-specified pattern(s).
match = make([]func(*Package) bool, len(cfg.BuildCoverPkg))
match = make([]func(*modload.State, *Package) bool, len(cfg.BuildCoverPkg))
for i := range cfg.BuildCoverPkg {
match[i] = MatchPackage(loaderstate, cfg.BuildCoverPkg[i], base.Cwd())
match[i] = MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
}
} else {
// Without -coverpkg, instrument only packages in the main module
// (if any), as well as packages/files specifically named on the
// command line.
match = []func(*Package) bool{matchMainModAndCommandLine}
match = []func(*modload.State, *Package) bool{matchMainModAndCommandLine}
}
// Visit the packages being built or installed, along with all of
// their dependencies, and mark them to be instrumented, taking
// into account the matchers we've set up in the sequence above.
SelectCoverPackages(loaderstate, PackageList(pkgs), match, "build")
SelectCoverPackages(s, PackageList(pkgs), match, "build")
}
func SelectCoverPackages(loaderstate *modload.State, roots []*Package, match []func(*Package) bool, op string) []*Package {
func SelectCoverPackages(s *modload.State, roots []*Package, match []func(*modload.State, *Package) bool, op string) []*Package {
var warntag string
var includeMain bool
switch op {
@@ -3540,7 +3540,7 @@ func SelectCoverPackages(loaderstate *modload.State, roots []*Package, match []f
for _, p := range roots {
haveMatch := false
for i := range match {
if match[i](p) {
if match[i](s, p) {
matched[i] = true
haveMatch = true
}
@@ -3602,7 +3602,7 @@ func SelectCoverPackages(loaderstate *modload.State, roots []*Package, match []f
// Force import of sync/atomic into package if atomic mode.
if cfg.BuildCoverMode == "atomic" {
EnsureImport(loaderstate, p, "sync/atomic")
EnsureImport(s, p, "sync/atomic")
}
}

View File

@@ -14,7 +14,7 @@ import (
)
// MatchPackage(pattern, cwd)(p) reports whether package p matches pattern in the working directory cwd.
func MatchPackage(loaderstate *modload.State, pattern, cwd string) func(*Package) bool {
func MatchPackage(pattern, cwd string) func(*modload.State, *Package) bool {
switch {
case search.IsRelativePath(pattern):
// Split pattern into leading pattern-free directory path
@@ -29,10 +29,10 @@ func MatchPackage(loaderstate *modload.State, pattern, cwd string) func(*Package
}
dir = filepath.Join(cwd, dir)
if pattern == "" {
return func(p *Package) bool { return p.Dir == dir }
return func(_ *modload.State, p *Package) bool { return p.Dir == dir }
}
matchPath := pkgpattern.MatchPattern(pattern)
return func(p *Package) bool {
return func(_ *modload.State, p *Package) bool {
// Compute relative path to dir and see if it matches the pattern.
rel, err := filepath.Rel(dir, p.Dir)
if err != nil {
@@ -49,22 +49,22 @@ func MatchPackage(loaderstate *modload.State, pattern, cwd string) func(*Package
// This is slightly inaccurate: it matches every package, which isn't the same
// as matching the "all" package pattern.
// TODO(matloob): Should we make this more accurate? Does anyone depend on this behavior?
return func(p *Package) bool { return true }
return func(_ *modload.State, p *Package) bool { return true }
case pattern == "std":
return func(p *Package) bool { return p.Standard }
return func(_ *modload.State, p *Package) bool { return p.Standard }
case pattern == "cmd":
return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
case pattern == "tool" && modload.Enabled(loaderstate):
return func(p *Package) bool {
return loaderstate.MainModules.Tools()[p.ImportPath]
}
case pattern == "work" && modload.Enabled(loaderstate):
return func(p *Package) bool {
return p.Module != nil && loaderstate.MainModules.Contains(p.Module.Path)
}
return func(_ *modload.State, p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
default:
matchPath := pkgpattern.MatchPattern(pattern)
return func(p *Package) bool { return matchPath(p.ImportPath) }
return func(s *modload.State, p *Package) bool {
switch {
case pattern == "tool" && modload.Enabled(s):
return s.MainModules.Tools()[p.ImportPath]
case pattern == "work" && modload.Enabled(s):
return p.Module != nil && s.MainModules.Contains(p.Module.Path)
default:
matchPath := pkgpattern.MatchPattern(pattern)
return matchPath(p.ImportPath)
}
}
}
}

View File

@@ -311,7 +311,7 @@ func TestPackagesAndErrors(loaderstate *modload.State, ctx context.Context, done
if cover != nil {
deps = append(deps, "internal/coverage/cfile")
}
ldDeps, err := LinkerDeps(p)
ldDeps, err := LinkerDeps(loaderstate, p)
if err != nil && pmain.Error == nil {
pmain.Error = &PackageError{Err: err}
}
@@ -337,7 +337,7 @@ func TestPackagesAndErrors(loaderstate *modload.State, ctx context.Context, done
allTestImports = append(allTestImports, pmain.Internal.Imports...)
allTestImports = append(allTestImports, imports...)
allTestImports = append(allTestImports, ximports...)
setToolFlags(allTestImports...)
setToolFlags(loaderstate, allTestImports...)
// Do initial scan for metadata needed for writing _testmain.go
// Use that metadata to update the list of imports for package main.

View File

@@ -865,9 +865,9 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
var writeCoverMetaAct *work.Action
if cfg.BuildCoverPkg != nil {
match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg))
match := make([]func(*modload.State, *load.Package) bool, len(cfg.BuildCoverPkg))
for i := range cfg.BuildCoverPkg {
match[i] = load.MatchPackage(modload.LoaderState, cfg.BuildCoverPkg[i], base.Cwd())
match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
}
// Select for coverage all dependencies matching the -coverpkg

View File

@@ -395,7 +395,7 @@ func (b *Builder) NewObjdir() string {
// at shlibpath. For the native toolchain this list is stored, newline separated, in
// an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
// .go_export section.
func readpkglist(loaderstate *modload.State, shlibpath string) (pkgs []*load.Package) {
func readpkglist(s *modload.State, shlibpath string) (pkgs []*load.Package) {
var stk load.ImportStack
if cfg.BuildToolchainName == "gccgo" {
f, err := elf.Open(shlibpath)
@@ -415,7 +415,7 @@ func readpkglist(loaderstate *modload.State, shlibpath string) (pkgs []*load.Pac
for _, line := range bytes.Split(data, []byte{'\n'}) {
if path, found := bytes.CutPrefix(line, pkgpath); found {
path = bytes.TrimSuffix(path, []byte{';'})
pkgs = append(pkgs, load.LoadPackageWithFlags(loaderstate, string(path), base.Cwd(), &stk, nil, 0))
pkgs = append(pkgs, load.LoadPackageWithFlags(s, string(path), base.Cwd(), &stk, nil, 0))
}
}
} else {
@@ -426,7 +426,7 @@ func readpkglist(loaderstate *modload.State, shlibpath string) (pkgs []*load.Pac
scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
for scanner.Scan() {
t := scanner.Text()
pkgs = append(pkgs, load.LoadPackageWithFlags(loaderstate, t, base.Cwd(), &stk, nil, 0))
pkgs = append(pkgs, load.LoadPackageWithFlags(s, t, base.Cwd(), &stk, nil, 0))
}
}
return
@@ -446,9 +446,9 @@ func (b *Builder) cacheAction(mode string, p *load.Package, f func() *Action) *A
}
// AutoAction returns the "right" action for go build or go install of p.
func (b *Builder) AutoAction(loaderstate *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
func (b *Builder) AutoAction(s *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
if p.Name == "main" {
return b.LinkAction(loaderstate, mode, depMode, p)
return b.LinkAction(s, mode, depMode, p)
}
return b.CompileAction(mode, depMode, p)
}
@@ -869,13 +869,13 @@ func (b *Builder) cgoAction(p *load.Package, objdir string, deps []*Action, hasC
// It depends on the action for compiling p.
// If the caller may be causing p to be installed, it is up to the caller
// to make sure that the install depends on (runs after) vet.
func (b *Builder) VetAction(loaderstate *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
a := b.vetAction(loaderstate, mode, depMode, p)
func (b *Builder) VetAction(s *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
a := b.vetAction(s, mode, depMode, p)
a.VetxOnly = false
return a
}
func (b *Builder) vetAction(loaderstate *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
func (b *Builder) vetAction(s *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
// Construct vet action.
a := b.cacheAction("vet", p, func() *Action {
a1 := b.CompileAction(mode|ModeVetOnly, depMode, p)
@@ -891,7 +891,7 @@ func (b *Builder) vetAction(loaderstate *modload.State, mode, depMode BuildMode,
deps = []*Action{a1}
}
for _, p1 := range p.Internal.Imports {
deps = append(deps, b.vetAction(loaderstate, mode, depMode, p1))
deps = append(deps, b.vetAction(s, mode, depMode, p1))
}
a := &Action{
@@ -916,7 +916,7 @@ func (b *Builder) vetAction(loaderstate *modload.State, mode, depMode BuildMode,
// LinkAction returns the action for linking p into an executable
// and possibly installing the result (according to mode).
// depMode is the action (build or install) to use when compiling dependencies.
func (b *Builder) LinkAction(loaderstate *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
func (b *Builder) LinkAction(s *modload.State, mode, depMode BuildMode, p *load.Package) *Action {
// Construct link action.
a := b.cacheAction("link", p, func() *Action {
a := &Action{
@@ -951,7 +951,7 @@ func (b *Builder) LinkAction(loaderstate *modload.State, mode, depMode BuildMode
}
a.Target = a.Objdir + filepath.Join("exe", name) + cfg.ExeSuffix
a.built = a.Target
b.addTransitiveLinkDeps(loaderstate, a, a1, "")
b.addTransitiveLinkDeps(s, a, a1, "")
// Sequence the build of the main package (a1) strictly after the build
// of all other dependencies that go into the link. It is likely to be after
@@ -1037,7 +1037,7 @@ func (b *Builder) installAction(a1 *Action, mode BuildMode) *Action {
// makes sure those are present in a.Deps.
// If shlib is non-empty, then a corresponds to the build and installation of shlib,
// so any rebuild of shlib should not be added as a dependency.
func (b *Builder) addTransitiveLinkDeps(loaderstate *modload.State, a, a1 *Action, shlib string) {
func (b *Builder) addTransitiveLinkDeps(s *modload.State, a, a1 *Action, shlib string) {
// Expand Deps to include all built packages, for the linker.
// Use breadth-first search to find rebuilt-for-test packages
// before the standard ones.
@@ -1078,7 +1078,7 @@ func (b *Builder) addTransitiveLinkDeps(loaderstate *modload.State, a, a1 *Actio
// we'll end up building an overall library or executable that depends at runtime
// on other libraries that are out-of-date, which is clearly not good either.
// We call it ModeBuggyInstall to make clear that this is not right.
a.Deps = append(a.Deps, b.linkSharedAction(loaderstate, ModeBuggyInstall, ModeBuggyInstall, p1.Shlib, nil))
a.Deps = append(a.Deps, b.linkSharedAction(s, ModeBuggyInstall, ModeBuggyInstall, p1.Shlib, nil))
}
}
}
@@ -1114,26 +1114,26 @@ func (b *Builder) addInstallHeaderAction(a *Action) {
// buildmodeShared takes the "go build" action a1 into the building of a shared library of a1.Deps.
// That is, the input a1 represents "go build pkgs" and the result represents "go build -buildmode=shared pkgs".
func (b *Builder) buildmodeShared(loaderstate *modload.State, mode, depMode BuildMode, args []string, pkgs []*load.Package, a1 *Action) *Action {
func (b *Builder) buildmodeShared(s *modload.State, mode, depMode BuildMode, args []string, pkgs []*load.Package, a1 *Action) *Action {
name, err := libname(args, pkgs)
if err != nil {
base.Fatalf("%v", err)
}
return b.linkSharedAction(loaderstate, mode, depMode, name, a1)
return b.linkSharedAction(s, mode, depMode, name, a1)
}
// linkSharedAction takes a grouping action a1 corresponding to a list of built packages
// and returns an action that links them together into a shared library with the name shlib.
// If a1 is nil, shlib should be an absolute path to an existing shared library,
// and then linkSharedAction reads that library to find out the package list.
func (b *Builder) linkSharedAction(loaderstate *modload.State, mode, depMode BuildMode, shlib string, a1 *Action) *Action {
func (b *Builder) linkSharedAction(s *modload.State, mode, depMode BuildMode, shlib string, a1 *Action) *Action {
fullShlib := shlib
shlib = filepath.Base(shlib)
a := b.cacheAction("build-shlib "+shlib, nil, func() *Action {
if a1 == nil {
// TODO(rsc): Need to find some other place to store config,
// not in pkg directory. See golang.org/issue/22196.
pkgs := readpkglist(loaderstate, fullShlib)
pkgs := readpkglist(s, fullShlib)
a1 = &Action{
Mode: "shlib packages",
}
@@ -1147,8 +1147,8 @@ func (b *Builder) linkSharedAction(loaderstate *modload.State, mode, depMode Bui
// we let them use the flags specified for the command-line arguments.
p := &load.Package{}
p.Internal.CmdlinePkg = true
p.Internal.Ldflags = load.BuildLdflags.For(p)
p.Internal.Gccgoflags = load.BuildGccgoflags.For(p)
p.Internal.Ldflags = load.BuildLdflags.For(s, p)
p.Internal.Gccgoflags = load.BuildGccgoflags.For(s, p)
// Add implicit dependencies to pkgs list.
// Currently buildmode=shared forces external linking mode, and
@@ -1176,7 +1176,7 @@ func (b *Builder) linkSharedAction(loaderstate *modload.State, mode, depMode Bui
}
}
var stk load.ImportStack
p := load.LoadPackageWithFlags(loaderstate, pkg, base.Cwd(), &stk, nil, 0)
p := load.LoadPackageWithFlags(s, pkg, base.Cwd(), &stk, nil, 0)
if p.Error != nil {
base.Fatalf("load %s: %v", pkg, p.Error)
}
@@ -1196,7 +1196,7 @@ func (b *Builder) linkSharedAction(loaderstate *modload.State, mode, depMode Bui
// The linker step still needs all the usual linker deps.
// (For example, the linker always opens runtime.a.)
ldDeps, err := load.LinkerDeps(nil)
ldDeps, err := load.LinkerDeps(s, nil)
if err != nil {
base.Error(err)
}
@@ -1204,7 +1204,7 @@ func (b *Builder) linkSharedAction(loaderstate *modload.State, mode, depMode Bui
add(a, dep, true)
}
}
b.addTransitiveLinkDeps(loaderstate, a, a1, shlib)
b.addTransitiveLinkDeps(s, a, a1, shlib)
return a
})