SDL3 loader fix for MacOS
This commit is contained in:
@@ -5,11 +5,11 @@ Collapsed=0
|
|||||||
|
|
||||||
[Window][Settings & Info]
|
[Window][Settings & Info]
|
||||||
Pos=0,0
|
Pos=0,0
|
||||||
Size=700,1080
|
Size=700,720
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Stats]
|
[Window][Stats]
|
||||||
Pos=1460,0
|
Pos=820,0
|
||||||
Size=460,510
|
Size=460,510
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
|
|||||||
+71
-2
@@ -1,7 +1,9 @@
|
|||||||
package sdl
|
package sdl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@@ -70,16 +72,82 @@ var (
|
|||||||
sdlFree func(memory uintptr)
|
sdlFree func(memory uintptr)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func libraryCandidates() ([]string, error) {
|
||||||
|
return libraryCandidatesForOS(runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func libraryCandidatesForOS(goos string) ([]string, error) {
|
||||||
|
switch goos {
|
||||||
|
case "linux":
|
||||||
|
return []string{
|
||||||
|
"libSDL3.so.0",
|
||||||
|
"libSDL3.so",
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
case "darwin":
|
||||||
|
return []string{
|
||||||
|
"libSDL3.0.dylib",
|
||||||
|
"libSDL3.dylib",
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
case "windows":
|
||||||
|
return []string{
|
||||||
|
"SDL3.dll",
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("SDL3: unsupported operating system %q", goos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func openLibrary() (uintptr, error) {
|
||||||
|
var candidates []string
|
||||||
|
|
||||||
|
if explicit := os.Getenv("SDL3_LIBRARY"); explicit != "" {
|
||||||
|
candidates = append(candidates, explicit)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults, err := libraryCandidates()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
candidates = append(candidates, defaults...)
|
||||||
|
|
||||||
|
var attempts []error
|
||||||
|
|
||||||
|
for _, name := range candidates {
|
||||||
|
handle, err := purego.Dlopen(
|
||||||
|
name,
|
||||||
|
purego.RTLD_NOW|purego.RTLD_GLOBAL,
|
||||||
|
)
|
||||||
|
if err == nil && handle != 0 {
|
||||||
|
return handle, nil
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
err = errors.New("loader returned a zero handle")
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts = append(attempts, fmt.Errorf("%s: %w", name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf(
|
||||||
|
"SDL3: unable to load shared library: %w",
|
||||||
|
errors.Join(attempts...),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var loaded = false
|
var loaded = false
|
||||||
|
|
||||||
func Load() error {
|
func Load() error {
|
||||||
if loaded {
|
if loaded {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
h, err := purego.Dlopen("libSDL3.so.0", purego.RTLD_NOW|purego.RTLD_GLOBAL)
|
|
||||||
|
h, err := openLibrary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("win: load SDL3: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
purego.RegisterLibFunc(&sdlInit, h, "SDL_Init")
|
purego.RegisterLibFunc(&sdlInit, h, "SDL_Init")
|
||||||
purego.RegisterLibFunc(&sdlQuit, h, "SDL_Quit")
|
purego.RegisterLibFunc(&sdlQuit, h, "SDL_Quit")
|
||||||
purego.RegisterLibFunc(&sdlGetError, h, "SDL_GetError")
|
purego.RegisterLibFunc(&sdlGetError, h, "SDL_GetError")
|
||||||
@@ -104,6 +172,7 @@ func Load() error {
|
|||||||
purego.RegisterLibFunc(&sdlGetClipboardText, h, "SDL_GetClipboardText")
|
purego.RegisterLibFunc(&sdlGetClipboardText, h, "SDL_GetClipboardText")
|
||||||
purego.RegisterLibFunc(&sdlSetClipboardText, h, "SDL_SetClipboardText")
|
purego.RegisterLibFunc(&sdlSetClipboardText, h, "SDL_SetClipboardText")
|
||||||
purego.RegisterLibFunc(&sdlFree, h, "SDL_free")
|
purego.RegisterLibFunc(&sdlFree, h, "SDL_free")
|
||||||
|
|
||||||
loaded = true
|
loaded = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package sdl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLibraryCandidatesForOS(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
goos string
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Linux",
|
||||||
|
goos: "linux",
|
||||||
|
want: []string{"libSDL3.so.0", "libSDL3.so"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "macOS",
|
||||||
|
goos: "darwin",
|
||||||
|
want: []string{"libSDL3.0.dylib", "libSDL3.dylib"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Windows",
|
||||||
|
goos: "windows",
|
||||||
|
want: []string{"SDL3.dll"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := libraryCandidatesForOS(tt.goos)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("libraryCandidatesForOS(%q): %v", tt.goos, err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Fatalf("libraryCandidatesForOS(%q) = %v, want %v", tt.goos, got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLibraryCandidatesForOSRejectsUnsupportedOS(t *testing.T) {
|
||||||
|
got, err := libraryCandidatesForOS("plan9")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("libraryCandidatesForOS(plan9) returned no error")
|
||||||
|
}
|
||||||
|
if got != nil {
|
||||||
|
t.Fatalf("libraryCandidatesForOS(plan9) = %v, want nil", got)
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), `"plan9"`) {
|
||||||
|
t.Fatalf("error %q does not identify the unsupported OS", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user