gcc에서 공유 라이브러리 함수의 정적 링크


138

gcc에서 공유 라이브러리 함수를 정적으로 링크하려면 어떻게해야합니까?


14
정적으로 연결되었다는 것은 무슨 뜻입니까? .so를 요구하지 않고 실행 파일을 배포 하시겠습니까?
Emiliano

답변:


108

인용하다:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

라이브러리를 연결하려면 정적 버전의 라이브러리가 필요합니다.

공유 라이브러리는 실제로 진입 점이 지정된 특수 형식의 실행 파일입니다 (일부 문제 해결 포함). 정적으로 연결하는 데 필요한 모든 정보가 없습니다.

공유 라이브러리를 정적으로 링크하거나 정적 라이브러리를 동적으로 링크 할 수 없습니다.

플래그 -static는 링커가 공유 라이브러리 (.so) 대신 정적 라이브러리 (.a)를 사용하도록합니다. 그러나 정적 라이브러리가 항상 기본적으로 설치되는 것은 아니므로 정적 라이브러리를 직접 설치해야 할 수도 있습니다.

또 다른 가능한 방법은 statifier 또는 Ermine 을 사용하는 입니다. 두 도구 모두 동적으로 연결된 실행 파일을 입력으로 사용하고 출력으로 모든 공유 라이브러리가 포함 된 자체 포함 된 실행 파일을 생성합니다.


11
정적 라이브러리에는 어떤 정보가있어서 정적으로 링크 될 수 있고 동적 라이브러리에는없는 정보가 있습니까?
kbolino

75

libapplejuice를 정적으로 연결하고 싶지만 liborangejuice와는 연결 하지 않으 려면 다음과 같이 연결할 수 있습니다.

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

유의할 점은있다 - 경우에 liborangejuice사용이 libapplejuice다음 libapplejuice동적으로도 연결됩니다.

liborangejuice정적으로 libapplejuice얻으려면 libapplejuice정적 으로 링크해야합니다 .

그리고 그렇지 않으면 유지 -Wl,-Bdynamic하는 것이 libc좋지 않은 것을 포함하여 모든 것을 정적으로 연결하는 것을 잊지 마십시오.


2
gcc에게 정적으로 연결하는 것을 직접 알려주고, 우회하지 않고 링커와 대화하지 않는 방법이 있습니까?
Elazar Leibovich

1
@ElazarLeibovich 당신은 그런 식으로 정적과 동적의 조합을 얻을 수 없습니다.
Haozhun

@ EugeneBujak : 경고 는 내 시스템에 적용되지 않습니다. 예 : gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libBlibA를 사용 하며 링크되어 있고 libA에ldd 대한 참조를 표시하지 않습니다 . 실행 파일이 제대로 작동합니다. g ++ 4.7.3으로 테스트되었습니다.
기수

직접적인 동적 종속성의 간접적 (중첩 된) 정적 종속성은 동적으로 연결되지 않습니다.
Vinny

binA는 libC.a에 의존하는 libB.so에 의존합니다. 다른 사람들이 이미 언급했듯이 .so는 스스로 실행 파일이므로 공유 객체가 링크되면 정적 라이브러리 종속 항목은 링커에 의해 거의 동일한 방식으로 처리됩니다. 실행 파일이 연결되었습니다. .a 정적 lib에서 가져온 유일한 기호는 .so에서 참조하고 확인되지 않은 기호입니다. 이것은 binA가 libC.a의 어떤 심볼도 참조하지 않고 libB.so의 어느 곳에서도 참조되지 않으면, binA가 libB.so에 링크 되더라도 해당 심볼은 정의되지 않습니다 (링크 할 때 -Wl,-전체 아카이브를 사용하지 않는 한) libB.so).
Vinny

18

공유 라이브러리 (.so)의 .a 파일이 있으면 다음과 같이 객체 파일처럼 전체 경로와 함께 간단히 포함시킬 수 있습니다.

다음과 같이 컴파일하여 main.o를 생성합니다.

gcc -c main.c

그러면 해당 객체 파일을 해당 정적 라이브러리와 연결하고 실행 파일 ( "main")을 만듭니다.

gcc main.o mylibrary.a -o main

또는 단일 명령으로 :

gcc main.c mylibrary.a -o main

또한 절대 또는 상대 경로 일 수 있습니다.

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

예, 이것이 8 살짜리 질문이라는 것을 알고 있지만 공유 객체 라이브러리에 정적으로 링크 할 수 있다는 말을 들었습니다. 이것은 문자 그대로 그것에 대한 자세한 정보를 검색했을 때 가장 큰 인기를 얻었습니다.

실제로 정적 공유 객체 라이브러리를 연결하는 것을 증명하는 것은 불가능합니다 ld( gcc의 링커) - 그것은 불가능하다고 주장 명에 불과 무리에 반대 - 다음 사용 gcc명령을 :

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(물론 당신은 컴파일해야합니다 objectname.o에서 sourcename.c, 당신은 아마뿐만 아니라 자신의 공유 객체 라이브러리를 구성해야합니다. 당신이 경우에 사용 -Wl,--library-path,.하는 LD 때문에 로컬 디렉토리에 라이브러리를 찾을 수 있습니다.)

실제 오류는 다음과 같습니다.

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

희망이 도움이됩니다.


10

조금 늦었지만 ... 나는 몇 년 전에 저축 한 링크를 발견했으며 그것이 당신에게 유용 할 것이라고 생각했습니다.

CDE : 휴대용 Linux 응용 프로그램 자동 생성

http://www.pgbovine.net/cde.html

  • 그냥 프로그램을 다운로드하십시오
  • 이식 할 바이너리 이름을 인수로 전달하여 바이너리를 실행하십시오 (예 : nmap).

    ./cde_2011-08-15_64 비트 nmap

프로그램은 nmap 및 그 종속 항목에 연결된 모든 라이브러리를 읽고 cde-package / 라는 폴더 (현재와 같은 디렉토리)에 모든 라이브러리를 저장합니다 .

  • 마지막으로 모든 시스템에 폴더를 압축하고 이식 가능한 바이너리를 배포 할 수 있습니다.

이식 가능한 프로그램을 시작하려면 cde-package / nmap.cde 에있는 바이너리를 실행해야합니다.

친애하는


2
질문에 대한 답변을 정확하게 제공하지는 않지만 문제에 대한 주목할만한 해결책입니다.
Razong

링크가 지금 죽었을 것 같습니다.
시난

0

gcc에서는 지원되지 않습니다. 사실 이것은 내가 알고있는 기존 컴파일러 / 링커에서 지원되지 않습니다.


4
기존 컴파일러에서 정적 링크를 지원하지 않는 방법을 설명해 주시겠습니까?
jww

5
@noloader, 동적 라이브러리의 정적 링크?
nothrow
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.