سؤال

أقوم بإنشاء مشروع باستخدام سلسلة أدوات GNU وكل شيء يعمل بشكل جيد حتى أتمكن من ربطه، حيث يشكو الرابط من أنه مفقود/لا يمكن العثور عليه crti.o.هذا ليس أحد ملفات الكائنات الخاصة بي، ويبدو أنه مرتبط بـ libc ولكن لا يمكنني فهم سبب احتياجه إلى هذا crti.o, ، ألن يستخدم ملف مكتبة، على سبيل المثال؟ libc.a?

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

crti.o موجود على أحد مسارات البحث "المكتبات"، ولكن هل ينبغي البحث عنه .o الملف على مسار المكتبة؟

هل مسار البحث هو نفسه بالنسبة لـ gcc و ld?

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

المحلول

crti.o هي مكتبة bootstrap، وهي صغيرة جدًا بشكل عام.عادةً ما يتم ربطه بشكل ثابت بالثنائي الخاص بك.ينبغي العثور عليه في /usr/lib.

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

أنت لا تقوم بالتجميع المتبادل، أليس كذلك؟

إذا كنت تقوم بالتجميع المتبادل، فعادةً ما تكون هناك مشكلة في عدم تطابق مسار بحث gcc مع مكان crti.o الخاص بك.كان ينبغي أن يتم بناؤه عندما كانت سلسلة الأدوات موجودة.أول شيء يجب التحقق منه هو gcc -print-search-dirs ومعرفة ما إذا كان crti.o موجودًا في أي من هذه المسارات.

يتم إجراء الارتباط بالفعل بواسطة ld ولكن يتم تمرير مساراته إليه بواسطة gcc.ربما تكون أسرع طريقة لمعرفة ما يحدث هي تجميع برنامج helloworld.c وتتبعه لمعرفة ما يتم تمريره إلى ld ومعرفة ما يحدث.

strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test

افتح ملف السجل وابحث عن crti.o، كما ترون المترجم غير المتقاطع الخاص بي:

10616 execve("/usr/bin/ld", ["/usr/bin/ld", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=both", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o"
, "test", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-g
nu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/lib/../lib", "-L/usr/lib/../lib", "-L/usr/lib/gcc/x86_64-linux-gnu
/"..., "/tmp/cc4rFJWD.o", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "/usr/lib/gcc/x86_
64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."...],  "COLLECT_GCC=gcc", "COLLECT_GCC_OPTIONS=\'-o\' \'test\' "..., "COMPILER_PATH=/usr/lib/gcc/x86_6"..., "LIBRARY_PATH=/usr/lib/gcc/x86_64"..., "CO
LLECT_NO_DEMANGLE="]) = 0
10616 open("/etc/ld.so.cache", O_RDONLY) = 3
10616 open("/usr/lib/libbfd-2.18.0.20080103.so", O_RDONLY) = 3
10616 open("/lib/libc.so.6", O_RDONLY)  = 3
10616 open("test", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crt1.o", O_RDONLY) = 4
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crti.o", O_RDONLY) = 5
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/crtbegin.o", O_RDONLY) = 6
10616 open("/tmp/cc4rFJWD.o", O_RDONLY) = 7

إذا رأيت مجموعة من المحاولات ل open(...crti.o) = -1 ENOENT, ld تشعر بالارتباك وتريد أن ترى من أين جاء المسار الذي يفتحه ...

نصائح أخرى

واجهت نفس المشكلة أثناء التجميع المتقاطع.كان crti.o موجودًا <sysroot>/usr/lib64 لكن الرابط لن يجده.

وتبين أن إنشاء دليل فارغ <sysroot>/usr/lib إصلاح المشكلة.يبدو أن الرابط سيبحث عن مسار <sysroot>/usr/lib أولا، وفقط إذا كان موجودا فإنه حتى النظر <sysroot>/usr/lib64.

هل هذا خلل في الرابط؟أم أن هذا السلوك موثق في مكان ما؟

في حالتي Linux Mint 18.0/Ubuntu 16.04, ، ليس لدي crti.o على الاطلاق:

$ find /usr/ -name crti*

لم أجد شيئًا لذلك قمت بتثبيت حزمة المطور:

sudo apt-get install libc6-dev

إذا وجدت بعض libs قرأت هنا

حسنًا، كان عليّ إعادة تثبيت سلسلة الأدوات، بحيث يتم بعد ذلك تضمين الملفات المفقودة.يبدو الأمر غريبًا لأنه كان ينبغي العثور عليه في مسار مجلس التعاون الخليجي.أعتقد أن المشكلة الرئيسية هي أنه كان لدي 15 ملفًا مختلفًا من ملفات crti.o على جهاز الكمبيوتر الخاص بي ولم أشر إلى الملف الصحيح.لا يزال لا يعمل منذ ذلك الحين ولكنه يعمل الآن :-) شكرًا لمساعدتك :-)

لقد واجهت مشكلة مماثلة مع مترجم مشترك تم إعداده بشكل سيء.لقد حولت الأمر هكذا:

/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c

يفترض هذا أن /lib و/usr/include وما إلى ذلك موجودون في الموقع المشار إليه بواسطة خيار sysroot.ربما ليست هذه هي الطريقة التي من المفترض أن تتم بها الأمور، ولكنها أخرجتني من المشاكل عندما كنت بحاجة إلى تجميع ملف C بسيط.

أواجه نفس النوع من المشكلة عند تثبيت Ubuntu 8.04 الافتراضي.اضطررت إلى الحصول على رؤوس/ملفات مطور libc يدويًا حتى تعمل.

تم حل هذا بالنسبة لي (تجميع pjsip المتقاطع لـ ARM):

export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top