A noter avant de lire le reste : Le shell script présenté ici n'est certainement pas sûr à utiliser et bien testé. Utilisez-le à vos risques et périls !
J'ai écrit un bash script pour accomplir cette tâche. Supposons que votre bibliothèque soit lib1 et que celle dont vous devez inclure certains symboles soit lib2. Le script tourne maintenant dans une boucle, où il vérifie d'abord quels symboles non définis de lib1 peuvent être trouvés dans lib2. Il extrait ensuite les fichiers objets correspondants de la lib2 avec ar
les renomme un peu, et les place dans lib1. Maintenant, il peut y avoir d'autres symboles manquants, parce que les éléments de la lib2 que vous avez inclus ont besoin d'autres éléments de la lib2, que nous n'avons pas encore inclus, donc la boucle doit être exécutée à nouveau. Si après quelques passages de la boucle, il n'y a plus de changements, c'est-à-dire aucun fichier objet de la lib2 ajouté à la lib1, la boucle peut s'arrêter.
Notez, que les symboles inclus sont toujours signalés comme non définis par nm
Je suis donc en train de suivre les fichiers objets qui ont été ajoutés à la lib1, afin de déterminer si la boucle peut être arrêtée.
#! /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
J'ai nommé ce script libcomp
vous pouvez donc l'appeler par exemple avec
./libcomp libmylib.a libwhatever.a
où libwhatever est l'endroit d'où vous voulez inclure les symboles. Cependant, je pense qu'il est plus sûr de tout copier d'abord dans un répertoire séparé. Je ne ferais pas tellement confiance à mon script (cependant, cela a fonctionné pour moi ; je pouvais inclure libgsl.a dans ma bibliothèque numérique avec cela et laisser de côté le commutateur de compilateur -lgsl).