تطبيق C ++ - هل يجب علي استخدام الارتباط الثابت أو الديناميكي للمكتبات؟

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

سؤال

سأبدأ مشروع C ++ جديد يعتمد على سلسلة من المكتبات ، بما في ذلك جزء من مكتبات Boost ، و Log4CXX أو مكتبة تسجيل Google - وبما أن المشروع يتطور أيضًا (والذي لا يمكنني توقعه بعد) .

سيتعين على كل من أنظمة 32 و 64 بت ، على الأرجح في بيئة Linux متنوعة للغاية حيث لا أتوقع أن تتوفر جميع المكتبات المطلوبة ولا امتيازات SU.

سؤالي هو ، هل يجب أن أقوم بإنشاء طلبي من خلال الارتباط ديناميكيًا أو ثابتًا بجميع هذه المكتبات؟

ملاحظات:

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

(2) من ناحية أخرى ، فإن طبقات الربط الديناميكية أسهل أثناء مرحلة التطوير - أوقات ترجمة قصيرة ، (لا تعرف حقًا كيفية التعامل مع الارتباط الديناميكي بمكتبات 64 بت من بيئة ديف 32 بت) ، لا صخب مع سلاسل التبعية. يمكن أن يكون نشر إصدارات جديدة من ناحية أخرى قبيحة - خاصةً عندما تكون المكتبات الجديدة مطلوبة (انظر الشرط أعلاه من عدم وجود حقوق SU على الآلات المستهدفة ، ولا هذه المكتبات المتاحة).

(3) لقد قرأت الأسئلة ذات الصلة المتعلقة بهذا الموضوع ، لكنني لم أستطع معرفة النهج الذي يناسب السيناريو الخاص بي.

الاستنتاجات:

  1. شكرا لكم جميعا على آرائكم!
  2. من المحتمل أن أذهب مع الربط الثابت لأن:
    • انتشار أسهل
    • أداء يمكن التنبؤ به ونتائج أكثر اتساقا خلال perf. اختبار (انظر إلى هذه الورقة: http://www.inf.usi.ch/faculty/hauswirth/publications/cu-cs-1042-08.pdf)
    • كما أشير ، لا يبدو أن حجم ومدة تجميع الثابتة مقابل الديناميكي
    • دورات اختبار أسهل وأسرع
    • يمكنني الحفاظ على كل dev. دورة على ديف بلدي. آلة
هل كانت مفيدة؟

المحلول

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

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

أظن أن هذا لن يكون رأيًا مشهورًا. بخير. لكن لديّ 11 عامًا من الخبرة في نشر تطبيقات على Linux ، وإلى أن تقلع شيء مثل LSB حقًا ويمتد حقًا ، سيظل Linux أكثر صعوبة في نشر الطلبات عليها. حتى ذلك الحين ، قم بربط تطبيقك بشكل ثابت ، إذا كان عليك تشغيل مجموعة واسعة من المنصات.

نصائح أخرى

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

هذا هو تصويت آخر للربط الثابت. لم ألاحظ أوقات ربط أطول بكثير للتطبيق. التطبيق المعني هو تطبيق وحدة تحكم خط ~ 50K ، مع العديد من المكتبات التي يتم تجميعها لمجموعة من الآلات العادية ، ومعظمها من الحاسبات الفائقة مع 100-10،000 نوى. من خلال الارتباط الثابت ، يمكنك بالضبط أن تعرف المكتبات التي ستستخدمها بالضبط ، يمكنها بسهولة اختبار إصدارات جديدة منها.

بشكل عام ، هذه هي الطريقة التي يتم بها بناء معظم تطبيقات Mac. هذا هو ما يسمح بالتثبيت ببساطة نسخ دليل على النظام.

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

لاحظ أنه إذا لم يكن لديك امتيازات الجذر لتثبيت المكتبات في أدلة النظام ، فيمكنك تجميع البرنامج بحيث يبدو أولاً في مكان آخر عن أي مكتبات ديناميكية مطلوبة ، يتم تحقيق ذلك من خلال تعيين توجيه RunPath في ثنائيات ELF. يمكنك تحديد مثل هذا الدليل مع خيار -rpath من Linker LD.

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