2016-07-07 17 views
3

C++ Linux 프로그램에 플러그인을로드하는 가장 좋은 방법은 무엇입니까?Linux에서 플러그인을 사용하는 C++ 프로그램 모범 사례

우리는 플러그인 (libsyntax.so)이있는 프로그램 (편집기)이 있다고 가정 해보십시오. 편집기의 설정 파일에는 libsyntax.so 라이브러리 (plugin1 =/opt/editor/gizmos/libsyntax.so)에 대한 경로가 들어 있습니다. 편집기가 설정을 읽으면 다음을 호출합니다.

void* library = dlopen(path, RTLD_NOW|RTLD_GLOBAL); 
MYFUN* function = (MYFUN*)dlsym(library, "function"); 

모든 것이 잘 작동합니다.

이제 (libsyntax.so)가 도우미 라이브러리 (libcolor.so)에 의존한다고 가정합시다. 우리가 readelf를 실행하면 다음을 얻게됩니다 :

readelf -d libsyntax.so 

Dynamic section at offset 0x12b6b48 contains 31 entries: 
    Tag  Type       Name/Value 
0x0000000000000001 (NEEDED)    Shared library: [libcolor.so] 
... 

그러나이 시점에서 위의 dlopen()은 실패하고 "No such file or directory"입니다.

28664: file=libcolor.so [0]; needed by /home/.../libsyntax.so [0] 
28664: find library=libcolor.so [0]; searching 
28664: search cache=/etc/ld.so.cache 
28664: search path=/lib64/tls/x86_64:/lib64/tls:...:/usr/lib64 (system search path) 
28664: trying file=/lib64/tls/x86_64/libcolor.so 
      ... and so on 

로더/링커 내 의존성을 발견하지, 분명히, 표준 장소에서보고됩니다 : LD_DEBUG를 사용하여 = 모든 libsyntax.so로드 한 후, 메시지가 있음을 알 수있다. 이것은 ldconfig 또는 LD_LIBRARY_PATH로 쉽게 처리 할 수 ​​있지만 두 솔루션 모두 더러워집니다.

플러그인과 종속성을 모두로드하는 명확한 방법이 있습니까? 어떻게 지내니?

답변

1

종속성을 확인하는 확실한 방법은 프로그램과 해당 플러그인을 종속성을 찾을 수있는 적절한 위치에 연결하는 동안 런타임 검색 경로 (RPATH)를 설정하는 것입니다.

rpath가 readelf으로 볼 수있는 바이너리로 설정된 경우 링커는 기본 시스템 위치 외에 나열된 추가 경로와 LD_LIBRARY_PATH을 사용합니다.

또한 특수 변수 인 $ORIGIN이 있습니다.이 변수는 런타임 중에 항상 현재 바이너리의 위치로 확인되며 이에 대한 경로를 설정할 수 있습니다! 응용 프로그램의 루트 경로 (즉, 주요 실행 파일을 포함) /opt/editor 경우

예를 들어, 플러그인을 사용하면 링커 옵션을 사용할 수 있습니다, /opt/editor/gizmos에서, 그리고 이제 다른 폴더 추가 종속성 /opt/editor/lib가 있다고 가정 해 봅시다 :

# editor executable 
-Wl,-rpath=$ORIGIN/lib 
# plugins 
-Wl,-rpath=$ORIGIN/../lib,-rpath=$ORIGIN 
+0

나는 RPATH와 RUNPATH를 피하기를 희망했다. 어쨌든 RPATH는 더 이상 사용하지 않을 예정입니다. – JurekM

+0

IIRC에서는'$ ORIGIN'을 쉘 인용 부호로 묶어야합니다. –

+0

'libsyntax.so'를 링크 할 때'-Wl, -rpath,/path1/path2' 옵션 (libcolor.so가 실제로있는 경로)을 사용하십시오. –

0

Persinally, 나는 LD_LIBARY_PATH가 여기 당신의 친구라고 생각합니다. 플러그인 인터페이스에 대한 정의로서, 플러그인이 필요로하는 라이브러리가 어디에 위치해야 하는지를 정의하고 프로그램에서 해당 위치로 LD_LIBARY_PATH를 설정해야합니다.

dlopen을 호출하기 전에 라이브러리를로드하기 만하면됩니다. 프로그램에는 다른 변경이 필요하지 않으며 플러그인 자체의 특별한 연결도 필요하지 않습니다.