Forma correcta de vincular una biblioteca estática usando GCC


¿Por qué es que algunas bibliotecas estáticas (lib*.a) se puede vincular de la misma manera que las bibliotecas compartidas (lib*.so) están vinculadas (conmutador ld-l), pero algunas no pueden?

Siempre me habían enseñado que todas las bibliotecas, estáticas o no, se pueden vincular con-l..., sin embargo, me he encontrado con una biblioteca hasta ahora (GLFW), que no hace más que vomitar "referencia indefinida" errores de enlace si intento vincularlo de esta manera.

De acuerdo con la respuesta a esta pregunta , la forma "adecuada" de vincular las bibliotecas estáticas son incluirlas directamente, junto con mis propios archivos objeto, en lugar de usar -l. Y, en el caso de la biblioteca GLFW, esto ciertamente resuelve el problema. Pero todas las demás bibliotecas estáticas que estoy usando funcionan bien cuando se vinculan con-l.

Entonces:

  • ¿Qué podría hacer que esta biblioteca no funcione cuando se enlaza en lugar de incluirse directamente? Si supiera la causa, tal vez podría editar y recompilar la biblioteca para solucionar el problema.
  • ¿Es cierto que no eres ¿se supone que enlaza bibliotecas estáticas de la misma manera que enlaza bibliotecas compartidas? (Y si no, ¿por qué no?)
  • ¿Es el enlazador todavía capaz de eliminar las funciones de biblioteca no utilizadas del ejecutable de salida cuando la biblioteca se incluye directamente de esta manera?
Author: Community, 2012-03-31

4 answers

Gracias por las respuestas! Resulta que el problema se debió al orden del enlace. Aparentemente, si utilizas una biblioteca que a su vez tiene otras dependencias de biblioteca, esas otras dependencias deben ser listadas después de la biblioteca, no antes como yo había estado haciendo. Aprendí algo nuevo!

 25
Author: Nairou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-01 21:26:00

La forma correcta de vincular una biblioteca estática es usando-l, pero eso solo funciona si la biblioteca se puede encontrar en la ruta de búsqueda. Si no lo es, puede agregar el directorio a la lista usando-L o nombrar el archivo por nombre, como usted dice.

Lo mismo es cierto para las bibliotecas compartidas, en realidad, aunque es más probable que se encuentren, tal vez.

 6
Author: ams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-31 13:02:59

¿Le ha importado indicar a GCC la ruta de acceso de su biblioteca (usando-L) ? Al usar-l únicamente, GCC solo podrá vincular bibliotecas disponibles en directorios estándar.

-L[path] -l[lib]
 5
Author: Vincent L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-31 01:29:05

La razón es histórica. La herramienta" ar "era la herramienta de archivo original en PDP11 unix, aunque más tarde fue reemplazada completamente por" tar " para ese propósito. Almacena archivos (archivos objeto, en este caso) en un paquete. Y hay una extensión separada que contiene la tabla de símbolos para que el enlazador use. Es posible que si está administrando manualmente los archivos en el archivo que la tabla de símbolos pueda quedar desactualizada.

La respuesta corta es que puede usar la herramienta" ranlib " en cualquier archivo para recrear la tabla de símbolos. Prueba eso. En términos más generales, trate de averiguar de dónde vienen las bibliotecas corruptas y arreglarlo.

 1
Author: Andy Ross,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-31 04:34:59