"testing"
)
-func TestInternalLinkerCgoFile(t *testing.T) {
- if !canInternalLink() {
- t.Skip("skipping; internal linking is not supported")
- }
- testGoFile(t, true, false)
-}
-
func canInternalLink() bool {
switch runtime.GOOS {
case "dragonfly":
return true
}
-func TestExternalLinkerCgoFile(t *testing.T) {
- testGoFile(t, true, true)
+func TestInternalLinkerCgoExec(t *testing.T) {
+ if !canInternalLink() {
+ t.Skip("skipping; internal linking is not supported")
+ }
+ testGoExec(t, true, false)
+}
+
+func TestExternalLinkerCgoExec(t *testing.T) {
+ testGoExec(t, true, true)
}
return m.Run()
}
-func TestNonGoFiles(t *testing.T) {
+func TestNonGoExecs(t *testing.T) {
testfiles := []string{
"elf/testdata/gcc-386-freebsd-exec",
"elf/testdata/gcc-amd64-linux-exec",
}
}
-func testGoFile(t *testing.T, iscgo, isexternallinker bool) {
- tmpdir, err := ioutil.TempDir("", "TestGoFile")
+func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
+ tmpdir, err := ioutil.TempDir("", "TestGoExec")
if err != nil {
t.Fatal(err)
}
if err != nil {
t.Fatal(err)
}
- err = template.Must(template.New("main").Parse(testprog)).Execute(file, iscgo)
+ err = template.Must(template.New("main").Parse(testexec)).Execute(file, iscgo)
+ if e := file.Close(); err == nil {
+ err = e
+ }
if err != nil {
- file.Close()
t.Fatal(err)
}
- file.Close()
exe := filepath.Join(tmpdir, "a.exe")
args := []string{"build", "-o", exe}
}
}
-func TestGoFile(t *testing.T) {
- testGoFile(t, false, false)
+func TestGoExec(t *testing.T) {
+ testGoExec(t, false, false)
}
-const testprog = `
+func testGoLib(t *testing.T) {
+ tmpdir, err := ioutil.TempDir("", "TestGoLib")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ gopath := filepath.Join(tmpdir, "gopath")
+ libpath := filepath.Join(gopath, "src", "mylib")
+
+ err = os.MkdirAll(libpath, 0777)
+ if err != nil {
+ t.Fatal(err)
+ }
+ src := filepath.Join(libpath, "a.go")
+ file, err := os.Create(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, nil)
+ if e := file.Close(); err == nil {
+ err = e
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ args := []string{"install", "mylib"}
+ cmd := exec.Command(testenv.GoToolPath(t), args...)
+ cmd.Env = append(os.Environ(), "GOPATH="+gopath)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("building test lib failed: %s %s", err, out)
+ }
+ pat := filepath.Join(gopath, "pkg", "*", "mylib.a")
+ ms, err := filepath.Glob(pat)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(ms) == 0 {
+ t.Fatalf("cannot found paths for pattern %s", pat)
+ }
+ mylib := ms[0]
+
+ out, err = exec.Command(testnmpath, mylib).CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm: %v\n%s", err, string(out))
+ }
+ type symType struct {
+ Type string
+ Name string
+ Found bool
+ }
+ var syms = []symType{
+ {"B", "%22%22.Testdata", false},
+ {"T", "%22%22.Testfunc", false},
+ }
+ scanner := bufio.NewScanner(bytes.NewBuffer(out))
+ for scanner.Scan() {
+ f := strings.Fields(scanner.Text())
+ if len(f) < 3 {
+ continue
+ }
+ typ := f[1]
+ name := f[2]
+ for i := range syms {
+ sym := &syms[i]
+ if sym.Type == typ && sym.Name == name {
+ if sym.Found {
+ t.Fatalf("duplicate symbol %s %s", sym.Type, sym.Name)
+ }
+ sym.Found = true
+ }
+ }
+ }
+ err = scanner.Err()
+ if err != nil {
+ t.Fatalf("error reading nm output: %v", err)
+ }
+ for _, sym := range syms {
+ if !sym.Found {
+ t.Errorf("cannot found symbol %s %s", sym.Type, sym.Name)
+ }
+ }
+}
+
+func TestGoLib(t *testing.T) {
+ testGoLib(t)
+}
+
+const testexec = `
package main
import "fmt"
fmt.Printf("testdata=%p\n", &testdata)
}
`
+
+const testlib = `
+package mylib
+
+var Testdata uint32
+
+func Testfunc() {}
+`