Pregunta

En mi proyecto hay una dependencia de una biblioteca estática (llamado simplemente libsomething de ahora en adelante) de una tercera parte. Recientemente, se ha convertido en libsomething disponible en otra versión. Mi tarea es proporcionar el software con soporte para la vieja y la nueva versión. Sólo una versión de libsomething se utiliza en tiempo de ejecución en un momento dado, pero la versión que se trata debe ser configurable entre ejecuciones del programa.

Estoy utilizando MSVC2005 en WinXP, un objetivo secundario es llegar a ser preparado para cambiar a Linux y GCC.

Dado que ambas versiones de libsomething están utilizando los mismos símbolos, que une a los dos en mi ejecutable está fuera de la cuestión de los símbolos de ambas versiones se van a chocar en todo durante el enlace.

Mientras que podría crear dos archivos ejecutables (uno unen en contra de la versión antigua, la otra utilizando la nueva versión), no puedo poner en práctica una decisión sobre qué ejecutable a llamar en el entorno de despliegue final (razones de herencia).

Se me ocurrió la idea de crear un envoltorio librería dinámica para cada versión de libsomething y vincularlos en tiempo de ejecución en función de algún archivo de configuración. Con MSCV, esto significaría que va por el camino de la utilización de LoadLibrary(), GetProcAddress(), etc., mientras que en Linux que tendría que usar dlopen() y dlsym().

Yo entiendo que el uso de libtool (es decir, libtldl) está terminando esta plataforma dependencia para el uso de bibliotecas compartidas. Es este un camino adecuado a seguir? ¿Hay mejor (o, al menos, diferentes formas)? Hacer alternativas para existir como libtldl de código abierto?

¿Fue útil?

Solución

Ha habido pocos años, pero me gustaría mencionar otra solución para la integridad. En lugar de dlopen manual y dlsym podría generar recibos simples para todas las funciones necesarias y en la primera llamada (o al inicio del programa) decidir qué versión de la biblioteca que se necesita, cargarlo y resolver las direcciones.

Se puede escribir un guión adaptado específicamente para su proyecto o usar Implib.so herramienta:

# This will generate mylib.so.init.c and mylib.so.tramp.S
# which implement stubs. These need to be linked to your
# executable.
$ implib-gen.py mylib.so

Implib.so es sólo Linux atm, pero debería ser fácilmente adaptable a Windows.

Otros consejos

Sé que dijo que no podía utilizar dos ejecutables debido a la decisión de que desea ejecutar, pero podría no exec ida y vuelta entre los ejecutables en función de los que se selecciona la versión en la configuración?

En Linux que sería más fácil para que usted enlace a la biblioteca y el uso compartido de enlaces simbólicos a la versión correcta -. OMI es mucho más fácil de utilizar dlopen() + dlsym()

bibliotecas Así se crearía compartidos para las viejas y las nuevas versiones de su biblioteca:

g++ -shared -o libshared.so.1.1 -Wl,-soname=libshared.so.1 -L. -Wl,--whole-archive libstatic.a.old -Wl,-no-whole-archive

y

g++ -shared -o libshared.so.1.2 -Wl,-soname=libshared.so.1 -L. -Wl,--whole-archive libstatic.a.new -Wl,-no-whole-archive

Crea los enlaces simbólicos:

ln -s libshared.so.1.1 libshared.so.1
ln -s libshared.so.1 libshared.so

Construir su aplicación, vinculándola a la antigua versión de la biblioteca. Supongo que ambas versiones son compatibles binaria (ABI no roto), pero el nuevo podría tener algunos nuevos símbolos.

g++ -o myapp myapp.cpp -L. -lshared

Desde SONAME de biblioteca compartida es libshared.so.1 su aplicación dependerá de él y buscará libshared.so.1 en caminos de /etc/ld.so.conf o LD_LIBRARY_PATH

Antes de ejecutar la aplicación puede establecer el enlace simbólico libshared.so.1 a punto de libshared.so.1.2 o libshared.so.1.1.


Poca información sobre las opciones del vinculador utiliza aquí:

  

- todo-
Archivo              Para cada archivo mencionado en la línea de comandos después de la opción --whole-archivo, incluir todos los archivos objeto en el archivo en el              enlace, en lugar de buscar el archivo para los archivos de objetos requeridos. Esto se utiliza normalmente para convertir un archivo de almacenamiento en una compartida              biblioteca, obligando a todos los objetos que se incluirán en la biblioteca compartida resultante. Esta opción se puede usar más de una vez.   
             Dos notas cuando se utiliza esta opción de gcc: En primer lugar, GCC no saber acerca de esta opción, así que hay que utilizar -Wl, -whole-archivo.              En segundo lugar, no se olvide de utilizar -Wl, -no-toda-archivo tras su lista de archivos, porque gcc agregará su propia lista de archivos a su              enlace y puede que no quiera esta bandera para afectar esos también.

     

-soname = nombre
             Cuando se crea un objeto compartido ELF, defina el campo DT_SONAME interno para el nombre especificado. Cuando un ejecutable está vinculada con una              objeto compartido que tiene un campo DT_SONAME, entonces cuando el ejecutable se ejecuta el enlazador dinámico intentará cargar el objeto compartido              especificada por el campo DT_SONAME en lugar de la usando el nombre de archivo dado al enlazador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top