"os/exec"
"path/filepath"
"runtime"
+ "sync"
"testing"
"unicode/utf8"
)
-var (
- buildDir string
- go1obj string
- go2obj string
- goarchive string
- cgoarchive string
-)
+var buildDir string
func TestMain(m *testing.M) {
if !testenv.HasGoBuild() {
return
}
- if err := buildGoobj(); err != nil {
- fmt.Println(err)
- os.RemoveAll(buildDir)
- os.Exit(1)
- }
-
exit := m.Run()
- os.RemoveAll(buildDir)
+ if buildDir != "" {
+ os.RemoveAll(buildDir)
+ }
os.Exit(exit)
}
return nil
}
-func buildGoobj() error {
- var err error
+var (
+ buildOnce sync.Once
+ builtGoobjs goobjPaths
+ buildErr error
+)
- buildDir, err = ioutil.TempDir("", "TestGoobj")
- if err != nil {
- return err
- }
+type goobjPaths struct {
+ go1obj string
+ go2obj string
+ goarchive string
+ cgoarchive string
+}
- go1obj = filepath.Join(buildDir, "go1.o")
- go2obj = filepath.Join(buildDir, "go2.o")
- goarchive = filepath.Join(buildDir, "go.a")
+func buildGoobj(t *testing.T) goobjPaths {
+ buildOnce.Do(func() {
+ buildErr = func() (err error) {
+ buildDir, err = ioutil.TempDir("", "TestGoobj")
+ if err != nil {
+ return err
+ }
- gotool, err := testenv.GoTool()
- if err != nil {
- return err
- }
+ go1obj := filepath.Join(buildDir, "go1.o")
+ go2obj := filepath.Join(buildDir, "go2.o")
+ goarchive := filepath.Join(buildDir, "go.a")
+ cgoarchive := ""
- go1src := filepath.Join("testdata", "go1.go")
- go2src := filepath.Join("testdata", "go2.go")
+ gotool, err := testenv.GoTool()
+ if err != nil {
+ return err
+ }
- out, err := exec.Command(gotool, "tool", "compile", "-p=p", "-o", go1obj, go1src).CombinedOutput()
- if err != nil {
- return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out)
- }
- out, err = exec.Command(gotool, "tool", "compile", "-p=p", "-o", go2obj, go2src).CombinedOutput()
- if err != nil {
- return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out)
- }
- out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
- if err != nil {
- return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out)
- }
+ go1src := filepath.Join("testdata", "go1.go")
+ go2src := filepath.Join("testdata", "go2.go")
- if testenv.HasCGO() {
- gopath := filepath.Join(buildDir, "gopath")
- err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo"))
- if err == nil {
- err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666)
- }
- if err != nil {
- return err
- }
- cmd := exec.Command(gotool, "install", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
- cmd.Dir = filepath.Join(gopath, "src", "mycgo")
- cmd.Env = append(os.Environ(), "GOPATH="+gopath)
- out, err = cmd.CombinedOutput()
- if err != nil {
- return fmt.Errorf("go install mycgo: %v\n%s", err, out)
- }
- pat := filepath.Join(gopath, "pkg", "*", "mycgo.a")
- ms, err := filepath.Glob(pat)
- if err != nil {
- return err
- }
- if len(ms) == 0 {
- return fmt.Errorf("cannot found paths for pattern %s", pat)
- }
- cgoarchive = ms[0]
- }
+ out, err := exec.Command(gotool, "tool", "compile", "-p=p", "-o", go1obj, go1src).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out)
+ }
+ out, err = exec.Command(gotool, "tool", "compile", "-p=p", "-o", go2obj, go2src).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out)
+ }
+ out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out)
+ }
- return nil
+ if testenv.HasCGO() {
+ cgoarchive = filepath.Join(buildDir, "mycgo.a")
+ gopath := filepath.Join(buildDir, "gopath")
+ err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo"))
+ if err == nil {
+ err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666)
+ }
+ if err != nil {
+ return err
+ }
+ cmd := exec.Command(gotool, "build", "-buildmode=archive", "-o", cgoarchive, "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
+ cmd.Dir = filepath.Join(gopath, "src", "mycgo")
+ cmd.Env = append(os.Environ(), "GOPATH="+gopath)
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("go install mycgo: %v\n%s", err, out)
+ }
+ }
+
+ builtGoobjs = goobjPaths{
+ go1obj: go1obj,
+ go2obj: go2obj,
+ goarchive: goarchive,
+ cgoarchive: cgoarchive,
+ }
+ return nil
+ }()
+ })
+
+ if buildErr != nil {
+ t.Helper()
+ t.Fatal(buildErr)
+ }
+ return builtGoobjs
}
func TestParseGoobj(t *testing.T) {
- path := go1obj
+ path := buildGoobj(t).go1obj
f, err := os.Open(path)
if err != nil {
}
func TestParseArchive(t *testing.T) {
- path := goarchive
+ path := buildGoobj(t).goarchive
f, err := os.Open(path)
if err != nil {
func TestParseCGOArchive(t *testing.T) {
testenv.MustHaveCGO(t)
- path := cgoarchive
+ path := buildGoobj(t).cgoarchive
f, err := os.Open(path)
if err != nil {