gcc - una - librerias dinamicas linux
¿Cómo tratar las dependencias recursivas entre bibliotecas estáticas utilizando el vinculador binutils? (2)
Estoy portando un sistema existente de Windows a Linux. La construcción está estructurada con múltiples bibliotecas estáticas. Me encontré con un error de enlace en el que no se podía encontrar un símbolo (definido en libA) en un objeto de libB. La línea del enlazador se veía como
g ++ test_obj.o -lA -lB -o test
Por supuesto, el problema es que cuando el enlazador encuentra que necesita el símbolo de libA, ya lo ha pasado, y no vuelve a escanear, por lo que simplemente se equivoca aunque el símbolo esté allí para tomarlo.
Mi idea inicial fue, por supuesto, simplemente cambiar el enlace (a -lB-lA) para que luego se escanee libA, y se eliminen los símbolos que falten de libB que estén en libA. ¡Pero luego descubrí que en realidad hay una dependencia recursiva entre libA y libB! Supongo que el enlazador de Visual C ++ maneja esto de alguna manera (¿vuelve a escanear por defecto?).
Maneras de lidiar con esto que he considerado:
Usa objetos compartidos. Desafortunadamente, esto no es deseable desde la perspectiva de requerir la compilación de PIC (este es el código de rendimiento sensible y perder% ebx para mantener el GOT realmente dolería), y los objetos compartidos no son necesarios.
Construya un mega ar de todos los objetos, evitando el problema.
Reestructurar el código para evitar la dependencia recursiva (que obviamente es lo correcto, pero estoy tratando de hacer este puerto con cambios mínimos).
¿Tienes otras ideas para lidiar con esto? ¿Hay alguna manera de convencer al enlazador de binutils para que vuelva a analizar las bibliotecas que ya ha examinado cuando falta un símbolo?
Mientras @nos proporciona una solución simple, no escala cuando hay múltiples bibliotecas involucradas y las dependencias mutuas son más complejas. Para resolver los problemas que proporciona ld
--start-group archives --end-group
.
En tu caso particular:
g++ test_obj.o --start-group -lA -lB --end-group -o test
Solo haz esto:
g++ test_obj.o -lA -lB -lA -o test
Cuando el enlazador lea el primer libA en la línea de comando, descartará el objeto / símbolos en el que aún nadie ha dependido, por ejemplo, todos los símbolos que libB necesita pero no test_obj.o. Entonces solo haz que lea libA nuevamente, y recogerá esos símbolos también.