Commit 12b05bf8 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by Ian Lance Taylor

cmd/go: support -buildmode=shared with gccgo

Change-Id: Id93b8ab42fa311ce32209734ec9a0813f8736e25
Reviewed-on: https://go-review.googlesource.com/9914Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
parent f74ea6cd
......@@ -20,6 +20,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"testing"
"time"
......@@ -274,13 +275,17 @@ func dynStrings(path string, flag elf.DynTag) []string {
return dynstrings
}
func AssertIsLinkedTo(t *testing.T, path, lib string) {
func AssertIsLinkedToRegexp(t *testing.T, path string, re *regexp.Regexp) {
for _, dynstring := range dynStrings(path, elf.DT_NEEDED) {
if dynstring == lib {
if re.MatchString(dynstring) {
return
}
}
t.Errorf("%s is not linked to %s", path, lib)
t.Errorf("%s is not linked to anything matching %v", path, re)
}
func AssertIsLinkedTo(t *testing.T, path, lib string) {
AssertIsLinkedToRegexp(t, path, regexp.MustCompile(regexp.QuoteMeta(lib)))
}
func AssertHasRPath(t *testing.T, path, dir string) {
......@@ -306,7 +311,7 @@ func TestTrivialExecutable(t *testing.T) {
// Build a GOPATH package into a shared library that links against the goroot runtime
// and an executable that links against both.
func TestGOPathShlib(t *testing.T) {
func TestGopathShlib(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep")
AssertIsLinkedTo(t, filepath.Join(gopathInstallDir, "libdep.so"), soname)
goCmd(t, "install", "-linkshared", "exe")
......@@ -437,13 +442,85 @@ func TestNotes(t *testing.T) {
// Build a GOPATH package (dep) into a shared library that links against the goroot
// runtime, another package (dep2) that links against the first, and and an
// executable that links against dep2.
func TestTwoGOPathShlibs(t *testing.T) {
func TestTwoGopathShlibs(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep")
goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep2")
goCmd(t, "install", "-linkshared", "exe2")
run(t, "executable linked to GOPATH library", "./bin/exe2")
}
// Build a GOPATH package into a shared library with gccgo and an executable that
// links against it.
func TestGoPathShlibGccgo(t *testing.T) {
gccgoName := os.Getenv("GCCGO")
if gccgoName == "" {
gccgoName = "gccgo"
}
_, err := exec.LookPath(gccgoName)
if err != nil {
t.Skip("gccgo not found")
}
libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
gccgoContext := build.Default
gccgoContext.InstallSuffix = suffix + "_fPIC"
gccgoContext.Compiler = "gccgo"
gccgoContext.GOPATH = os.Getenv("GOPATH")
depP, err := gccgoContext.Import("dep", ".", build.ImportComment)
if err != nil {
t.Fatalf("import failed: %v", err)
}
gccgoInstallDir := filepath.Join(depP.PkgTargetRoot, "shlibs")
goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "dep")
AssertIsLinkedToRegexp(t, filepath.Join(gccgoInstallDir, "libdep.so"), libgoRE)
goCmd(t, "install", "-compiler=gccgo", "-linkshared", "exe")
AssertIsLinkedToRegexp(t, "./bin/exe", libgoRE)
AssertIsLinkedTo(t, "./bin/exe", "libdep.so")
AssertHasRPath(t, "./bin/exe", gccgoInstallDir)
// And check it runs.
run(t, "gccgo-built", "./bin/exe")
}
// The gccgo version of TestTwoGopathShlibs: build a GOPATH package into a shared
// library with gccgo, another GOPATH package that depends on the first and an
// executable that links the second library.
func TestTwoGopathShlibsGccgo(t *testing.T) {
gccgoName := os.Getenv("GCCGO")
if gccgoName == "" {
gccgoName = "gccgo"
}
_, err := exec.LookPath(gccgoName)
if err != nil {
t.Skip("gccgo not found")
}
libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
gccgoContext := build.Default
gccgoContext.InstallSuffix = suffix + "_fPIC"
gccgoContext.Compiler = "gccgo"
gccgoContext.GOPATH = os.Getenv("GOPATH")
depP, err := gccgoContext.Import("dep", ".", build.ImportComment)
if err != nil {
t.Fatalf("import failed: %v", err)
}
gccgoInstallDir := filepath.Join(depP.PkgTargetRoot, "shlibs")
goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "dep")
goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "dep2")
goCmd(t, "install", "-compiler=gccgo", "-linkshared", "exe2")
AssertIsLinkedToRegexp(t, filepath.Join(gccgoInstallDir, "libdep.so"), libgoRE)
AssertIsLinkedToRegexp(t, filepath.Join(gccgoInstallDir, "libdep2.so"), libgoRE)
AssertIsLinkedTo(t, filepath.Join(gccgoInstallDir, "libdep2.so"), "libdep.so")
AssertIsLinkedToRegexp(t, "./bin/exe2", libgoRE)
AssertIsLinkedTo(t, "./bin/exe2", "libdep2")
AssertIsLinkedTo(t, "./bin/exe2", "libdep.so")
// And check it runs.
run(t, "gccgo-built", "./bin/exe2")
}
// Testing rebuilding of shared libraries when they are stale is a bit more
// complicated that it seems like it should be. First, we make everything "old": but
// only a few seconds old, or it might be older than 6g (or the runtime source) and
......
This diff is collapsed.
......@@ -530,7 +530,12 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
shlib, err := ioutil.ReadFile(shlibnamefile)
if err == nil {
libname := strings.TrimSpace(string(shlib))
p.Shlib = filepath.Join(p.build.PkgTargetRoot, libname)
if buildContext.Compiler == "gccgo" {
p.Shlib = filepath.Join(p.build.PkgTargetRoot, "shlibs", libname)
} else {
p.Shlib = filepath.Join(p.build.PkgTargetRoot, libname)
}
} else if !os.IsNotExist(err) {
fatalf("unexpected error reading %s: %v", shlibnamefile, err)
}
......
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