لماذا يتعين علي تحديد LD_LIBRARY_PATH مع التصدير في كل مرة أقوم فيها بتشغيل التطبيق الخاص بي؟
-
22-08-2019 - |
سؤال
لدي بعض التعليمات البرمجية التي تستخدم بعض المكتبات المشتركة (رمز c في دول مجلس التعاون الخليجي).عند التجميع، لا بد لي من تحديد أدلة التضمين والمكتبة بشكل صريح باستخدام -I و -L، نظرًا لأنها ليست في الأماكن القياسية.عندما أحاول تشغيل الكود يظهر لي الخطأ التالي:
./sync_test
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory
ومع ذلك، قم بما يلي، كل شيء يعمل بشكل جيد:
export LD_LIBRARY_PATH="/path/to/library/"
./sync_test
الآن، الجزء الغريب هو أن هذا يعمل مرة واحدة فقط.إذا حاولت تشغيل sync_test مرة أخرى، سأحصل على نفس الخطأ ما لم أقوم بتشغيل أمر التصدير أولاً.لقد حاولت إضافة ما يلي إلى ملف .bashrc الخاص بي، لكن لم يحدث أي فرق:
LD_LIBRARY_PATH="/path/to/library/"
المحلول
استخدم
export LD_LIBRARY_PATH="/path/to/library/"
وفي .bashrc على خلاف ذلك، وأنها سوف تكون متاحة فقط لسحق وليس أي البرامج التي تبدأ.
وحاول العلم -R/path/to/library/
عندما كنت ربط، وأنها سوف تجعل مظهر البرنامج في هذا الدليل، وأنك لن تحتاج إلى تعيين أي متغيرات البيئة.
وتحرير: يبدو وكأنه -R
هو سولاريس فقط، وكنت على لينكس
وهناك طريقة بديلة سيكون لإضافة مسار ل/etc/ld.so.conf
وتشغيل ldconfig
. لاحظ أن هذا هو التغير العالمي التي سيتم تطبيقها على جميع الثنائيات مرتبطة بشكل حيوي.
نصائح أخرى
ويجب تجنب وضع LD_LIBRARY_PATH
في .bashrc
الخاص بك. انظر "Why LD_LIBRARY_PATH is bad
" للحصول على مزيد من المعلومات.
استخدم خيار رابط -rpath في حين ربط بحيث رابط ديناميكي يعرف أين تجد libsync.so
أثناء وقت التشغيل.
gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test
تحرير:
وهناك طريقة أخرى تتمثل في استخدام المجمع مثل هذا
#!/bin/bash
LD_LIBRARY_PATH=/path/to/library sync_test "$@"
إذا يبدأ sync_test
أي برامج أخرى، لأنها قد ينتهي باستخدام يبس في /path/to/library
التي قد تكون أو لا تكون المقصود.
هل "تصدير" في .bashrc بك؟
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"
ويمكنك فقط وضع هذا كل على سطر واحد:
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test
وإذا ما جعل الأمور أسهل قليلا، حتى لو كان ذلك لا يغير شيئا أساسيا
وبدلا من تجاوز مسار البحث المكتبة في وقت التشغيل مع LD_LIBRARY_PATH، هل يمكن بدلا من ذلك خبز في ثنائي نفسها مع rpath
. إذا قمت بربط مع إضافة دول مجلس التعاون الخليجي -Wl,-rpath,<libdir>
ينبغي أن تفعل خدعة، إذا قمت بربط مع دينار انها مجرد -rpath <libdir>
.
ما يمكنك فعله أيضًا، إذا كان هذا شيئًا قمت بتثبيته على نظامك، هو إضافة الدليل الذي يحتوي على المكتبات المشتركة إلى جهازك /etc/ld.so.conf الملف، أو إنشاء ملف جديد فيه /etc/ld.so.conf.d/
(لقد قمت بفحص توزيع RHEL5 وUbuntu لذا أعتقد أنه عام لنظام التشغيل Linux)
سيتأكد برنامج ldconfig من تضمينها على مستوى النظام.
انظر الرابط التالي لمزيد من المعلومات:www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/dlls.html
هل يمكن أن تضيف في التعليمات البرمجية نظام المكالمات مع التعريف الجديد:
sprintf(newdef,"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s:%s",ld1,ld2);
system(newdef);
ولكن، أنا لا أعرف أن هو الحل RIGTH لكنه يعمل.
والتحيات