حدث خطأ في الارتباط عند تجميع العملية الذرية لدول مجلس التعاون الخليجي في وضع 32 بت

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

  •  02-07-2019
  •  | 
  •  

سؤال

لدي البرنامج التالي :

~/test> cat test.cc
int main()
{
  int i = 3;
  int j = __sync_add_and_fetch(&i, 1);
  return 0;
}

أقوم بتجميع هذا البرنامج باستخدام الإصدار 4.2.2 من نظام Linux على نظام Linux الذي يعمل على جهاز Intel متعدد وحدات المعالجة المركزية 64 بت:

~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

عندما أقوم بتجميع البرنامج في وضع 64 بت، فإنه يجمع ويربط بشكل جيد:

~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>

عندما أقوم بتجميعه في وضع 32 بت، أحصل على الخطأ التالي:

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test>

على الرغم من أنني لن أعمل أبدًا على معالج 32 بت، إلا أنني أحتاج إلى معالج 32 بت قابل للتنفيذ حتى أتمكن من الارتباط ببعض مكتبات 32 بت.

أسئلتي 2 هي:

  1. لماذا أحصل على خطأ في الارتباط عندما أقوم بالتجميع في وضع 32 بت؟

  2. هل هناك طريقة ما لجعل البرنامج يتم تجميعه وربطه، مع الاستمرار في القدرة على الارتباط بمكتبة 32 بت؟

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

المحلول

من صفحة دول مجلس التعاون الخليجي على Atomic Buildins:

لا يتم دعم جميع العمليات من قبل جميع المعالجات المستهدفة.إذا تعذر تنفيذ عملية معينة على المعالج المستهدف ، فسيتم إنشاء تحذير وسيتم إنشاء دالة خارجية.ستحمل الوظيفة الخارجية نفس الاسم مثل Buildin ، مع لاحقة إضافية "_n" حيث يكون N هو حجم نوع البيانات.

انطلاقا من مخرجات المترجم الخاص بك، والذي يشير إلى __sync_add_and_fetch_4, هذا ما يحدث.لسبب ما، لا يقوم مجلس التعاون الخليجي بإنشاء الوظيفة الخارجية بشكل صحيح.

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

إذا لم يكن الأمر كذلك، فسيتعين عليك معرفة سبب عدم تضمين مجلس التعاون الخليجي للوظيفة المناسبة التي ينبغي أن يقوم بإنشائها.

نصائح أخرى

كانت إجابة دان أودي قريبة، قريبة بما يكفي في الواقع للسماح لي بإيجاد الحل الحقيقي.

وفقًا لصفحة الدليل، يعد "-mcpu" مرادفًا مهملًا لـ "-mtune" ويعني فقط "تحسين وحدة المعالجة المركزية (CPU) معينة (ولكن لا يزال يعمل على وحدات المعالجة المركزية الأقدم، وإن كان أقل مثالية)".لقد جربت هذا، ولم يحل المشكلة.

ومع ذلك، "-march=" يعني "إنشاء تعليمات برمجية لوحدة المعالجة المركزية (CPU) معينة (ولا تعمل على وحدات المعالجة المركزية القديمة)".عندما حاولت ذلك حلت المشكلة:تحديد وحدة المعالجة المركزية لـ i486 أو أفضل تخلص من خطأ الارتباط.

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32  test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top