Domanda

Ho un piccolo pezzo di codice che dipende da molte librerie statiche (a_1-a_n). Mi piacerebbe impacchettare quel codice in una libreria statica e renderlo disponibile ad altre persone.

La mia libreria statica, consente di chiamare X, compila bene.

Ho creato un semplice programma di esempio che utilizza una funzione da X, ma quando provo a collegarlo a X, ottengo molti errori sui simboli mancante da librerie A_1 - a_n

.

C'è un modo che io possa creare una nuova libreria statica, Y che contiene X e tutte le funzionalità necessarie per X (selezionato i bit da a_1 - a_n), in modo che possa distribuire solo Y per le persone a collegare i loro programmi per ?


UPDATE:

Ho guardato tutto solo dumping ar e fare una mega-lib, tuttavia, che finisce tra cui un sacco di simboli che non sono necessari (tutti i file .o sono circa 700 MB, tuttavia, un eseguibile collegato in modo statico è di 7 MB). C'è un bel modo per includere solo ciò che è realmente necessario?


Questo sembra strettamente legato al Come combinare diversi C / C ++ le librerie in uno? .

È stato utile?

Soluzione

Le librerie statiche sono prive di collegamenti con le altre librerie statiche. L'unico modo per farlo è quello di utilizzare il vostro strumento di bibliotecario / archiviazione (ad esempio ar su Linux) per creare un unico nuovo libreria statica concatenando i più librerie.

Modifica In risposta alla sua aggiornamento, l'unico modo che conosco per selezionare solo i simboli che sono necessari è quello di creare manualmente la libreria dal sottoinsieme dei file .o che li contengono. Questo è difficile, che richiede tempo e soggetto a errori. Io non sono a conoscenza di strumenti per aiutare fare questo (per non dire che non esistono), ma vorrei fare un progetto molto interessante per la produzione di uno.

Altri suggerimenti

Se si utilizza Visual Studio allora sì, si può fare questo.

Lo strumento di costruttore di libreria che viene fornito con Visual Studio consente di unire le librerie insieme sulla riga di comando. Io non conosco alcun modo per fare questo nel editor visuale però.

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

In Linux o MinGW, con GNU toolchain:

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

se non eliminare liba.a e libb.a, è possibile effettuare un "archivio sottile":

ar crsT libab.a liba.a libb.a

In Windows, con MSVC toolchain:

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

Una libreria statica è solo un archivio di file oggetto .o. estrarli con ar (supponendo Unix) e comprimerle di nuovo in una grande libreria.

In alternativa al Link Library Dependencies nelle proprietà del progetto c'è un altro modo per collegare le librerie in Visual Studio.

  1. Aprire il progetto della biblioteca (X) che si desidera essere combinato con altre biblioteche.
  2. Aggiungere le altre librerie che si desidera in combinazione con X (tasto destro, Add Existing Item...).
  3. Vai alle loro proprietà e assicurarsi Item Type è Library

Ciò comprende le altre biblioteche in X come se è stato eseguito

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

Nota prima di leggere il resto: Lo script di shell mostrato qui non è certamente sicuro da usare e ben collaudato. Usare a proprio rischio e pericolo!

ho scritto uno script bash per realizzare questo compito. Supponiamo che il vostro libreria è lib1 e quello è necessario includere alcuni simboli da è lib2. Lo script funziona ora in un ciclo, in cui primi controlli che i simboli non definiti da lib1 possono essere trovati in lib2. E poi estrae i file oggetto corrispondente da lib2 con ar, rinomina loro un po ', e le mette in lib1. Ora ci possono essere più simboli mancanti, perché la roba è stato incluso dal lib2 ha bisogno di altre cose da lib2, che non abbiamo ancora inserito, in modo che il ciclo deve funzionare di nuovo. Se dopo alcuni passaggi del ciclo non ci sono più cambiamenti, vale a dire nessun file oggetto da lib2 aggiunti lib1, il ciclo può fermare.

Si noti che i simboli inclusi sono ancora segnalati come non definito da nm, quindi sono tenere traccia dei file oggetto, che sono stati aggiunti a lib1, se stessi, al fine di determinare se il ciclo può essere fermato.

#! /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

ho chiamato che libcomp sceneggiatura, così si può chiamare, allora per esempio con

./libcomp libmylib.a libwhatever.a

dove libwhatever è dove si desidera includere simboli. Tuttavia, penso che sia più sicuro per copiare tutto in una directory separata prima. Non mi fiderei mio script così tanto (tuttavia, ha funzionato per me, ho potuto includere libgsl.a nella mia libreria numerici con quello e lasciare fuori che l'interruttore del compilatore -lgsl).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top