GNU/Linux >> Belajar Linux >  >> Linux

Tidak dapat menemukan .so di direktori yang sama dengan executable?

Solusi 1:

Meskipun Anda dapat menyetel LD_LIBRARY_PATH agar penaut dinamis tahu ke mana harus mencari, ada opsi yang lebih baik. Anda dapat menempatkan perpustakaan bersama Anda di salah satu tempat standar, lihat /etc/ld.so.conf (di Linux) dan /usr/bin/crle (di Solaris) untuk daftar tempat-tempat ini

Anda dapat melewati -R <path> ke linker saat membangun biner Anda, yang akan menambahkan <path> ke daftar direktori yang dipindai untuk perpustakaan bersama Anda. Ini sebuah contoh. Pertama, menunjukkan masalahnya:

libtest.h:

void hello_world(void);

libtest.c:

#include <stdio.h>
void hello_world(void) {
  printf("Hello world, I'm a library!\n");
}

halo.c:

#include "libtest.h"
int main(int argc, char **argv) {
  hello_world();
}

Makefile (tab harus digunakan):

all: hello
hello: libtest.so.0
%.o: %.c
        $(CC) $(CFLAGS) -fPIC -c -o [email protected] $<
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 $< [email protected]
clean:
        rm -f hello libtest.o hello.o libtest.so.0.0.1 libtest.so.0

Mari kita jalankan:

$ 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

Bagaimana memperbaikinya? Tambahkan -R <path> ke flag linker (di sini, dengan menyetel 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!

Melihat binernya, Anda dapat melihat bahwa itu membutuhkan libtest.so.0 :

$ objdump -p hello | grep NEEDED
  NEEDED               libtest.so.0
  NEEDED               libc.so.6

Biner akan mencari pustakanya, selain dari tempat standar, di direktori yang ditentukan:

$ objdump -p hello | grep RPATH
  RPATH                /home/maciej/src/tmp

Jika Anda ingin biner terlihat di direktori saat ini, Anda dapat mengatur RPATH ke $ORIGIN . Ini agak rumit, karena Anda perlu memastikan bahwa tanda dolar tidak diartikan dengan make. Inilah salah satu cara untuk melakukannya:

$ make CFLAGS="-fPIC" LDFLAGS="-Wl,-rpath '-Wl,\$\$ORIGIN'"
$ objdump -p hello | grep RPATH
  RPATH                $ORIGIN
$ ./hello 
Hello world, I'm a library!

Solusi 2:

Pemuat tidak pernah memeriksa direktori saat ini untuk objek bersama kecuali secara eksplisit diarahkan melalui $LD_LIBRARY_PATH . Lihat ld.so(8) halaman manual untuk detail lebih lanjut.

Solusi 3:

Untuk memuat objek bersama dari direktori yang sama dengan executable Anda, cukup jalankan:

$ LD_LIBRARY_PATH=. ./binary

Catatan:Ini tidak akan mengubah variabel LD_LIBRARY_PATH sistem Anda. Perubahan hanya memengaruhi ini, dan hanya ini, eksekusi program Anda.

Solusi 4:

Bagi siapa pun yang menggunakan CMake untuk build mereka, Anda dapat menyetel CMAKE_EXE_LINKER_FLAGS berikut ini:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'")

Ini akan mempropagandakan flag linker dengan benar untuk semua jenis build (mis., Debug, Rilis, dll...) untuk mencari file .so di direktori kerja saat ini terlebih dahulu.

Solusi 5:

Bagi siapa pun yang masih berjuang tanpa jawaban, saya menemukan sendiri dengan saran berikut:

Anda dapat mencoba memperbarui ld.so.cache menggunakan:sudo ldconfig -v

Bekerja untuk saya.


Linux
  1. Cara Menemukan File Terlama Di Pohon Direktori Di Linux

  2. Lihat File Di Bawah Direktori Skrip yang Sama Ditemukan Di $path?

  3. Bagaimana cara menemukan versi Fedora yang saya gunakan?

  1. Bagaimana cara menemukan lokasi yang dapat dieksekusi di C?

  2. Bagaimana saya bisa menghitung checksum md5 dari sebuah direktori?

  3. cara menemukan pemilik file atau direktori dengan python

  1. Di mana saya dapat menemukan file buildinfo.sh?

  2. Di mana file header <conio.h> di Linux? Mengapa saya tidak dapat menemukan <conio.h>?

  3. Bagaimana saya bisa menjalankan dos2unix di seluruh direktori?