2012-02-21 18 views
26

Tenemos una base de código dividida en bibliotecas estáticas. Desafortunadamente, las bibliotecas tienen dependencias circulares; por ejemplo, libfoo.a depende de libbar.a y viceversa.Resolviendo dependencias circulares uniendo la misma biblioteca dos veces?

sé la forma "correcta" de manejar esto es usar --start-group y --end-group opciones del enlazador, así:

g++ -o myApp -Wl,--start-group -lfoo -lbar -Wl,--end-group 

Pero en nuestros Makefiles existentes, el problema se maneja normalmente como esto:

g++ -o myApp -lfoo -lbar -lfoo 

(Imagínese esto se extendió a ~ 20 bibliotecas con interdependencias complejas.)

he estado yendo a través ou r Makefiles cambia el segundo formulario al primero, pero ahora mis compañeros de trabajo me preguntan por qué ... Y aparte de "porque es más limpio" y una vaga sensación de que la otra forma es arriesgada, no tengo una buena respuesta.

Entonces, ¿puede unir la misma biblioteca varias veces alguna vez crear un problema? Por ejemplo, ¿podría fallar el enlace con símbolos definidos de forma múltiple si el mismo .o se extrae dos veces? ¿O hay algún riesgo de que podamos terminar con dos copias del mismo objeto estático, creando errores sutiles?

Básicamente, quiero saber si existe la posibilidad de que el tiempo de enlace o las fallas de tiempo de ejecución vinculen la misma biblioteca varias veces; y si es así, cómo activarlos. Gracias.

+0

El único problema que se me ocurre es cuando logras vincular dos versiones diferentes de la misma biblioteca. Eso es difícil de hacer y (IMO) es poco probable que ocurra en Linux. Además, solo 20 bibliotecas no se parecen mucho. ¿Vale la pena caminar a través de makefiles? Podrías pasar ese tiempo haciendo otra cosa. – SigTerm

+3

Este problema simplemente desaparece si arregla sus bibliotecas para que no tengan dependencias circulares. –

+3

Supongo que eliminar las dependencias circulares al examinar y dividir las bibliotecas no es factible? Porque esa sería la forma más limpia –

Respuesta

5

Todo lo que puedo ofrecer es una falta de contra-ejemplo. En realidad, nunca he visto la primera forma (aunque es claramente mejor) y siempre he visto esto resuelto con la segunda forma, y ​​no he observado problemas como resultado.

Aun así, yo sugeriría cambiar a la primera forma porque muestra claramente la relación entre las bibliotecas en lugar de confiar en que el enlazador se comporte de una manera particular.

Dicho esto, sugeriría al menos considerar si existe la posibilidad de refactorizar el código para extraer las piezas comunes en bibliotecas adicionales.

+5

Gracias, Mark. Aunque me parece divertido, la mitad de los comentarios sobre mi pregunta dicen "¡Arregla tu código base!" y la otra mitad dice "¿Por qué estás manipulando una base de código de trabajo?" :-) – Nemo

+0

El primer formulario presentaría un costo de rendimiento ya que el vinculador intentará encontrar símbolos repetidos en todas las bibliotecas enumeradas. vea esto: http://stackoverflow.com/a/409470/70198 –

+0

El primer formulario también solo está funcionando para GNU ld y, por lo tanto, no es una solución portátil. – user1225999

1

Dado que es una aplicación heredada, apuesto a que la estructura de las bibliotecas se hereda de algún arreglo que probablemente ya no importa, como ser usado para construir otro producto que ya no se usa.

Incluso si todavía existen razones estructurales para la estructura heredada de la biblioteca, casi seguro que sería aceptable construir una biblioteca más a partir de la disposición heredada. Simplemente coloque todos los módulos de las 20 bibliotecas en una nueva biblioteca, liballofthem.a. Entonces, cada aplicación es simplemente g++ -o myApp -lallofthem ...

Cuestiones relacionadas