2011-12-02 1 views
5

Ho un progetto di pitone che si basa su alcuni file LUA, uno dei quali richiede 'presa'. Ricevo un errore durante il caricamento di socket.core "simbolo non definito: lua_getmetatable" quando provo a richiedere il file lua da python 2.7.Linker Error Lunatic Python lua.require ('presa') -> simbolo indefinito: lua_getmetatable

semplice riproduttore:

$ python 
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import lua 
>>> lua.require('socket') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
Exception: error: error loading module 'socket.core' from file 
    '/usr/lib/lua/5.1/socket/core.so': 
    /usr/lib/lua/5.1/socket/core.so: undefined symbol: lua_getmetatable 

Sto usando un recent Lunatic Python branch dove ho ripulito gli avvertimenti Py_ssize_t e liblua5.1-socket2 su Ubuntu 11.04

ottengo lo stesso errore se uso il principale codice sorgente lunatic-python e/o aggiornamento a luasocket 2.0.2.

edit: Che cosa è la causa di questo errore, e come posso risolvere il problema?

Edit # 2: Ecco l'output di costruire luasocket-2.0.2. Il make predefinita non ha costruito unix.so, e ho curato per costruire che pure in modo non ho mescolare ed abbinare 2.0.0 con 2.0.2:

$ make 
cd src; make all 
make[1]: Entering directory `/sandbox/luasocket/luasocket-2.0.2/src' 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o luasocket.o luasocket.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o timeout.o timeout.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o buffer.o buffer.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o io.o io.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o auxiliar.o auxiliar.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o options.o options.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o inet.o inet.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o tcp.o tcp.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o udp.o udp.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o except.o except.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o select.o select.c 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o usocket.o usocket.c 
gcc -O -shared -fpic -o socket.so.2.0.2 luasocket.o timeout.o buffer.o io.o auxiliar.o options.o inet.o tcp.o udp.o except.o select.o usocket.o 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o mime.o mime.c 
gcc -O -shared -fpic -o mime.so.1.0.2 mime.o 
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o unix.o unix.c 
gcc -O -shared -fpic -o unix.so buffer.o auxiliar.o options.o timeout.o io.o usocket.o unix.o 
make[1]: Leaving directory `/sandbox/luasocket/luasocket-2.0.2/src' 
+0

Qual è la domanda, però? ;) – 0xC0000022L

+1

Qual è la causa di questo errore e come risolverlo? – RedCup

+0

I simboli non vengono esportati correttamente dal modulo 'lua' che potrebbe essere utilizzato nel modulo richiesto. Potresti anche pubblicare un log della fase di compilazione, principalmente la parte finale del link? –

risposta

6

Il problema non è nel luasocket, ma nel modo in cui vengono gestiti i simboli delle librerie condivise.

Il problema è che il mentre le lua.so (modulo Python) legami liblua5.1.so, moduli condivise caricate da require non hanno accesso ai simboli da liblua5.1.so. Su Mac OS X funziona, perché i simboli da dlopen vengono caricati come RTLD_GLOBAL per impostazione predefinita.

Ho sperimentato con modificando il sorgente Lua (lua-5.1.4/src/loadlib.c:69), tuttavia non aiuta, perché quando require è chiamato da lua.so, i simboli liblua5.1.so sono già stati caricati localmente per lua.so. Questo è il motivo per cui luasocket non li vede.

Fortunatamente, Python consente di modificare la semantica dlopen utilizzando il modulo sys. Ciò consente di forzare il caricamento dei moduli con RTLD_GLOBAL, che è esattamente ciò che è necessario. Prova a eseguire il seguente codice e vedere se funziona per voi:

$ python 
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys, DLFCN 
>>> sys.setdlopenflags(DLFCN.RTLD_NOW | DLFCN.RTLD_GLOBAL) 
>>> import lua 
>>> lua.require("socket") 
<Lua table at 0x22ccef0> 
+0

Wow ... Grazie per la grande spiegazione troppo. Per i curiosi, puoi saperne di più su ldload tramite 'man ldload' e il [Python docs per il modulo sys] (http://docs.python.org/library/sys.html). sys.setdlopenflags (n) è solo unix. – RedCup

+0

Sto incontrando un problema simile tranne sul lato lua invece che su python. Ho provato a ricostruire lunatic con '-export-dynamic' sperando che i simboli da cui dipende sarebbero visibili ai moduli successivi caricati in seguito - non ha funzionato.Per curiosità, perché questo problema non si verifica su Windows? – greatwolf