답변:
ranlib
정적 라이브러리 에서 객체 파일 을 추가하거나 업데이트 합니다 . 링커는 링크 할 때 정적 라이브러리를 사용 하여 코드가 작동하는 데 필요한 기호 를 제공 할 수 있습니다 ( 로더 가 실행 파일을 실행할 때 동적 라이브러리 에서 해당 심볼 을 찾는 것과는 반대 ).
ranlib
라이브러리를 작성하고 수정하는 데 사용됩니다. 일반적으로 명령 행에서 라이브러리 위치 및 / 또는 이름을 전달하여 사용하는 것은 링커의 책임입니다. 자세한 내용은 gcc에 대한 -L
및 -l
인수를 참조 하십시오.
ar
않습니까? 차이점이 뭐야?
이 설명은 매우 명확 해 보입니다 : http://sourceware.org/binutils/docs/binutils/ranlib.html
따라서 객체 파일 모음을 보관하는 경우 다음과 같이 말합니다.
$ ar r fruits.a apple.o orange.o pineapple.o
그런 다음 실행
$ ranlib fruits.a
과일의 내용에 대한 색인을 작성하고 과일에 저장합니다. 이것은 링크 및 객체가 서로를 호출하는 경우에 유용합니다.
tar
매우 명확하지 않습니다.
ar
Linux에서는 ar
GNU 범용 아카이버입니다. ( ar
다른 유닉스 계열 OS에는 GNU 이외의 변형이 있습니다 ). 옵션으로c
ar c... archive-name file...
의 사본이 포함 된 아카이브를 만듭니다 file...
. 은 archive-name
종래 그러나 반드시 확장자가 .a
(에 대한 아카이브 ). 각각 file...
은 객체 파일 일 필요는 없으며 어떤 파일이든 상관 없습니다.
아카이브 된 파일이 모든 오브젝트 파일 인 경우, 일반적으로 아카이브를 사용하여 선택한 오브젝트 파일을 프로그램 또는 DSO (Dynamic Shared Objects)의 링크로 전달합니다. 이 경우 archive-name
에도 lib
, 예를 들어 libfoo.a
, 링커 옵션을 통해 후보 링커 입력 파일로서 발견 될 수 있도록 ,
통상적으로 접두어가 제공 될 것이다 -lfoo
.
링커 입력 파일로 사용되며 libfoo.a
일반적으로 정적 라이브러리 라고합니다 . 이 사용법은 전문가가 아닌 프로그래머에게 영원한 혼란의 원인이되는데, 이는 아카이브 libfoo.a
가 libfoo.so
일반적으로 동적 / 공유 라이브러리 라고하는 DSO와 거의 같은 종류의 것으로 생각하고 이를 바탕으로 잘못된 기대를 구축하기 때문입니다. 실제로 "정적 라이브러리"와 "동적 라이브러리"는 전혀 유사한 것이 아니며 완전히 다른 방식으로 연결되어 사용됩니다.
눈에 띄는 차이점은 정적 라이브러리는 링커 가 아니라에 의해 생성된다는 것 ar
입니다. 따라서 연결이 발생하지 않고 심볼 분석이 발생하지 않습니다. 보관 된 객체 파일은 변경되지 않습니다. 가방에 넣습니다.
아카이브 뭔가의 링크에 입력하면 된다 발생한 한 해결되지 않은 기호 참조에 대한 정의를 제공 거기에 어떤 오브젝트 파일이 있는지 확인하기 위해 가방에 링커 외모 - 같은 프로그램 또는 DSO로 - 링커에 의해 생산 연결의 초기에. 발견 된 경우, 해당 오브젝트 파일을 백에서 추출 하여 링커 명령 행에서 개별적으로 이름이 지정되고 아카이브가 전혀 언급되지 않은 것처럼 출력 파일에 링크 합니다 . 따라서 링키지에서 아카이브의 전체 역할은 링커에서 링키지에 필요한 파일을 선택할 수있는 개체 파일의 백입니다.
기본적으로 GNU ar
는 출력 아카이브를 링커 입력으로 사용할 수 있도록 준비합니다. 이 파일은 매직 파일 이름으로 아카이브에 가짜 "파일"을 추가하며,이 가짜 파일에는 링커가 아카이브의 모든 오브젝트 파일에 의해 정의 된 전역 기호에서 조회 테이블로 읽을 수있는 컨텐츠를 작성합니다. 아카이브에서 해당 오브젝트 파일의 이름과 위치 이 찾아보기 테이블은 링커가 아카이브를 찾아보고 해결되지 않은 기호 참조를 정의하는 모든 오브젝트 파일을 식별 할 수있게합니다.
q
(= quick ) 옵션 (
실제로 자신의 ar
예 에서 사용한) 옵션 과 (capital) S
(= no symbol table ) 옵션을 사용 하여이 조회 테이블을 작성하거나 업데이트 하지 않을 수 있습니다. ar
어떤 이유로 든 최신 기호 테이블이없는 아카이브를 작성하거나 업데이트하기 위해 호출하면 옵션이 있는 아카이브를 제공 할 수 있습니다 s
.
ranlib
ranlib
라이브러리를 전혀 만들지 않습니다. Linux에서 아카이브 ranlib
테이블 ar
이없는 경우 최신 심볼 테이블을 아카이브에 추가하는 레거시 프로그램입니다 . 효과는 ar s
GNU와 정확히 동일 ar
합니다. 역사적으로, ar
심볼 테이블 자체를 생성 하기 전에는 ranlib
링커가 오브젝트 파일을 선택할 수 있도록 매직 포니 파일을 아카이브에 삽입 한 kludge가있었습니다. GNU Unix와 유사한 OS에서는 ranlib
이 목적을 위해 여전히 필요할 수 있습니다. 귀하의 예 :
ar qc libgraphics.a *.o
ranlib libgraphics.a
말한다 :
libgraphics.a
모든 *.o
파일을 아카이브에 추가하여 작성하십시오 .libgraphics.a
리눅스에서 이것은 다음과 같은 순 효과를 갖습니다 :
ar cr libgraphics.a *.o
자체적으로 ar qc libgraphics.a *.o
는 심볼 테이블이 없기 때문에 링커에서 사용할 수없는 아카이브를 만듭니다.
ld
귀하의 예 :
ld -r -o libgraphics.a *.o
실제로 꽤 정통합니다. 이것은의 비교적 드문 사용 도시 링커 ,
ld
하는 생성하기 위해 병합 된 심볼 해석이 완료되어있는 단일 출력 오브젝트 파일로 여러 입력 파일을 링크하여 오브젝트 파일 까지만큼 가능 입력 파일 주어진다. -r
(= 재배치 ) 옵션은 정의되지 않은 기호 참조 출력 파일에 남아 있으면 linkaqe을 실패 가능한 아닌 같은 입력에 연결하여 오브젝트 파일 타겟 (아닌 프로그램, DSO)를 생성하는 링커를 지시한다. 이 사용법을 부분 연결 이라고 합니다.
의 출력 파일은 ld -r ...
오브젝트 파일이 아닌 것입니다 ar
아카이브 , 그 출력 파일 이름 지정 외모 의 같은 ar
아카이브가 하나가되지 않습니다를. 따라서 귀하의 예는 속임수를 보여줍니다. 이:
ld -r -o graphics.o *.o
진실 할 것입니다. ELF 객체 파일이 호출 libgraphics.a
되고 해당 이름으로 또는 링크에 의해 링크에 입력 되더라도 -lgraphics
링커가이를 ELF 객체 파일로 올바르게 식별 하기 때문에 그러한 속임수의 목적이 무엇인지 확실하지 않습니다. 아닌 ar
아카이브와는 명령 줄에있는 모든 오브젝트 파일을 소비하는 방식을 소모합니다 : 진정한 아카이브를 입력하는 포인트가 링크 아카이브 멤버 반면 그것은 출력 파일에 무조건 링크 그들 만이 참조되는 것을 조건으로 . 아마도 당신은 여기에 잘못된 정보 링크의 예를 가지고있을 것입니다.
마무리...
우리는 실제로 라이브러리 라고 불리는 것을 생성하는 한 가지 방법 만을 보았습니다. 이것은 일부 객체 파일을 아카이브하고 기호 테이블을 아카이브에 넣어 소위 정적 라이브러리 를 생성하는 것입니다.
그리고 우리는 일반적으로 라이브러리 ( 동적 공유 객체 / 공유 라이브러리 / 동적 라이브러리) 라고하는 다른 가장 중요한 종류의 물건을 만드는 방법을 전혀 보지 못했습니다 .
프로그램과 마찬가지로 DSO는 링커에서 생성 합니다 . 프로그램과 DSO는 OS 로더가 이해하고 실행중인 프로세스를 조립하는 데 사용할 수있는 ELF 바이너리의 변형입니다. 일반적으로 우리는 하나 GCC 프론트 엔드 중 하나 (을 통해 링커를 호출 gcc
, g++
, gfortran
, 등) :
프로그램 연결
gcc -o prog file.o ... -Ldir ... -lfoo ...
DSO 연결 :
gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...
공유 라이브러리와 정적 라이브러리는 -lfoo
다른 프로그램이나 DSO를 링크 할 때 균일 한 프로토콜로 링커에 제공 할 수 있습니다 . 그 옵션 중 하나를 찾기 위해 지정 또는 기본 검색 directrories를 스캔 링커 지시
libfoo.so
또는 libfoo.a
. 기본적으로 둘 중 하나를 찾으면 해당 파일을 링크에 입력하고 동일한 검색 디렉토리에서 둘 다 찾으면 선호합니다 libfoo.so
. 을 libfoo.so
선택하면 링커에서 해당 DSO를 프로그램 또는 DSO의 런타임 종속성 목록에 추가합니다. 이 libfoo.a
옵션을 선택하면 링커에서 아카이브를 출력 파일에 링크하기위한 객체 파일 선택으로 사용합니다 (필요한 경우). 에 대한 런타임 종속성이 없습니다.
libfoo.a
그 자체가 가능하다; 프로세스에 맵핑 될 수 없습니다. OS 로더에는 아무런 의미가 없습니다.
https://stackoverflow.com/a/47924864/195787 에서 복사했습니다 .