나머지를 읽기 전에 참고하십시오 : 여기에 표시된 쉘 스크립트는 사용하기에 안전하지 않으며 테스트를 거쳤습니다. 자신의 책임하에 사용하십시오!
해당 작업을 수행하기 위해 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 컴파일러 스위치를 생략 할 수 있습니다).