github.com/kidsbmilk/gofronted_all@v0.0.0-20220701224323-6479d5976c5d/libgo/misc/cgo/testso/so_test.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build cgo 6 // +build cgo 7 8 package so_test 9 10 import ( 11 "log" 12 "os" 13 "os/exec" 14 "path/filepath" 15 "runtime" 16 "strings" 17 "testing" 18 ) 19 20 func requireTestSOSupported(t *testing.T) { 21 t.Helper() 22 switch runtime.GOARCH { 23 case "arm64": 24 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { 25 t.Skip("No exec facility on iOS.") 26 } 27 case "ppc64": 28 if runtime.GOOS == "linux" { 29 t.Skip("External linking not implemented on linux/ppc64 (issue #8912).") 30 } 31 } 32 if runtime.GOOS == "android" { 33 t.Skip("No exec facility on Android.") 34 } 35 } 36 37 func TestSO(t *testing.T) { 38 requireTestSOSupported(t) 39 40 GOPATH, err := os.MkdirTemp("", "cgosotest") 41 if err != nil { 42 log.Fatal(err) 43 } 44 defer os.RemoveAll(GOPATH) 45 46 modRoot := filepath.Join(GOPATH, "src", "cgosotest") 47 if err := overlayDir(modRoot, "testdata"); err != nil { 48 log.Panic(err) 49 } 50 if err := os.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil { 51 log.Panic(err) 52 } 53 54 cmd := exec.Command("go", "env", "CC", "GOGCCFLAGS") 55 cmd.Dir = modRoot 56 cmd.Stderr = new(strings.Builder) 57 cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) 58 out, err := cmd.Output() 59 if err != nil { 60 t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) 61 } 62 lines := strings.Split(string(out), "\n") 63 if len(lines) != 3 || lines[2] != "" { 64 t.Fatalf("Unexpected output from %s:\n%s", strings.Join(cmd.Args, " "), lines) 65 } 66 67 cc := lines[0] 68 if cc == "" { 69 t.Fatal("CC environment variable (go env CC) cannot be empty") 70 } 71 gogccflags := strings.Split(lines[1], " ") 72 73 // build shared object 74 ext := "so" 75 args := append(gogccflags, "-shared") 76 switch runtime.GOOS { 77 case "darwin", "ios": 78 ext = "dylib" 79 args = append(args, "-undefined", "suppress", "-flat_namespace") 80 case "windows": 81 ext = "dll" 82 args = append(args, "-DEXPORT_DLL") 83 // At least in mingw-clang it is not permitted to just name a .dll 84 // on the command line. You must name the corresponding import 85 // library instead, even though the dll is used when the executable is run. 86 args = append(args, "-Wl,-out-implib,libcgosotest.a") 87 case "aix": 88 ext = "so.1" 89 } 90 sofname := "libcgosotest." + ext 91 args = append(args, "-o", sofname, "cgoso_c.c") 92 93 cmd = exec.Command(cc, args...) 94 cmd.Dir = modRoot 95 cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) 96 out, err = cmd.CombinedOutput() 97 if err != nil { 98 t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) 99 } 100 t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) 101 102 if runtime.GOOS == "aix" { 103 // Shared object must be wrapped by an archive 104 cmd = exec.Command("ar", "-X64", "-q", "libcgosotest.a", "libcgosotest.so.1") 105 cmd.Dir = modRoot 106 out, err = cmd.CombinedOutput() 107 if err != nil { 108 t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) 109 } 110 } 111 112 cmd = exec.Command("go", "build", "-o", "main.exe", "main.go") 113 cmd.Dir = modRoot 114 cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) 115 out, err = cmd.CombinedOutput() 116 if err != nil { 117 t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) 118 } 119 t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) 120 121 cmd = exec.Command("./main.exe") 122 cmd.Dir = modRoot 123 cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) 124 if runtime.GOOS != "windows" { 125 s := "LD_LIBRARY_PATH" 126 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { 127 s = "DYLD_LIBRARY_PATH" 128 } 129 cmd.Env = append(os.Environ(), s+"=.") 130 131 // On FreeBSD 64-bit architectures, the 32-bit linker looks for 132 // different environment variables. 133 if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" { 134 cmd.Env = append(cmd.Env, "LD_32_LIBRARY_PATH=.") 135 } 136 } 137 out, err = cmd.CombinedOutput() 138 if err != nil { 139 t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) 140 } 141 t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) 142 }