정적 링킹, 동적 링킹
Static Linking (정적 링킹)
정적 링킹이란 실행 가능한 목적 파일을 만들 때 프로그램에서 사용하는 모든 라이브러리 모듈을 복사하는 방식을 말한다.
5개의 프로그램에서 A라는 외부 함수를 이용하는데 이때 정적 링킹 방식을 사용하면 5개의 프로그램의 실행 가능한 목적파일 각각에 A의 정보가 담긴다. 즉, 중복이 발생한다. 따라서 정적 링킹으로 만들어진 프로그램은 크기가 크고 메모리 효율이 좋지 않다.
정적 링킹을 이용하면, 동적 링킹 라이브러리를 사용하는 프로그램보다 빠르다. 또한 정적 링킹 프로그램에서 모든 코드는 하나의 실행 모듈에 담기기 때문에 compatibility issues 즉, 불일치에 대한 걱정을 하지 않아도 된다. 그러나 함수에 변화가 생길 경우 그 변화를 적용하기 위해서 다시 컴파일하여 다시 링킹을 해야만 한다.
Dynamic Linking (동적 링킹)
동적 링킹이란 실행 가능한 목적 파일을 만들 때 프로그램에서 사용하는 모든 라이브러리 모듈을 복사하지 않고 해당 모듈의 주소만을 가지고 있다가, 런타임에 실행 파일과 라이브러리가 메모리에 위치될 때 해당 모듈의 주소로 가서 필요한 것을 들고 오는 방식이다. 런타임에 운영체제에 의하여 이루어진다.
동적 링킹 방식을 이용하면 5개의 프로그램에서 A라는 외부 함수를 이용한다고 해도 함수의 정보는 하나만 있으면 된다. 즉, 메모리와 디스크 공간을 더 아낄 수 있다.
동적 링킹을 이용하면, A라는 함수에 변화가 생겨도 그 변화를 적용하기 위해 다시 컴파일하여 다시 링킹할 필요가 없다. 실행 가능한 목적파일을 만들 때 A에 관한 정보를 그냥 복사해온 것이 아니라 A가 있는 곳의 주소를 담았기 때문이다. 그저 가리키는 곳을 따라가면 변화된 A가 있다.
정적 링킹이 사용된 프로그램이 실행을 위해 메모리에 로드되는 데 일정한 시간이 걸리는 반면, 동적 링킹 방식이 사용된 프로그램은, 동적 라이브러리가 메모리에 이미 존재하는 경우 로드되는 시간을 단축시킬 수 있다. 하지만 동적 링킹 방식은 정적 링킹 방식보다 느리다. 매번 주소를 따라가야하는 오버헤드가 존재하기 때문이다.
동적 링킹 방식은 compatibility issues 즉, 불일치에 대한 문제를 고려해야 한다. 왜냐하면 동적 링킹 방식은 불일치가 존재할 수 있기 때문이다. 예를 들어 어떤 프로그램에서 A라는 함수를 동적 링킹 방식으로 사용하고 있을 때, A라는 함수가 시스템에서 제거되면 이는 불일치 상황이다. 해당 프로그램의 실행 가능 목적파일에는 A의 주소가 있어서 마치 A가 존재하는 것처럼 움직이지만 실제 A는 시스템에 더이상 존재하지 않기 때문이다. 따라서 이 프로그램은 제대로 실행될 수 없다.
확장자별 라이브러리 구분
- .a : 리눅스 / 정적 라이브러리
- .so : 리눅스 / 동적 라이브러리
- .lib : 윈도우 / 정적 라이브러리
- .dll : 윈도우 / 동적 라이브러리
- DLL을 구현하고 컴파일하고 나면 Static library와는 다르게 output file이 2개가 생성된다. 하나는 *.lib 파일이고 하나는 *.dll 파일이다.
- Static library의 *.lib 파일은 라이브러리 전체 코드를 포함하는 바이너리이며, DLL의 *.lib 파일은 DLL이 제공하고자 하는 함수 정보(함수명)을 가지는 정보 파일이다.
- 링크 단계에서 실행 바이너리의 *.obj 파일들과 DLL의 *.lib 파일을 함께 링크하여 이 정보를 토대로 runtime에 DLL의 함수 코드를 참조한다. 이를 암시적 링킹(implicit linking)이라고 한다. 즉 *.lib 파일은 링크시 필요하고, *.dll 파일은 실행시 필요하다.