Rust: الارتباط بـ LLD

تم إنشاؤها على ١٧ فبراير ٢٠١٧  ·  94تعليقات  ·  مصدر: rust-lang/rust

يتم شحن LLVM 4.0 مع تمكين LLD ، على الرغم من أن AFAIK ليس جاهزًا بعد للإنتاج على جميع المنصات. أعتقد أننا حصلنا على ترقية LLVM مخطط لها قريبًا لحل مشكلات AVR / emscripten على أي حال ، لذلك حان الوقت الآن للبدء في تحديد ما قد نحتاج إلى القيام به لدعمه ، وكيف يؤثر على أداء المترجم / الحجم الثنائي / أداء وقت التشغيل مقارنةً بأداءنا الروابط المعتادة ، والأنظمة الأساسية التي قد نرغب في تمكينها افتراضيًا.

الحالة الحالية (2020-04-24) ملخصة في https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211

A-linkage C-feature-request I-compiletime T-compiler

التعليق الأكثر فائدة

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

ما هو lld

رابط هو جزء من مشروع llvm ، وهو أمر مرغوب فيه لسببين:

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

الأشياء التي يفعلها Rust مع lld اليوم

  • يقوم Rust حاليًا بشحن نسخته الخاصة من lld على معظم المنصات باعتباره ثنائيًا يسميه rust-lld
  • يتم استخدام rust-lld افتراضيًا في العديد من الأهداف المعدنية
  • يتم استخدام rust-lld افتراضيًا مع wasm
  • (؟) يمكنك طلب استخدام rust-lld بشكل صريح باستخدام "-C linker-flavour" (غامض بشأن ما يفعله هذا بالضبط على المنصات غير المعدنية ، انظر أدناه)

مشاكل استخدام rust-lld في أماكن أكثر (مثل سطح المكتب Linux / mac / windows)

  • واجهة macOS (Mach-O) الخلفية لـ lld مكسورة ومهجورة

    • بدأت عملية إعادة الكتابة من الصفر ، لكنها الأيام الأولى

  • في الأنظمة الأساسية لينكس / يونكس ، ليس من المفترض أن تستدعي ld / lld مباشرة. من المفترض أن تستدعي الرابط من خلال برنامج التحويل البرمجي c في نظامك (مثل gcc) ، الذي تقع على عاتقه مسؤولية اكتشاف رموز النظام مثل crt1.o وتزويدها بـ ld. هذا يعني أننا لا نستطيع "فقط" استخدام rust-lld ؛ يجب علينا إطعامها في دول مجلس التعاون الخليجي / clang / أيا كان. (لا نريد تطبيق منطق رمز النظام هذا بأنفسنا)

    • بشكل عام ، لا يمكنك توفير الرابط كمسار ، يجب عليك حقنه في مسار بحث مترجم لغة سي على هيئة "ld"

    • بدلاً من ذلك ، يمكنك فعل الشيء نفسه ولكن حقنه كـ "ld.lld" ، وتمرير "-fuse-ld = lld"



      • قد يكون هذا مهمًا ، فعلى ما يبدو أن lld يقوم بالكشف عن اسم ثنائي على غرار رنكة إذا كان يتم تنفيذه كـ "ld" أو "ld.lld" (يحتاج إلى التحقيق)


      • لسوء الحظ -fuse-ld = lld هو جزء فقط من GCC 9 ، لذلك قد نطلب ميزة / اكتشاف الإصدار لاستخدامه (كان clang يستخدمه لفترة طويلة)



  • نوافذ MSVC على ما يبدو في حالة جيدة، ويبدو أن لديها بعض الدعم المحدود لاستخدام الصدأ وبكالوريوس في القانون في الخلفية، ولكن أنا غير واضحة حول ما يجب القيام به هنا.
  • يبدو أن windows-mingw في نفس المكان تقريبًا مثل linux / unix ، باستثناء أنك عرضة للحصول على دول مجلس التعاون الخليجي القديمة ، والأشياء متزعزعة بعض الشيء لأن pseudo-windows-linux ليست بالضبط تكوينًا تم اختباره جيدًا؟

بشكل عام أيضًا ، يعد lld أحدث ، وليس الإعداد الافتراضي لمعظم أنظمة التشغيل ، فمن المؤكد تقريبًا ظهور أخطاء عشوائية متوافقة إذا بدأنا في استخدام هذا في أماكن أكثر.

لقد قدمت جهازي تعريف لجهود مركزة على استخدام (rust-) lld افتراضيًا على نظامين أساسيين:

  • # 71515 - x64 Ubuntu 20.04 LTS (وعلى نطاق أوسع جميع منصات x64 ELF)
  • # 71520 - نوافذ x64 msvc

ال 94 كومينتر

راجع أيضًا PoC في # 36120.

قد يكون LLD مرشحًا جيدًا جدًا لأهداف MinGW ، لأننا نقوم حاليًا بتجميع رابط معهم على أي حال ، ولرابط MinGW مجموعة متنوعة من المشكلات التي تتراوح من نقص ASLR إلى عدم وجود دعم bigobj. إذا تمكنا بطريقة ما من إحضار مكتبات mingw الضرورية عند التجميع المتقاطع وليس فقط الاستهداف المحلي (الذي تقتصر عليه حزمة rustup's mingw حاليًا) ، فسيؤدي ذلك إلى تمكين تجميع الصدأ المتقاطع من نظام التشغيل Linux خارج الصندوق ، والذي سيكون بمثابة تحسين كبير على الوضع الحالي حيث يحصل الأشخاص على MinGW من توزيعاتهم ثم يواجهون مشكلات لأن التوزيعات تستخدم دائمًا MinGW غير متوافق.

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

مشكلة التتبع الخاصة بالترقية إلى LLVM 4.0 هي https://github.com/rust-lang/rust/issues/37609 .

للتسجيل ، فإن lld ليست جاهزة بالتأكيد لأهداف سولاريس. ولكن في Solaris ، لا يوجد سبب يجعلني على دراية باستخدام lld بدلاً من ld الأصلي. لقد بحثنا بالفعل في ما يتطلبه استخدام الصدأ Solaris ld على Solaris بدلاً من استخدام دول مجلس التعاون الخليجي للربط.

binarycrusader أحد أسباب استخدام lld هو عند البناء لـ Solaris ، وليس على Solaris.

يضيف PR rust-lang / rust # 40018 علامة -Z linker-flavor إلى rustc لتمكين استخدام LLD كرابط. لا تقوم العلاقات العامة بتضمين LLD في الصدأ ولكنه يسمح بالتجربة خارج الشجرة معه.

binarycrusader ^ قد يساعدك في تجربتك لاستخدام Solaris 'ld مباشرةً بدلاً من دول مجلس التعاون الخليجي.

يبدو أننا الآن نعمل على LLVM 4.0. japaric ، هل هذا يعني أنه يمكن الآن استخدام علامة linker-flavour بسهولة لمقارنة وتباين LLD مع رابط النظام؟

bstrie # 40018 هبطت قبل بضعة أسابيع. منذ ذلك الحين ، تمكن الشخص من استخدام -Z linker-flavor=ld -C linker=ld.lld لاستخدام ثنائي LLD خارجي كرابط. لاحظ أنه ، على عكس مجلس التعاون الخليجي ، لا يعرف LLD مكان مكتبات النظام ، لذا سيتعين عليك تمرير مسار بحث المكتبة إلى الرابط باستخدام -C link-args='-L ...' إذا كنت تقوم بالارتباط بأي مكتبة نظام.

ما يساعده LLVM 4.0 هو دمج LLD في rustc. مع هذا التغيير ، لن نطلب رابطًا خارجيًا في بعض السيناريوهات مثل ربط ثنائيات MUSL أو البرامج المعدنية. أقول بعض السيناريوهات لأن معظم الأهداف تتطلب الارتباط بمكتبات النظام حيث ستواجه مشكلة مسار بحث المكتبة التي ذكرتها أعلاه. بالنسبة لتلك الأهداف ، لن يعمل LLD خارج الصندوق. ليس من الواضح كيف وأين يتم حل هذه المشكلة وبدون حل لذلك لا يمكننا التبديل إلى LLD لأهم أهداف (المستوى 1) ، والتي تقلل من جاذبية تضمين LLD في rustc في المقام الأول.

japaric ما هي الحجج ضد تضمين مسارات البحث (مكتبة نسبية sysroot) ، بالإضافة إلى أشياء مثل -lc -lpthread crt0.o ، مباشرة في rustc؟ بعد كل شيء ، يجب أن تقوم بعض مكونات سلسلة الأدوات بتضمينها لأننا لا نملك أي معيار تتبعه الأنظمة الأساسية ، كما أن binutils ليست مصدرًا ذهبيًا جيدًا لهذه المعرفة.

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

@ retep998 لقد

آمل أن أكون مخطئا.

وضع علامة على هذا على أنه خطأ في الأداء ، نظرًا لأنه وفقًا لمعايير LLD يبدو أنه يتفوق على GNU ld بعشرة أضعاف ، وربط الأداء هو مكون كبير لسرعة المترجم حاليًا.

إيه ، نسيت ربط المعايير: https://lld.llvm.org/#performance

(مناسب اليوم منذ إصدار LLVM 5.0 للتو.)

يعد الارتباط بـ LLD أسرع بكثير من bfd أو الذهب ، لكنني أشك في أن استخدامه سيحسن الأداء العام بشكل كبير. ما زلت أعتقد أن هذه القضية مهمة ويجب أن تكون ذات أولوية.

tpimh لست متأكدًا تمامًا مما إذا كان من المفترض أن تمثل علامة I-slow أخطاء أداء وقت التشغيل أو أخطاء أداء compiletime ، كنت أنوي ذلك باعتباره الأخير. وعندما أنظر إلى ربط المخرجات بمرور الوقت ، عادة ما يكون في المراحل الثلاث الأولى الأطول ، وهو أطول بكثير من معظمها ، لذا فمن المحتمل أن يكون قطع وقت الربط إلى النصف بمثابة فوز كبير (خاصة بالنسبة للأشياء الكبيرة مثل Servo و rustc).

bstrie I-slow للأداء السيئ في وقت التشغيل ، I-compiletime مخصص لأداء المترجم آخر مرة راجعت فيها

بشرى سارة لأي شخص مهتم بالموضوع الغامض للربط المتقاطع من Linux إلى Windows. لقد قلت سابقًا أنه لم يكن ممكنًا مع lld ، لكن هذا صحيح فقط لنكهة lld's ld. من الممكن لنكهة lld's link.exe (lld-link).

على وجه التحديد بالنسبة لـ Rust ، يمكننا القيام بذلك اليوم من خلال بعض التغييرات في الكود.

  1. نحتاج إلى تجميع مجموعة فرعية صغيرة جدًا من CRT الخاص بـ mingw-w64 في ملفات كائن .o. وهي بعض عناصر التخزين المحلي لمؤشر الترابط. نحتاج أيضًا إلى chkstk.

  2. lld لا يحب مكتبات الاستيراد المعتادة لـ MinGW. بدلاً من ذلك ، نحتاج إلى إنشاء ملفات .def في ملفات .lib بأنفسنا ، باستخدام lld-link أو llvm-dlltool

  3. قم بتعديل lld لمعاملة IMPORT_NAME_NOPREFIX مثل
    IMPORT_NAME_UNDECORATE ، لأنه حتى مع الخطوة 2 ، فإن ملفات .lib ليست مثالية

  4. قم بتعديل seh.rs الخاص بـ Rust لاستبدال TYPE_INFO_VTABLE بـ ptr :: null (). مطلوب لأن الرمز ??_7type_info@@6B@ غير معرّف في MinGW. ثم قم ببناء وتثبيت الصدأ.

  5. استخدم .cargo / config لتحديد برنامج غلاف مخصص ليكون الرابط.

  6. يجب أن يستدعي البرنامج النصي لرابط الغلاف الخاص بنا lld-link في الغالب باستخدام المعلمات التي يتم تمريرها. ومع ذلك ، يجب إجراء بعض التعديلات:

    أ) إصلاح غلاف اسم الملف ، مثل تغيير AdvAPI32.Lib إلى advapi32.lib

    ب) تعديل ملف .def يولد Rust لرموز بادئة بشرطة سفلية إضافية

    ج) تجاوز نقطة الدخول (/ الدخول). مطلوب على الأرجح بسبب مشكلة في تغيير الاسم.

    د) قم بإلحاق ملفات كائن mingw-crt التي جمعتها في الخطوة 1

  7. قم ببناء مشروع Rust الخاص بك باستخدام xargo --target = i686-pc-windows-msvc

يسمح لي القيام بالخطوات المذكورة أعلاه بتجميع كود Rust. يمكنني حتى الذعر والتقاط الذعر باستخدام حل Rust القائم على SEH.

iainnicol أنت تخلط هدف msvc مع وحدات بت MinGW ، ولهذا السبب يتعين عليك إجراء كل تلك التعديلات الغريبة. إذا قمت فقط بنسخ المكتبات من تثبيت VC ++ موجود ، فيمكنك استخدام lld-link بشكل طبيعي بدون كل هذه التعديلات أو أي MinGW بتات.

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

تعتبر أدوات البناء المستقلة أخف وزنًا بكثير ، ما لم يكن هذا هو ما تشير إليه بالفعل ، وفي هذه الحالة ربما يتعين علينا بذل بعض العمل لتحسين أو إعادة إنشاء ما قام به MinGW ، لذا فهو متوافق بالفعل مع MSVC.

أدوات البناء المستقلة أخف وزنًا بكثير

لم أدرك أن Microsoft توزع هؤلاء. هل يمكنك الارتباط بهم؟ هل هناك أي طريقة معقولة لاستخراج أرشيف التثبيت دون تشغيله فعليًا ، أي هل هو msi أو شيء مشابه؟

ها هم: http://landinghub.visualstudio.com/visual-cpp-build-tools

يعد كل من إصداري 2015 و 2017 إصدارات ، ولكن قد تتمكن من إقناع 2017 exe بإعطائك ما تريد عبر هذا: https://docs.microsoft.com/en-us/visualstudio/install/install-vs- شبكة ذات جودة غير متسقة

إذا كنا نريد حقًا القيام بذلك بشكل صحيح لنظام التشغيل Windows ، فسنحتاج أولاً وقبل كل شيء إلى https://github.com/rust-lang/rust/issues/30027 للتخلص من الحاجة إلى مكتبات استيراد Windows SDK أو MinGW. ثم كل ما تبقى لدينا هو استبدال بتات CRT بإصداراتنا الخاصة من الصدأ (وظائف الرياضيات / الذاكرة ، نقطة الدخول ، عدد قليل من أجزاء وقت التشغيل الأخرى التي يحتاجها الصدأ) وسيكون لدينا سلسلة أدوات Rust قائمة بذاتها يمكنها إنشاء ثنائيات Windows! الجانب السلبي لهذا هو أنك لن تكون قادرًا على ربط كود C / C ++ بشكل ثابت لأن ذلك يعتمد بشكل كبير على الارتباط في CRT المناسب من MinGW أو VC ++. بالطبع ، الهدف الأساسي من Rust هو إعادة كتابة كل شيء في Rust ، لذا فهذه ليست مشكلة كبيرة حقًا.

بشرى سارة لأي شخص مهتم بالموضوع الغامض للربط المتقاطع من Linux إلى Windows. لقد قلت سابقًا أنه لم يكن ممكنًا مع lld ، لكن هذا صحيح فقط لنكهة lld's ld. من الممكن لنكهة lld's link.exe (lld-link).

يبدو أنه يجب أن يكون ممكنًا الآن مع نكهة ld أيضًا: https://reviews.llvm.org/rL312926

برنامج التشغيل المتوافق مع MinGW من lld الجديد عبارة عن غلاف لرابط lld-linker. يترجم داخليًا خيارات Unix-ish إلى خيارات Windows-ish ثم استدعاء نقطة دخول lld-link. لست متأكدًا مما إذا كنت ترغب في استخدامه يا رفاق لأنه (باستثناء أن برنامج تشغيل الغلاف غير مكتمل وغير جاهز للاستخدام) لا يبدو أنه يجعل الأمور أسهل ما لم يكن لديك بالفعل ملفات Makefiles لـ MinGW.

لدي سؤال (ربما سخيف) لكم يا رفاق حول التجميع المتقاطع. في نظام التشغيل Windows ، تحتوي جميع رموز dllimport'ed على أسماء DLL التي يتم استيرادها منها. إذا لم يكن لديك أي ملفات مكتبة MSVC ، كيف تعرف الملفات التي يتم استيراد رموز dllimport'ed منها؟

لدي سؤال (ربما سخيف) لكم يا رفاق حول التجميع المتقاطع. في نظام التشغيل Windows ، تحتوي جميع رموز dllimport'ed على أسماء DLL التي يتم استيرادها منها. إذا لم يكن لديك أي ملفات مكتبة MSVC ، كيف تعرف الملفات التي يتم استيراد رموز dllimport'ed منها؟

إذا لم يكن لديك أي مكتبات استيراد ، فعليك إما إنشاء مكتبات استيراد أو تنفيذ https://github.com/rust-lang/rust/issues/30027 حتى يتمكن winapi القيام بكل ما هو صعب العمل على تحديد مكتبة الارتباط الديناميكي التي يأتي كل رمز منها جنبًا إلى جنب مع الأناقة مثل القيم الترتيبية. يجب أن يحدد شيء ما تعيين الرموز في وقت الارتباط بالرموز / الترتيب الترتيبي في مكتبات DLL ، سواء كانت مكتبات استيراد أو تعليقات توضيحية في التعليمات البرمجية الخاصة بك.

بعد سحب https://reviews.llvm.org/rL311734 ، أصبحت قادرًا تقريبًا على تمهيد rustc باستخدام lld على macOS. يبدو أن هناك مشكلة في البيانات الوصفية لـ dylib ، والتي ما زلت بحاجة إلى التحقيق فيها.

لدي فرع يقوم بإحياء https://github.com/rust-lang/rust/pull/36120 ؛ نظرًا لأننا نحتاج إلى إصلاح lld (حديث جدًا) ، تم حظر هذا على https://github.com/rust-lang/rust/issues/43370.

tamird : # 43370 مغلق.

تمت إضافة LLD في https://github.com/rust-lang/rust/pull/48125 ويتم شحنه الآن مع منصات المستوى 1 (mac و linux و windows). يمكنك اختبارها -Z linker-flavor لكل منصة ، على الرغم من أنه من غير المحتمل أن تعمل مع معظم الأنظمة الأساسية افتراضيًا. ومع ذلك ، فإنه يعمل بشكل افتراضي على MSVC. على سبيل المثال:

$ RUSTFLAGS='-Z linker-flavor=lld-link' cargo build

خفض وقت الارتباط الخاص بشركة Cargo من 2.5 ثانية إلى 1.5 ثانية ، وهو تحسن رائع!

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

خاصة مع التجميع المتزايد ، سيكون ربط الأداء أكثر أهمية من أي وقت مضى.

من المؤسف أن ربط الأداء لا يزال غير مهم بما يكفي بالنسبة لنا للقيام بأشياء مثل تمكين الارتباط المتزايد على الأنظمة الأساسية التي تدعمه. https://github.com/rust-lang/rust/issues/37543

bstrie أعتقد أن هذه هي الخطوات التالية ، وجعلها تعمل على منصات أخرى :)

بالنسبة لما يستلزمه ذلك ، لست متأكدًا ، لكنه يعمل بالفعل على MSVC ، أعتقد أنه بعيد عن العمل على MinGW / Linux ، ونحن قريبون جدًا من OSX. بالنسبة للدعم المتقاطع ، لست متأكدًا أيضًا. لا أتوقع أننا سنقوم "بتثبيته" لأي شيء آخر غير منصة wasm في المستقبل القريب.

alexcrichton هل لي أن أسأل كيف تحدد "الاستقرار"؟ لماذا لا يكون من الممكن "تثبيت" الارتباط بـ lld للمنصات الرئيسية الأخرى التي تدعم الصدأ؟ (على سبيل المثال ، التحويل البرمجي المتقاطع لملف تنفيذي من نظام التشغيل Linux لنظام التشغيل macOS).

في الوقت الحالي ، من الصعب إجراء ترجمة متقاطعة ، على سبيل المثال ، يتطلب العمل المطلوب لتجميع ملف تنفيذي لنظام التشغيل macOS (x86_64-apple-darwin) من Linux خطوات غير تافهة مثل الحصول على xcode sdk وبناء سلسلة الأدوات بالكامل.

@ cynecx سؤال جيد! واحد لم أفكر فيه كثيرًا. أعتقد ، مع ذلك ، أننا لا نرغب في تحقيق الاستقرار الفعلي لـ LLD لمجرد أننا أضفناه لمنصة أخرى ، فسوف يتطلب الأمر وقتًا والعمل على تصحيحه وفضحه جيدًا.

على سبيل المثال ، يتطلب العمل المطلوب لتجميع ملف تنفيذي لنظام التشغيل macOS (x86_64-apple-darwin) من Linux خطوات غير تافهة مثل الحصول على xcode sdk وبناء سلسلة الأدوات بالكامل.

لن يساعدك LLD حقًا هنا ، ما زلت بحاجة إلى Xcode SDK لأنه يحتوي على رؤوس لا يمكنك إعادة توزيعها (واعتمادًا على ما تقوم ببنائه ، ستحتاج إلى أدوات SDK أخرى أيضًا).

ما هو لطيف حقًا حول LLD التي يتم تضمينها الآن ليلاً هو أنه يمكنك بسهولة تجميع مشاريع Rust الخالصة من Windows إلى Linux RUSTFLAGS='-Z linker-flavor=ld.lld' cargo build --target x86_64-unknown-linux-musl . رائعة لكتابة الأدوات الصغيرة لأجهزة Linux التي لا يمكنك ببساطة تثبيت Rust عليها.

لا أتوقع أننا سنقوم "بتثبيته" لأي شيء آخر غير منصة wasm في المستقبل القريب.

كما قال rkarp ، هناك حالة استخدام شائعة جدًا تستهدف x86_64-unknown-linux-musl (وفي النهاية ستيد) لدعم أعباء عمل Linux المعبأة في حاويات. هذا هو أحد تلك الأشياء التي يقوم Go بعملها جيدًا وحيث يبدو أننا قريبون جدًا من قدرة Rust على القيام بالمثل. من حيث الاستخدام الفعلي ، أراهن على استخدام LLD لـ x86_64-unknown-linux-musl على نطاق أوسع بكثير من wasm.

بشكل عام ، عندما يتعلق الأمر بالبناء المتبادل ، لا أعتقد أن نهج "يجب أن يعمل مع جميع المضيفين و / أو جميع الأهداف" منطقي. أعتقد أنه من المنطقي تثبيت هذا على أساس كل هدف على حدة عندما تبدأ الأهداف في العمل.

على وجه الخصوص ، أود المساعدة في الجهود المبذولة للحصول على LLD لهدف x86_64-unknown-linux-musl المستقر في أسرع وقت ممكن.

يحتوي مشروعي على 37 صندوقًا ، ويربط التصميم حوالي 70 ثنائياً (الكثير من الاختبارات). بشكل غير علمي (eyeballing top ) نصف وقت الإنشاء على الأقل نحن نشغل فقط ld. أتوقع أن يؤدي استخدام lld إلى تسريع عمليات الإنشاء لدينا كثيرًا. نحن في حالة Rust مستقرة ولم أتمكن من الحصول على 6.0 lld للعمل حتى الآن.

briansmith هل اختبرت LLD من أجل musl وحالة الاستخدام الخاصة بك؟ نظريًا ، كل ما عليك فعله لاختباره هو اجتياز -Z linker-flavor=ld.lld ، وإذا كان هذا يبدو معقولاً يمكننا تبديل الإعدادات الافتراضية!

rocallahan فقط للتأكيد ، -Z linker-flavor=ld.lld يعمل (وكان أسرع) ، فيمكننا أن نتطلع إلى تثبيته ربما! على أي منصة كان ذلك؟

غير علمي (الجزء العلوي من العين) على الأقل نصف وقت الإنشاء الذي نقوم بتشغيله فقط.

هذا لبناء تصحيح راجع للشغل.

أنتم تستخدمون رابط الذهب حاليًا ، أليس كذلك؟ (لأن afaik أسرع من رابط binutils القياسي)

لا ، هذا هو رابط نظام فيدورا ، رابط جنو القياسي.

على أي منصة كان ذلك؟

فيدورا 27 ، كمبيوتر محمول رباعي النواة Skylake مزود بذاكرة مصنوعة من مكونات صلبة (SSD). سأحصل على بعض أرقام الأداء.

آه حسنًا ، من الجيد معرفة! من المحتمل أن تحصل تصميمات التصحيح على أكبر فائدة في وقت الارتباط من التقزم المقسم (https://github.com/rust-lang/rust/issues/34651) بدلاً من تحسينات الرابط.

للحصول على معلومات حول التوقيت ، على الرغم من ذلك ، rocallahan إذا حصلت على فرصة لاختبار العقل باستخدام ld.gold و ld.lld ؟

بالتأكيد. يجب أن أذكر أيضًا أن المشكلة رقم 48762 هي ثمرة منخفضة جدًا لتسريع أوقات ارتباط تصحيح أخطاء Linux. (نحن بالفعل نستخدم نصًا برمجيًا للرابط المخترق يسقط .debug_pubnames / .debug_pubtypes من الملف القابل للتنفيذ.)

قد يكون Split DWARF جيدًا ولكنه قد يتسبب أيضًا في حدوث مشكلات للمستخدمين. سأعلق في هذا الموضوع.

briansmith هل اختبرت LLD من أجل musl وحالة الاستخدام الخاصة بك؟ نظريًا ، كل ما عليك فعله لاختباره هو تمرير -Z linker-flavour = ld.lld ، وإذا كان ذلك يبدو معقولاً يمكننا تبديل الإعدادات الافتراضية!

حسنًا ، سأختبر الأشياء. ربما في البداية يجب أن يكون هناك حل وسط بين "افتراضي" و "فقط في الليل" ، طريقة ما لاختيار استخدام LLD كما يمكننا مع -Z ، ولكن بدون استخدام -Z حتى يعمل في بنيات مستقرة.

ولكن بدون استخدام -Z بحيث يعمل في تصميمات مستقرة.

يمكنك تجربة RUSTC_BOOTSTRAP=1 RUSTFLAGS="-Z linker-flavor=foo" cargo build

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

آسف = /

كنقطة بيانات ، انخفض ربط الصندوق rustc_trans في Rust repo نفسه من وقت ارتباط 78 ثانية إلى وقت ارتباط 1 ثانية على جهازي المحلي.

ينتج أدائي من تغيير المسافة البيضاء إلى صندوق بالقرب من أسفل التسلسل الهرمي للصندوق. كمبيوتر محمول رباعي النواة Skylake ، ذاكرة وصول عشوائي 16 جيجا ، رستك 1.24.0 ، LLD 7.0.0 ، GNU LD 2.29-13. نستخدم برنامج نصي رابط مخصص يتجاهل .debug_pubnames و .debug_pubtypes ؛ يستخدم LLD مسارات رمز مختلفة تمامًا عند وجود نص رابط ، لذلك قد يؤثر ذلك على الأشياء.

جنو لد:

real    2m39.138s
user    8m18.992s
sys 1m37.513s

LLD:

real    2m19.164s
user    6m4.477s
sys 0m56.858s

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

انظر # 50584 للحصول على مثال من العالم الحقيقي حيث يؤدي التبديل من GNU ld إلى lld إلى تنفيذ "تغيير طفيف وإعادة بناء" عبء العمل بشكل أسرع بأكثر من 2.5 مرة.

Er https://github.com/rust-lang/rust/issues/50584#issuecomment -400918647 هو أكثر ملاءمة هنا:


ستكون الخطوة التالية لتحقيق الاستقرار في LLD هي الحصول على علامة ، مثل -Z ​​linker-flavour = lld ، تعمل لجميع الأهداف (Windows + Mac + Linux). ستفعل كل ما تحتاج إلى القيام به للعمل عبر الأنظمة الأساسية المختلفة.

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

لقد تحولنا إلى lld لبعض الأهداف: https://rust-embedded.github.io/blog/2018-08-2x-psa-cortex-m-breakage/

اعتقد ل wasm كذلك؟

هل تغطي هذه المشكلة كلاً من الارتباط مع ثنائي lld خارجي والربط مع دعم lld داخلي مضمن في rustc نفسه؟ أم فقط السابق؟

هل تغطي هذه المشكلة كلاً من الارتباط مع ثنائي lld خارجي والربط مع دعم lld داخلي مضمن في rustc نفسه؟ أم فقط السابق؟

فقط ثنائي lld الخارجي ، IIUC.

nnethercote هل هناك مشكلة أخرى تتعلق بتتبع استخدام رابط داخلي ، أم يجب علي تقديم مشكلة منفصلة لذلك؟

لم اسمع بفكرة الرابط الداخلي من قبل. أنا لست على علم بالعلاقات العامة لذلك.

https://github.com/rust-lang/rust/pull/57514 أرضية مُعدة لاستخدام LLD لربط LLVM.

ربما في البداية يجب أن يكون هناك حل وسط بين "الافتراضي" و "فقط في الليل" ، طريقة ما لاختيار استخدام LLD كما يمكننا مع -Z ، ولكن بدون استخدام -Z بحيث يعمل في بنى مستقرة.

https://github.com/rust-lang/rust/pull/56351 أضاف -C linker-flavor .

ليس من الواضح ما الذي تهدف هذه المشكلة إلى تتبعه. يبدو أنه سيكون من الأفضل إغلاق هذا لصالح وجود مشكلات محددة ، على سبيل المثال "الارتباط بـ LLD لأهداف msvc عندما لا تكون سلسلة أدوات Microsoft متاحة".

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

FWIW لقد قدمت خطأ لدعم LLD على macOS في BMO. يبدو أن هذا هو WONTFIX. من التعليقات هناك ، يبدو أن الأمر ليس بهذه البساطة مثل "LLD سريع للغاية" ، نظرًا لأن LLDs على منصات مختلفة هي برامج مختلفة ، والبرامج الموجودة على macOS معطلة بسبب توقف التطوير.

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

هل الارتباط بـ LLD موثق في أي مكان؟ لدي (على نظام التشغيل Linux) rustc -C linker-flavor=ld.lld hello.rs ، لكن لم يحالفني الحظ. اعتقدت أنه تم توزيع LLD مع نسختنا من LLVM ، هل أنا مخطئ؟ لقد حاولت أيضًا تثبيت LLD عبر apt ، لكن rustc لا يزال محيرًا. ما هي الخطوات التي يجب اتخاذها لتجربة LLD مع كود Rust اليوم؟

bstrie يجب عليك أيضًا تمرير الوسيطة -C linker=rust-lld .

هل من المفترض أن تعمل مع البضائع؟ أتلقى حاليًا الأخطاء التالية عند محاولة إنشاء مشروع فارغ على أحدث بناء ليلي من الصدأ والبضائع.

$ RUSTFLAGS='-C linker=rust-lld' cargo build
   Compiling rust3 v0.1.0 (/home/carado/tmp/rust3)
error: linking with `rust-lld` failed: exit code: 1
  |
  = note: "rust-lld" "-flavor" "gnu" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.2ualxzb8lqn4ho3y.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.32vfyq64cfbzv618.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.4rbt3m5y8o8cl09t.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.ben0932xzwyt64v.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.fzsdnygvstiwzxo.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.x0rq6ifodcf11zi.rcgu.o" "-o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.1m259ox4uzrzk583.rcgu.o" "--gc-sections" "-pie" "-zrelro" "-znow" "-L" "/home/carado/tmp/rust3/target/debug/deps" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--start-group" "-Bstatic" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-44988553032616b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-607feef6be9150b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-a8dbf6d92401e34a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-9a4716f5e8a3e722.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-988a64d96b043c6d.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-cadd6177b8c6d586.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-8f1d8efc92b45369.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-1e76014677816767.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-cc28bce38cb195d9.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4123e9e89add689a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4d259c17788c1fb5.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-9495dbda85bb8f16.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-793d0026c575805f.rlib" "--end-group" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-33c3162edae6574e.rlib" "-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: rust-lld: error: unable to find library -ldl
          rust-lld: error: unable to find library -lrt
          rust-lld: error: unable to find library -lpthread
          rust-lld: error: unable to find library -lgcc_s
          rust-lld: error: unable to find library -lc
          rust-lld: error: unable to find library -lm
          rust-lld: error: unable to find library -lrt
          rust-lld: error: unable to find library -lpthread
          rust-lld: error: unable to find library -lutil
          rust-lld: error: unable to find library -lutil


error: aborting due to previous error

error: Could not compile `rust3`.

To learn more, run the command again with --verbose.

أنا أتلقى نفس أخطاء كارادو. تمت إدارتها إلى "قرن الحذاء" -L / usr / lib في استدعاء الرابط ولكن هذا يختصر فقط قائمة libs المفقودة إلى -lgcc والتي لا توجد في أي مكان في النظام مثل libgcc (هناك libgcc_s.a ) أظن أن هذا نتيجة لبعض gnu-ism ولكن لا يمكنني معرفة كيفية إصلاحه.

almindor جرب RUSTFLAGS='-C linker=rust-lld -L /usr/lib -L /usr/lib/gcc/x86_64-pc-linux-gnu/9.1.0' أو شيء مشابه. سيعتمد المسار على إصدار التوزيعة والمجمع.

هل تعليقي أعلاه هو الطريقة الصحيحة لاستخدام LLD؟ لا يمكنني تشغيله ، حيث يتعطل كل برنامج مع SIGSEGV :

Reading symbols from target/debug/hello...
(gdb) show directories
Source directories searched: ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/etc:$cdir:$cwd
(gdb) r
Starting program: target/debug/hello 

Program received signal SIGSEGV, Segmentation fault.
core::ops::function::FnOnce::call_once{{vtable-shim}} () at /rustc/a7f28678bbf4e16893bb6a718e427504167a9494/src/libcore/ops/function.rs:231
(gdb) l
226     #[stable(feature = "fn_once_output", since = "1.12.0")]
227     type Output;
228 
229     /// Performs the call operation.
230     #[unstable(feature = "fn_traits", issue = "29625")]
231     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
232 }
233 
234 mod impls {
235     #[stable(feature = "rust1", since = "1.0.0")] 
(gdb) info reg
rax            0x0                 0
rbx            0x0                 0
rcx            0x0                 0
rdx            0x0                 0
rsi            0x0                 0
rdi            0x0                 0
rbp            0x0                 0x0
rsp            0x7fffffffddb0      0x7fffffffddb0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
r13            0x0                 0
r14            0x0                 0
r15            0x0                 0
rip            0x7ffff7ffc000      0x7ffff7ffc000 <core::ops::function::FnOnce::call_once{{vtable-shim}}>
eflags         0x10202             [ IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
(gdb) disassemble 
Dump of assembler code for function core::ops::function::FnOnce::call_once{{vtable-shim}}:
=> 0x00007ffff7ffc000 <+0>: mov    (%rdi),%rax
   0x00007ffff7ffc003 <+3>: mov    (%rax),%rdi
   0x00007ffff7ffc006 <+6>: jmpq   *0x11d4(%rip)        # 0x7ffff7ffd1e0
End of assembler dump.

بالنسبة لأي شخص ينتهي هنا ، فإن التعويذة السحرية هي RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo build إذا كان لديك GCC 9 أو Clang كمترجم. بدلاً من ذلك ، يجب أن يعمل -C linker=clang بغض النظر عن إصدار GCC ، لذلك قد يكون مفضلاً.

لجعل ذلك دائمًا ، يمكنك إضافته إلى ~/.cargo/config أو .cargo/config في مشروع معين:

[build]
rustflags = ["-C", "linker=clang"]
# rustflags = ["-C", "link-arg=-fuse-ld=lld"]

lnicola لاحظ أنه يعمل فقط عند استخدام GCC 9 أو Clang كـ CC.

bstrie هل تعرف ما هو الوضع الحالي لهذا؟ ما هي الحواجز للمضي قدما معها؟

@ mati865 هل تعرف استدعاء بديل للأشخاص الذين لديهم دول مجلس التعاون الخليجي القديمة؟

lnicola جميع أتحقق من كيفية استخدامها مع المجمعين غير المتوافقين.

jonhoo لست على اطلاع بأي عمل في هذا المجال ، أعتقد أنك تريد أن تسأل فريق المترجم.

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

نخب؛ @ rust-lang / compiler هل يعرف أحد ما هو الوضع الحالي لهذه المشكلة؟

لأي شخص هنا يدير تشغيل LLD مع Rust ، هل يمكنك إضافة تفاصيل حول النظام الأساسي الخاص بك والإصدارات المحددة لجميع المجمعات المستخدمة؟ ما زلت أرى أشخاصًا في البرية يواجهون مشكلة في تشغيله ، حتى مع النصيحة المدرجة هنا.

يعمل الأمر الذي نشرته أعلاه على Linux مع GCC 9.2.0 و LLD 9.0.0. أعتقد أنه يعمل أحيانًا أيضًا على Windows ، لكنني رأيت شخصًا لديه GCC 9 لنظام التشغيل Windows لا يدعم -fuse = lld. على نظام MacOS ، لا يستحق المحاولة ، وفقًا لبعض الروابط المنشورة هنا.

لأي شخص هنا يدير تشغيل LLD مع Rust ، هل يمكنك إضافة تفاصيل حول النظام الأساسي الخاص بك والإصدارات المحددة لجميع المجمعات المستخدمة؟ ما زلت أرى أشخاصًا في البرية يواجهون مشكلة في تشغيله ، حتى مع النصيحة المدرجة هنا.

cat / etc / system-release
الإصدار 30 فيدورا (الثلاثين)

نسخة
سم مكعب (دول مجلس التعاون الخليجي) 9.2.1 20190827 (ريد هات 9.2.1-1)

ld.lld - الإصدار
LLD 8.0.0 (متوافق مع روابط جنو)

نأمل أن يساعد هذا

لكني رأيت شخصًا لديه GCC 9 لنظام التشغيل Windows لا يدعم -fuse = lld

تضمين التغريدة
تدعم إصدارات Windows GCC 9 -fuse-ld=lld (ما لم يتم تصحيحها لعدم دعمها ولكن لماذا يقوم شخص ما بذلك؟).
أفترض أنه تم تثبيت المكون rust-mingw ولم يتم تجاوز الرابط في .cargo/config . وبهذه الطريقة ، اختار Rustc دول مجلس التعاون الخليجي 6 لشحنها بدلاً من النظام الأول.

هناك مشكلة أخرى على Windows وهي علامة الرابط الثابتة --enable-long-section-names التي لا يدعمها LLD 9 وما فوق (هناك خطط لدعمه في المستقبل). للتغلب على هذا يمكنك:

  • إنشاء غلاف الذي يزيل هذا العلم
  • تصحيح LLD لقبول هذه العلامة على أنها no-op
  • استخدام تصميمات Rust المحلية المصححة التي لا تستخدم هذه العلامة

هناك مشكلة أخرى على Windows وهي علامة الرابط الثابت - أسماء المقاطع الطويلة القابلة للتمكين والتي لا يدعمها LLD 9 وما بعده (هناك خطط لدعمه في المستقبل).

تم إصلاح هذا الجزء من خلال: https://github.com/rust-lang/rust/pull/66257
لا يزال يتعين على مستخدمي Windows-gnu القيام بعمل يدوي لاستخدام مترجم C الذي يدعم -fuse-ld=lld رغم ذلك.

bstrie : هذا يعمل مع Stable and Nightly على Windows-MSVC ، التفاصيل في المنشور الأول لمشكلة gamedev-wg هذه: https://github.com/rust-gamedev/wg/issues/50

نقطة بيانات أخرى: باستخدام RUSTFLAGS="-C link-arg=-fuse-ld=lld" عند إنشاء rustc نفسه ، ينخفض ​​ربط الوقت من 93 إلى 41 ثانية في صندوق Linux السريع الذي يحتوي على 14 نواة.

nnethercote : هل هذا يختلف عن تعيين linker=lld في (على سبيل المثال) قسم [target.x86_64-unknown-linux-gnu] في config.toml ؟

@ Aaron1011 : تخميني سيكون لهما نفس التأثير ، لكني لم أتحقق من هذا بنفسي.

@ Aaron1011 يجب أن يكون رنة ، انظر https://github.com/rust-lang/rust/issues/39915#issuecomment -538049306.

يارب
هل حاولت إنشاء rustc على x86_64-pc-windows-gnu باستخدام LLD كرابط؟

لقد جربته اليوم و LLD إما معلق في منتصف البناء ويتوقف عن القيام بأي عمل ، أو يشتكي من unknown argument: --version-script=... .
يحدث التعليق أيضًا إذا تم استخدام LLD لربط LLVM فقط ، مع

[llvm]
use-linker = "lld"

إصدارات الأداة:

$ ld.lld --version
LLD 9.0.1 (https://github.com/msys2/MINGW-packages.git 5e3b8820ed9f04221affee4197e458aca2612e87) (compatible with GNU linkers)

$ gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

petrochenkov نعم يمكنني بناءه ببعض الاختراقات:

  • لا تدعم الواجهة الخلفية LLD COFF البرامج النصية للرابط ولكن كل من LD و LLD جيدان مع نمط MSVC .def الملفات ؛ سهل الحل
  • يتوقع LLD أن تبدأ المكتبات بـ lib (إنه معيار في عالم UNIX) ولكن بطريقة ما انتهى الأمر بـ Rust بعدم القيام بذلك لجميع أهداف windows-* : https://github.com/rust-lang/ الصدأ / blob / 9ebf47851a357faa4cd97f4b1dc7835f6376e639 / src / libstd / sys / windows / env.rs # L4
    لا تمانع LD في كلتا الحالتين ولا أعرف ما إذا كنت سأضغط على جانب LLD أو الصدأ لإصلاحه.

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

  • بدلاً من استخدام lld الخارجي المقدم ، قم ببنائه واستخدامه كمكتبات ثابتة داخل rustc. يتيح ذلك تكاملًا أكثر إحكامًا لصدأ نفسه ، وتحسين التجربة خارج الصندوق ، وإطلاق العنان للإمكانيات المستقبلية.
  • بدلاً من تمرير الكثير من أسماء المسارات إلى lld كأمر رابط ، استخدم نظام ملفات ظاهري ، وقم بتمرير هذه البيانات من ذاكرة إلى ذاكرة بدلاً من استخدام قرص الإدخال / الإخراج كلما كان هناك مساحة ذاكرة كافية للقيام بها. بالنسبة للمشاريع الأكبر ، قد يوفر هذا مئات أو حتى آلاف ميغا بايت من قرص الإدخال والإخراج ، وبالتالي يحسن وقت الترجمة.

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

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

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

ما هو lld

رابط هو جزء من مشروع llvm ، وهو أمر مرغوب فيه لسببين:

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

الأشياء التي يفعلها Rust مع lld اليوم

  • يقوم Rust حاليًا بشحن نسخته الخاصة من lld على معظم المنصات باعتباره ثنائيًا يسميه rust-lld
  • يتم استخدام rust-lld افتراضيًا في العديد من الأهداف المعدنية
  • يتم استخدام rust-lld افتراضيًا مع wasm
  • (؟) يمكنك طلب استخدام rust-lld بشكل صريح باستخدام "-C linker-flavour" (غامض بشأن ما يفعله هذا بالضبط على المنصات غير المعدنية ، انظر أدناه)

مشاكل استخدام rust-lld في أماكن أكثر (مثل سطح المكتب Linux / mac / windows)

  • واجهة macOS (Mach-O) الخلفية لـ lld مكسورة ومهجورة

    • بدأت عملية إعادة الكتابة من الصفر ، لكنها الأيام الأولى

  • في الأنظمة الأساسية لينكس / يونكس ، ليس من المفترض أن تستدعي ld / lld مباشرة. من المفترض أن تستدعي الرابط من خلال برنامج التحويل البرمجي c في نظامك (مثل gcc) ، الذي تقع على عاتقه مسؤولية اكتشاف رموز النظام مثل crt1.o وتزويدها بـ ld. هذا يعني أننا لا نستطيع "فقط" استخدام rust-lld ؛ يجب علينا إطعامها في دول مجلس التعاون الخليجي / clang / أيا كان. (لا نريد تطبيق منطق رمز النظام هذا بأنفسنا)

    • بشكل عام ، لا يمكنك توفير الرابط كمسار ، يجب عليك حقنه في مسار بحث مترجم لغة سي على هيئة "ld"

    • بدلاً من ذلك ، يمكنك فعل الشيء نفسه ولكن حقنه كـ "ld.lld" ، وتمرير "-fuse-ld = lld"



      • قد يكون هذا مهمًا ، فعلى ما يبدو أن lld يقوم بالكشف عن اسم ثنائي على غرار رنكة إذا كان يتم تنفيذه كـ "ld" أو "ld.lld" (يحتاج إلى التحقيق)


      • لسوء الحظ -fuse-ld = lld هو جزء فقط من GCC 9 ، لذلك قد نطلب ميزة / اكتشاف الإصدار لاستخدامه (كان clang يستخدمه لفترة طويلة)



  • نوافذ MSVC على ما يبدو في حالة جيدة، ويبدو أن لديها بعض الدعم المحدود لاستخدام الصدأ وبكالوريوس في القانون في الخلفية، ولكن أنا غير واضحة حول ما يجب القيام به هنا.
  • يبدو أن windows-mingw في نفس المكان تقريبًا مثل linux / unix ، باستثناء أنك عرضة للحصول على دول مجلس التعاون الخليجي القديمة ، والأشياء متزعزعة بعض الشيء لأن pseudo-windows-linux ليست بالضبط تكوينًا تم اختباره جيدًا؟

بشكل عام أيضًا ، يعد lld أحدث ، وليس الإعداد الافتراضي لمعظم أنظمة التشغيل ، فمن المؤكد تقريبًا ظهور أخطاء عشوائية متوافقة إذا بدأنا في استخدام هذا في أماكن أكثر.

لقد قدمت جهازي تعريف لجهود مركزة على استخدام (rust-) lld افتراضيًا على نظامين أساسيين:

  • # 71515 - x64 Ubuntu 20.04 LTS (وعلى نطاق أوسع جميع منصات x64 ELF)
  • # 71520 - نوافذ x64 msvc

يبدو أن windows-msvc في حالة جيدة ، ويبدو أن لديها بعض الدعم المحدود لاستخدام rust-lld في الواجهة الخلفية ، لكنني غير واضح بشأن ما يجب القيام به هنا.

LLD + windows-msvc في حالة جيدة جدًا ، وأنا أستخدم حاليًا هذا الإعداد لتطوير rustc .

كل الدعم اللازم لـ lld-link موجود في الواجهة الخلفية rustc ، ولكن هناك أخطاء مثل https://github.com/rust-lang/rust/issues/68647.

  • قد يكون هذا مهمًا ، فعلى ما يبدو أن lld يقوم بالكشف عن اسم ثنائي على غرار رنكة إذا كان يتم تنفيذه كـ "ld" أو "ld.lld" (يحتاج إلى التحقيق)

إنه كذلك ، لكن ld و ld.lld هما نفس الوضع: https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-02-05/lld/tools/lld/lld. حزب الشعب الكمبودي (نفس منذ 8.0-2019-01-16)

  • لسوء الحظ -fuse-ld = lld هو جزء فقط من GCC 9 ، لذلك قد نطلب ميزة / اكتشاف الإصدار لاستخدامه (كان clang يستخدمه لفترة طويلة)

نظرًا لأن ld.lld هو نفسه ld ، ووفقًا لـ https://patches-gcc.linaro.org/patch/11148/ التغيير الوحيد باستخدام -fuse-ld = lld هو تشغيل ld.lld بدلاً من ld ، إذا نحن نستخدم حقن PATH ، يجب أن يكون جيدًا. أعتقد أن قفل هذا الأمر على gcc 9+ ليس جيدًا على الرغم من أن إسطبل دبيان لديه 8.3 فقط ، ومن المحتمل ألا يتم إصدار Bullseye حتى عام 2021.

  • يبدو أن windows-mingw في نفس المكان تقريبًا مثل linux / unix ، باستثناء أنك عرضة للحصول على دول مجلس التعاون الخليجي القديمة ، والأشياء متزعزعة بعض الشيء لأن pseudo-windows-linux ليست بالضبط تكوينًا تم اختباره جيدًا؟

mingw-w64 6.0.0 ، الذي تم إصداره في 2018-09-16 ، به إصدار gcc 8.3.0 ، والذي لا يحتوي على -fuse-ld = lld ، ولكنه لا يزال جديدًا بشكل معقول. الإصدار mingw-w64 7.0.0 ، الذي تم إصداره في 2019-11-11 ، يحتوي على 9.3.0 مجلس التعاون الخليجي ، والتي تحتوي على -fuse-ld = lld. ديبيان باستر (مستقر) 6.0.0 ، بولس (اختبار) 7.0.0. امتداد دبيان (Oldstable) يحتوي على 5.0.1 فقط مع الإصدار 6.3.0 من مجلس التعاون الخليجي ، لكنني أعتقد أنه سيكون من المعقول طلب أحدث نسخة من دبيان للدعم القديم إذا كانت هناك مشكلات مهمة مع مجلس التعاون الخليجي 6.3.0.

لقد قدمت جهازي تعريف لجهود مركزة على استخدام (rust-) lld افتراضيًا على نظامين أساسيين:

  • # 71515 - x64 Ubuntu 20.04 LTS (وعلى نطاق أوسع جميع منصات x64 ELF)
  • # 71520 - نوافذ x64 msvc

حول منفذ macOS (Mach-O) من lld: يبدو أنه يعمل ، أو على الأقل ، يكون في حالة أفضل بشكل ملحوظ منذ https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211 كتب!

باستخدام التزام LLVM هذا ، قمت ببناء lld وقمت بتعيينه كرابط خاص بالمشروع لـ nightly-x86_64-apple-darwin وقمت بإجراء جميع الاختبارات بنجاح. أنا سعيد بشكل خاص بأوقات إنشاء (التصحيح):

  • باستخدام ld ، استغرق cargo build النظيف 35 ثانية.
  • باستخدام lld ، استغرق cargo build 20 ثانية.

لاحظ أن:

  • جاءت أرقام الأداء هذه من جهاز MacBook Pro حديثًا بسعة 32 جيجابايت من ذاكرة الوصول العشوائي و 8-Core i9 و
  • هناك بعض المشكلات المعلقة لـ lld و Mach-O.

تضمين التغريدة بدافع الفضول ، كيف يقارن هذا الأداء بـ zld ؟ (https://github.com/michaeleisel/zld)

أيضا ، هل قمت بحساب الحرارة؟ تدخل MBPs في الاختناق الحراري بسرعة كبيرة ، خاصة مع ملف تعريف سرعة المروحة الافتراضي. مجرد الانتظار حتى يصبح الجزء السفلي من الماكينة بالقرب من المفصلة باردًا عند لمسه قبل القيام بالجري من شأنه أن يساعد في الاتساق.

أنا فقط مثل هذا الخطأ ، على Ubuntu 16 i686

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات