컴파일러는 각 global symbol
을 strong
또는 weak
로 마킹함
함수와 초기화된 글로벌 변수는 strong symbol
초기화되지 않은 글로벌 변수는 weak symbol
리눅스 링커는 다음과 같은 규칙으로 중복된 symbol
이름을 처리함
strong symbol
은 여러 개 존재할 수 없음 (에러 발생)symbol
중 string symbol
이 하나뿐이면 strong symbol
을 선택symbol
들이 모두 weak symbol
이면 그 중 아무거나 선택모든 compilation system
은 관련된 object module
들을 함께 패키징해서 하나의 파일로 만드는 매커니즘을 제공하고 이 파일을 정적 라이브러리
라고 부름
링커가 실행 파일을 생성할 때 프로그램이 참조하는 object module
만 라이브러리로부터 복사함
프로그래머는 링크 시 몇 개의 라이브러리 파일 이름만 command-line argument
로 포함하면 됨
리눅스 시스템은 정적 라이브러리를 archive
파일 포맷으로 저장
archive
는 a collection of concatenated relocatable object file
임
archive
파일 이름은 .a
suffix를 가짐
링커는 compiler driver
의 command line
에 등장하는 순서대로 relocatable object file
과 archive
를 스캔함
스캔하는 동안 링커는 실행 파일을 구성하기 위해 병합될 relocatable object file
의 집합 E
, unresolved symbol
의 집합 U
, 이전 input file에서 정의된 symbol
의 집합 D
를 유지함
처음에 E, U, D는 비어 있음
command line의 각 input file f에 대해 링커는 f가 object file인지 archive인지 판별함
만약 f가 object file이면 f를 E에 추가하고, f의 symbol definition/reference를 반영해서 U와 E를 업데이트하고, 다음 input file로 넘어감
만약 f가 archive이면 U에 포함된 unresolved symbol을 archive에 속한 member들이 정의한 symbol과 매치 시도함, 만약 매치된다면 m을 E에 추가하고, m의 symbol definition/reference를 반영해서 U와 E를 업데이트함, U와 D가 더 이상 업데이트되지 않을 때까지 f의 member들을 iterate하는 작업을 반복함, 이 과정이 끝나면 E에 포함되지 않은 f의 member들은 버려지고 다음 input file로 넘어감
모든 input file을 스캔한 뒤에도 U가 비어 있지 않으면 링커는 에러를 출력하고 실행을 끝냄, U가 비어 있으면 E에 포함된 object file을 병합하고 relocate해서 실행 파일을 생성함
이 알고리즘은 command line에 포함된 라이브러리와 object file의 순서에 크게 영향받음
일반적으로 라이브러리는 커맨드 라인 뒤쪽에 배치함