공유 라이브러리를 구축 할 때 -fPIC는 무엇을 의미합니까?


109

' -fPIC'옵션이 개별 모듈 간의 주소 및 독립성을 확인하는 것과 관련이 있다는 것을 알고 있지만 이것이 실제로 무엇을 의미하는지 잘 모르겠습니다. 설명 할 수 있습니까?


1
또한 더 자세히 알고 싶다면 여기에 훌륭한 기사가 있습니다 ( akkadia.org/drepper/dsohowto.pdf )
MJ

답변:


61

PIC는 Position Independent Code를 나타냅니다.

그리고 인용 man gcc:

대상 기계에 대해 지원되는 경우 동적 연결에 적합하고 전역 오프셋 테이블의 크기에 대한 제한을 피하는 위치 독립적 코드를 내 보냅니다. 이 옵션은 m68k, PowerPC 및 SPARC에서 차이를 만듭니다. 위치 독립적 코드는 특별한 지원이 필요하므로 특정 기계에서만 작동합니다.

언급 된 아키텍처에서 공유 객체 (* .so)를 빌드 할 때 이것을 사용하십시오.


1
f는 아무 의미가 없으며 옵션 이름의 일부일뿐입니다.
Zifre

17
fpic과 fPIC에는 차이가 있습니다. 둘 다 동일한 작업을 수행하지만 fpic은 가능한 경우 더 짧은 상대 오프셋을 사용합니다. 따라서 fpic으로 컴파일하면 잠재적으로 더 작은 파일이 생성 될 수 있습니다. 불행히도 항상 예상대로 작동하지는 않으므로 fPIC를 사용하십시오. 또한 모든 프로세서가 더 짧은 오프셋을 지원하는 것은 아니므로 차이가 없을 수 있습니다.
Martin York

2
'f'는 gcc가 명령 줄 인수를 처리하는 방식의 숙취입니다 (이것은 몇 년 전이었고 최근에 보지 않은 코드 부분을 변경했습니다). 그러나 당시에는 특정 문자 또는 조합 만 다른 조건 (명령 줄 인수를 정의하는 데 매우 복잡한 언어가 있음)에서 허용되었으므로 'f'를 사용하여 명령 줄 인수로 쉽게 정의 할 수있었습니다.
Martin York

2
fPIC없이 * .so를 빌드하면 어떻게됩니까?
Isa A

2
@IsaA 오늘 소스에서 c-api mysql 함수를 컴파일하고 있었는데 빌드되지 않았기 /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC때문에 fPIC를 추가하고 빌드했습니다.
chiliNUT

32

f"코드 생성에 사용되는 인터페이스 규칙을 제어"라는 옵션에 대한 GCC의 접두사

PIC"Position Independent Code" 의 약자이며 fpicm68K 및 SPARC 의 전문화입니다 .

편집 : 0x6adb015 에서 참조 하는 문서의 11 페이지 와 coryan 의 주석을 읽은 후 몇 가지 변경 사항을 적용했습니다.

이 옵션은 공유 라이브러리에만 의미가 있으며 OS에 Global Offset Table, GOT를 사용하고 있음을 알려줍니다. 이는 모든 주소 참조가 GOT에 상대적이며 코드가 여러 프로세스에서 공유 될 수 있음을 의미합니다.

그렇지 않으면이 옵션이 없으면 로더가 모든 오프셋 자체를 수정해야합니다.

말할 필요도없이, 우리는 거의 항상 -fpic / PIC를 사용합니다.


1
나는 OS가 모든 가상 주소에서 라이브러리를 자유롭게로드 할 수 있다고 생각했지만, pic / PIC가 없으면 로더가 코드를 수정하고 루틴 / 라이브러리의 실제 위치에 대한 모든 절대 점프 + 간접 방향을 조정해야합니다. pic / PIC를 사용하면 코드가 수정되지 않으므로 실제로 여러 프로세스에서 공유됩니다.
coryan 09-06-08

여러 프로세스는 거의 우연입니다. 핵심은 코드를 최소한의 주소 수정으로 모든 가상 주소에로드 할 수 있다는 것입니다.
Jonathan Leffler

16

man gcc 말한다 :

-fpic
  공유 장소에서 사용하기에 적합한 위치 독립적 코드 (PIC) 생성
  라이브러리 (대상 컴퓨터에 지원되는 경우) 이러한 코드는
  글로벌 오프셋 테이블 (GOT)을 통한 상수 주소. 역학
  로더는 프로그램이 시작될 때 GOT 항목을 해석합니다 (동적
  로더는 GCC의 일부가 아닙니다. 운영 체제의 일부입니다). 만약
  연결된 실행 파일의 GOT 크기가 기계 별 크기를 초과합니다.
  최대 크기, 링커에서 다음을 나타내는 오류 메시지가 표시됩니다.
  -fpic은 작동하지 않습니다. 이 경우 대신 -fPIC를 사용하여 다시 컴파일하십시오.
  (이러한 최대 값은 SPARC에서 8k이고 m68k 및 RS / 6000에서 32k입니다.
  386에는 그러한 제한이 없습니다.)

  위치 독립적 인 코드에는 특별한 지원이 필요하므로
  특정 컴퓨터에서만 작동합니다. 386의 경우 GCC는 다음을 위해 PIC를 지원합니다.
  System V이지만 Sun 386i 용은 아닙니다. 에 대해 생성 된 코드
  IBM RS / 6000은 항상 위치 독립적입니다.

-fPIC
  대상 기계에 지원되는 경우 위치 독립적 코드를 내 보냅니다.
  동적 연결에 적합하고 크기 제한을 피합니다.
  글로벌 오프셋 테이블. 이 옵션은 m68k에서 차이를 만듭니다.
  그리고 SPARC.

  위치 독립적 인 코드에는 특별한 지원이 필요하므로
  특정 컴퓨터에서만 작동합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.