আপনি বিশ্রামটি পড়ার আগে দ্রষ্টব্য: এখানে প্রদর্শিত শেল স্ক্রিপ্টটি অবশ্যই ব্যবহার করা নিরাপদ নয় এবং ভালভাবে পরীক্ষা করা হয়েছে। আপনার নিজের ঝুঁকিতে ব্যবহার করুন!
সেই কাজটি সম্পাদনের জন্য আমি বাশ স্ক্রিপ্ট লিখেছিলাম। ধরুন আপনার লাইব্রেরিটি lib1 এবং আপনার যেটি থেকে কিছু চিহ্ন অন্তর্ভুক্ত করা দরকার তা হল lib2। স্ক্রিপ্টটি এখন একটি লুপে চলেছে, যেখানে এটি প্রথমে lib1 থেকে কোন পূর্বনির্ধারিত প্রতীকগুলি lib2 তে পাওয়া যাবে তা পরীক্ষা করে। এরপরে এটি lib2 এর সাথে সম্পর্কিত অবজেক্ট ফাইলগুলি বের করে ar
, তাদের কিছুটা নাম পরিবর্তন করে এবং তাদেরকে lib1 এ রাখে। এখন আরও বেশি নিখোঁজ প্রতীক থাকতে পারে, কারণ আপনি যে লাইব 2 থেকে অন্তর্ভুক্ত করেছেন সেগুলিতে lib2 থেকে অন্য স্টাফের প্রয়োজন আছে, যা আমরা এখনও অন্তর্ভুক্ত করি নি, তাই লুপটি আবার চালানো দরকার। লুপের কিছু পাসের পরে যদি আর কোনও পরিবর্তন হয় না, যেমন lib2 থেকে কোনও অবজেক্ট ফাইল lib1 এ যুক্ত হয় না, লুপটি থামতে পারে।
দ্রষ্টব্য, অন্তর্ভুক্ত চিহ্নগুলি এখনও অপরিবর্তিত হিসাবে রিপোর্ট করা হয়েছে nm
, সুতরাং লুপটি থামানো যায় কিনা তা নির্ধারণ করার জন্য আমি অবজেক্ট ফাইলগুলিতে নজর রাখছি, যেগুলি lib1 এ যুক্ত হয়েছিল themselves
#! /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
যেখানে ইচ্ছামত যেখানে আপনি প্রতীক অন্তর্ভুক্ত করতে চান। যাইহোক, আমি মনে করি প্রথমে পৃথক ডিরেক্টরিতে সমস্ত অনুলিপি করা সবচেয়ে নিরাপদ। আমি আমার স্ক্রিপ্টকে এতটা বিশ্বাস করব না (তবে এটি আমার পক্ষে কাজ করেছে; আমি তার সাথে আমার সংখ্যার লাইব্রেরিতে libgsl.a অন্তর্ভুক্ত করতে পারি এবং সেই -lgsl সংকলক সুইচটি ছেড়ে দিতে পারি)।