Question

J'ai un petit morceau de code qui dépend de nombreuses bibliothèques statiques (A_1-a_n). Je voudrais empaqueter ce code dans une bibliothèque statique et la rendre accessible à d'autres personnes.

Ma bibliothèque statique, permet de l'appeler X, compile très bien.

J'ai créé un programme simple exemple qui utilise une fonction de X, mais lorsque je tente de le lier à X, je reçois beaucoup d'erreurs sur les symboles manquants dans les bibliothèques A_1 - a_n

.

Est-il possible que je peux créer une nouvelle bibliothèque statique, Y qui contient X et toutes les fonctionnalités requises par X (bits sélectionnés de A_1 - a_n), afin que je puisse distribuer simplement Y pour les personnes de relier leurs programmes ?


Mise à jour:

J'ai regardé le dumping juste tout avec ar et faire cependant, un méga-lib, qui finit par y compris un grand nombre de symboles qui ne sont pas nécessaires (tous les fichiers .o sont environ 700 MB, cependant, un exécutable lié statiquement est de 7 Mo). Y at-il un bon moyen d'inclure uniquement ce qui est réellement nécessaire?


Cela semble étroitement lié à Comment combiner plusieurs C / C ++ bibliothèques en un? .

Était-ce utile?

La solution

Les bibliothèques statiques ne lient pas avec d'autres bibliothèques statiques. La seule façon de le faire est d'utiliser votre bibliothécaire / outil d'archivage (par exemple ar sous Linux) pour créer une seule nouvelle bibliothèque statique par les concaténer plusieurs bibliothèques.

Modifier En réponse à votre mise à jour, la seule façon que je connaisse de ne sélectionner que les symboles qui sont nécessaires est de créer manuellement la bibliothèque à partir du sous-ensemble des fichiers .o qui les contiennent. Cela est difficile, beaucoup de temps et d'erreurs. Je ne suis pas au courant des outils pour aider à faire cela (ne veut pas dire qu'ils n'existent pas), mais il serait tout à fait un projet intéressant pour produire un.

Autres conseils

Si vous utilisez Visual Studio puis oui, vous pouvez le faire.

L'outil de création de bibliothèque qui est livré avec Visual Studio vous permet de joindre les bibliothèques ainsi que sur la ligne de commande. Je ne connais aucune façon de le faire dans l'éditeur visuel bien.

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

Sur Linux ou MinGW, avec GNU toolchain:

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

Si vous ne supprimez pas liba.a et libb.a, vous pouvez faire une « mince archive »:

ar crsT libab.a liba.a libb.a

Sous Windows, avec MSVC toolchain:

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

Une bibliothèque statique est juste une archive de fichiers objet .o. les extraire avec ar (en supposant Unix) et les emballer de nouveau dans une grande bibliothèque.

Alternativement à Link Library Dependencies dans les propriétés du projet, il est une autre façon de relier les bibliothèques dans Visual Studio.

  1. Ouvrez le projet de la bibliothèque (X) que vous voulez être combiné avec d'autres bibliothèques.
  2. Ajoutez les autres bibliothèques que vous voulez avec X (regroupé, clic droit, Add Existing Item...).
  3. Accédez à leurs propriétés et faire Item Type vous est Library

Cela inclut les autres bibliothèques dans X comme si vous exécutiez

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

Note avant de lire le reste: Le script shell montré ici est certainement pas sûr à utiliser et bien testé. A utiliser à vos risques et périls!

J'ai écrit un script bash pour accomplir cette tâche. Supposons que votre bibliothèque est lib1 et celui que vous avez besoin d'inclure des symboles de lib2 est. Le script fonctionne maintenant dans une boucle, où il vérifie d'abord les symboles non définis de lib1 se trouvent dans lib2. Il extrait ensuite les fichiers objets correspondants de lib2 avec ar, les renomme un peu, et les met en lib1. Maintenant, il peut y avoir des symboles plus manquants, parce que les choses que vous avez inclus de lib2 a besoin d'autres choses de lib2, que nous n'avons pas encore inclus, de sorte que la boucle doit fonctionner à nouveau. Si après quelques passages de la boucle, il n'y a pas de changements plus, à savoir aucun fichier objet de lib2 ajoutés à LIB1, la boucle peut arrêter.

Notez que les symboles inclus sont toujours déclarés comme non défini par nm, donc je garder la trace des fichiers objets, qui ont été ajoutés à lib1, eux-mêmes, afin de déterminer si la boucle peut être arrêté.

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

Je nommé que libcomp script, vous pouvez donc l'appeler alors par exemple avec

./libcomp libmylib.a libwhatever.a

où libwhatever est l'endroit où vous voulez inclure des symboles de. Cependant, je pense qu'il est plus sûr de copier tout dans un répertoire distinct en premier. Je ne voudrais pas faire confiance à mon script tellement (cependant, il a travaillé pour moi, je pourrais inclure libgsl.a dans ma bibliothèque numerics avec cela et laisser que le commutateur de compilation -lgsl).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top