ranlib는 무엇입니까?


13

나는 한동안 MacOSX 시스템을 사용해 왔지만 최근에야 배짱을 파기 시작했다. 'sudo ranlib /usr/local/lib/libjpeg.a'(libjpeg 설치)를 실행하라는 지침을 찾았습니다. ranlib 매뉴얼을 읽었으며 온라인에서 찾아보십시오. 나는 단순히 이해하지 못한다. 자세한 내용을 알아 보려면 어떤 리소스를 찾아야합니까, 아니면 누군가 사용에 대해 간결하게 설명 할 수 있습니까? 미리 감사드립니다!

답변:


7

ranlib정적 라이브러리 에서 객체 파일 을 추가하거나 업데이트 합니다 . 링커는 링크 할 때 정적 라이브러리를 사용 하여 코드가 작동하는 데 필요한 기호 를 제공 할 수 있습니다 ( 로더 가 실행 파일을 실행할 때 동적 라이브러리 에서 해당 심볼 을 찾는 것과는 반대 ).


안녕하세요 Ignacio, 답변 주셔서 감사합니다. 라이브러리에서 ranlib를 실행하면 링커가 라이브러리를 '참조'하려고 할 때마다 사용할 수 있습니까? 어떻게 제거합니까?
Ying

ranlib라이브러리를 작성하고 수정하는 데 사용됩니다. 일반적으로 명령 행에서 라이브러리 위치 및 / 또는 이름을 전달하여 사용하는 것은 링커의 책임입니다. 자세한 내용은 gcc에 대한 -L-l인수를 참조 하십시오.
Ignacio Vazquez-Abrams

5
하지만 그렇게하지 ar않습니까? 차이점이 뭐야?
greatwolf

18

이 설명은 매우 명확 해 보입니다 : http://sourceware.org/binutils/docs/binutils/ranlib.html

따라서 객체 파일 모음을 보관하는 경우 다음과 같이 말합니다.

$ ar r fruits.a apple.o orange.o pineapple.o

그런 다음 실행

$ ranlib fruits.a

과일의 내용에 대한 색인을 작성하고 과일에 저장합니다. 이것은 링크 및 객체가 서로를 호출하는 경우에 유용합니다.


"ranlib는 아카이브의 내용에 대한 색인을 생성하여이를 아카이브에 저장합니다." 이것은 결합되어야 할 것 같고 tar매우 명확하지 않습니다.
Codebling

9

ranlib는 아카이브 내용에 대한 색인을 생성하여이를 아카이브에 저장합니다. 색인은 재배치 가능 오브젝트 파일 인 아카이브의 구성원이 정의한 각 기호를 나열합니다. 이러한 색인이있는 아카이브는 라이브러리에 대한 링크 속도를 높이고 라이브러리의 루틴이 아카이브의 배치에 관계없이 서로 호출 할 수 있도록합니다.

출처 : ranlib 매뉴얼 페이지


2

ar

Linux에서는 arGNU 범용 아카이버입니다. ( 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.alibfoo.so일반적으로 동적 / 공유 라이브러리 라고하는 DSO와 거의 같은 종류의 것으로 생각하고 이를 바탕으로 잘못된 기대를 구축하기 때문입니다. 실제로 "정적 라이브러리"와 "동적 라이브러리"는 전혀 유사한 것이 아니며 완전히 다른 방식으로 연결되어 사용됩니다.

눈에 띄는 차이점은 정적 라이브러리는 링커 가 아니라에 의해 생성된다는 것 ar입니다. 따라서 연결이 발생하지 않고 심볼 분석이 발생하지 않습니다. 보관 된 객체 파일은 변경되지 않습니다. 가방에 넣습니다.

아카이브 뭔가의 링크에 입력하면 된다 발생한 한 해결되지 않은 기호 참조에 대한 정의를 제공 거기에 어떤 오브젝트 파일이 있는지 확인하기 위해 가방에 링커 외모 - 같은 프로그램 또는 DSO로 - 링커에 의해 생산 연결의 초기에. 발견 된 경우, 해당 오브젝트 파일을 백에서 추출 하여 링커 명령 행에서 개별적으로 이름이 지정되고 아카이브가 전혀 언급되지 않은 것처럼 출력 파일에 링크 합니다 . 따라서 링키지에서 아카이브의 전체 역할은 링커에서 링키지에 필요한 파일을 선택할 수있는 개체 파일의 백입니다.

기본적으로 GNU ar는 출력 아카이브를 링커 입력으로 사용할 수 있도록 준비합니다. 이 파일은 매직 파일 이름으로 아카이브에 가짜 "파일"을 추가하며,이 가짜 파일에는 링커가 아카이브의 모든 오브젝트 파일에 의해 정의 된 전역 기호에서 조회 테이블로 읽을 수있는 컨텐츠를 작성합니다. 아카이브에서 해당 오브젝트 파일의 이름과 위치 이 찾아보기 테이블은 링커가 아카이브를 찾아보고 해결되지 않은 기호 참조를 정의하는 모든 오브젝트 파일을 식별 할 수있게합니다.

q(= quick ) 옵션 ( 실제로 자신의 ar예 에서 사용한) 옵션 과 (capital) S(= no symbol table ) 옵션을 사용 하여이 조회 테이블을 작성하거나 업데이트 하지 않을 수 있습니다. ar어떤 이유로 든 최신 기호 테이블이없는 아카이브를 작성하거나 업데이트하기 위해 호출하면 옵션이 있는 아카이브를 제공 할 수 있습니다 s.

ranlib

ranlib라이브러리를 전혀 만들지 않습니다. Linux에서 아카이브 ranlib테이블 ar이없는 경우 최신 심볼 테이블을 아카이브에 추가하는 레거시 프로그램입니다 . 효과는 ar sGNU와 정확히 동일 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 에서 복사했습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.