ในขณะที่คุณสามารถตั้งค่า LD_LIBRARY_PATH เพื่อให้ตัวเชื่อมโยงแบบไดนามิกทราบตำแหน่งที่จะดู แต่ก็มีตัวเลือกที่ดีกว่า คุณสามารถใส่ไลบรารี่ที่แชร์ไว้ในหนึ่งในสถานที่มาตรฐานดู/etc/ld.so.conf
(บน Linux) และ/usr/bin/crle
(บนโซลาริส) สำหรับรายการของสถานที่เหล่านี้
คุณสามารถส่ง-R <path>
ต่อไปยังตัวเชื่อมโยงเมื่อสร้างไบนารีของคุณซึ่งจะเพิ่มลง<path>
ในรายการไดเรกทอรีที่สแกนสำหรับห้องสมุดสาธารณะของคุณ นี่คือตัวอย่าง ก่อนแสดงปัญหา:
libtest.h:
void hello_world(void);
libtest.c:
#include <stdio.h>
void hello_world(void) {
printf("Hello world, I'm a library!\n");
}
สวัสดีซี:
#include "libtest.h"
int main(int argc, char **argv) {
hello_world();
}
Makefile (ต้องใช้แท็บ):
all: hello
hello: libtest.so.0
%.o: %.c
$(CC) $(CFLAGS) -fPIC -c -o $@ $<
libtest.so.0.0.1: libtest.o
$(CC) -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
libtest.so.0: libtest.so.0.0.1
ln -s $< $@
clean:
rm -f hello libtest.o hello.o libtest.so.0.0.1 libtest.so.0
มาเริ่มกันเลย:
$ make
cc -fPIC -c -o libtest.o libtest.c
cc -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o
ln -s libtest.so.0.0.1 libtest.so.0
cc hello.c libtest.so.0 -o hello
$ ./hello
./hello: error while loading shared libraries: libtest.so.0: cannot open shared object file: No such file or directory
จะแก้ไขได้อย่างไร? เพิ่ม-R <path>
ในธงลิงเกอร์ (ที่นี่โดยการตั้งค่าLDFLAGS
)
$ make clean
(...)
$ make LDFLAGS="-Wl,-R -Wl,/home/maciej/src/tmp"
(...)
cc -Wl,-R -Wl,/home/maciej/src/tmp hello.c libtest.so.0 -o hello
$ ./hello
Hello world, I'm a library!
เมื่อมองไปที่ไบนารี่คุณจะเห็นว่ามันต้องการlibtest.so.0
:
$ objdump -p hello | grep NEEDED
NEEDED libtest.so.0
NEEDED libc.so.6
ไบนารีจะมองหาไลบรารีนอกเหนือจากตำแหน่งมาตรฐานในไดเรกทอรีที่ระบุ:
$ objdump -p hello | grep RPATH
RPATH /home/maciej/src/tmp
หากคุณต้องการไบนารีที่จะมองในไดเรกทอรีปัจจุบันคุณสามารถตั้งค่า RPATH $ORIGIN
ไป นี่เป็นเรื่องยุ่งยากเล็กน้อยเพราะคุณต้องตรวจสอบให้แน่ใจว่าเครื่องหมายดอลลาร์ไม่ได้ถูกตีความโดยการทำ นี่เป็นวิธีหนึ่งในการทำ:
$ make CFLAGS="-fPIC" LDFLAGS="-Wl,-rpath '-Wl,\$\$ORIGIN'"
$ objdump -p hello | grep RPATH
RPATH $ORIGIN
$ ./hello
Hello world, I'm a library!
echo $LD_LIBRARY_PATH
ว่างเปล่าในเครื่องของฉัน :(