لماذا يتعين علي تحديد LD_LIBRARY_PATH مع التصدير في كل مرة أقوم فيها بتشغيل التطبيق الخاص بي؟

StackOverflow https://stackoverflow.com/questions/695530

سؤال

لدي بعض التعليمات البرمجية التي تستخدم بعض المكتبات المشتركة (رمز 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 لكنه يعمل.

والتحيات

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top