残りを読む前に注意してください:ここに示されているシェルスクリプトは確かに安全に使用できず、十分にテストされています。自己責任!
そのタスクを実行するためにbashスクリプトを作成しました。ライブラリがlib1であり、いくつかのシンボルを含める必要があるのがlib2であるとします。スクリプトはループで実行され、lib1の未定義のシンボルがlib2にあるかどうかを最初にチェックします。次に、対応するオブジェクトファイルをlib2から抽出しar
、名前を少し変更して、lib1に配置します。lib2からインクルードしたものには、まだ含まれていないlib2からの他のものが必要であるため、欠落しているシンボルがさらにある可能性があります。そのため、ループを再度実行する必要があります。ループを何度か通過した後、変更がなくなった場合、つまりlib2のオブジェクトファイルがlib1に追加されていない場合、ループを停止できます。
含まれているシンボルはまだによって未定義として報告されるnm
ため、ループを停止できるかどうかを判断するために、lib1自体に追加されたオブジェクトファイルを追跡していることに注意してください。
#! /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
私はそのスクリプトに名前を付けたlibcomp
ので、たとえば次のように呼び出すことができます
./libcomp libmylib.a libwhatever.a
ここで、libwhateverは、シンボルを含める場所です。ただし、最初にすべてを別のディレクトリにコピーするのが最も安全だと思います。私は自分のスクリプトをあまり信用しませんでした(ただし、それは私にとってはうまくいきました。それを使ってlibgsl.aを数値ライブラリに含め、-lgslコンパイラスイッチを省略できます)。