답변
1) 예, 참조 된 코드 만 가져옵니다. 정적 라이브러리에는 라이브러리에서 내 보낸 모든 심볼의 인덱스 테이블이 포함되어 있기 때문에 작은 크기 외에도 링크 속도가 향상됩니다. 객체 파일을 하나 하나 찾아 보는 것과는 대조적으로이 테이블에서 조회가 더 빠릅니다.
또는 참조에 관계없이 정적 라이브러리의 모든 심볼을 가져 오려는 경우 --whole-archive 스위치를 ld에 전달할 수 있습니다.
2) ld (gnu 링커)의 문맥에서이 질문을하는 것이 더 정확할 것입니다. 왜냐하면 이것이 실제로 참조를 끌어 들이기 때문입니다. GCC는 컴파일이 끝나면 링커를 호출한다 (gcc -c를하지 않으면 컴파일이 중단된다). 따라서 컴파일이 완료되면 ld는 객체 (.o) 파일 및 라이브러리의 정렬 된 목록으로 호출됩니다. ld는 .o 파일을 하나씩 처리하고 각 링커에 대해 a) 아직 해결할 수없는이 파일에 필요한 외부 기호를 적어 두십시오. 이것들을 미해결의 테이블에 추가합니다. b)이 파일에서 내 보낸 기호 (함수, 전역 변수)를보고 이전에 수행 한 모든 참조를 해결합니다. 이것은 연결 프로세스에 대한 매우 간단한 개요입니다. 이제 링커가 정적 라이브러리에 오면 기본적으로 정적 라이브러리를 사용하여 심볼을 해석하는 것과 동일한 작업을 수행합니다. 그러나 한 가지 차이점이 있습니다. 링커는 확인되지 않은 기호와 종속 항목 만 가져옵니다. 따라서 우리는 a.o와 libstatic.a를 가지고 있고, 차례로 b.o와 c.o가 있다고 가정합니다.
b.o는 bar() 및 moreBar()를 정의합니다.
c.o는 baz() 및 moreBaz()를 정의합니다.
a.o는 foo()를 정의합니다.
여기서 foo는 baz를 호출하는 bar를 호출합니다. 이제 당신이 할 때 gcc -o app a.o libstatic.a 링커는 a.o를 처리 한 후에 바를 해결해야한다는 것을 알고 있지만 바를 해결하는 동안 링커는 바가 baz가 필요하다는 것을 알게됩니다. 이것은 libstatic.a에서 다시 해결됩니다. moreBar() 및 moreBaz()는 참조가 없으므로 무시됩니다.