내 바이너리에 다음 줄이 표시됩니다.
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
없애면 안되는 걸까요? 실제로 더 혼란스러운 것은 애초에 이것이 존재하는 이유입니다. 호스트에서만 실행되는 gcc의 기본 컴파일이 약간 이상하다고 생각합니다. 이 바이너리를 복사하여 붙여넣는 컴퓨터에 있을 수도 있고 없을 수도 있는 임의의 libc에 의존하는 것은 위험하지 않습니까? 난 이해가 안 돼요. Windows에서는 컴파일한 정확한 런타임에 맞게 버전이 관리되는 일종의 "런타임 누락" 오류가 발생하는 것 같습니다. 따라서 특정 컴파일러를 사용하여 XP에서 컴파일하는 경우 호스트에도 런타임이 설치되어 있어야 합니다. 그러나 Linux에서는 이런 일이 발생한다는 소식을 들어본 적이 없습니다. 아니면 어딘가에 50개의 서로 다른 libc.so 디렉터리가 있고 내 응용 프로그램이 시작하려고 할 때 올바른 디렉터리가 연결되어 있습니까? Linux에는 .dll 지옥이 존재한다고 생각하지만 그렇지 않습니다.
답변1
적어도 GNU C 라이브러리의 경우 링크는 사용된 모든 기호(함수 등)에 대한 버전 정보를 전달합니다. objdump -T
예를 들어 다음을 사용하여 이를 볼 /bin/ls
수 있습니다 .
DYNAMIC SYMBOL TABLE:
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3 __ctype_toupper_loc
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __uflow
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 getenv
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 sigprocmask
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3.4 __snprintf_chk
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 raise
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 abort
등.
C 라이브러리 개발자는 C 라이브러리가 이전 버전과 호환되도록 하기 위해 많은 노력을 기울입니다. 위 출력은 C 라이브러리 버전 2.3 이상이 ls
필요함을 의미합니다. __ctype_toupper_loc
필요한 모든 기호를 제공하는 모든 C 라이브러리는 지정된 바이너리를 실행할 수 있으며 GNU C 라이브러리의 특정 버전은 이전 버전의 C 라이브러리(1997년까지 거슬러 올라감)에서 제공되는 모든 기호의 구현을 제공합니다.
이를 수행하는 또 다른 방법은 Linux 기반 시스템(실제로는 ELF 기반 시스템 및 기타 시스템)의 대부분의 라이브러리에서 사용되는 soname입니다. 각 라이브러리는 이름뿐만 아니라 주요 변경 사항이 도입될 때마다(경우에 따라 더 자주) 변경되는 버전 번호도 정의합니다. 서로 다른 이름을 가진 여러 버전의 라이브러리를 병렬로 설치할 수 있습니다.
-rw-r--r-- 1 root root 2500416 Dec 16 21:07 libcrypto.so.1.0.2
-rw-r--r-- 1 root root 2711616 Nov 28 23:43 libcrypto.so.1.1
(이것은반품종속성 이름에서 알 수 있듯이 C 라이브러리에서 사용되지만 libc.so.6
마지막 GNU C 라이브러리 soname 충돌은 수년 전에 발생했습니다. )
제목의 문제를 해결하기 위해 C 라이브러리를 정적으로 링크하는 것이 가능하지만 이는 거의 필요하지 않거나 유용하지 않습니다. (그리고 C 라이브러리가 정적으로 링크되어 있어도 C 라이브러리의 일부가 동적으로 링크되기 때문에 혼란스러울 수 있습니다.) . 다른 라이브러리를 정적으로 연결하는 것이 유용할 수 있습니다. 다른 언어는 다른 접근 방식을 사용합니다. 예를 들어 Go 프로그램은 정적으로 링크됩니다.