๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(shared library)์ Linker/Loader ์ดํดํ๊ธฐ
์ด์ ๋ ์ง์ C ์ธ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ์ ํ ์ผ์ด ๋ง์ง ์์ง๋ง C ์ธ์ด๋ก ๋ง๋ค์ด์ง ํ๋ก๊ทธ๋จ๊ณผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ์ ํ ์๋น์ค ์ธํ๋ผ์์ ์ค์ํ ์์น๋ฅผ ์ฐจ์งํ๊ณ ์์ต๋๋ค.
linux ๋ฑ ์ด์์ฒด์ ๊ฐ C ๋ก ๋ง๋ค์ด์ ธ ์๊ณ ํธ๋ฆฌํ๊ฒ ๊ฐ๋ฐ์ ํ ์ ์๋ ์์ฐ์ฑ ์ข์ script(ruby ๋ python, PHP ๋ฑ..) ์ธ์ด์ ์์ง๋ค์ ๋๋ถ๋ถ C ๋ก ์ ์๋์๊ณ openssl, database driver ๋ฑ์ ๊ธฐ๋ฅ์ C ๋ก ์์ฑ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํธ์ถํ์ฌ ์ธ์ด์ ๊ธฐ๋ฅ์ ํ์ฅํ๊ณ ์์ต๋๋ค.
์ด์์ฒด์ ์์ ํ๋ก๊ทธ๋จ์ด ์ด๋ป๊ฒ ๋์ํ๋์ง ์ดํดํ๋ ๊ฒ์ ๊ฒฌ๊ณ ํ ์๋น์ค๋ฅผ ๋ง๋ค๊ณ ๋ฌธ์ ๊ฐ ์๊ฒผ์ ๋ ๋์์ ํ๋๋ฐ ๋์์ด ๋๋ ์ง์์ด์ง๋ง ๋ฐ์ ์๋์์ ์ด๋ฐ ์ง์์ ์ฒด๊ณ์ ์ผ๋ก ํ์ตํ๊ธฐ๋ ์ฝ์ง๊ฐ ์์ต๋๋ค.
๊ทธ๋์ ํ๋ก๊ทธ๋จ์ ๋์ ๋ฐฉ์์ ์ดํดํ๊ธฐ ์ํ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(shared library, ๋๋ ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ผ๊ณ ๋ ํฉ๋๋ค.)์ ํ๋ก๊ทธ๋จ ๋ก๋์ ๋ํด์ ๋ค๋ค๋ณผ๊น ํฉ๋๋ค.
๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(shared library)
์ปดํ์ผ๋ฌ๋ ๋ฌด์จ ์ผ๋ค์ ํ ๊น.
#include <stdio.h> int main(int argc, char** argv) { printf("Hello World\n"); return 0; }
์์ ๊ฐ์ hello.c ์์ค๊ฐ ์์ ๊ฒฝ์ฐ gcc hello.c ๋ช ๋ น์ด๋ก ์ปดํ์ผ์ ํ๋ฉด ์ปดํ์ผ๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ์ ์ฐจ๋ฅผ ๊ฑฐ์ณ์ ์คํ ํ์ผ์ ์์ฑํ๊ฒ ๋ฉ๋๋ค. (๊ดํธ ์์ ์๋ ๊ฒ์ gcc ์์ ํด๋น ๊ธฐ๋ฅ์ ์ํํ๋ ๋ช ๋ น์ด์ ๋๋ค.)
C Pre Processor(cpp) ๊ฐ #define, #include ๊ตฌ๋ฌธ๋ฑ์ ์ ์ฒ๋ฆฌํ์ฌ hello.i ์์ฑ
cpp hello.c > hello.i
C compiler(cc1) ๊ฐ ์ ์ฒ๋ฆฌํ hello.i ์์ค๋ฅผ ์ด์ ๋ธ๋ฆฌ๋ก ์ปดํ์ผํ์ฌ hello.s ์์ฑ
gcc -S hello.i
assembler(as) ๋ hello.s ๋ฅผ ์ด์ ๋ธํ์ฌ object (hello.o) ์์ฑ
as -o hello.o hello.s
linker(collect2) ๋ printf ๋ฑ ์ธ๋ถ library ์ ์๋ symbol ์ ๋งํฌํด์ ์ต์ข ํ๋ก๊ทธ๋จ ์์ฑ(a.out)
gcc๋ ์์ ๊ณผ์ ์ ๊ฐํธํ๊ฒ ํด์ฃผ๋ wrapper ์ญํ ์ ์ํํ๋ฉฐ -v ์ต์ ์ ์ฃผ๊ณ ์คํํ ๊ฒฝ์ฐ ์ด ๋ชจ๋ ๊ณผ์ ์ ํ์ธํ ์ ์์ต๋๋ค.
gcc -v hello.c
๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
printf ๊ฐ์ด ํ๋ก๊ทธ๋จ๋ง๋ค ์์ฃผ ์ฌ์ฉํ๋ ์ธ๋ถ ํจ์๋ฅผ ์คํ ํ๋ก๊ทธ๋จ์ ํฌํจ์ํฌ ๊ฒฝ์ฐ ํ๋ก๊ทธ๋จ์ ๋ฉ์น๊ฐ ์ปค์ง๊ณ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ทธ๋ ์ด๋ ๋์ ๊ฒฝ์ฐ ์ด๋ฅผ ์ฌ์ฉํ๋ ํ๋ก๊ทธ๋จ์ ๋ค์ ์ปดํ์ผํด์ผ ํ๋ ๋ถ๋ด์ด ์์ต๋๋ค.
์ธ๋ถ ํจ์๋ฅผ ํฌํจํด์ ํ๋ก๊ทธ๋จ์ ๋ง๋๋ ๊ฒ์ ์ ์ ๋งํฌ(static linking)๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.)
๊ทธ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(shared library)๋ผ๋ ํ์์ผ๋ก ๋ง๋ค์ด ๋๊ณ ์ปดํ์ผ ์์ ์ ์ฌ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐ๊ฒฐ๋ง ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.
windows ์์๋ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋์ DLL(Dynamic Link Library) ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
์ด๋ค ํ๋ก๊ทธ๋จ์ด ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋์ง ์์๋ณด๋ ค๋ฉด ๋ฆฌ๋ ์ค์๋ file ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ฉฐ ์๋๋ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ ๋ ๊ฒฐ๊ณผ์ ๋๋ค.
$ file a.out a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
์ ์ ๋งํฌ๋ ํ๋ก๊ทธ๋จ์ ์๋์ ๊ฐ์ด ํ์ํฉ๋๋ค.
$ file a.out a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.18, not stripped
dynamic loader
๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฐ๊ฒฐ๋ ํ๋ก๊ทธ๋จ์ ์คํํ๋ฉด ๋ด๋ถ์ ์ผ๋ก dynamic loader๋ผ๋ ํ๋ก๊ทธ๋จ์ด ๋จผ์ ๋์ํ์ฌ ๋๋ต ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์คํํฉ๋๋ค.
- dynamic link ๋ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐพ์์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ฉ
- entry function (C ์ธ์ด์ผ ๊ฒฝ์ฐ main ํจ์)๋ฅผ ์ฐพ์์ ํธ์ถ
- ํ๋ก๊ทธ๋จ ์คํ
๊ฐ ์ด์์ฒด์ ์ ๋ก๋ ์ด๋ฆ์ ์๋์ ๊ฐ์ต๋๋ค.
์ด์์ฒด์ | ๋ก๋ |
---|---|
Linux | ld.so ๋๋ ld-linux.so |
Mac OS X | dyld |
Solaris | ld.so |
HP-UX | dld.so |
์ด๋์์ shared library ๋ฅผ ์ฐพ์๊น?
LD_LIBRARY_PATH
loader ๋ program ๊ตฌ๋์ ํ์ํ shared library ๋ฅผ ์ฐพ์ ๋ LD_LIBRARY_PATH(๋ฆฌ๋ ์ค์ ๊ฒฝ์ฐ)์ ๊ฐ์ ๊ณ ์ ์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฐธ๊ณ ํ๋ฉฐ OS ๋ง๋ค ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ์์๊ฐ ๋ค๋ฆ ๋๋ค.
์ด์์ฒด์ | ํ๊ฒฝ ๋ณ์ | ๋น๊ณ |
---|---|---|
Windows | PATH | Windows์์ DLL์ ์ฐพ๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ฒ์ ๊ฒฝ๋ก ์์ |
Linux | LD_LIBRARY_PATH | LD_LIBRARY_PATH ๊ฐ ์ค์ ๋์ง ์์๋ /lib64, /usr/lib64 ํด๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ ๋ฉ๋๋ค. |
Mac OS X | DYLD_LIBRARY_PATH | LD_LIBRARY_PATH ์ ๋์ผ ์ญํ |
DYLD_FALLBACK_LIBRARY_PATH | ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชป ์ฐพ์ ๊ฒฝ์ฐ ๊ฒ์ํ ๊ฒฝ๋ก. $(HOME)/lib:/usr/local/lib:/lib:/usr/lib ๋ก ์ค์ ๋์ด ์์ |
์ฌ์ฉํ ์ผ์ด ๋ง์ง๋ ์๊ฒ ์ง๋ง ์์ฉ ์ ๋์ค์ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- Solaris : LD_LIBRARY_PATH,
- AIX: LIBPATH
- HP-UX: SHLIB_PATH
RPATH
๋ฆฌ๋ ์ค๋ ELF ํ์์ ๋ฐ์ด๋๋ฆฌ๋ rpath ๋ผ๊ณ ๋ถ๋ฅด๋ "์คํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐพ์ ๊ฒฝ๋ก ์ ๋ณด"๋ฅผ ์ปดํ์ผ ์์ ์ ๋ฃ์ด์ค ์ ์์ผ๋ฉฐ ์ด ์ ๋ณด๋ LD_LIBRARY_PATH ํ๊ฒฝ ๋ณ์ ์ ์ ์ฐธ๊ณ ๋ฉ๋๋ค.
rpath ์ ๋ณด๋ ์๋์ ๊ฐ์ด gcc ๋ฅผ ์คํํ ๋ -Wl,-rpath ์ต์ ์ ์ถ๊ฐํด ์ฃผ๋ฉด ๋ฉ๋๋ค.
gcc -Wl,-rpath,/usr/local/lib hello.c
๋ฐ์ด๋๋ฆฌ์ rpath๊ฐ ์๋์ง ์ฌ๋ถ๋ readelf ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ์ ํค๋๋ฅผ ํ์ธํ๋ฉด ๋ฉ๋๋ค.
$ readelf -d a.out | grep RPATH 0x000000000000000f (RPATH) Library rpath: [/usr/local/lib]
LD_PRELOAD
LD_PRELOAD ํ๊ฒฝ ๋ณ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํํน(hooking)์ด ํ์ํ ๋ ์ฌ์ฉํ๋ ํ๊ฒฝ ๋ณ์๋ก ์ด๊ฒ ์ค์ ๋์ด ์์ผ๋ฉด ์ฌ๊ธฐ์ ์ง์ ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ด ํจ์๋ฅผ ๋จผ์ ํธ์ถํด ์ค๋๋ค.
๋ํ์ ์ธ ์ฉ๋๋ก๋ debugging ๋๋ฌธ์ ๊ตฌ๋์์ ํน์ ๋์ library ๋ฅผ ๋ณ๊ฒฝํด์ผํ ๊ฒฝ์ฐ๋ฑ์ ์ฌ์ฉํฉ๋๋ค.
์๋ก ๋ฉ๋ชจ๋ฆฌ leak์ ์ฐพ๋๋ฐ ์ฌ์ฉํ๋ memory debugger๋ runtime ์ ๊ธฐ์กด ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉํ malloc/free ๋ฅผ debugger ๊ฐ ๊ตฌํํ ํจ์๋ก ๋์ฒดํด์ ๋์ํ๊ธฐ ์ํด LD_PRELOAD ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ๋๋ฒ๊น ์ ์ํํฉ๋๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ ํ์ธ
ํ๊ฒฝ ๋ณ์๊ฐ ์๋ชป ์ค์ ๋์ด ์๊ฑฐ๋ ํ๋ก๊ทธ๋จ ์ค์น๋ฅผ ์๋ชปํ๊ฑฐ๋ ๋ฑ์ ์ด์ ๋ก ํ๋ก๊ทธ๋จ ์คํ์ "Can't load library libevent.so"์ ๋น์ทํ ๋ฅ์ ์๋ฌ๋ฅผ ๋ง๋๋ฉด ๊ฒฝํ์ด ์์ ๊ฒฝ์ฐ ๋จธ๋ฆฌํธ์ ์ฅ์ด ๋ฏ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋์ ํ๋ก๊ทธ๋จ์ด ์์กดํ๋ shared library ๋ ๋ฌด์์ด๊ณ ๋ก๋๊ฐ ์ด๋ป๊ฒ ์ฐพ๋์ง๋ฅผ ์ดํดํ๋ ๊ฒ์ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด ๊ผญ ํ์ํ ์ง์์ ๋๋ค.
์ด์์ฒด์ ๋ณ๋ก ์์กดํ๋ shared library๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Windows
Dependency Walker ๊ฐ 32/64 Windows์์ ๋ชจ๋ ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ ๊ณต๊ฐ์ด๋ฉฐ ์ ์ฉํ๋ ์ด ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์กด์ฑ์ ํ์ธํ์ธ์.
Linux
ํน์ ํ๋ก๊ทธ๋จ์ด ์ฐธ๊ณ ํ๋ shared library๋ฅผ ํ์ธํ๋ ค๋ฉด ldd ๋ช ๋ น์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
$ ldd /usr/bin/vim linux-vdso.so.1 => (0x00007ffd9167b000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd8375d5000) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fd8373ac000) libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fd837189000) libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007fd836f81000) libgpm.so.2 => /usr/lib/x86_64-linux-gnu/libgpm.so.2 (0x00007fd836d7a000)
์ข์ธก์ ์๋ ํญ๋ชฉ(์: libm.so.6) ์ด ์์กดํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ์ด๋ฉฐ ์ฐ์ธก์ ์๋ ํญ๋ชฉ์ด ๋ก๋ฉํ ์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: /lib/x86_64-linux-gnu/libm.so.6) ์ ๋๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค๋ฉด ์ฐ์ธก ํญ๋ชฉ์๋ ๋์ "not found" ๋ผ๋ ๋ฌธ๊ตฌ๊ฐ ํ์๋๋ฉฐ ํ๋ก๊ทธ๋จ์ ์คํํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉฐ ์ด ๊ฒฝ์ฐ /lib64, /usr/lib64 ์ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋์ง ํ์ธํ ํ์
์์ ๊ฒฝ์ฐ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ ๊ฒฝ๋ก๋ฅผ LD_LIBRARY_PATH ํ๊ฒฝ ๋ณ์์ ์ถ๊ฐํด ์ฃผ๋ฉด ๋ฉ๋๋ค.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/myprog/lib
Mac OS X
OS X ๋ otool (object file displaying tool) ๋ผ๋ ๋ช ๋ น์ด๋ฅผ -L ์ต์ ์ ์ฃผ๊ณ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์กด์ฑ ์๋ ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ๋ฒ์ ์ ํ์ธํ ์ ์์ต๋๋ค.
otool -L /usr/bin/afplay /usr/bin/afplay: /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.42.0) /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 44.0.0) /System/Library/Frameworks/vecLib.framework/Versions/A/vecLib (compatibility version 1.0.0, current version 268.0.1) /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.10)
์ฝ์์์๋ ์ ๋๋๋ฐ cron ์์๋ ์๋ฌ๊ฐ ๋๋ ์ด์
cron์ ๋ณด์์์ ์ด์ ๋ก ์คํ์ ์์ ์ด๊ธฐํ ํ์ผ์ ์ฐธ๊ณ ํ์ง ์์ต๋๋ค.
์ฌ์ฉ์ ๊ณ์ ์ผ๋ก๋ ์ ์คํ๋๋๋ฐ cron ์ ๋ฑ๋กํ์ฌ ํ๋ก๊ทธ๋จ์ ์คํํ ๋ ์ ๋๋ก ์คํ์ด ์ ๋๋ค๋ฉด ๋๋ถ๋ถ์ ์์ธ์ ๋ฐ๋ก ํด๋น ํ๋ก๊ทธ๋จ์ ์คํํ๋๋ฐ ํ์ํ ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชป ์ฐพ์์์ ๋๋ค.
์ด๋ด ๊ฒฝ์ฐ ์ฒ๋ฆฌ ๋ฐฉ์์ cron์์ ์คํํ๋ ํ๋ก๊ทธ๋จ์ ๋ณ๋์ ์ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด์ ๊ตฌ๋ํ๊ณ ๊ทธ ์์์ PATH, LD_LIBRARY_PATH ๋ณ์๋ฅผ ์ค์ ํ๊ณ ์คํํ๋ ๊ฒ์ ๋๋ค.
#!/bin/bash export PATH=$PATH:/opt/prog/lib export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/prog/bin myprog --option
cron์ ๋ํ ์์ธํ ๋ด์ฉ์ "๋ฆฌ๋ ์ค๋ฅผ ํ์ฉํ ํ์ฌ ์ธํ๋ผ ๊ตฌ์ถ์ ๋ชจ๋ ๊ฒ"์ค cron ์ฌ์ฉ๋ฒ ํญ๋ชฉ์ ์ฐธ๊ณ ํ์ธ์.
ํ๋ก๊ทธ๋จ์์ dynamic link๋ฅผ ํ๋ ค๋ฉด?
ํ๋ก๊ทธ๋จ๋ด์์๋ ๋ฐํ์์ ์ฌ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ์๋ฅผ ๋์ ์ผ๋ก ๋ก๋ฉํ ์ ์์ต๋๋ค.
windows ์์๋ LoadLibrary ๋ฅผ ์ฌ์ฉํ์ฌ dll ์ ๋ก๋ฉํ ํ์ GetProcAddress ๋ก ์คํํ๋ ค๋ ํจ์์ ์ฃผ์๋ฅผ ์ป์ ํ์ ํธ์ถํ ์ ์์ผ๋ฉฐ ๋ฆฌ๋ ์ค๋ dlopen, dlsym ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๊ฐ ์ด์์ฒด์ ๋ง๋ค dynamic link๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์์ ํธ์ถ ๋ฐฉ์์ด ์์ดํ๋ฏ๋ก ์ด์์ฑ ์ข์ ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ค๋ฉด GNU์ libtool์ ํฌํจ๋์ด ์๋ libltdl ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.