Geri kalanını okumadan önce not: Burada gösterilen kabuk betiğinin kullanımı kesinlikle güvenli değildir ve iyi test edilmiştir. Kendi sorumluluğunuzdadır kullanın!
Bu görevi gerçekleştirmek için bir bash senaryosu yazdım. Kütüphanenizin lib1 olduğunu ve bazı sembolleri dahil etmeniz gereken lib2 olduğunu varsayalım. Komut dosyası şimdi bir döngüde çalışır ve burada lib1'den hangi tanımsız sembollerin lib2'de bulunabileceğini kontrol eder. Daha sonra, karşılık gelen nesne dosyalarını lib2'den ayıklar, ar
onları yeniden adlandırır ve lib1'e koyar. Şimdi daha eksik semboller olabilir, çünkü lib2'den eklediğiniz şeylerin henüz eklemediğimiz lib2'den başka şeylere ihtiyacı vardır, bu nedenle döngü tekrar çalıştırılmalıdır. Döngünün bazı geçişlerinden sonra artık değişiklik yoksa, yani lib1'e lib1'e hiçbir nesne dosyası eklenmezse, döngü durabilir.
Not, dahil sembolleri hala tarafından tanımsız olarak rapor nm
, bu yüzden döngü durdurulabilir olup olmadığını belirlemek için lib1, kendilerine eklenmiş olan nesne dosyalarını izliyorum.
#! /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
Bu komut dosyasını adlandırdım libcomp
, böylece daha sonra çağırabilirsiniz
./libcomp libmylib.a libwhatever.a
libwhatever, semboller eklemek istediğiniz yerdir. Ancak, her şeyi önce ayrı bir dizine kopyalamanın en güvenli yol olduğunu düşünüyorum. Senaryomuma o kadar çok güvenmezdim (ancak benim için çalıştı; libgsl.a'yı sayısal kütüphaneme ekleyebilir ve -lgsl derleyici anahtarını bırakabilirim).