หมายเหตุก่อนอ่านส่วนที่เหลือ: เชลล์สคริปต์ที่แสดงที่นี่ไม่ปลอดภัยที่จะใช้และผ่านการทดสอบอย่างดี ใช้ความเสี่ยงของคุณเอง!
ฉันเขียนสคริปต์ทุบตีเพื่อทำงานนั้นให้สำเร็จ สมมติว่าไลบรารีของคุณคือ 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
ที่ใดก็ตามที่คุณต้องการรวมสัญลักษณ์จาก อย่างไรก็ตามฉันคิดว่าการคัดลอกทุกอย่างลงในไดเร็กทอรีแยกต่างหากจะปลอดภัยที่สุดก่อน ฉันจะไม่เชื่อถือสคริปต์ของฉันมากนัก (อย่างไรก็ตามมันใช้ได้ผลสำหรับฉันฉันสามารถรวม libgsl.a ไว้ในไลบรารีตัวเลขของฉันด้วยสิ่งนั้นและทิ้งสวิตช์คอมไพเลอร์ -lgsl นั้นไว้)