Pregunta

Tengo una pequeña pieza de código que depende de muchas bibliotecas estáticas (a_1-a_n). Me gustaría empaquetar ese código en una biblioteca estática y ponerlo a disposición de otras personas.

Mi biblioteca estática, permite llamarlo X, compila bien.

He creado un programa de ejemplo simple que utiliza una función de X, pero cuando intento de vincularlo a X, consigo muchos errores por perder símbolos de las bibliotecas a_1 -. A_n

¿Hay una manera que puedo crear una nueva biblioteca estática, Y que contiene X y toda la funcionalidad necesaria por X (seleccionado trozos de a_1 - a_n), de modo que pueda distribuir acaba Y para las personas a vincular sus programas de ?


ACTUALIZACIÓN:

He mirado simplemente vertido todo con ar y haciendo un mega-lib, sin embargo, que termina incluyendo una gran cantidad de símbolos que no son necesarios (todos los archivos .o son alrededor de 700 MB, sin embargo, un ejecutable enlazado estáticamente es 7 MB). ¿Hay una buena manera de incluir sólo lo que realmente se necesita?


Esto se ve muy relacionada con Cómo combinar varias bibliotecas de C / C ++ en una sola? .

¿Fue útil?

Solución

Las librerías estáticas no se vinculan con otras bibliotecas estáticas. La única manera de hacer esto es usar su / bibliotecario archivador herramienta (por ejemplo, ar en Linux) para crear una sola biblioteca estática nueva mediante la concatenación de las múltiples bibliotecas.

Editar En respuesta a su actualización, la única forma que conozco para seleccionar sólo los símbolos que se requieren es crear manualmente la biblioteca del subconjunto de los archivos .o que los contienen. Esto es difícil, lento y propenso a errores. No estoy al tanto de ninguna herramienta para ayudar a hacer esto (por no decir que no existen), pero sería hacer un proyecto bastante interesante para un solo producto.

Otros consejos

Si está utilizando Visual Studio entonces sí, se puede hacer esto.

La herramienta de creación de la biblioteca que viene con Visual Studio le permite unirse a las bibliotecas juntos en la línea de comandos. No sé de ninguna manera de hacer esto en el editor visual sin embargo.

lib.exe /OUT:compositelib.lib  lib1.lib lib2.lib

En Linux o MingW, con herramientas GNU:

ar -M <<EOM
    CREATE libab.a
    ADDLIB liba.a
    ADDLIB libb.a
    SAVE
    END
EOM
ranlib libab.a

Por si lo hace liba.a no borrar y libb.a, se puede hacer un "archivo fina":

ar crsT libab.a liba.a libb.a

En Windows, la cadena de herramientas MSVC:

lib.exe /OUT:libab.lib liba.lib libb.lib

Una biblioteca estática es simplemente un archivo de los archivos objeto .o. Extraerlos con ar (suponiendo Unix) y el paquete de nuevo en una biblioteca grande.

Como alternativa a Link Library Dependencies en las propiedades del proyecto hay otra forma de librerías de enlace en Visual Studio.

  1. Abra el proyecto de la biblioteca (X) que desea combinar con otras bibliotecas.
  2. Añadir el resto de bibliotecas que desea que se combina con X (clic derecho, Add Existing Item...).
  3. Vaya a sus propiedades y asegúrese Item Type es Library

Esto incluirá las otras bibliotecas de X como si ejecutó

lib /out:X.lib X.lib other1.lib other2.lib

Nota Antes de leer el resto: El script se muestra aquí no es ciertamente seguro de usar y bien probado. Uso en su propio riesgo!

Me escribió un script bash para realizar esa tarea. Suponga que su biblioteca es LIB1 y el que usted necesita incluir algunos símbolos de LIB2 es. La secuencia de comandos ahora se ejecuta en un bucle, donde primero comprueba que undefined símbolos de lib1 se pueden encontrar en lib2. A continuación, extrae los archivos de objetos correspondientes a LIB2 con ar, les cambia el nombre un poco, y los pone en LIB1. Ahora puede haber más símbolos que faltan, porque las cosas que abarcaba desde LIB2 necesita otras cosas de LIB2, que no hemos incluido, sin embargo, por lo que el bucle tiene que ejecutar de nuevo. Si después de algunas pasadas del bucle no hay cambios más, es decir, no hay archivos objeto desde lib2 añadido a lib1, el bucle puede parar.

Tenga en cuenta, que los símbolos incluidos todavía son reportados como no definidos por nm, así que estoy un seguimiento de los archivos de objetos, que se agregaron a LIB1, ellos mismos, con el fin de determinar si el bucle se puede detener.

#! /bin/bash

lib1="$1"
lib2="$2"

if [ ! -e $lib1.backup ]; then
    echo backing up
    cp $lib1 $lib1.backup
fi

remove_later=""

new_tmp_file() {
    file=$(mktemp)
    remove_later="$remove_later $file"
    eval $1=$file
}
remove_tmp_files() {
    rm $remove_later
}
trap remove_tmp_files EXIT

find_symbols() {
    nm $1 $2 | cut -c20- | sort | uniq 
}

new_tmp_file lib2symbols
new_tmp_file currsymbols

nm $lib2 -s --defined-only > $lib2symbols

prefix="xyz_import_"
pass=0
while true; do
    ((pass++))
    echo "Starting pass #$pass"
    curr=$lib1
    find_symbols $curr "--undefined-only" > $currsymbols
    changed=0
    for sym in $(cat $currsymbols); do
        for obj in $(egrep "^$sym in .*\.o" $lib2symbols | cut -d" " -f3); do
            echo "  Found $sym in $obj."
            if [ -e "$prefix$obj" ]; then continue; fi
            echo "    -> Adding $obj to $lib1"
            ar x $lib2 $obj
            mv $obj "$prefix$obj"
            ar -r -s $lib1 "$prefix$obj"
            remove_later="$remove_later $prefix$obj"
            ((changed=changed+1))
        done
    done
    echo "Found $changed changes in pass #$pass"

    if [[ $changed == 0 ]]; then break; fi
done

Me nombrado libcomp que la escritura, por lo que se le puede llamar a continuación, por ejemplo, con

./libcomp libmylib.a libwhatever.a

donde libwhatever es la que desea incluir símbolos de. Sin embargo, creo que es más seguro para copiar todo en un directorio independiente en primer lugar. No confiaría en mi guión tanto (sin embargo, que trabajó para mí, pude incluir libgsl.a en mi biblioteca numéricos con eso y dejar de lado que el modificador de compilador -lgsl).

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