Kitaplıkların konumunu bir ikili dosyaya nasıl belirlersiniz? (Linux)


34

Bu soru için belirli bir örnek kullanacağım, ancak gerçekten linux üzerinde 'bağımlı kütüphanelerini bulamayan herhangi bir ikili'ye genelleme yapıyor. Bu yüzden, eksik kütüphanelerden dolayı çalışmayacak bir programım var:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd bu konuda biraz ışık tutuyor:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

Ancak, korona yüklenir:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

İkili dosyaya "eksik" kütüphaneyi nerede arayacağımı nasıl söylerim?

Yanıtlar:


43

Bir kereye mahsus olmak üzere, değişkeni LD_LIBRARY_PATH, aranacak dizinlerin iki nokta üst üste işaretli bir dizin listesine ayarlayın. Bu, PATHstandart sistem dizinlerinin ek olarak çevrede belirtilenlerden sonra aranması dışında çalıştırılabilirler için benzerdir .

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Kütüphaneleri standart olmayan bir konumda tutan ve bunları tek başına bulamayan bir programınız varsa, bir sarmalayıcı komut dosyası yazabilirsiniz:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

Standart sistem dizinlerinin listesi tutulur /etc/ld.so.conf. Son sistemler bu dosyanın başka dosyalar içermesine izin veriyor; sizinki gibi include /etc/ld.so.conf.d/*.confbir şey içeriyorsa , /etc/ld.so.conf.d/mala.confeklemek istediğiniz dizinleri içeren yeni bir dosya oluşturun . Değişiklik yaptıktan /etc/ld.so.confveya ekli bir dosyayı değiştirdikten sonra /sbin/ldconfigdeğişikliklerin etkili olması için çalıştırın (bu bir önbelleği günceller).

( LD_LIBRARY_PATHAyrıca. FreeBSD, NetBSD, OpenBSD, Solaris ve Tru64 dahil birçok Unix'lerde için geçerlidir HP-UX sahiptir SHLIB_PATHve Mac OS X vardır DYLD_LIBRARY_PATH. /etc/ld.so.confDaha yaygın çoğu Unix'lerde ancak konum ve sözdizimi farklıdır üzerinde analoglarını yoktur.)


1
Harika, çok teşekkür ederim. /Etc/ld.so.conf hakkında hiçbir fikrim yoktu ve gelecekte benim için çok faydalı olacak.
Mala

15

LD_LIBRARY_PATH’den kaçınmak istiyorsanız, bunu bağlantı sırasında da yapabilirsiniz:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

-Wl, ..., bağlayıcıya fazladan komutlar iletmek için kullanılır ve bu durumda, -R ile linkere bu yolu .so için "varsayılan arama yolu" olarak kaydetmesini söylersiniz.

Sitemde bunun gibi birçok küçük ipucunun notlarını tutuyorum:

https://www.thanassis.space/tricks.html


Ancak, söz konusu kütüphanenin kendisi aranacak kütüphaneleri paylaştıysa, ikili dosyada depolanan rpat, alt kütüphane aramalarına tekrarlı bir şekilde uygulanmaz. Bu çevrede LD_LIBRARY_PATH ayarlamaktan başka bir yol bulamadım, ki bu da özyinelemeli aramalara uygulandı ...
Ethan

@Ethan: Doğru. Ancak asıl doğru olan şey, bazı ikili dosyalar için paylaşılan kütüphaneleri "paketlemek" istediğiniz her zamanki senaryoların hepsini bir araya getirdiğiniz yer olmasıdır; örneğin /opt/mypackage/bin/someBinarysakladığınız kütüphanelere ihtiyaç duyacak /opt/mypackage/lib/. / Opt altında yüklenen hemen hemen tüm özel SW bu kuralı izler - bu, yukarıda gösterilen yolun bu tür yüklemeleri kapsayacağı anlamına gelir. Daha sonra, genellikle / usr / bin altında / opt altındaki ikili işarete işaret eden bir "link" eklerler - "varsayılan arama yolunun" .sos 'un uygun /opt/.../libklasörün altında bulunacağını bilerek .
ttsiodras

evet, benim durumumda, bir paketi kurmak yerine derleme dizinine bağlayarak bir paketi test etmek istiyordum ... (ama paketin bazı bağımlılıkları olan birkaç içsel ekleri vardı ... çeşitli geçici çözümler ama sadece sinir bozucu)
Ethan

0

Bu, libkorona doğru yolda kurulmadığını gösterir. Libcorona dizinini doğru yola taşıyın, sorun çözülecektir.


Bu diğer cevaplardan daha iyi nasıl?
Toto

@Toto, diğer cevaplardan farklı olarak, temelde dosyaları elle yüklüyorsunuz ... Bu, tam olarak bu cevabın daha iyi olduğu anlamına gelmese de, dikkate alınması gereken bir seçenek. system32 / sysWOW64, uygulamaları bulamadığında), önerilmez, çünkü kesinlikle önerilmez.
Tcll
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.