SDL3 loader fix for MacOS

This commit is contained in:
Dmitry Sergeev
2026-09-03 10:13:47 +03:00
parent 6058d3ae64
commit a61767f668
3 changed files with 129 additions and 4 deletions
+71 -2
View File
@@ -1,7 +1,9 @@
package sdl
import (
"errors"
"fmt"
"os"
"runtime"
"unsafe"
@@ -70,16 +72,82 @@ var (
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
func Load() error {
if loaded {
return nil
}
h, err := purego.Dlopen("libSDL3.so.0", purego.RTLD_NOW|purego.RTLD_GLOBAL)
h, err := openLibrary()
if err != nil {
return fmt.Errorf("win: load SDL3: %w", err)
return err
}
purego.RegisterLibFunc(&sdlInit, h, "SDL_Init")
purego.RegisterLibFunc(&sdlQuit, h, "SDL_Quit")
purego.RegisterLibFunc(&sdlGetError, h, "SDL_GetError")
@@ -104,6 +172,7 @@ func Load() error {
purego.RegisterLibFunc(&sdlGetClipboardText, h, "SDL_GetClipboardText")
purego.RegisterLibFunc(&sdlSetClipboardText, h, "SDL_SetClipboardText")
purego.RegisterLibFunc(&sdlFree, h, "SDL_free")
loaded = true
return nil
}
+56
View File
@@ -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)
}
}