como crear librerias dinamicas en java
Restricción de símbolos en una biblioteca estática de Linux (4)
Las bibliotecas estáticas no pueden hacer lo que usted quiere para el código compilado con GCC 3.xo 4.x.
Si puede usar objetos compartidos (bibliotecas), el enlazador GNU hace lo que necesita con una característica llamada script de versión. Esto generalmente se usa para proporcionar puntos de entrada específicos de la versión, pero el caso degenerado solo distingue entre símbolos públicos y privados sin ningún control de versiones. Se especifica un script de versión con la opción de línea de comando --version-script = para ld.
El contenido de un script de versión que hace que los puntos de entrada foo y bar sean públicos y oculta todas las demás interfaces:
{ global: foo; bar; local: *; };
Consulte el documento de ld en: http://sourceware.org/binutils/docs/ld/VERSION.html#VERSION
Soy un gran defensor de las bibliotecas compartidas, y esta capacidad de limitar la visibilidad de los globales es una de sus grandes virtudes.
Un documento que proporciona más de las ventajas de los objetos compartidos, pero escrito para Solaris (por Greg Nakhimovsky de memoria feliz), está en http://developers.sun.com/solaris/articles/linker_mapfiles.html
Espero que esto ayude.
Estoy buscando formas de restringir el número de símbolos C exportados a una biblioteca estática de Linux (archivo). Me gustaría limitar estos a solo aquellos símbolos que son parte de la API oficial de la biblioteca. Ya uso ''estático'' para declarar la mayoría de las funciones como estáticas, pero esto las restringe al alcance del archivo. Estoy buscando una forma de restringir el alcance a la biblioteca.
Puedo hacer esto para bibliotecas compartidas utilizando las técnicas de Cómo escribir bibliotecas compartidas de Ulrich Drepper, pero no puedo aplicar estas técnicas a archivos estáticos. En su anterior trabajo Buenas prácticas en diseño de bibliotecas , escribe:
La única posibilidad es combinar todos los archivos de objeto que necesitan ciertos recursos internos en uno usando ''ld -r'' y luego restringir los símbolos que se exportan mediante este archivo de objeto combinado. El enlazador GNU tiene opciones para hacer esto.
¿Alguien podría ayudarme a descubrir cuáles podrían ser estas opciones? He tenido cierto éxito con ''strip -w -K prefix_ *'', pero esto se siente brutal. Idealmente, me gustaría una solución que funcione tanto con GCC 3 como con la 4.
¡Gracias!
Los méritos de esta respuesta dependerán de por qué está utilizando bibliotecas estáticas. Si es para permitir que el enlazador deje caer objetos no utilizados más tarde, entonces tengo poco que agregar. Si es por motivos de organización, lo que minimiza el número de objetos que se deben pasar para vincular aplicaciones, esta extensión de la respuesta del ruso empleado puede ser útil.
En tiempo de compilación, la visibilidad de todos los símbolos dentro de una unidad de compilación se puede establecer usando:
-fvisibility=hidden
-fvisibility=default
Esto implica que se puede compilar un único archivo "interface.c" con visibilidad predeterminada y una mayor cantidad de archivos de implementación con visibilidad oculta, sin anotar la fuente. Un enlace reubicable producirá un único archivo de objeto donde las funciones que no son api están "ocultas":
ld -r interface.o implementation0.o implementation1.o -o relocatable.o
El archivo de objeto combinado ahora puede estar sujeto a objcopy:
objcopy --localize-hidden relocatable.o mylibrary.o
Por lo tanto, tenemos un solo objeto de archivo "biblioteca" o "módulo" que expone solo la API deseada.
La estrategia anterior interactúa moderadamente bien con la optimización del tiempo de enlace. Compila con -flto y realiza el enlace reubicable pasando -r al enlazador a través del compilador:
gcc -fuse-linker-plugin -flto -nostdlib -Wl,-r {objects} -o relocatable.o
Use objcopy para localizar los símbolos ocultos como antes, luego llame al enlazador por última vez para quitar los símbolos locales y cualquier otro código muerto que pueda encontrar en el objeto post-lto. Tristemente, es poco probable que reubicable.o haya retenido información lto relacionada:
gcc -nostdlib -Wl,-r,--discard-all relocatable.o mylibrary.o
Las implementaciones actuales de lto parecen estar activas durante la etapa de enlace reubicable. Con lto on, los símbolos ocultos => locales fueron eliminados por el enlace reubicable final. Sin lto, los símbolos ocultos => locales sobrevivieron al último enlace reubicable.
Es probable que las implementaciones futuras de lto conserven los metadatos requeridos a través de la etapa de enlace reubicable, pero en la actualidad el resultado del enlace reubicable parece ser un simple archivo de objeto antiguo.
No creo que GNU ld tenga tales opciones; Ulrich debe haber significado objcopy
, que tiene muchas de estas opciones: --localize-hidden
, --localize-symbol=symbolname
, --localize-symbols=filename
.
El --localize-hidden
en particular le permite a uno tener un control muy fino sobre qué símbolos están expuestos. Considerar:
int foo() { return 42; }
int __attribute__((visibility("hidden"))) bar() { return 24; }
gcc -c foo.c
nm foo.o
000000000000000b T bar
0000000000000000 T foo
objcopy --localize-hidden foo.o bar.o
nm bar.o
000000000000000b t bar
0000000000000000 T foo
Así que bar()
ya no se exporta desde el objeto (aunque todavía está presente y se puede usar para la depuración). También puede eliminar la bar()
junto con objcopy --strip-unneeded
.
Mi forma de hacerlo es marcar todo lo que no se va a exportar con INTERNAL, incluir guardar todos los archivos .h, compilar compilaciones de desarrollo con -DINTERNAL = y compilar compilaciones de lanzamiento con un solo archivo .c que incluya todos los demás archivos .c de la biblioteca. con -DINTERNAL = estático.