41 votos

¿Cómo puedo ejecutar los nuevos juegos de Unity en OS X 10.9 Mavericks?

La mayoría de los juegos creados con Unity 2018 y Unity 2019 no funcionan en Mac OS X 10.9. Se inician inicialmente, y a veces llegan hasta el menú principal, pero siempre se bloquean antes de entrar en el juego.

Dyld Error Message:
  Symbol not found: _getattrlistbulk
  Referenced from: /Users/USER/Desktop/Sayonara Wild Hearts.app/Contents/MacOS/../Frameworks/UnityPlayer.dylib
  Expected in: /usr/lib/libSystem.B.dylib

Problem Report Screenshot

¿Cómo puedo ejecutar estos juegos sin actualizar a una fea versión plana de OS X?

0 votos

Los comentarios no son para ampliar la discusión; esta conversación ha sido trasladado al chat .

0 votos

La razón subyacente es, probablemente, que las nuevas versiones de Unity se compilan con las nuevas versiones de Xcode, que sólo se dirigen a las nuevas versiones de OS X.

0 votos

@ThorbjørnRavnAndersen Yo habría pensado, sin embargo, que si 10.10 era el objetivo mínimo de despliegue, habría hecho falta mucho más que stubear un método para que los juegos funcionaran.

85voto

Wowfunhappy Puntos 33

El registro de fallos indica que el juego está buscando una función llamada getattrlistbulk . Como esta función no existe en Mavericks, el juego no sabe qué hacer y se bloquea. Ergo, para que el juego se ejecute, tendremos que darle lo que quiere: una copia del getattrlistbulk función.

(En otras palabras, tenemos que escribir algo de código. Asegúrate de tener instaladas las herramientas de línea de comandos Xcode de Apple).

getattrlistbulk es un parte del núcleo y no entiendo lo que hace. Pero, ¿y si no tuviera que hacerlo? ¿Y si los juegos de Unity no necesitaran realmente getattrlistbulk ¿para algo importante? Si ese fuera el caso, podría ser que getattrlistbulk no necesitaría realmente hacer cualquier cosa para que un juego se ejecute, la función sólo tendría que existe .

Sólo hay una forma de averiguarlo. Probemos este código:

#include <sys/attr.h>

int getattrlistbulk(int dirfd, struct attrlist * attrList, void * attrBuf, size_t attrBufSize, uint64_t options) {
    return 0;
}

Esta copia de getattrlistbulk siempre devolverá 0 No importa lo que suceda.

Si guarda este código como UnityMavericksWorkarounds.m puede compilarlo con:

clang -compatibility_version 9999 -o UnityMavericksWorkarounds.dylib -dynamiclib UnityMavericksWorkarounds.m

Ahora, tenemos que hacer que el juego cargue nuestra nueva biblioteca UnityMavericksWorkarounds. Esto debería ser fácil de hacer con el DYLD_INSERT_LIBRARIES variable de entorno. Ejecutar en el Terminal:

DYLD_INSERT_LIBRARIES=UnityMavericksWorkarounds.dylib Sayonara\ Wild\ Hearts.app/Contents/MacOS/Sayonara\ Wild\ Hearts

...y ver cómo el juego se bloquea exactamente igual que antes:

Dyld Error Message:
  Symbol not found: _getattrlistbulk
  Referenced from: /Users/USER/Desktop/Sayonara Wild Hearts.app/Contents/MacOS/../Frameworks/UnityPlayer.dylib
  Expected in: /usr/lib/libSystem.B.dylib

¿Por qué no puede UnityPlayer.dylib encontrar nuestro nuevo y elegante getattrlistbulk ¿función?

Veamos de nuevo el informe del accidente. UnityPlayer no espera getattrlistbulk que esté en cualquier sitio, espera que esté en /usr/lib/libSystem.B.dylib y por lo tanto no está buscando dentro de nuestra biblioteca UnityMavericksWorkarounds. Esto se debe a un concepto llamado namespaces de dos niveles, sobre el que puede leer más aquí . Y, aunque el namespacing de dos niveles se puede desactivar mediante DYLD_FORCE_FLAT_NAMESPACE=1 Los juegos de Unity no funcionarán sin él.

Probemos otra cosa. ¿Y si hacemos que el juego cargue nuestra biblioteca, UnityMavericksWorkarounds.dylib en lugar de libSystem.B.dylib ? Apple's install_name_tool hace que esto sea fácil. Copie UnityMavericksWorkarounds.dylib en la carpeta de la aplicación Contents/Frameworks y ejecutarlo:

install_name_tool -change /usr/lib/libSystem.B.dylib @executable_path/../Frameworks/UnityMavericksWorkarounds.dylib Sayonara\ Wild\ Hearts.app/Contents/Frameworks/UnityPlayer.dylib

(Sustituir Sayonara\ Wild\ Hearts con el nombre de su juego).

Ahora, intenta lanzar el juego de nuevo, y...

Application Specific Information:
dyld: launch, loading dependent libraries

Dyld Error Message:
  Symbol not found: dyld_stub_binder
  Referenced from: /Users/USER/Desktop/Sayonara Wild Hearts.app/Contents/MacOS/Sayonara Wild Hearts
  Expected in: /Users/USER/Desktop/Sayonara Wild Hearts.app/Contents/MacOS/../Frameworks/UnityMavericksWorkarounds.dylib
 in /Users/USER/Desktop/Sayonara Wild Hearts.app/Contents/MacOS/Sayonara Wild Hearts

Oye, ¡al menos el registro de accidentes ha cambiado esta vez! Probablemente puedes adivinar por qué esto no funcionó. libSystem.B.dylib es una biblioteca de sistema esencial que contiene muchas, muchas funciones. UnityMavericksWorkarounds sólo contiene getattrlistbulk . Y así, aunque el juego ahora tiene acceso a getattrlistbulk ¡le falta todo lo demás!

Lo que queremos es que nuestra biblioteca UnityMavericksWorkarounds también proporcione todas las demás funciones de libSystem además de las suyas propias. Podemos hacer esto haciendo libSystem.B.dylib a sub-biblioteca de nuestro UnityMavericksWorkarounds.dylib .

Hice esto usando optool :

optool install -c reexport -p /usr/lib/libSystem.B.dylib -t Sayonara\ Wild\ Hearts.app/Contents/Frameworks/UnityMavericksWorkarounds.dylib

(Probablemente hay una forma más limpia de enlazar esto en tiempo de compilación, pero no pude averiguar cómo, y optool funcionó).

Ahora, intenta lanzar el juego de nuevo, y...

It works!


Preguntas teóricas frecuentes

(Preguntas de seguimiento que nadie ha hecho, pero que teóricamente podrían).

P: ¿Es el valor de retorno de 0 ¿Importante?

A : Sí. Originalmente intenté 1 pero eso hacía que algunos juegos asignaran toda la memoria disponible y se bloquearan cuando no quedaba ninguna.

P: ¿Esto hará que todo ¿Los juegos de Unity funcionan correctamente en Mavericks?

A : No. Que yo sepa, permitirá arrancar cualquier juego de Unity 2018/2019, ¡pero nadie ha dicho nada de que funcione correctamente! Los juegos son complejos, y estos claramente nunca han sido probados en Mavericks antes, por lo que pueden tener otros fallos. Timelie es un ejemplo de un juego que técnicamente funciona con este arreglo, pero tiene problemas gráficos muy graves.

Sin embargo, muchos otros juegos parecen funcionar perfectamente.

P: ¿Es posible reimplantar realmente getattrlistbulk en lugar de utilizar una función stub?

A : ¿Tal vez? Internet™ dice getattrlistbulk es un sustituto de getdirentriesattr . Entonces, en un momento dado lo intenté:

#include <sys/attr.h>
#include <unistd.h>

int getattrlistbulk(int dirfd, struct attrlist * attrList, void * attrBuf, size_t attrBufSize, uint64_t options) {

    unsigned int count;
    unsigned int basep;
    unsigned int newState;

    return getdirentriesattr(dirfd, &attrList, &attrBuf, attrBufSize, &count, &basep, &newState, options);
}

Esto se escribió comparando el código de ejemplo de getattrlistbulk y getdirentriesattr en la documentación para desarrolladores. Funciona (en la medida en que los juegos se ejecutan), pero entonces, también lo hace return 0 Así que realmente no tengo forma de probar el código. En estas circunstancias, return 0 parece más seguro.

P: ¿Pueden darme un resumen?

A : Claro:

  1. Copie el primer bloque de código de esta respuesta en un archivo llamado UnityMavericksWorkarounds.m .
  2. clang -compatibility_version 9999 -o /Path/To/Game.app/Contents/Frameworks/UnityMavericksWorkarounds.dylib -dynamiclib /Path/To/UnityMavericksWorkarounds.m
  3. install_name_tool -change /usr/lib/libSystem.B.dylib @executable_path/../Frameworks/UnityMavericksWorkarounds.dylib /Path/To/Game.app/Contents/Frameworks/UnityPlayer.dylib
  4. Descargar optool .
  5. /Path/To/optool install -c reexport -p /usr/lib/libSystem.B.dylib -t /Path/To/Game.app/Contents/Frameworks/UnityMavericksWorkarounds.dylib

4 votos

Como referencia, la fuente de getattrlistbulk como se encuentra en OS X 10.10 se puede encontrar aquí .

2 votos

Tengo que preguntar: ¿Por qué no actualizar a Yosemite? Apple ofrece una enlace para descargar.

21 votos

@DavidAnderson ¿Y sustituir esta obra maestra rápida, estable y exquisitamente diseñada por una imitación de iOS que provoca dolor de cabeza? Debe estar de broma, buen señor.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X