lab.nexedi.com will be down from Thursday, 20 March 2025, 07:30:00 UTC for a duration of approximately 2 hours

Commit 4e8be995 authored by Russ Cox's avatar Russ Cox

cmd/go: clean up compile vs link vs shared library actions

Everything got a bit tangled together in b.action1.
Try to tease things apart again.

In general this is a refactoring of the existing code, with limited
changes to the effect of the code.

The main additional change is to complete a.Deps for link actions.
That list now directly contains all the inputs the linker will attempt
to read, eliminating the need for a transitive traversal of the entire
action graph to find those. The comepleteness of a.Deps will be
important when we eventually use it to decide whether an cached
action output can be reused.

all.bash passes, but it's possible I've broken some subtety of
buildmode=shared again. Certainly that code took the longest
to get working.

Change-Id: I34e849eda446dca45a9cfce02b07bec6edb6d0d4
Reviewed-on: https://go-review.googlesource.com/69831
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 2595fe7f
...@@ -134,8 +134,10 @@ func cmdToRun(name string) []string { ...@@ -134,8 +134,10 @@ func cmdToRun(name string) []string {
} }
func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) { func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
t.Helper()
cmd := exec.Command(buildcmd[0], buildcmd[1:]...) cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
......
...@@ -465,13 +465,13 @@ func TestGopathShlib(t *testing.T) { ...@@ -465,13 +465,13 @@ func TestGopathShlib(t *testing.T) {
// that is not mapped into memory. // that is not mapped into memory.
func testPkgListNote(t *testing.T, f *elf.File, note *note) { func testPkgListNote(t *testing.T, f *elf.File, note *note) {
if note.section.Flags != 0 { if note.section.Flags != 0 {
t.Errorf("package list section has flags %v", note.section.Flags) t.Errorf("package list section has flags %v, want 0", note.section.Flags)
} }
if isOffsetLoaded(f, note.section.Offset) { if isOffsetLoaded(f, note.section.Offset) {
t.Errorf("package list section contained in PT_LOAD segment") t.Errorf("package list section contained in PT_LOAD segment")
} }
if note.desc != "depBase\n" { if note.desc != "depBase\n" {
t.Errorf("incorrect package list %q", note.desc) t.Errorf("incorrect package list %q, want %q", note.desc, "depBase\n")
} }
} }
...@@ -480,7 +480,7 @@ func testPkgListNote(t *testing.T, f *elf.File, note *note) { ...@@ -480,7 +480,7 @@ func testPkgListNote(t *testing.T, f *elf.File, note *note) {
// bytes into it. // bytes into it.
func testABIHashNote(t *testing.T, f *elf.File, note *note) { func testABIHashNote(t *testing.T, f *elf.File, note *note) {
if note.section.Flags != elf.SHF_ALLOC { if note.section.Flags != elf.SHF_ALLOC {
t.Errorf("abi hash section has flags %v", note.section.Flags) t.Errorf("abi hash section has flags %v, want SHF_ALLOC", note.section.Flags)
} }
if !isOffsetLoaded(f, note.section.Offset) { if !isOffsetLoaded(f, note.section.Offset) {
t.Errorf("abihash section not contained in PT_LOAD segment") t.Errorf("abihash section not contained in PT_LOAD segment")
...@@ -501,13 +501,13 @@ func testABIHashNote(t *testing.T, f *elf.File, note *note) { ...@@ -501,13 +501,13 @@ func testABIHashNote(t *testing.T, f *elf.File, note *note) {
return return
} }
if elf.ST_BIND(hashbytes.Info) != elf.STB_LOCAL { if elf.ST_BIND(hashbytes.Info) != elf.STB_LOCAL {
t.Errorf("%s has incorrect binding %v", hashbytes.Name, elf.ST_BIND(hashbytes.Info)) t.Errorf("%s has incorrect binding %v, want STB_LOCAL", hashbytes.Name, elf.ST_BIND(hashbytes.Info))
} }
if f.Sections[hashbytes.Section] != note.section { if f.Sections[hashbytes.Section] != note.section {
t.Errorf("%s has incorrect section %v", hashbytes.Name, f.Sections[hashbytes.Section].Name) t.Errorf("%s has incorrect section %v, want %s", hashbytes.Name, f.Sections[hashbytes.Section].Name, note.section)
} }
if hashbytes.Value-note.section.Addr != 16 { if hashbytes.Value-note.section.Addr != 16 {
t.Errorf("%s has incorrect offset into section %d", hashbytes.Name, hashbytes.Value-note.section.Addr) t.Errorf("%s has incorrect offset into section %d, want 16", hashbytes.Name, hashbytes.Value-note.section.Addr)
} }
} }
...@@ -515,14 +515,14 @@ func testABIHashNote(t *testing.T, f *elf.File, note *note) { ...@@ -515,14 +515,14 @@ func testABIHashNote(t *testing.T, f *elf.File, note *note) {
// was linked against in an unmapped section. // was linked against in an unmapped section.
func testDepsNote(t *testing.T, f *elf.File, note *note) { func testDepsNote(t *testing.T, f *elf.File, note *note) {
if note.section.Flags != 0 { if note.section.Flags != 0 {
t.Errorf("package list section has flags %v", note.section.Flags) t.Errorf("package list section has flags %v, want 0", note.section.Flags)
} }
if isOffsetLoaded(f, note.section.Offset) { if isOffsetLoaded(f, note.section.Offset) {
t.Errorf("package list section contained in PT_LOAD segment") t.Errorf("package list section contained in PT_LOAD segment")
} }
// libdepBase.so just links against the lib containing the runtime. // libdepBase.so just links against the lib containing the runtime.
if note.desc != soname { if note.desc != soname {
t.Errorf("incorrect dependency list %q", note.desc) t.Errorf("incorrect dependency list %q, want %q", note.desc, soname)
} }
} }
...@@ -560,7 +560,7 @@ func TestNotes(t *testing.T) { ...@@ -560,7 +560,7 @@ func TestNotes(t *testing.T) {
abiHashNoteFound = true abiHashNoteFound = true
case 3: // ELF_NOTE_GODEPS_TAG case 3: // ELF_NOTE_GODEPS_TAG
if depsNoteFound { if depsNoteFound {
t.Error("multiple abi hash notes") t.Error("multiple depedency list notes")
} }
testDepsNote(t, f, note) testDepsNote(t, f, note)
depsNoteFound = true depsNoteFound = true
......
...@@ -911,16 +911,16 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { ...@@ -911,16 +911,16 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
if cfg.BuildLinkshared { if cfg.BuildLinkshared {
shlibnamefile := p.Internal.Target[:len(p.Internal.Target)-2] + ".shlibname" shlibnamefile := p.Internal.Target[:len(p.Internal.Target)-2] + ".shlibname"
shlib, err := ioutil.ReadFile(shlibnamefile) shlib, err := ioutil.ReadFile(shlibnamefile)
if err != nil && !os.IsNotExist(err) {
base.Fatalf("reading shlibname: %v", err)
}
if err == nil { if err == nil {
libname := strings.TrimSpace(string(shlib)) libname := strings.TrimSpace(string(shlib))
if cfg.BuildContext.Compiler == "gccgo" { if cfg.BuildContext.Compiler == "gccgo" {
p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname) p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
} else { } else {
p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname) p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
} }
} else if !os.IsNotExist(err) {
base.Fatalf("unexpected error reading %s: %v", shlibnamefile, err)
} }
} }
} }
......
...@@ -110,7 +110,7 @@ func runRun(cmd *base.Command, args []string) { ...@@ -110,7 +110,7 @@ func runRun(cmd *base.Command, args []string) {
base.Fatalf("go run: no suitable source files%s", hint) base.Fatalf("go run: no suitable source files%s", hint)
} }
p.Internal.ExeName = src[:len(src)-len(".go")] // name temporary executable for first go file p.Internal.ExeName = src[:len(src)-len(".go")] // name temporary executable for first go file
a1 := b.Action(work.ModeBuild, work.ModeBuild, p) a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p)
a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}} a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
b.Do(a) b.Do(a)
} }
......
...@@ -524,7 +524,7 @@ func runTest(cmd *base.Command, args []string) { ...@@ -524,7 +524,7 @@ func runTest(cmd *base.Command, args []string) {
a := &work.Action{Mode: "go test -i"} a := &work.Action{Mode: "go test -i"}
for _, p := range load.PackagesForBuild(all) { for _, p := range load.PackagesForBuild(all) {
a.Deps = append(a.Deps, b.Action(work.ModeInstall, work.ModeInstall, p)) a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
} }
b.Do(a) b.Do(a)
if !testC || a.Failed { if !testC || a.Failed {
...@@ -651,7 +651,7 @@ var windowsBadWords = []string{ ...@@ -651,7 +651,7 @@ var windowsBadWords = []string{
func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) { func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
build := b.Action(work.ModeBuild, work.ModeBuild, p) build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}} run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}} print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
return build, run, print, nil return build, run, print, nil
...@@ -896,7 +896,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin ...@@ -896,7 +896,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
load.ComputeStale(pmain) load.ComputeStale(pmain)
a := b.Action(work.ModeBuild, work.ModeBuild, pmain) a := b.LinkAction(work.ModeBuild, work.ModeBuild, pmain)
a.Target = testDir + testBinary + cfg.ExeSuffix a.Target = testDir + testBinary + cfg.ExeSuffix
if cfg.Goos == "windows" { if cfg.Goos == "windows" {
// There are many reserved words on Windows that, // There are many reserved words on Windows that,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment