development

정적 라이브러리를 다른 정적 라이브러리에 링크

big-blog 2020. 7. 12. 08:58
반응형

정적 라이브러리를 다른 정적 라이브러리에 링크


많은 정적 라이브러리 (a_1-a_n)에 의존하는 작은 코드 조각이 있습니다. 해당 코드를 정적 라이브러리에 패키지하고 다른 사람들이 사용할 수 있도록 만들고 싶습니다.

내 정적 라이브러리는 X라고하고 잘 컴파일합니다.

X의 함수를 사용하는 간단한 샘플 프로그램을 만들었지 만 X에 연결하려고하면 라이브러리 a_1-a_n에서 누락 된 기호에 대한 많은 오류가 발생합니다.

X를 포함하는 새로운 정적 라이브러리 인 Y와 X에 필요한 모든 기능 (a_1-a_n에서 선택된 비트)을 만들어 사람들이 자신의 프로그램을 연결할 수 있도록 Y 만 배포 할 수있는 방법이 있습니까?


최신 정보:

나는 ar로 모든 것을 버리고 하나의 mega-lib를 만드는 것을 보았습니다 . 그러나 필요하지 않은 많은 기호를 포함합니다 (모든 .o 파일은 약 700MB이지만 정적으로 링크 된 실행 파일은 7입니다) MB). 실제로 필요한 것만 포함시키는 좋은 방법이 있습니까?


이것은 여러 C / C ++ 라이브러리를 하나로 결합하는 방법 과 밀접한 관련이 있습니다 . .


정적 라이브러리는 다른 정적 라이브러리와 연결되지 않습니다. 이를 수행하는 유일한 방법은 라이브러리 / 리버 도구 (예 : Linux의 경우 ar )를 사용하여 여러 라이브러리를 연결하여 하나의 새 정적 라이브러리를 작성하는 것입니다.

편집 : 업데이트에 응답하여 필요한 기호 만 선택하는 유일한 방법은 심볼이 포함 된 .o 파일의 하위 집합에서 라이브러리를 수동으로 만드는 것입니다. 어렵고 시간이 많이 걸리며 오류가 발생하기 쉽습니다. 나는이 작업을 수행하는 데 도움이되는 도구를 알지 못하지만 (존재하지 않는다는 말은 아니지만) 제작하는 데 매우 흥미로운 프로젝트가 될 것입니다.


Visual Studio를 사용하고 있다면 가능합니다.

Visual Studio와 함께 제공되는 라이브러리 작성 도구를 사용하면 명령 줄에서 라이브러리를 함께 연결할 수 있습니다. 그래도 비주얼 편집기 에서이 작업을 수행하는 방법을 모르겠습니다.

lib.exe /OUT:compositelib.lib  lib1.lib lib2.lib

GNU 툴체인이있는 Linux 또는 MingW :

ar -M <<EOM
    CREATE libab.a
    ADDLIB liba.a
    ADDLIB libb.a
    SAVE
    END
EOM
ranlib libab.a

삭제하지 않는 경우 중 liba.alibb.a, 당신은 "얇은 아카이브를"할 수 있습니다 :

ar crsT libab.a liba.a libb.a

Windows에서 MSVC 툴체인 사용 :

lib.exe /OUT:libab.lib liba.lib libb.lib

정적 라이브러리는 .o객체 파일 의 아카이브 일뿐 입니다. ar(유닉스 가정)으로 추출하고 하나의 큰 라이브러리에 다시 넣습니다.


Link Library Dependencies프로젝트 속성 대신 Visual Studio에서 라이브러리를 연결하는 다른 방법이 있습니다.

  1. 다른 라이브러리와 결합하려는 라이브러리 (X)의 프로젝트를여십시오.
  2. X와 결합하려는 다른 라이브러리를 추가하십시오 (오른쪽 클릭, Add Existing Item...).
  3. 자신의 특성에 가서 확인 Item Type하다Library

이것은 마치 마치 마치 X의 다른 라이브러리를 포함합니다.

lib /out:X.lib X.lib other1.lib other2.lib

나머지를 읽기 전에 참고하십시오 : 여기에 표시된 쉘 스크립트는 사용하기에 안전하지 않으며 테스트를 거쳤습니다. 자신의 책임하에 사용하십시오!

해당 작업을 수행하기 위해 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 컴파일러 스위치를 생략 할 수 있습니다).

참고 URL : https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries

반응형