2010-01-05 31 views
13

Supongo que tengo una biblioteca libfoo.so.1, que depende (de acuerdo con ldd) en libbar.so.1. Sin embargo, libbar.so.1 no está disponible en este momento. Mi aplicación necesita llamar a una función en libfoo.so.1 que no requiere libbar.so.1 en absoluto.¿Cómo cargar una biblioteca compartida sin cargar sus dependencias?

¿Hay alguna manera de cargar libfoo.so.1, resolver el símbolo de la función y llamarlo sin tener libbar.so.1 para satisfacer la dependencia? Es un caso de "Sé lo que estoy haciendo, solo déjame hacerlo ya". Intenté el indicador RTLD_LAZY, pero todavía intenta cargar la biblioteca libbar.so.1 antes de no cargando los símbolos.


EDITAR

Esta es la situación exacta.

tenemos 3 jugadores:

  • libbar.so.1, una biblioteca compartida ubicada en un camino no en LD_LIBRARY_PATH o ldconfig, y cuyas dependencias están todos resueltos
  • libfoo.so.1, una biblioteca compartida situada en un directorio diferente a libbar, pero que depende de libbar. En tiempo de ejecución, libfoo sabrá dónde ubicar libbar.
  • App, una aplicación binaria que necesita cargar libfoo en algún momento durante el tiempo de ejecución.

App no sabe dónde encontrar libbar, pero sabe que libfoo sabe. Lo que estoy tratando de lograr es tener una función init en libfoo que simplemente cambiaría el directorio de trabajo actual de App donde se encuentra libbar para finalmente resolver todas las dependencias y hacer felices a todos.

libfoo se finalmente necesidad de llamar a las cosas en libbar, pero no en esta función init. No creo que la creación de un apéndice funcione, ya que los símbolos eventualmente tendrían que resolverse a las funciones reales.

+1

Es bueno que hayas mencionado RTLD_LAZY: muestra que has intentado y me impide seguir el camino del arenque rojo de sugerirlo. –

Respuesta

4

Bueno, las variables aún se resuelven incluso con RTLD_LAZY, por lo que en general se necesitan todas las bibliotecas para vincular. Parece que debe crear un stub libbar.so.1 que no tiene ninguna funcionalidad y lo puede encontrar el vinculador.

+0

Creo que esto funcionaría, pero necesitas el código auxiliar para definir todos los símbolos de los que depende libfoo.so. Las definiciones en sí mismas pueden ser trozos. –

+1

Como señala tommieb75, los stubs en realidad no tienen que estar en libbar.so, pero sus símbolos deben definirse en alguna parte. –

+0

No creo que deba definir todos los símbolos, ¿no es eso lo que 'RTLD_LAZY' hará? –

0

Solo un pensamiento, ¿ha pensado en la interposición de la dependencia? Simplemente cree una función idéntica con la misma firma, parámetros, etc. y deje que el enlazador resuelva esta función e ignore libbar.so.1? Como no mencionaste esto, pensé en sugerir esto.

Espero que esto ayude, Saludos cordiales, Tom.

+0

No creo que esto funcione. Cada biblioteca tiene una lista de dependencias codificadas en ella en el momento del enlace que es independiente del conjunto de símbolos indefinidos. El cargador intentará encontrar esas dependencias, sean o no realmente necesarias. –

+0

@Jay: la ruta del cargador está integrada en el ejecutable para la carga dinámica de la función ... Estaba pensando en términos de evitar la carga dinámica especificando una función duplicada con la misma firma, lo que obliga al vinculador a usar esa versión en su lugar ... – t0mm13b

+0

@Jay: Acabo de ver su respuesta a la respuesta de Adam, esa era mi línea de pensamiento ... un trozo a falta de una mejor palabra ... – t0mm13b

-1

Use dlopen para cargar la biblioteca y dlsym para obtener la función que necesita.

+0

Así es como probó la bandera RTLD_LAZY; no puede especificar eso cuando la biblioteca está vinculada al inicio. –

+0

@Jonathan, tienes razón. Cerebro congelado. –

0

Otro pensamiento: ¿Sería extracción (uso ar (1)) la función (s) necesaria de libfoo.so.1, ya sea en un .o o en otro archivo .so, y luego se une contra la que el extracto de ayuda? Supongo que la referencia a libbar.so.1 está en una función libfoo que no se llama (ni siquiera indirectamente) desde su programa.

+1

En realidad, las bibliotecas dinámicas no son 'ar'chives. –

0

¿Cuál es el requisito real aquí? Simplemente vincular una biblioteca no hace mucho, y generalmente es benigno. ¿Te falta la biblioteca? Simplemente cree una biblioteca de código auxiliar del mismo nombre. ¿Desea controlar o adelantarse al uso de símbolos en la biblioteca? Póngalos en otra biblioteca (¡con las etiquetas de versión correctas!) Y LD_PRELOAD.

Supongo que la meta-pregunta aquí es que no veo qué valor puede adelantarse a la vinculación de dependencia. Es solo una función de ayuda.

Cuestiones relacionadas