Cargando librerías locales en Pyglet
El principal punto débil de pyglet a la hora de distribuir los proyectos es AVbin, que es el único componente no python que propociona un API
estable para acceder a la parte audio/video de pyglet
.
Bueno, en realidad no es tan difícil ya que solo hay que instalar la librería, pero la versión que suele venir empaquetada en las distribuciones es algo vieja, y con AVbin
es mejor ir siempre a la última.
¿Podemos instalar con el instalador de AVbin
? Sí, pero no es tan cómodo y conveniente como por ejemplo los paquetes binarios para Windows
creados con py2exe, y los jugones quieren jugar, no pelearse con dependencias :P.
En Windows
se pueden incluir las DLL
y al final tenemos un ZIP
que es solo descomprimir y ya se puede jugar, así que he estado pensando: ¿se podría hacer algo así en Linux
? Ojeando el código de pyglet
resulta que es muy fácil de hacer ;).
pyglet
utiliza ctypes.util.find_library para encontrar las librerías a cargar, que a su vez utiliza diferentes mecanismos dependiendo del sistema operativo. La idea es cambiar el comportamiento de esa función de forma que cuando se busque AVbin
devolvamos la ruta a una librería local que podemos distribuir con nuestro juego.
Por ejemplo:
def find_local_library(path, fn): """Load libraries for a local path""" LOCAL = { "avbin": r"%s/lib/%s/libavbin.so.11" } bits = "64bit" if sys.maxsize > 2**32 else "32bit" if path in LOCAL: return LOCAL[path] % (pyglet.resource.get_script_home(), bits) return fn(path) _find_library = ctypes.util.find_library ctypes.util.find_library = lambda path: find_local_library(path, _find_library)
Lo que hago es monkeypatch ctypes.util.find_library
para que si se pide la ibrería avbin
, se devuelva una ruta relativa a la ubicación del script que ejecuta el juego tal que .../lib/BITS/libavbin.so.11
.
He incluído la parte de los bits
porque al ser una librería binaria tenemos que incluir una versión para 32-bit
y otra para 64-bit
. Además notar que solo lo uso en Linux y por eso no me he preocupado de poner la ruta de una forma portable.
De esta forma es sencillo incluir las librerías que queramos de forma que sea descomprimir y jugar; o incluso empaquetar en formato deb
o rpm
incluyendo una librería local independiente de lo que el usuario tenga instalado en el sistema.
El caso es que funciona muy bien y lo he usado para construir los paquetes de Lunar y For Science! para Debian
y Ubuntu
(aunque he hecho un paquete para 32-bit
y otro para 64-bit
, la idea es la misma).
Potencialmente se podría hacer lo mismo en Mac
, pero no tengo un sistema para hacer pruebas, así que por ahora no he podido empaquetar para el sistema de Apple
:(.
Actualización: he compartido la idea en la lista de correo y hemos acabado haciendo esto: search for local libs based on the script path (Linux, Mac), así que si usas el código del repo no es necesario recurrir al monkeypatching ;).
Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.