github.com/jwijenbergh/purego@v0.0.0-20240126093400-70ff3a61df13/dlfcn_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2023 The Ebitengine Authors 3 4 //go:build darwin || freebsd || linux 5 6 package purego_test 7 8 import ( 9 "errors" 10 "fmt" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "runtime" 15 "strings" 16 "testing" 17 18 "github.com/jwijenbergh/purego" 19 ) 20 21 func TestSimpleDlsym(t *testing.T) { 22 if _, err := purego.Dlsym(purego.RTLD_DEFAULT, "dlsym"); err != nil { 23 t.Errorf("Dlsym with RTLD_DEFAULT failed: %v", err) 24 } 25 } 26 27 func TestNestedDlopenCall(t *testing.T) { 28 libFileName := filepath.Join(t.TempDir(), "libdlnested.so") 29 t.Logf("Build %v", libFileName) 30 31 if err := buildSharedLib("CXX", libFileName, filepath.Join("libdlnested", "nested.cpp")); err != nil { 32 t.Fatal(err) 33 } 34 defer os.Remove(libFileName) 35 36 lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL) 37 if err != nil { 38 t.Fatalf("Dlopen(%q) failed: %v", libFileName, err) 39 } 40 41 purego.Dlclose(lib) 42 } 43 44 func buildSharedLib(compilerEnv, libFile string, sources ...string) error { 45 out, err := exec.Command("go", "env", compilerEnv).Output() 46 if err != nil { 47 return fmt.Errorf("go env %s error: %w", compilerEnv, err) 48 } 49 50 compiler := strings.TrimSpace(string(out)) 51 if compiler == "" { 52 return errors.New("compiler not found") 53 } 54 55 var args []string 56 if runtime.GOOS == "freebsd" { 57 args = []string{"-shared", "-Wall", "-Werror", "-fPIC", "-o", libFile} 58 } else { 59 args = []string{"-shared", "-Wall", "-Werror", "-o", libFile} 60 } 61 62 // macOS arm64 can run amd64 tests through Rossetta. 63 // Build the shared library based on the GOARCH and not 64 // the default behavior of the compiler. 65 if runtime.GOOS == "darwin" { 66 var arch string 67 switch runtime.GOARCH { 68 case "arm64": 69 arch = "arm64" 70 case "amd64": 71 arch = "x86_64" 72 default: 73 return fmt.Errorf("unknown macOS architecture %s", runtime.GOARCH) 74 } 75 args = append(args, "-arch", arch) 76 } 77 cmd := exec.Command(compiler, append(args, sources...)...) 78 if out, err := cmd.CombinedOutput(); err != nil { 79 return fmt.Errorf("compile lib: %w\n%q\n%s", err, cmd, string(out)) 80 } 81 82 return nil 83 }