سؤال

عندما أفعل ls -l في /usr/lib أرى الكثير من libs مع "sameName.so.*.*" امتداد.

  1. ما هي أهمية هذه الامتدادات؟
  2. لماذا يتم إنشاء softlinks؟ ما هي استخدامها؟

مثال واحد سوف يساعد كثيرا في الفهم.

هل كانت مفيدة؟

المحلول

هذه خدعة تستخدم لإصدار ملفات الكائن المشتركة. إنها وسيلة لتجنب الجحيم DLL اللعين الذي جاء بسبب الارتباط كسول.

تتمثل ميزة الارتباط الكسول (أو الربط المتأخر) في أنه يمكن تغيير مكونات قابلة للتنفيذ دون ربط هذه الأدوات التنفيذية بالفعل. هذا يسمح بإصلاحات الأخطاء في مكونات الطرف الثالث دون الحاجة إلى شحن جهاز تنفيذ جديد ، من بين أشياء أخرى.

العيب هو بالضبط نفس الميزة. يمكن أن تجد قابلة للتنفيذ أن الافتراضات التي وضعتها حول المكتبات الأساسية قد تم تغييرها ، ومن المحتمل أن تتسبب ذلك في جميع أنواع المشكلات.

إصدار الكائنات المشتركة هو إحدى الطرق لتجنب ذلك. آخر سيكون ل ليس مشاركة الأشياء على الإطلاق ولكن هذا يحتوي أيضًا على إيجابيات وسلبيات لن أذهب إليها هنا.

على سبيل المثال ، دعنا نقول أن لديك نسخة 1 من xyz.so. لديك ملف ورابط رمزي لهذا الملف:

pax> ls -al xyz*
-rw-r--r--  1 pax paxgroup    12345 Nov 18  2009 xyz.so.1
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so -> xyz.so.1

الآن ، عند إنشاء ملف قابل للتنفيذ exe1, ، ربطه مع xyz.so, ، سوف يتبع الرابط الرمزي بحيث يخزن xyz.so.1 في التنفيذ كشيء يحتاج إلى تحميله في وقت التشغيل.

بهذه الطريقة ، عند ترقية المكتبة المشتركة هكذا:

pax> ls -al xyz*
-rw-r--r--  1 pax paxgroup    12345 Nov 18  2009 xyz.so.1
-rw-r--r--  1 pax paxgroup    67890 Nov 18  2009 xyz.so.2
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so -> xyz.so.2

الخاص بك القابل للتنفيذ الأصلي exe1 إرادة ساكن تحميل الإصدار 1 من الكائن المشترك.

ومع ذلك ، أي تنفيذيات تنشئها الآن (مثل exe2) سيتم ربطها بالإصدار 2 من الكائن المشترك.


قد تختلف تفاصيل التنفيذ الفعلية إلى حد ما (أنا أستند إلى إجابتي على Unixes السابقة ويبدو أن Linux تقوم بعمل الإصدار أكثر ذكاءً بقليل من مجرد اتباع الروابط الرمزية). لدى IBM DeveloperWorks مقالة لطيفة حول كيفية القيام بها هنا.

عند إنشاء كائن مشترك ، تعطيه اسمًا حقيقيًا و soname. يتم استخدامها لتثبيت الكائن المشترك (الذي ينشئ كل من الكائن ورابط إليه).

لذلك يمكنك أن ينتهي بك الأمر مع الموقف:

pax> ls -al xyz*
-rw-r--r--  1 pax paxgroup    12345 Nov 18  2009 xyz.so.1.5
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so.1 -> xyz.so.1.5
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so -> xyz.so.1

مع xyz.so.1.5 امتلاك SONAME من xyz.so.1.

عندما يرتبط الرابط في xyz.so, ، يتبع الروابط على طول الطريق إلى xyz.so.1.5 ويستخدمها SONAME من xyz.so.1 لتخزين في التنفيذ. ثم ، عندما تكون يجري القابل للتنفيذ ، يحاول التحميل xyz.so.1 والتي ستشير إلى محدد xyz.so.1.N (وليس بالضرورة الإصدار 1.5).

لذلك يمكنك التثبيت xyz.so.1.6 وتحديث xyz.so.1 رابط للإشارة إليها بدلاً من ذلك ، وسوف تستخدم التنفيذيون المرتبطون بالفعل بذلك بدلاً من ذلك.

ميزة واحدة من هذه الطريقة متعددة الطبقات هي أنه يمكنك الحصول على العديد من المكتبات غير المتوافقة التي تحمل نفس الاسم (xyz.so.1.*, xyz.so.2.*) ولكن ، في كل إصدار رئيسي ، يمكنك ترقيتها بحرية بما أنه من المفترض أن يكونوا متوافقين.

عندما تقوم بربط التنفيذيين الجدد:

  • أولئك الذين يربطون xyz.so سوف تحصل على أحدث إصدار من أحدث إصدار رئيسي.
  • الآخرين يرتبطون xyz.so.1 سيحصل على أحدث إصدار من إصدار رئيسي محدد.
  • لا يزال الآخرون يرتبطون به xyz.so.1.2 سيحصل على نسخة ثانوية محددة من إصدار رئيسي محدد.

نصائح أخرى

انه مخطط الإصدار للمكتبات المشتركة. يجب أن يكون لكل مكتبة 3 أسماء:

  1. الاسم الحقيقي: اسم المكتبة الفعلي ، libfoo.so.1.2.3
  2. "سونام": الاسم المسجل في الرابط الديناميكي القابل للتنفيذ ، والاسم يبحث عن ، libfoo.so.1.2. هذا الاسم مكتوب بالفعل داخل المكتبة الثنائية نفسها ، وسيتم تسجيله في وقت التنفيذ في وقت الرابط. عادةً ما يكون ترابطًا للاسم الحقيقي للمكتبة (عادةً الإصدار الأخير).
  3. اسم الرابط: الاسم الذي تعطيه للرابط عند إنشاء برنامجك. عادة ما يرتبط بأحدث سونام.

مثال

قل لديك libfoo الإصدار 1 مثبت: libfoo.so -> libfoo.so.1.0 -> libfoo.so.1.0.0. أنت تبني برنامجك bar مع -lfoo. يرتبط الآن libfoo وسوف تحميل libfoo.so.1.0 في وقت التشغيل بسبب سونام. ثم تقوم بالترقية إلى مصلحة ولكن متوافقة مع ثنائية libfoo.so.1.0.1 عن طريق استبدال ثنائي حقيقي. bar لا يزال يرتبط libfoo.so.1.0 ولا يحتاج إلى إعادة بناء.

تخيل الآن أنك تريد بناء برنامج جديد baz هذا يستفيد من التغييرات غير المتوافقة في libfoo v1.1. تقوم بتثبيت إصدار جديد ونظامك لديه الآن نسختان مثبتان على التوازي:

  1. libfoo.so.1.0 -> libfoo.so.1.0.1
  2. libfoo.so -> libfoo.so.1.1 -> libfoo.so.1.1.0

ملاحظة تم تحديث اسم الرابط إلى أحدث إصدار (هذا هو الإصدار المقابل للرؤوس التي قمت بتثبيتها فيها /usr/include).

يمكنك بناء baz, ، ويرتبط بـ libfoo.so والأحمال libfoo.so.1.1 في وقت التشغيل. ليس هذا bar لا يزال يعمل ضد libfoo.so.1.0 ولا يحتاج إلى تحديث.

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