GCC 컴 파일 은 동적 링크 라 이브 러 리 와 정적 링크 라 이브 러 리 를 사용 하 는 방법
4478 단어 동적 연결 라 이브 러 리정적 연결 라 이브 러 리
링크 시기 에 따라 라 이브 러 리 는 정적 라 이브 러 리 와 동적 라 이브 러 리 로 나 뉜 다.
정적 라 이브 러 리 는 링크 단계 에서 링크 되 어 있 기 때문에 실행 가능 한 파일 은 라 이브 러 리 의 영향 을 받 지 않 습 니 다.라 이브 러 리 가 삭제 되 더 라 도 프로그램 은 성공 적 으로 실 행 될 수 있 습 니 다.
정적 라 이브 러 리 와 달리 동적 라 이브 러 리 의 링크 는 프로그램 이 실 행 될 때 연 결 됩 니 다.따라서 프로그램 이 컴 파일 되 더 라 도 라 이브 러 리 는 프로그램 이 실 행 될 때 호출 할 수 있 도록 시스템 에 보관 해 야 합 니 다.(TODO:동적 라 이브 러 리 를 연결 할 때 링크 단 계 는 도대체 무엇 을 했 습 니까?)
2 정적 라 이브 러 리 와 동적 라 이브 러 리 의 비교
정적 라 이브 러 리 를 연결 하 는 것 은 어떤 의미 에서 볼 때 붙 여 넣 기 복사 이기 도 합 니 다.다만 원본 코드 가 아 닌 대상 코드 일 뿐 입 니 다.정적 라 이브 러 리 가 연 결 된 후 라 이브 러 리 가 실행 가능 한 파일 에 직접 삽입 되 어 두 가지 문 제 를 가 져 왔 기 때문이다.
우선 시스템 공간 이 낭비 되 었 다.이것 은 분명 하 다.만약 에 여러 프로그램 이 같은 라 이브 러 리 를 연결 하면 모든 실행 가능 한 파일 에 라 이브 러 리 의 복사 본 이 있 고 시스템 공간 을 낭비 할 것 이 라 고 상상 해 보 자.
게다가 사람 은 성현 이 아니 라 정성 들 여 디 버 깅 한 창고 라 도 잘못 이 있 을 수 밖 에 없다.창고 에 bug 가 있 는 것 을 발견 하면 구 하 는 것 이 비교적 번거롭다.이 라 이브 러 리 를 연결 하 는 프로그램 을 일일이 찾 아서 다시 컴 파일 해 야 합 니 다.
동적 라 이브 러 리 의 출현 은 정적 라 이브 러 리 의 이상 의 폐단 을 보완 하고 있다.동적 라 이브 러 리 는 프로그램 이 실 행 될 때 연결 되 어 있 기 때문에 디스크 에 복사 본 만 보관 해 야 하기 때문에 디스크 공간 을 절약 합 니 다.bug 를 발견 하거나 업그레이드 하 는 것 도 간단 합 니 다.새로운 라 이브 러 리 로 원래 의 것 을 교체 하면 됩 니 다.
그렇다면 정적 라 이브 러 리 는 아무것도 아 닌 것 일 까?
대답:아니 야,아니 야.존재 가 합 리 적 이라는 말 이 있 잖 아.정적 라 이브 러 리 가 도도 한 역사의 긴 강 에 묻 히 지 않 았 으 니 반드시 그 용도 가 있 을 것 이다.이러한 상황 을 상상 해 보 세 요.만약 당신 이 libpcap 라 이브 러 리 로 프로그램 을 만 들 었 다 면 다른 사람 에 게 실행 되 어야 합 니 다.그의 시스템 에 pcap 라 이브 러 리 가 설치 되 어 있 지 않 으 면 어떻게 해결 해 야 합 니까?가장 간단 한 방법 은 이 프로그램 을 컴 파일 할 때 연결 할 라 이브 러 리 를 모두 정적 라 이브 러 리 에 연결 하 는 것 이다.그러면 다른 사람의 시스템 에서 이 프로그램 을 직접 실행 할 수 있다.
얻 는 것 이 있 으 면 잃 는 것 이 있다 는 것 은 동적 라 이브 러 리 가 프로그램 이 실 행 될 때 연결 되 기 때문에 프로그램의 운행 속 도 는 정적 라 이브 러 리 를 연결 하 는 버 전에 비해 반드시 할인 된다.그러나 흠 이 많 지 않 습 니 다.동적 라 이브 러 리 의 부족 은 그 에 비해 좋 은 점 이 있 습 니 다.현재 하드웨어 에서 보 잘 것 없 기 때문에 링크 프로그램 은 링크 할 때 동적 라 이브 러 리 를 우선 연결 합 니 다.-static 매개 변수 로 링크 정적 라 이브 러 리 를 지정 하지 않 는 한.
동적 연결 라 이브 러 리
1.동적 링크 라 이브 러 리 만 들 기
#include<stdio.h>
void hello()
{
printf("hello world/n");
}
명령 gcc-shared hello.c-o libhello.so 를 동적 라 이브 러 리 로 컴 파일 합 니 다.현재 디 렉 터 리 아래 에 파일 libhello.so 가 하나 더 있 는 것 을 볼 수 있 습 니 다.2.테스트 파일 test.c 를 편집 합 니 다.내용 은 다음 과 같 습 니 다.
#include<stdio.h>
int main()
{
printf("call hello()");
hello();
}
gcc test.c-lehello-l 옵션 을 컴 파일 러 에 hello 라 이브 러 리 를 사용 하 라 고 알려 줍 니 다.이상 한 점 은 동적 라 이브 러 리 의 이름 이 libhello.so 인 데 여 기 는 hello 를 사용 합 니 다.그런데 아직 안 돼 서 컴 파일 이 잘못 될 수 있 습 니 다.In function`main':test.c:(.text+0x1d):undefined reference to`hello'collect 2:ld returned 1 exit status 이것 은 hello 라 이브 러 리 가 우리 자신의 경로 에서 컴 파일 러 를 찾 을 수 없 기 때 문 입 니 다.-L 옵션 을 사용 하여 hello 라 이브 러 리 의 위 치 를 알려 줍 니 다 gcc test.c-lhello-L.-o test-L.컴 파 일 러 에 게 현재 디 렉 터 리 에서 라 이브 러 리 파일 을 찾 으 라 고 알려 줍 니 다.
3.컴 파일 성공 후 실행./test,오류 발생
라 이브 러 리 를 못 찾 겠 대요.
두 가지 방법 이 있 습 니 다.하 나 는 현재 경 로 를/etc/ld.so.conf 에 추가 한 다음 Idconfig 를 실행 하거나 현재 경 로 를 매개 변수 로 Idconfig 를 실행 할 수 있 습 니 다(루트 권한 이 있어 야 합 니 다).2.현재 경 로 를 환경 변수 LD 에 추가 합 니 다.LIBRARY_PATH 에 서 는 물론 혼란 을 일 으 키 지 않 을 것 이 라 고 생각한다 면 이 라 이브 러 리 를/lib,/usr/lib/등 위치 로 직접 복사 할 수 있 습 니 다.(피 할 수 없습니다.이렇게 하 는 것 도 권한 이 있어 야 합 니 다)링크 기와 로 더 를 정확하게 찾 을 수 있 습 니 다.
우 리 는 두 번 째 방법 을 채택 한다:export LDLIBRARY_PATH=.:$LD_LIBRARY_PATH 이렇게 해서 다시 실행 하면 성공 합 니 다.
정적 링크 라 이브 러 리
아까 hello.c 와 test.c 를 사용 합 니 다.1.gcc-c hello.c 여기 서-shared 옵션 을 사용 하지 않 았 음 을 주의 하 십시오.2.대상 파일 을 압축 합 니 다. ar -r libhello.a hello.o 프로그램 ar 는 매개 변수-r 에 맞 춰 새 라 이브 러 리 libhello.a 를 만 들 고 명령 행 에 열 거 된 대상 파일 을 삽입 합 니 다.이 방법 을 사용 하면 라 이브 러 리 가 존재 하지 않 으 면 인자-r 는 새로운 라 이브 러 리 를 만 들 고 라 이브 러 리 가 존재 하면 새로운 모듈 로 원래 모듈 을 교체 합 니 다.3.프로그램 에 정적 라 이브 러 리 연결 gcc test.c-lehello-L.-static-o hello.static 또는 gcc test.c libhello.a -L. -o hello.static
생 성 된 hello.static 은 libhello.a 에 의존 하지 않 습 니 다.
두 가지 유용 한 명령
file 프로그램 은 파일 형식 을 판단 하 는 데 사 용 됩 니 다.file 명령 에 따라 모든 파일 이 정체 가 드 러 납 니 다.참고 로 기교 하나.때때로 윈도 우즈 에서 브 라 우 저 로 tar.gz 나 tar.bz2 파일 을 다운로드 하면 접미사 이름 이 이상 한 tar.tar 로 변 하고 리 눅 스에 가면 어떤 초보 자 들 은 어떻게 압축 을 풀 어야 할 지 모른다.그러나 Linux 의 파일 형식 은 파일 접미사 이름 에 영향 을 받 지 않 기 때문에 우 리 는 먼저 명령 file xxx.tar.tar 로 파일 형식 을 보고 tar 로 적당 한 파 라 메 터 를 추가 하여 압축 을 풀 수 있 습 니 다.
또 프로그램 ldd 유 틸 리 티 를 통 해 판단 할 수 있다.ldd 는 대상 프로그램(명령 행 매개 변수 지정)이 연 결 된 모든 동적 라 이브 러 리 의 정 보 를 인쇄 하 는 데 사 용 됩 니 다.대상 프로그램 이 동적 라 이브 러 리 를 연결 하지 않 으 면'not a dynamic executable'을 인쇄 합 니 다.ldd 의 용법 은 manpage 를 참고 하 십시오.