2012-06-20 9 views
6

He estado tratando de compilar mi proyecto y estoy recibiendo errores undefined reference. ej .:Linked no puede encontrar símbolos, pero las bibliotecas son leídas y existen símbolos

installertest.cpp:(.text+0x9d1): undefined reference to `XmlRpcValue::makeArray()' 
... 
installertest.cpp:(.text+0xede): undefined reference to `dbcancel' 
installertest.cpp:(.text+0xefd): undefined reference to `dbfcmd' 
installertest.cpp:(.text+0xf0f): undefined reference to `dbsqlexec' 
installertest.cpp:(.text+0xf2d): undefined reference to `SHA1_Init' 
... 

Mi línea de comandos es:

g++ -o installertest \ 
    -lsybdb \ 
    -lxmlrpc \ 
    -lxmlrpc_cpp \ 
    -lxmlrpc_xmlparse \ 
    -lxmlrpc_xmltok \ 
    -lxmlrpc_util \ 
    -lxmlrpc++ \ 
    -lxmlrpc_server_cgi \ 
    -lssl \ 
    -std=c++0x \ 
    ContractData.o installertest.o 

objdump -T muestra que los símbolos están en el archivo .so. ej .:

libsybdb.so: 
... 
0000000000011c30 g DF .text 0000000000000083 Base  dbcancel 
... 

/usr/lib/libxmlrpc_cpp.so: 
... 
0000000000002e78 g DF .text 0000000000000092 Base  _ZN11XmlRpcValue9makeArrayEv 
... 

strace muestra que los archivos de la biblioteca están siendo abierto y leído por el enlazador:

... 
[pid 5019] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libsybdb.so", {st_mode=S_IFREG|0644, st_size=421608, ...}) = 0 
[pid 5019] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libsybdb.so", O_RDONLY) = 7 
[pid 5019] fcntl(7, F_GETFD)   = 0 
[pid 5019] fcntl(7, F_SETFD, FD_CLOEXEC) = 0 
[pid 5019] fstat(7, {st_mode=S_IFREG|0644, st_size=421608, ...}) = 0 
[pid 5019] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16c200c000 
[pid 5019] lseek(7, 0, SEEK_SET)  = 0 
[pid 5019] read(7, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\0\0\0\0\0\0"..., 4096) = 4096 
... 
[pid 5019] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libxmlrpc.so", {st_mode=S_IFREG|0644, st_size=80936, ...}) = 0 
[pid 5019] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libxmlrpc.so", O_RDONLY) = 8 
[pid 5019] fcntl(8, F_GETFD)   = 0 
[pid 5019] fcntl(8, F_SETFD, FD_CLOEXEC) = 0 
[pid 5019] fstat(8, {st_mode=S_IFREG|0644, st_size=80936, ...}) = 0 
[pid 5019] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16c200d000 
[pid 5019] lseek(8, 0, SEEK_SET)  = 0 
[pid 5019] read(8, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300?\0\0\0\0\0\0"..., 4096) = 4096 
... 

Todos los archivos involucrados están dirigidos a x86-64 y la cabecera para el C bibliotecas son extern "C" . He intentado todo lo que puedo pensar y todavía no enlazaré.

Incluso he intentado eliminar todo el código de C++ 11 y compilar sin el modificador de línea de comandos, todavía nada.

Mi sistema es Ubuntu Precise (12,04) 64-bit usando g ++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 si eso ayuda. Todos los paquetes fueron instalados desde el administrador de paquetes y los paquetes de desarrollo están instalados.

edición (05/30/2017): marcado como duplicado de https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc
Otra pregunta se refiere a qué orden de los argumentos es importante. No se sabe que el orden de discusión sea un problema cuando se formula la pregunta.
Además, la pregunta anterior no contiene ninguna expansión útil, mientras que esta pregunta muestra el problema en cuestión.
La pregunta anterior puede verse como una expansión útil en la respuesta a esta, pero no una duplicación.

+0

Hola, Ben. ¿Podrías por favor mostrarme cómo usar el strace para verificar el proceso? Mi principal dificultad es cómo obtener el PID, ya que el proceso de compilación se muere muy rápido. Solo uso ps aux | grep para obtener el PID, pero el proceso ya está muerto. – William

+0

@ XingWang, no hay problema. Simplemente debe anteponer "strace -f -e trace = all" a su línea de comando. Dependiendo de su sistema, también puede necesitar agregar "sudo". Entonces, de mi ejemplo: "strace -f -e trace = all g ++ -o installertest ContractData.o installertest.o" ... –

+0

Posible duplicado de [¿Por qué el orden en que las bibliotecas están vinculadas a veces causa errores en GCC?] (https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc) –

Respuesta

9

Debe colocar los marcadores del enlazador de las bibliotecas después de los archivos del objeto. Así, en lugar de

g++ -o installertest \ 
-lsybdb \ 
-lxmlrpc \ 
-lxmlrpc_cpp \ 
-lxmlrpc_xmlparse \ 
-lxmlrpc_xmltok \ 
-lxmlrpc_util \ 
-lxmlrpc++ \ 
-lxmlrpc_server_cgi \ 
-lssl \ 
-std=c++0x \ 
ContractData.o installertest.o 

uso

g++ -o installertest \ 
ContractData.o installertest.o \ 
-lsybdb \ 
-lxmlrpc \ 
-lxmlrpc_cpp \ 
-lxmlrpc_xmlparse \ 
-lxmlrpc_xmltok \ 
-lxmlrpc_util \ 
-lxmlrpc++ \ 
-lxmlrpc_server_cgi \ 
-lssl \ 
-std=c++0x 
+0

Lo intenté correctamente, funcionó. ¿¡De Verdad!? No puedo creer que haya sido así de simple. –

+1

Para cualquier otra persona que se encuentre con este problema, este es el razonamiento. Parece que gcc ahora envía la bandera del enlazador --as necesario para ld. Esto tiene el efecto de descartar cualquier biblioteca especificada que no tenga símbolos necesarios para vincular. En la primera instancia, se descartaron todas las bibliotecas porque no había símbolos no resueltos, en la fase de enlace no se pudieron encontrar los símbolos. En la segunda instancia, ld había recopilado la lista de símbolos no resueltos y luego los había encontrado en las bibliotecas especificadas y, por lo tanto, los conservaba cuando se trataba de la fase de enlace real. –

Cuestiones relacionadas