Journey to Security/리눅스

/lib : 정적 라이브러리(.a) vs 동적 공유 라이브러리(.so)

Cordilog 2026. 2. 15. 18:59

리눅스 시스템 프로그래밍의 기초이자, 효율적인 소프트웨어 빌드 전략을 세우기 위해 반드시 이해해야 할 정적 라이브러리(Static Library)와 공유(동적) 라이브러리(Shared Library)의 차이점을 알아보자.

1. 라이브러리 결합 방식의 이해

라이브러리란 자주 사용되는 함수들을 미리 컴파일하여 모아놓은 파일이다.

프로그램이 빌드될 때 이 라이브러리를 어떻게 포함하느냐에 따라 정적과 동적으로 나뉜다.

🟣정적 라이브러리 (Static Library, .a)

정적 라이브러리는 컴파일의 마지막 단계인 링크(Linking) 시점에 라이브러리 파일 내의 필요한 기계어 코드를 실행 파일에 직접 복사한다.

  • 독립성: 필요한 모든 코드가 실행 파일 내부에 포함되어 있어, 실행 환경에 해당 라이브러리가 없어도 단독으로 돌아간다.
  • 파일 크기: 라이브러리의 복사본이 내장되므로 실행 파일의 용량이 커진다.
  • 업데이트: 라이브러리 코드가 수정되면, 이를 사용하는 모든 실행 프로그램을 다시 컴파일하고 링크해야 한다.

🟢공유(동적) 라이브러리 (Shared Library, .so)

공유 라이브러리는 실행 파일에 코드를 복사하지 않는다.

대신 라이브러리가 어디에 있는지, 어떤 함수를 사용하는지에 대한 참조(주소) 정보만 기록해둔다.

실제 코드는 프로그램이 메모리에 로드되어 실행될 때 연결된다.

🌀간접 참조

정적 라이브러리의 경우 소스 코드 바로 뒤에 함수가 붙어 있어서 그냥 순서대로 읽으면 되지만, 공유 라이브러리는 함수가 메모리의 전혀 다른 번지에 올라가 있다.

그래서 프로그램은 함수를 실행할 때 라이브러리가 로드된 메모리 주소값을 찾아 그곳으로 점프해서 코드를 실행하고 다시 돌아온다.

  • 효율성: 여러 프로그램이 동일한 라이브러리를 사용하더라도 메모리에는 단 하나의 복사본만 로드되어 자원을 절약한다.
  • 유지보수: 라이브러리 파일(.so)만 교체하면 해당 라이브러리를 사용하는 프로그램들을 재빌드하지 않아도 업데이트 내용이 반영된다.
  • 의존성: 실행 환경에 필요한 .so 파일이 없으면 프로그램이 구동되지 않는 '의존성 문제'가 발생할 수 있다.

 

 

2. 요약

구분 정적 라이브러리 (.a) 공유 라이브러리 (.so)
확장자 Windows: .lib / Linux: .a Windows: .dll / Linux: .so
결합 시점 컴파일(링크) 단계 프로그램 실행(Runtime) 단계
파일 크기 큼 (코드 포함) 작음 (참조만 포함)
실행 속도 빠름 (주소 점프 없음) 느림 (주소 확인 과정 필요)
장점 배포가 간편하고 독립적임 메모리 절약 및 업데이트 용이

 

 

3. 리눅스 시스템 내 라이브러리 경로

 

전통적인 리눅스 파일 시스템 계층 구조(FHS)에서는 라이브러리 위치를 다음과 같이 구분했다.

  • /lib: 시스템 부팅 및 루트 파일 시스템 작동에 필수적인 공유 라이브러리.
  • /usr/lib: 사용자 프로그램 및 개발용 정적 라이브러리들이 위치하는 곳.

하지만 최신 우분투(Ubuntu)를 포함한 현대적인 리눅스 배포판에서는 'Usr Merge' 전략을 취하고 있다.

실제로 터미널에서 ls -ld /lib를 입력해 확인해보면, /lib은 독립된 디렉토리가 아니라 /usr/lib을 가리키는 심볼릭 링크(Symbolic Link)임을 알 수 있다.

이는 관리의 효율성과 경로의 일관성을 위한 변화다.

$ ls -ld /lib
lrwxrwxrwx 1 root root 7  4월 22  2024 /lib -> usr/lib

 

 

4. 언제 어떤 라이브러리 방식을 선택해야 할까?

일반적인 서비스 개발이나 시스템 패키징에서는 동적 공유 라이브러리를 사용하는 것이 표준이다.

메모리 효율성과 보안 패치 적용 측면에서 압도적으로 유리하기 때문이다.

반면, 네트워크 연결이 제한된 환경에 배포하거나, 특정 라이브러리 버전에 극도로 민감한 임베디드 시스템, 혹은 복잡한 의존성 문제를 피하고 싶은 단일 도구를 만들 때는 정적 라이브러리가 좋은 대안이 될 수 있다.