mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-17 16:50:31 +00:00
Drop dlfcn dependency on Windows
Use direct syscalls instead. Needed for static builds.
This commit is contained in:
parent
8361215a84
commit
3018a7da0d
5 changed files with 113 additions and 109 deletions
|
|
@ -54,17 +54,17 @@ a better sense of performance.
|
|||
## Development environment
|
||||
|
||||
* Install [Go](https://golang.org/doc/install)
|
||||
* Install GStreamer and SDL2:
|
||||
* Install GStreamer
|
||||
|
||||
```
|
||||
# Ubuntu / Windows (WSL2)
|
||||
apt-get install -y make gcc pkg-config libsdl2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-good
|
||||
apt-get install -y make gcc pkg-config libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-good
|
||||
|
||||
# macOS
|
||||
brew install pkg-config sdl2 gstreamer gst-plugins-base gst-plugins-good
|
||||
brew install pkg-config gstreamer gst-plugins-base gst-plugins-good
|
||||
|
||||
# Windows (MSYS2)
|
||||
pacman -Sy --noconfirm --needed git make mingw-w64-ucrt-x86_64-{gcc,pkgconf,dlfcn,SDL2,gstreamer,gst-plugins-base,gst-plugins-good}
|
||||
pacman -Sy --noconfirm --needed git make mingw-w64-ucrt-x86_64-{gcc,pkgconf,gstreamer,gst-plugins-base,gst-plugins-good}
|
||||
```
|
||||
|
||||
Because the coordinator and workers need to run simultaneously. Workers connect to the coordinator.
|
||||
|
|
|
|||
54
pkg/worker/caged/libretro/nanoarch/dl_unix.go
Normal file
54
pkg/worker/caged/libretro/nanoarch/dl_unix.go
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//go:build !windows
|
||||
|
||||
package nanoarch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
#cgo linux LDFLAGS: -ldl
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type dlib struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func open(file string) (*dlib, error) {
|
||||
cs := C.CString(file)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
handle := C.dlopen(cs, C.RTLD_LAZY)
|
||||
if handle == nil {
|
||||
e := C.dlerror()
|
||||
if e != nil {
|
||||
return nil, fmt.Errorf("couldn't load the lib: %s", C.GoString(e))
|
||||
}
|
||||
return nil, fmt.Errorf("couldn't load the lib")
|
||||
}
|
||||
return &dlib{ptr: handle}, nil
|
||||
}
|
||||
|
||||
func (d *dlib) load(name string) unsafe.Pointer {
|
||||
cs := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
ptr := C.dlsym(d.ptr, cs)
|
||||
if ptr == nil {
|
||||
panic("lib function not found: " + name)
|
||||
}
|
||||
return ptr
|
||||
}
|
||||
|
||||
func (d *dlib) close() error {
|
||||
if d.ptr == nil {
|
||||
return nil
|
||||
}
|
||||
code := int(C.dlclose(d.ptr))
|
||||
if code != 0 {
|
||||
return fmt.Errorf("couldn't close the lib (%d)", code)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
30
pkg/worker/caged/libretro/nanoarch/dl_windows.go
Normal file
30
pkg/worker/caged/libretro/nanoarch/dl_windows.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//go:build windows
|
||||
|
||||
package nanoarch
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type dlib struct {
|
||||
h syscall.Handle
|
||||
}
|
||||
|
||||
func open(file string) (*dlib, error) {
|
||||
h, err := syscall.LoadLibrary(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dlib{h: h}, nil
|
||||
}
|
||||
|
||||
func (d *dlib) load(name string) unsafe.Pointer {
|
||||
proc, err := syscall.GetProcAddress(d.h, name)
|
||||
if err != nil {
|
||||
panic("lib function not found: " + name)
|
||||
}
|
||||
return unsafe.Pointer(proc)
|
||||
}
|
||||
|
||||
func (d *dlib) close() error { return syscall.FreeLibrary(d.h) }
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
package nanoarch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -ldl
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func loadFunction(handle unsafe.Pointer, name string) unsafe.Pointer {
|
||||
cs := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
ptr := C.dlsym(handle, cs)
|
||||
if ptr == nil {
|
||||
panic("lib function not found: " + name)
|
||||
}
|
||||
return ptr
|
||||
}
|
||||
|
||||
func loadLib(filepath string) (handle unsafe.Pointer, err error) {
|
||||
handle = open(filepath)
|
||||
if handle == nil {
|
||||
e := C.dlerror()
|
||||
if e != nil {
|
||||
err = errors.New(C.GoString(e))
|
||||
} else {
|
||||
err = errors.New("couldn't load the lib")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func loadLibRollingRollingRolling(filepath string) (handle unsafe.Pointer, err error) {
|
||||
dir, lib := path.Dir(filepath), path.Base(filepath)
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, errors.New("couldn't find 'n load the lib")
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.HasPrefix(file.Name(), lib) {
|
||||
handle = open(path.Join(dir, file.Name()))
|
||||
if handle != nil {
|
||||
return handle, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New("couldn't find 'n load the lib")
|
||||
}
|
||||
|
||||
func open(file string) unsafe.Pointer {
|
||||
cs := C.CString(file)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
return C.dlopen(cs, C.RTLD_LAZY)
|
||||
}
|
||||
|
||||
func closeLib(handle unsafe.Pointer) (err error) {
|
||||
if handle == nil {
|
||||
return
|
||||
}
|
||||
code := int(C.dlclose(handle))
|
||||
if code != 0 {
|
||||
return errors.New("couldn't close the lib (" + strconv.Itoa(code) + ")")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -209,37 +209,32 @@ func (n *Nanoarch) CoreLoad(meta Metadata) {
|
|||
n.options4rom = meta.Options4rom
|
||||
|
||||
corePath := meta.LibPath + meta.LibExt
|
||||
coreLib, err = loadLib(corePath)
|
||||
// fallback to sequential lib loader (first successfully loaded)
|
||||
coreLib, err = open(corePath)
|
||||
if err != nil {
|
||||
n.log.Error().Err(err).Msgf("load fail: %v", corePath)
|
||||
coreLib, err = loadLibRollingRollingRolling(corePath)
|
||||
if err != nil {
|
||||
n.log.Fatal().Err(err).Msgf("core load: %s", corePath)
|
||||
}
|
||||
n.log.Fatal().Err(err).Msgf("core load: %s", corePath)
|
||||
}
|
||||
|
||||
retroInit = loadFunction(coreLib, "retro_init")
|
||||
retroDeinit = loadFunction(coreLib, "retro_deinit")
|
||||
retroAPIVersion = loadFunction(coreLib, "retro_api_version")
|
||||
retroGetSystemInfo = loadFunction(coreLib, "retro_get_system_info")
|
||||
retroGetSystemAVInfo = loadFunction(coreLib, "retro_get_system_av_info")
|
||||
retroSetEnvironment = loadFunction(coreLib, "retro_set_environment")
|
||||
retroSetVideoRefresh = loadFunction(coreLib, "retro_set_video_refresh")
|
||||
retroSetInputPoll = loadFunction(coreLib, "retro_set_input_poll")
|
||||
retroSetInputState = loadFunction(coreLib, "retro_set_input_state")
|
||||
retroSetAudioSample = loadFunction(coreLib, "retro_set_audio_sample")
|
||||
retroSetAudioSampleBatch = loadFunction(coreLib, "retro_set_audio_sample_batch")
|
||||
retroReset = loadFunction(coreLib, "retro_reset")
|
||||
retroRun = loadFunction(coreLib, "retro_run")
|
||||
retroLoadGame = loadFunction(coreLib, "retro_load_game")
|
||||
retroUnloadGame = loadFunction(coreLib, "retro_unload_game")
|
||||
retroSerializeSize = loadFunction(coreLib, "retro_serialize_size")
|
||||
retroSerialize = loadFunction(coreLib, "retro_serialize")
|
||||
retroUnserialize = loadFunction(coreLib, "retro_unserialize")
|
||||
retroSetControllerPortDevice = loadFunction(coreLib, "retro_set_controller_port_device")
|
||||
retroGetMemorySize = loadFunction(coreLib, "retro_get_memory_size")
|
||||
retroGetMemoryData = loadFunction(coreLib, "retro_get_memory_data")
|
||||
retroInit = coreLib.load("retro_init")
|
||||
retroDeinit = coreLib.load("retro_deinit")
|
||||
retroAPIVersion = coreLib.load("retro_api_version")
|
||||
retroGetSystemInfo = coreLib.load("retro_get_system_info")
|
||||
retroGetSystemAVInfo = coreLib.load("retro_get_system_av_info")
|
||||
retroSetEnvironment = coreLib.load("retro_set_environment")
|
||||
retroSetVideoRefresh = coreLib.load("retro_set_video_refresh")
|
||||
retroSetInputPoll = coreLib.load("retro_set_input_poll")
|
||||
retroSetInputState = coreLib.load("retro_set_input_state")
|
||||
retroSetAudioSample = coreLib.load("retro_set_audio_sample")
|
||||
retroSetAudioSampleBatch = coreLib.load("retro_set_audio_sample_batch")
|
||||
retroReset = coreLib.load("retro_reset")
|
||||
retroRun = coreLib.load("retro_run")
|
||||
retroLoadGame = coreLib.load("retro_load_game")
|
||||
retroUnloadGame = coreLib.load("retro_unload_game")
|
||||
retroSerializeSize = coreLib.load("retro_serialize_size")
|
||||
retroSerialize = coreLib.load("retro_serialize")
|
||||
retroUnserialize = coreLib.load("retro_unserialize")
|
||||
retroSetControllerPortDevice = coreLib.load("retro_set_controller_port_device")
|
||||
retroGetMemorySize = coreLib.load("retro_get_memory_size")
|
||||
retroGetMemoryData = coreLib.load("retro_get_memory_data")
|
||||
|
||||
C.bridge_retro_set_environment(retroSetEnvironment, C.core_environment_cgo)
|
||||
C.bridge_retro_set_input_state(retroSetInputState, C.core_input_state_cgo)
|
||||
|
|
@ -390,7 +385,7 @@ func (n *Nanoarch) Shutdown() {
|
|||
|
||||
setRotation(0)
|
||||
Nan0.sys.av = C.struct_retro_system_av_info{}
|
||||
if err := closeLib(coreLib); err != nil {
|
||||
if err := coreLib.close(); err != nil {
|
||||
n.log.Error().Err(err).Msg("lib close failed")
|
||||
}
|
||||
n.options = nil
|
||||
|
|
@ -611,11 +606,11 @@ func byteCountBinary(b int64) string {
|
|||
func (m Metadata) HasHack(h string) bool { return slices.Contains(m.Hacks, h) }
|
||||
|
||||
var (
|
||||
coreLib *dlib
|
||||
retroAPIVersion unsafe.Pointer
|
||||
retroDeinit unsafe.Pointer
|
||||
retroGetSystemAVInfo unsafe.Pointer
|
||||
retroGetSystemInfo unsafe.Pointer
|
||||
coreLib unsafe.Pointer
|
||||
retroInit unsafe.Pointer
|
||||
retroLoadGame unsafe.Pointer
|
||||
retroReset unsafe.Pointer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue