2012-03-07 3 views
4

나는 지금까지 문제에 대해 생각 해보지 않았지만 이제는 내 코드에서 많은 의존성을 다루어야하므로 사실을 더 잘 이해할 수 있다고 생각했습니다. 이것을 우분투 amd64와 같은 최신 리눅스 버전으로 제한 할 수 있습니다.C/C++ 정적 라이브러리에 대한 추론

정적 라이브러리에는 동적 라이브러리 참조가 포함되어 있지 않으므로 미정의 기호 은 정적 라이브러리에서 어떻게 해결됩니까? 종속 바이너리는 정의되지 않은 심볼을 동적으로로드 할 수 있습니까? 아니면 컴파일 타임에 다른 정적 라이브러리 또는 객체 파일에서 심볼을 확인해야합니까?

컴파일러는 동적 라이브러리에 대한 링크를 통해 (정적 라이브러리에 따라 응용 프로그램의) 종속성을 해결할 수 있으며, 그렇다면 코드 텍스트를 정적으로 결과 바이너리로 해석하거나 동적 참조가 존재합니까?

예를 들어 정적 라이브러리 Lmalloc에서 libc6.so을 사용하며 응용 프로그램 A에서 사용합니다. LA 모두 동적으로 libc6.so의 malloc을 사용합니까? (A foo.a 파일)

+0

'man gcc'를 실행하면'-static' 플래그가 보입니다. – Kevin

답변

7

정적 라이브러리는 함께 보관 된 개체 파일의 목록 일뿐입니다.

정적 라이브러리에서 정의되지 않은 기호는 어떻게 해결됩니까?

정의되지 않은 기호가 없으므로 해결되지 않았습니다. 심볼은 링키지 단계에서만 정의되지 않은 것으로 간주되며 정적 라이브러리를 만들 때 연결이 이루어지지 않습니다.

정적 라이브러리와 바이너리를 연결할 때 정의되지 않은 기호가있을 수 있습니다. 이 경우 정적 라이브러리는 프로그램의 일부처럼 취급되므로 정적 라이브러리에서 사용되는 심볼에 대한 모든 참조는 빌드하는 프로그램의 범위에서 사용할 수 있어야합니다. 예를 들어, 프로그램 A이 다른 라이브러리 D의 심볼 C을 사용하는 정적 라이브러리 B과 연결되면 A 프로그램은 BD과 연결해야합니다.

는 따라 진 동적으로 정의되지 않은 심볼 네, 할 수

를로드 할 수 있습니다. 그러나 당신이 정말로 게으르고 역동적 인 해결책을 필요로하지 않는다면 그렇게하지 말아야합니다.

또는 기호가 컴파일시에 다른 정적 라이브러리 또는 오브젝트 파일에 의해

개체 파일뿐만 아니라 정적 라이브러리를 해결해야, 어떤 기호를 확인할 수 없습니다. 그것을하는 링커입니다.

컴파일러의 해결은 ...

컴파일러는 종속성을 해결하지 않습니다 수 있습니다. 이것은 링커의 일입니다. 종속성은 연계 시간에 또는 런타임 중에 동적 링커에 의해 해결 될 수 있습니다. 동적 라이브러리에 연결하여 (정적 라이브러리에 를 따라 응용 프로그램의)

종속성 ...

링커가 사용하는 정적 라이브러리를 이해할 수있는 것은있는 문자에 따라 달라집니다 동적 라이브러리에서 링크 할 수 있습니다.

만약 그렇다면 결과 바이너리로 정적으로 해결 된 코드 텍스트 또는 동적 참조가 존재합니까?

공유 라이브러리에 링크하면 해당 프로그램에서 정적으로 사용할 수있는 프로그램이 없습니다. 그것이 공유 라이브러리의 핵심입니다. 단, LTO 만 예외입니다. 당신이 연결하는 정적 라이브러리는 정적 라이브러리의 어떤 것도 동적으로 사용할 수없고, 컴파일되며, 사용되지 않는 심볼은 제거됩니다. 예를 들어

정적 라이브러리 L은 libc6.so에서의 malloc을 사용하며이를 응용 A. 윌 L에 의해 사용될 것이다 및 모두 동적 libc6.so에서의 malloc를 사용합니까? malloc()의 정의는 어떤 이유로 정적 라이브러리와 컴파일러를 컴파일시 사용할 수있었습니다 않는

예, 단지 정적 라이브러리의 코드로 malloc()의 몸을 인라인. 그러나 malloc()으로는 발생하지 않습니다. 다른 기능들로 바꿀 수있었습니다.

+0

매우 포괄적 인 답변, 정말 고마워요. –

+0

@HassanSyed : 안녕하세요. 그리고 정적 연결은 일반적으로 해로운 것으로 생각된다는 것을 기억하십시오 - http://www.akkadia.org/drepper/no_static_linking.html –

+0

네, 그러나 저는 v8/mongodb/boost를 사용하고 있습니다. 그리고 내 애플 리케이션은 v8과 부스트에 의존한다. 그리고 boost와 v8은 정적으로 연결하는 것이 좋습니다. 이것이 몽고 (mongodb)가하는 것입니다. 그래서 나는 내 물건을 만드는 방법을 알아 내려고 노력하고 있습니다. –

1

정적 라이브러리이다 - 실제적 목적 - 아칸소, 아카이버로 포장 오브젝트 파일의 무리 (x.o, y.o, ...).

이 정적 라이브러리는 링크시에 정의되지 않은 참조를 충족시키기 위해 사용됩니다. 동적 라이브러리 (bar.so 파일)를 통해 링크 타임에 만족하지 않는 모든 사항 (여기서 컴파일 시간은 중요하지 않음)은로드시 충족되어야합니다. 당신이 마지막 예에서

, 정적 libary L과 프로그램 A, 모두 (A, L)은 부터, 인라인 mallocs을을 사전로드 사용하지 않는까지, libc6.so에서 같은 malloc에 ​​사용됩니다와 아마도 당신이 언급하지 않은 다른 헤더 파일이나 다른 트릭 일 수도 있습니다.

+0

고맙습니다. L이 특별히 정적 라이브러리임을 명시 해 주셔서 감사합니다. –

+0

오케이. 이것에 대한 나의 견해를 업데이트했다. "** 정적 라이브러리의 코드에서 메모리를 malloc하는 것이 안전할까요? **"라고 대답한다면, 그 대답은 다음과 같을 것이라고 생각합니다 : _ 보통은 예. –

관련 문제