Beachten Sie, bevor Sie den Rest lesen: Das hier gezeigte Shell-Skript ist sicherlich nicht sicher zu verwenden und gut getestet. Benutzung auf eigene Gefahr!
Ich habe ein Bash-Skript geschrieben, um diese Aufgabe zu erfüllen. Angenommen, Ihre Bibliothek ist lib1 und diejenige, aus der Sie einige Symbole einfügen müssen, ist lib2. Das Skript wird jetzt in einer Schleife ausgeführt, in der zunächst überprüft wird, welche undefinierten Symbole aus lib1 in lib2 gefunden werden können. Anschließend extrahiert es die entsprechenden Objektdateien aus lib2 mit ar
, benennt sie ein wenig um und fügt sie in lib1 ein. Jetzt fehlen möglicherweise mehr Symbole, da die Inhalte, die Sie aus lib2 hinzugefügt haben, andere Inhalte aus lib2 benötigen, die wir noch nicht aufgenommen haben. Daher muss die Schleife erneut ausgeführt werden. Wenn nach einigen Durchläufen der Schleife keine Änderungen mehr vorgenommen werden, dh keine Objektdateien von lib2 zu lib1 hinzugefügt wurden, kann die Schleife gestoppt werden.
Beachten Sie, dass die enthaltenen Symbole immer noch als undefiniert von gemeldet werden. nm
Daher verfolge ich die Objektdateien, die lib1 selbst hinzugefügt wurden, um festzustellen, ob die Schleife gestoppt werden kann.
#! /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
Ich habe dieses Skript benannt libcomp
, damit Sie es dann zB mit aufrufen können
./libcomp libmylib.a libwhatever.a
wo libwhatever ist, wo Sie Symbole einfügen möchten. Ich denke jedoch, dass es am sichersten ist, alles zuerst in ein separates Verzeichnis zu kopieren. Ich würde meinem Skript nicht so sehr vertrauen (es hat jedoch bei mir funktioniert; ich könnte libgsl.a damit in meine numerische Bibliothek aufnehmen und diesen -lgsl-Compiler-Schalter weglassen).