Source file
test/linkobj.go
Documentation: test
1
2
3
4
5
6
7
8
9
10 package main
11
12 import (
13 "fmt"
14 "io/ioutil"
15 "log"
16 "os"
17 "os/exec"
18 "strings"
19 )
20
21 var pwd, tmpdir string
22
23 func main() {
24 dir, err := ioutil.TempDir("", "go-test-linkobj-")
25 if err != nil {
26 log.Fatal(err)
27 }
28 pwd, err = os.Getwd()
29 if err != nil {
30 log.Fatal(err)
31 }
32 if err := os.Chdir(dir); err != nil {
33 os.RemoveAll(dir)
34 log.Fatal(err)
35 }
36 tmpdir = dir
37
38 writeFile("p1.go", `
39 package p1
40
41 func F() {
42 println("hello from p1")
43 }
44 `)
45 writeFile("p2.go", `
46 package p2
47
48 import "./p1"
49
50 func F() {
51 p1.F()
52 println("hello from p2")
53 }
54
55 func main() {}
56 `)
57 writeFile("p3.go", `
58 package main
59
60 import "./p2"
61
62 func main() {
63 p2.F()
64 println("hello from main")
65 }
66 `)
67
68
69 for round := 0; round < 2; round++ {
70 pkg := "-pack=" + fmt.Sprint(round)
71
72
73 o := "o"
74 if round == 1 {
75 o = "a"
76 }
77
78
79 run("go", "tool", "compile", pkg, "-D", ".", "-I", ".", "-l", "-o", "p1."+o, "-linkobj", "p1.lo", "p1.go")
80 run("go", "tool", "compile", pkg, "-D", ".", "-I", ".", "-l", "-o", "p2."+o, "-linkobj", "p2.lo", "p2.go")
81 run("go", "tool", "compile", pkg, "-D", ".", "-I", ".", "-l", "-o", "p3."+o, "-linkobj", "p3.lo", "p3.go")
82
83 cp("p1."+o, "p1.oo")
84 cp("p2."+o, "p2.oo")
85 cp("p3."+o, "p3.oo")
86 cp("p1.lo", "p1."+o)
87 cp("p2.lo", "p2."+o)
88 cp("p3.lo", "p3."+o)
89 out := runFail("go", "tool", "link", "p2."+o)
90 if !strings.Contains(out, "not package main") {
91 fatalf("link p2.o failed but not for package main:\n%s", out)
92 }
93
94 run("go", "tool", "link", "-L", ".", "-o", "a.out.exe", "p3."+o)
95 out = run("./a.out.exe")
96 if !strings.Contains(out, "hello from p1\nhello from p2\nhello from main\n") {
97 fatalf("running main, incorrect output:\n%s", out)
98 }
99
100
101 os.Remove("p1.o")
102 os.Remove("a.out.exe")
103 }
104
105 cleanup()
106 }
107
108 func run(args ...string) string {
109 out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
110 if err != nil {
111 fatalf("run %v: %s\n%s", args, err, out)
112 }
113 return string(out)
114 }
115
116 func runFail(args ...string) string {
117 out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
118 if err == nil {
119 fatalf("runFail %v: unexpected success!\n%s", args, err, out)
120 }
121 return string(out)
122 }
123
124 func cp(src, dst string) {
125 data, err := ioutil.ReadFile(src)
126 if err != nil {
127 fatalf("%v", err)
128 }
129 err = ioutil.WriteFile(dst, data, 0666)
130 if err != nil {
131 fatalf("%v", err)
132 }
133 }
134
135 func writeFile(name, data string) {
136 err := ioutil.WriteFile(name, []byte(data), 0666)
137 if err != nil {
138 fatalf("%v", err)
139 }
140 }
141
142 func cleanup() {
143 const debug = false
144 if debug {
145 println("TMPDIR:", tmpdir)
146 return
147 }
148 os.Chdir(pwd)
149 os.RemoveAll(tmpdir)
150 }
151
152 func fatalf(format string, args ...interface{}) {
153 cleanup()
154 log.Fatalf(format, args...)
155 }
156
View as plain text