공유 라이브러리를 갖는 데에는 두 가지 인수가 있습니다.
- 디스크 공간을 줄이는 데 도움이됩니다.
- 공유 라이브러리가 업데이트되면 이에 따라 모든 바이너리가 업데이트됩니다.
공유 라이브러리에는 주로 한 가지 단점이 있습니다.
- 그들은 의존성 지옥을 소개 할 수있다.
데스크톱 컴퓨터에서 첫 번째 장점은 더 이상 유지되지 않습니다. 요즘 디스크 공간 낭비는 그리 큰 문제가되지 않습니다.
정적 바이너리를 사용하면 더 나은 패키지 관리자를 얻을 수 있습니다. 즉, 종속성 지옥은 과거의 일이 될 것입니다. 프로그램을 추가하는 것은 바이너리를 추가하는 것입니다. 결국 파일을 처리 할 수있는 폴더입니다. 프로그램을 삭제하면이 파일 만 삭제됩니다. 의존성? 지나간.
두 번째 이점은 여전히 유효하지만 데스크톱 컴퓨터에서 정적 바이너리의 이점이 그보다 중요하다고 생각합니다. Go와 같은 새로운 언어조차도 편의 때문에 공유 라이브러리의 장점에도 불구하고 모든 바이너리를 컴파일합니다.
공유 라이브러리의 주요 장점 중 하나는 더 이상 큰 문제가 아니기 때문에 C 정적 라이브러리가 여전히 눈에 띄지 않습니까? 그렇다면 왜 그렇습니까?
답변
귀하의 질문의 전제가 잘못되었습니다. 눈살을 찌푸리는 것은 그 뒤에 기초를 이해하지 못하는 교리와 절대에 충실합니다 (Cargo Cult Programming?).
연결된 SO 답변 은 매우 흥미로운 주제입니다-질문은 -static 옵션으로 컴파일이 작동하지 않는 이유에 관한 것입니다. 링크 된 답변은 정적 링크를 사용하지 않는 것에 대한 열망에 지나지 않습니다. 왜 나쁜지에 대해 논의하지 않고 OP는 동적 링크를 사용합니다. 불행히도 정답으로 표시됩니다 (다음 답변은 두 배의 투표권을 가지며 OP 질문에 대한 정답입니다). 정답은 있지만 교의 적 의견 사이에 깊이 숨겨져 있기 때문입니다.
실제 문제는 정적 링크와 동적 링크의 장단점이 무엇이며 언제 다른 링크보다 선호 되는가입니다.
답변
개발자의 관점에서 동적 링크는 종종 컴파일 / 링크 / 테스트 루프 속도를 크게 높일 수 있습니다.
패키지 관리 관점에서 libGL을 예로들 수 있습니다. 패키지 관리자에서 사용할 수있는 대략 12 가지의 구현이 있으며 일부는 특정 그래픽 카드를 대상으로합니다. 동적으로 연결되어 있지 않다면 libGL과 연결되는 각 프로그램의 12 가지 버전이 있어야합니다. 그렇지 않으면 함수 호출만큼 효율적이지 않은 추가 추상화 계층을 고안해야합니다.
Qt와 같은 인기있는 라이브러리의 보안 문제를 생각해보십시오. 동적 연결을 사용하면 Qt에 연결된 모든 단일 패키지를 식별, 재 컴파일 및 배포하는 대신 해당 패키지 하나만 업데이트 할 수 있습니다.
정적 링크는 독립적으로 배포 된 폐쇄 형 소스 응용 프로그램에서 이점을 가질 수 있지만 오픈 소스 패키지 관리에서는 도움이되는 것보다 더 많은 문제가 있습니다.
답변
공유 라이브러리는 기본적으로 Linux 배포판 관리자가 선호하는 이유 # 2입니다. 예를 들어, 누군가 zlib에서 보안 버그를 발견하면 zlib 를 사용하는 모든 프로그램 중 하나를 다시 컴파일 할 필요가 없다는 점은 매우 중요 합니다. 다시 컴파일하면 배포판을 사용하는 모든 사람 이 해당 프로그램을 모두 다시 다운로드 해야합니다. 한편, 배포판에서 제공하는 패키지 세트 내에서 모든 것이 해당 라이브러리 세트에서 작동하도록 테스트 되었기 때문에 종속성 지옥은 문제가되지 않습니다.
배포판에없는 라이브러리가 필요한 타사 소프트웨어를 구축하는 경우 해당 라이브러리 를 정적으로 연결 하는 것이 대안보다 덜 번거로울 수 있습니다.
알아야 할 또 다른 중요한 점은 GNU libc
와 GCC libstdc++
모두 라이브러리가 정적으로 링크 된 경우 안정적으로 작동하지 않는 구성 요소를 가지고 있다는 것입니다. 가장 일반적인 문제는 함께 dlopen
당신이로드 모듈 무엇 때문에, dlopen
그 자체가되어 동적 으로 연결 libc.so.6
. 따라서 이제는 주소 공간에 두 개의 C 라이브러리 사본이 있으며 내부 malloc
데이터 구조의 사본 (예 : 권위있는)에 대해 동의하지 않을 경우에 문제가 발생합니다 . 그것은 악화 : 표시되지 않는 기능의 모두가 함께 할 수있는 아무것도 가지고 dlopen
, 같은 gethostbyname
과 iconv
, 사용dlopen
내부적으로 (동작이 런타임 구성 가능하도록) 다행히도 libc 및 libstdc ++ 용 ABI는 매우 안정적이므로 동적으로 연결하는 데 문제가 발생하지 않습니다.
답변
mattnz의 마지막 요점에 동의합니다.이 질문은로드 된 질문입니다. 정적 연결이 잘못되었다고 가정합니다. 이것이 사실이 아닌 두 가지 이유를 생각할 수 있습니다.
-
정적 연결은 안전합니다. 공유 라이브러리가 업데이트되어 응용 프로그램이 새 라이브러리를 사용하도록 (새 라이브러리가 기존 라이브러리를 덮어 쓰거나 이전 라이브러리를 제거 할 수 있음) 새 버전이 응용 프로그램을 손상시킬 위험이 있습니다. 이것은 응용 프로그램의 공식 업데이트 범위를 벗어난 코드 변경입니다. 테스트되지 않았을 수 있습니다. 정적 링크는 외부에서 라이브러리를 공유하지 않음으로써이를 회피합니다. 이 위험으로 인해 공유 라이브러리 에는 이것이 단점 이라고 생각합니다 . 공유 라이브러리의 새 버전에 특정 이전 응용 프로그램을 손상시키는 새로운 버그가 도입되면 어떻게됩니까?
-
정적 연결을 통해 응용 프로그램을보다 독립적으로 유지할 수 있습니다. 공유 라이브러리는 기본 실행 파일과 함께 배치 될 수 있지만 종종 공유 위치에 저장됩니다. 정적으로 링크 된 응용 프로그램은 “OS가 소유 한 파일, 디렉토리 또는 설정을 변경할 필요가 없음”(Windows 디렉토리, 레지스트리, / etc 등)에 대한 의미로 “휴대용”을 보장하기가 더 쉽습니다.
답변
정적 및 동적 라이브러리는 각각 자체 용도로 사용됩니다. 범위 내에서 단일 응용 프로그램을 보면 필요한 것과 그렇지 않은 것에 대해 다른 아이디어를 얻습니다.
정적 연결은 응용 프로그램 배포를 대폭 간소화합니다. 다른 버전을 감지하고 처리 할 필요가 없습니다. 굽고 배포하기 만하면됩니다.
동적 라이브러리의 장점은 업데이트를 독립적으로 적용 할 수 있다는 것입니다.
이것이 내가 maven과 다른 유사한 동적 링크 프로젝트 빌더를 java에 싫어하는 이유 중 하나입니다. 그들은 주어진 URL에서 영원히 단일 라이브러리 버전을 사용할 수있을 것으로 기대합니다. 모든 소스와 항아리가 없어서 아무도 응용 프로그램을 컴파일 할 수 없을 때 10 년 동안 발생하는 문제를 이해하지 못합니다.