Rust: Menghubungkan dengan LLD

Dibuat pada 17 Feb 2017  ·  94Komentar  ·  Sumber: rust-lang/rust

LLVM 4.0 dikirimkan dengan LLD diaktifkan, meskipun AFAIK belum siap produksi di semua platform. Saya yakin kami memiliki peningkatan LLVM yang direncanakan segera untuk menyelesaikan masalah AVR/emscripten, jadi sekarang saatnya untuk mulai menentukan apa yang mungkin perlu kami lakukan untuk mendukungnya, bagaimana hal itu memengaruhi kinerja kompiler/ukuran biner/kinerja runtime dibandingkan dengan kami linker biasa, dan platform apa yang mungkin ingin kami aktifkan secara default.

Status saat ini (2020-04-24) dirangkum di https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211

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

Komentar yang paling membantu

Bug ini sedikit berantakan, jadi inilah kesempatan terbaik saya untuk ringkasan singkat dari situasi saat ini, untuk orang-orang yang ingin memajukan ini.

Apa itu lld

Penghubung yang merupakan bagian dari proyek llvm, yang diinginkan karena dua alasan:

  • sangat ramah untuk kompilasi silang (karenanya penekanannya untuk target yang disematkan)
  • ini sangat cepat (sering berjalan dalam separuh waktu sebagai Emas -- penautan dapat memakan waktu beberapa menit untuk proyek besar (rustc, servo, dll.) dan penautan dapat menjadi % besar dari kompilasi dengan build tambahan, jadi mengurangi separuh runtime ini adalah a Masalah besar.)

Hal yang Rust lakukan dengan lld hari ini

  • Rust saat ini mengirimkan salinan lldnya sendiri di sebagian besar platform sebagai biner yang disebut rust-lld
  • rust-lld digunakan secara default pada banyak target bare-metal
  • rust-lld digunakan secara default untuk wasm
  • (?) Anda dapat secara eksplisit meminta rust-lld digunakan dengan menggunakan "-C linker-flavor" (tidak jelas tentang apa sebenarnya yang dilakukan pada platform non-bare-metal, lihat di bawah)

Masalah untuk menggunakan rust-lld di lebih banyak tempat (yaitu desktop linux/mac/windows)

  • Backend macOS (Mach-O) untuk lld rusak dan ditinggalkan

    • penulisan ulang dari awal telah dimulai, tetapi ini masih awal

  • Pada platform linux/unix, Anda tidak seharusnya langsung memanggil ld/lld. Anda seharusnya memanggil linker melalui kompilator c sistem Anda (yaitu gcc), yang bertanggung jawab untuk menemukan simbol sistem seperti crt1.o dan memberikannya ke ld. Ini berarti kita tidak bisa "hanya" menggunakan rust-lld; kita harus memasukkannya ke gcc/clang/whatever. (kami tidak ingin menerapkan logika simbol sistem ini sendiri)

    • Secara umum, Anda tidak dapat memberikan tautan sebagai jalur, Anda harus memasukkannya ke dalam jalur pencarian kompiler C sebagai "ld"

    • Atau, Anda dapat melakukan hal yang sama tetapi menyuntikkannya sebagai "ld.lld", dan meneruskan "-fuse-ld=lld"



      • Ini mungkin penting, tampaknya lld melakukan deteksi nama biner gaya dentang jika dieksekusi sebagai "ld" atau "ld.lld" (perlu penyelidikan)


      • Sayangnya -fuse-ld=lld hanya bagian dari GCC 9, jadi kami mungkin memerlukan deteksi fitur/versi untuk menggunakannya (dentang sudah lama)



  • windows-msvc tampaknya dalam kondisi yang baik, dan tampaknya memiliki beberapa dukungan terbatas untuk menggunakan rust-lld di backend, tetapi saya tidak jelas tentang apa yang perlu dilakukan di sini.
  • windows-mingw tampaknya berada di tempat yang kira-kira sama dengan linux/unix, kecuali Anda bertanggung jawab untuk mendapatkan GCC kuno, dan semuanya agak miring karena pseudo-windows-linux bukanlah konfigurasi yang benar-benar teruji?

Juga secara umum, lld lebih baru, ini bukan default untuk sebagian besar OS, bug compat acak hampir pasti akan muncul jika kita mulai menggunakan ini di lebih banyak tempat.

Saya telah mengajukan dua metabug untuk upaya terfokus menggunakan (karat-)lld secara default pada dua platform:

  • #71515 - x64 Ubuntu 20.04 LTS (dan lebih luas lagi semua platform x64 ELF)
  • #71520 - jendela x64 msvc

Semua 94 komentar

Lihat juga PoC di # 36120.

LLD mungkin merupakan kandidat yang sangat baik untuk target MinGW, karena saat ini kami menggabungkan linker dengan mereka dan linker MinGW memiliki berbagai masalah mulai dari kurangnya ASLR hingga tidak ada dukungan bigobj. Jika kita entah bagaimana juga dapat membawa perpustakaan mingw yang diperlukan saat kompilasi silang dan bukan hanya penargetan asli (yang saat ini terbatas pada paket mingw rustup), maka itu akan memungkinkan kompilasi rust cross dari linux di luar kotak, yang akan menjadi peningkatan besar atas situasi yang ada di mana orang mendapatkan MinGW dari distro mereka dan kemudian mengalami masalah karena distro hampir selalu menggunakan MinGW yang tidak kompatibel.

LLD bukan kandidat yang baik untuk menargetkan target MSVC secara native, karena beberapa alasan, alasan utamanya adalah kurangnya dukungan debuginfo. Kompilasi silang ke target MSVC memerlukan pustaka yang tidak dapat didistribusikan ulang sehingga kami tidak dapat mendukungnya secara langsung.

Masalah pelacakan untuk memutakhirkan ke LLVM 4.0 adalah https://github.com/rust-lang/rust/issues/37609 .

Sebagai catatan lld pasti belum siap untuk target Solaris. Tetapi di Solaris, tidak ada alasan yang saya ketahui untuk menggunakan lld alih-alih ld asli. Kami telah melihat apa yang diperlukan agar rust menggunakan Solaris ld di Solaris alih-alih menggunakan gcc untuk menautkan.

@binarycrusader Salah satu alasan untuk penggunaan lld adalah ketika membangun untuk Solaris, bukan pada Solaris.

PR rust-lang/rust#40018 menambahkan tanda -Z linker-flavor ke rustc untuk memungkinkan penggunaan LLD sebagai penghubung. PR itu tidak menyematkan LLD di rustc tetapi memungkinkan eksperimen di luar pohon dengannya.

@binarycrusader ^ yang dapat membantu eksperimen Anda menggunakan ld Solaris secara langsung alih-alih gcc.

Kami sekarang tampaknya berjalan di LLVM 4.0. @japaric , apakah ini berarti bahwa bendera rasa tautan sekarang dapat dengan mudah digunakan untuk membandingkan dan membedakan LLD dengan tautan sistem?

@bstrie #40018 mendarat beberapa minggu yang lalu. Sejak itu, seseorang telah dapat menggunakan -Z linker-flavor=ld -C linker=ld.lld untuk menggunakan biner LLD eksternal sebagai penghubung. Perhatikan bahwa, tidak seperti gcc, LLD tidak tahu di mana perpustakaan sistem berada sehingga Anda harus meneruskan jalur pencarian perpustakaan ke penaut menggunakan -C link-args='-L ...' jika Anda menautkan ke perpustakaan sistem mana pun.

Apa yang membantu LLVM 4.0 adalah menggabungkan LLD ke rustc. Dengan perubahan itu, kami tidak memerlukan tautan eksternal dalam beberapa skenario seperti menautkan binari MUSL atau program bare metal. Saya mengatakan beberapa skenario karena sebagian besar target memerlukan tautan ke perpustakaan sistem tempat Anda akan mengalami masalah jalur pencarian perpustakaan yang saya sebutkan di atas. Untuk target tersebut, LLD tidak akan bekerja di luar kotak. Tidak jelas bagaimana dan di mana untuk memecahkan masalah itu dan tanpa solusi untuk itu kami tidak dapat beralih ke LLD untuk target (tingkat 1) yang paling penting, yang mengurangi daya tarik penyematan LLD ke rustc di tempat pertama.

@japaric Apa argumen yang menentang penyematan (perpustakaan relatif sysroot) jalur pencarian, serta hal-hal seperti -lc -lpthread crt0.o , langsung ke rustc? Lagi pula, beberapa komponen dari rantai alat harus menyematkannya karena kami tidak memiliki standar apa pun untuk diikuti oleh platform, dan binutils bukanlah sumber emas yang baik untuk pengetahuan ini.

Satu-satunya kelemahan yang dapat saya pikirkan adalah situasi di mana triple yang sama akan memiliki jalur pencarian yang berbeda pada sistem yang berbeda (yang kemungkinan akan eksklusif untuk triple Linux/glibc, dan terutama buruk pada platform dengan multilib). Dalam hal ini, saya percaya dentang mengintip nama OS dan hardcode konvensi khusus OS, yang tampaknya buruk tetapi mungkin tidak dapat dihindari jika seseorang ingin mendistribusikan satu biner yang berjalan di Linux apa pun (dan tidak memerlukan tautan sistem).

@retep998 Saya melihat sekilas lld beberapa bulan yang lalu. Saya tidak dapat mengkompilasi silang (tautan silang?) .exe dari Linux. Sepertinya lld hanya mendukung format asli platform.

Semoga saya salah.

Menandai ini sebagai bug kinerja, karena menurut tolok ukur LLD tampaknya mengungguli GNU ld dengan faktor sepuluh, dan kinerja penautan merupakan komponen besar dari kecepatan kompiler saat ini.

Er, lupa menautkan tolok ukur: https://lld.llvm.org/#performance

(Relevan hari ini karena LLVM 5.0 baru saja dirilis.)

Menghubungkan dengan LLD jauh lebih cepat daripada bfd atau emas, tetapi saya ragu bahwa menggunakannya akan meningkatkan kinerja secara keseluruhan secara signifikan. Tetap saja saya pikir masalah ini penting dan harus menjadi prioritas.

@tpimh Saya sebenarnya tidak sepenuhnya yakin apakah tag I-slow seharusnya mewakili bug kinerja runtime atau bug kinerja waktu kompilasi, saya bermaksud sebagai yang terakhir. Dan IME ketika saya melihat penautan keluaran waktu berlalu biasanya berada di tiga fase terpanjang teratas, jauh lebih lama daripada kebanyakan, jadi bahkan memotong waktu penautan menjadi dua mungkin akan menjadi kemenangan besar (terutama untuk hal-hal besar seperti Servo dan rustc).

@bstrie I-slow adalah untuk kinerja runtime yang buruk, I-compiletime adalah untuk kinerja kompiler terakhir kali saya memeriksa

Kabar baik bagi siapa saja yang tertarik dengan topik yang tidak jelas tentang tautan silang dari Linux ke Windows. Saya katakan sebelumnya itu tidak mungkin dengan lld, tapi itu hanya berlaku untuk rasa lld. Ini mungkin untuk rasa link.exe lld (link-lld).

Khusus untuk Rust, kita dapat melakukannya hari ini dengan beberapa perubahan kode.

  1. Kita perlu mengkompilasi subset CRT mingw-w64 yang sangat kecil ke dalam file objek .o. Yaitu beberapa thread penyimpanan lokal init. Kami juga membutuhkan chkstk.

  2. lld tidak menyukai perpustakaan impor MinGW yang biasa. Sebagai gantinya kita perlu membangun file .def menjadi file .lib sendiri, menggunakan lld-link atau llvm-dlltool

  3. Ubah lld untuk memperlakukan IMPORT_NAME_NOPREFIX seperti
    IMPORT_NAME_UNDECORATE, karena bahkan dengan langkah 2 .libs tidak sempurna

  4. Ubah seh.rs Rust untuk mengganti TYPE_INFO_VTABLE dengan ptr::null(). Diperlukan karena simbol ??_7type_info@@6B@ tidak didefinisikan di MinGW. Kemudian bangun dan instal Rust.

  5. Gunakan .cargo/config untuk menentukan skrip pembungkus khusus sebagai tautan.

  6. Skrip wrapper linker kami harus memanggil lld-link sebagian besar menggunakan parameter yang diteruskan. Namun kita harus membuat beberapa tweak:

    a) Perbaiki casing nama file misalnya ubah AdvAPI32.Lib menjadi advapi32.lib

    b) Ubah file .def yang dihasilkan Rust menjadi simbol awalan dengan garis bawah tambahan

    c) Mengganti titik masuk (/entri). Diperlukan mungkin karena masalah kesalahan nama.

    d) Tambahkan file objek mingw-crt yang Anda kompilasi pada langkah 1

  7. Bangun proyek Rust Anda menggunakan xargo --target=i686-pc-windows-msvc

Melakukan langkah-langkah di atas memungkinkan saya untuk mengkompilasi silang kode Rust. Saya bahkan bisa panik dan panik menggunakan pelepasan berbasis SEH Rust.

@iainnicol Anda mencampur target msvc dengan bit MinGW, itulah sebabnya Anda harus melakukan semua modifikasi aneh itu. Jika Anda hanya menyalin pustaka dari instalasi VC++ yang ada maka Anda dapat menggunakan lld-link secara normal tanpa semua modifikasi atau bit MinGW apa pun.

Tetapi saya tidak ingin menggunakan instalasi VC++ yang ada. Bahkan tidak ada cara untuk mendapatkannya tanpa menghabiskan waktu seperti delapan jam untuk mengunduh dan memasang sampah, apalagi untuk mendistribusikan ulang.

Alat pembuatan mandiri jauh lebih ringan, kecuali jika itu yang Anda maksud, dalam hal ini mungkin kita harus berupaya meningkatkan atau menciptakan kembali apa yang dilakukan MinGW sehingga benar-benar kompatibel dengan MSVC.

Alat pembuatan mandiri jauh lebih ringan

Saya belum menyadari Microsoft mendistribusikannya. Bisakah Anda menautkannya? Apakah ada cara yang masuk akal untuk mengekstrak arsip instalasi tanpa benar-benar menjalankannya, apakah itu msi atau yang serupa?

Ini dia: http://landinghub.visualstudio.com/visual-cpp-build-tools

Baik versi 2015 dan 2017 adalah exe, tetapi Anda mungkin dapat meyakinkan exe 2017 untuk memberikan apa yang Anda inginkan melalui ini: https://docs.microsoft.com/en-us/visualstudio/install/install-vs- tidak konsisten-kualitas-jaringan

Jika kita benar-benar ingin melakukan ini dengan benar untuk Windows, pertama-tama kita membutuhkan https://github.com/rust-lang/rust/issues/30027 untuk menghilangkan kebutuhan akan Windows SDK atau perpustakaan impor MinGW. Kemudian yang tersisa adalah mengganti bit CRT dengan versi Rust murni kami sendiri (fungsi matematika/memori, titik masuk, beberapa bit runtime lainnya yang dibutuhkan Rust) dan kami akan memiliki rantai alat Rust mandiri yang dapat buat binari Windows! Kelemahan dari ini adalah Anda tidak akan dapat menautkan kode C/C++ secara statis karena itu sangat bergantung pada penautan dalam CRT yang sesuai dari MinGW atau VC++. Tentu saja inti dari Rust adalah menulis ulang semua yang ada di Rust, jadi ini bukan masalah besar.

Kabar baik bagi siapa saja yang tertarik dengan topik yang tidak jelas tentang tautan silang dari Linux ke Windows. Saya katakan sebelumnya itu tidak mungkin dengan lld, tapi itu hanya berlaku untuk rasa lld. Ini mungkin untuk rasa link.exe lld (link-lld).

Sepertinya sekarang mungkin dengan rasa ld juga: https://reviews.llvm.org/rL312926

Driver baru yang kompatibel dengan MinGW lld adalah pembungkus untuk lld-link linker. Ini secara internal menerjemahkan opsi Unix-ish ke opsi Windows-ish dan kemudian memanggil titik masuk lld-link. Saya tidak yakin apakah kalian ingin menggunakannya karena (kecuali driver pembungkusnya tidak lengkap dan belum siap untuk digunakan) sepertinya tidak membuat segalanya lebih mudah kecuali Anda sudah memiliki Makefiles untuk MinGW.

Saya punya pertanyaan (mungkin konyol) untuk kalian tentang kompilasi silang. Pada Windows, semua simbol dllimport'ed memiliki nama DLL dari mana mereka diimpor. Jika Anda tidak memiliki file perpustakaan MSVC, bagaimana Anda tahu dari file mana simbol dllimport diimpor?

Saya punya pertanyaan (mungkin konyol) untuk kalian tentang kompilasi silang. Pada Windows, semua simbol dllimport'ed memiliki nama DLL dari mana mereka diimpor. Jika Anda tidak memiliki file perpustakaan MSVC, bagaimana Anda tahu dari file mana simbol dllimport diimpor?

Jika Anda tidak memiliki perpustakaan impor, maka Anda harus membuat perpustakaan impor atau mengimplementasikan https://github.com/rust-lang/rust/issues/30027 sehingga winapi dapat melakukan semua yang sulit pekerjaan menentukan dari mana DLL setiap simbol berasal bersama dengan zaniness seperti ordinal. Sesuatu harus menentukan pemetaan simbol pada waktu tautan ke simbol/ordinal di DLL, apakah itu perpustakaan impor atau anotasi dalam kode Anda.

Setelah menarik di https://reviews.llvm.org/rL311734 Saya hampir dapat mem-bootstrap rustc menggunakan lld di macOS. Tampaknya ada masalah dengan metadata dylib, yang masih perlu saya selidiki.

Saya memiliki cabang yang membangkitkan https://github.com/rust-lang/rust/pull/36120; karena kami membutuhkan perbaikan lld (sangat baru), ini diblokir di https://github.com/rust-lang/rust/issues/43370.

@tamird : #43370 telah ditutup.

LLD telah ditambahkan di https://github.com/rust-lang/rust/pull/48125 dan sekarang dikirimkan dengan platform tingkat 1 (mac, linux, windows). Anda dapat mengujinya dengan -Z linker-flavor untuk setiap platform, meskipun tidak mungkin berfungsi untuk sebagian besar platform secara default. Namun, itu berfungsi, secara default di MSVC. Sebagai contoh:

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

mengurangi waktu tautan Cargo sendiri dari 2,5 detik menjadi 1,5 detik, peningkatan yang bagus!

@alexcrichton , apa langkah selanjutnya? Idealnya kami memiliki LLD yang berfungsi secara default di semua platform (saya tidak memiliki konsep tentang berapa banyak pekerjaan yang akan dilakukan), dan kemudian saya ingin menjalankan tolok ukur waktu kompilasi/runtime untuk melihat apakah masuk akal untuk menjadikan LLD sebagai default pada platform apa pun. Terutama dengan kompilasi tambahan, kinerja penautan akan menjadi lebih penting dari sebelumnya.

Terutama dengan kompilasi tambahan, kinerja penautan akan menjadi lebih penting dari sebelumnya.

Sayang sekali kinerja penautan masih belum cukup penting bagi kami untuk melakukan hal-hal seperti mengaktifkan penautan tambahan pada platform yang mendukungnya. https://github.com/rust-lang/rust/issues/37543

@bstrie Saya kira itu adalah langkah selanjutnya, membuatnya berfungsi di platform lain :)

Mengenai apa yang diperlukan, saya tidak yakin, tetapi itu sudah berfungsi di MSVC, saya pikir itu jauh dari bekerja di MinGW/Linux, dan kami cukup dekat di OSX. Adapun dukungan lintas arsitektur, saya tidak yakin juga. Saya tidak berharap kami akan "menstabilkannya" untuk apa pun selain platform wasm dalam waktu dekat.

@alexcrichton Bolehkah saya bertanya bagaimana Anda akan menentukan "menstabilkan"? Mengapa tidak mungkin untuk "menstabilkan" tautan dengan lld untuk platform utama lainnya yang didukung rust? (mis. kompilasi silang sebuah executable dari linux untuk macOS).

Saat ini, sangat sulit untuk mengkompilasi silang, misalnya pekerjaan yang diperlukan untuk mengkompilasi silang executable untuk macOS (x86_64-apple-darwin) dari linux memerlukan langkah-langkah non-sepele seperti memperoleh xcode sdk dan membangun keseluruhan rantai alat.

@cynecx pertanyaan yang bagus! Satu yang belum terlalu saya pikirkan. Saya pikir, bagaimanapun, kami tidak ingin menstabilkan LLD secara de facto hanya karena kami menambahkannya untuk platform lain, itu akan membutuhkan waktu dan usaha untuk memperbaikinya dan mengeksposnya dengan baik.

misalnya pekerjaan yang diperlukan untuk mengkompilasi silang executable untuk macOS (x86_64-apple-darwin) dari linux memerlukan langkah-langkah non-sepele seperti memperoleh xcode sdk dan membangun seluruh rantai alat.

LLD tidak akan terlalu membantu di sini, Anda masih memerlukan Xcode SDK karena memiliki header yang tidak dapat Anda distribusikan kembali (dan tergantung pada apa yang Anda buat, Anda juga memerlukan alat SDK lain).

Apa yang benar-benar bagus tentang LLD sekarang menjadi built-in di malam hari adalah Anda dapat dengan mudah mengkompilasi silang proyek Rust murni dari Windows ke Linux dengan RUSTFLAGS='-Z linker-flavor=ld.lld' cargo build --target x86_64-unknown-linux-musl . Sangat bagus untuk menulis alat kecil untuk mesin Linux yang tidak bisa Anda instal begitu saja dengan Rust.

Saya tidak berharap kami akan "menstabilkannya" untuk apa pun selain platform wasm dalam waktu dekat.

Seperti yang dikatakan @rkarp , kasus penggunaan yang sangat umum menargetkan x86_64-unknown-linux-musl (dan akhirnya kuda) untuk mendukung beban kerja Linux dalam container. Ini adalah salah satu hal yang Go lakukan dengan sangat baik dan di mana kami tampaknya sangat dekat dengan Rust untuk dapat melakukan hal yang sama. Dalam hal penggunaan aktual, saya yakin LLD untuk x86_64-unknown-linux-musl sebenarnya akan digunakan lebih luas daripada wasm.

Secara lebih umum, ketika menyangkut pembangunan silang, saya tidak berpikir pendekatan "itu harus bekerja untuk semua host dan/atau semua target" masuk akal. Saya pikir masuk akal untuk menstabilkan ini berdasarkan target demi target saat target mulai bekerja.

Secara khusus, saya ingin membantu dengan upaya untuk mendapatkan LLD untuk target x86_64-unknown-linux-musl stabil ASAP.

Proyek saya memiliki 37 peti, dan tautan build sekitar 70 binari (banyak tes). Secara tidak ilmiah (memperhatikan top ) setidaknya setengah dari waktu pembuatan kami hanya menjalankan ld. Saya berharap menggunakan lld akan sangat mempercepat pembangunan kami. Kami berada di Rust yang stabil dan saya belum berhasil menjalankan lld 6.0.

@briansmith apakah Anda sudah menguji LLD untuk musl dan kasus penggunaan Anda? Secara teori, yang perlu Anda lakukan untuk mengujinya adalah lulus -Z linker-flavor=ld.lld , dan jika itu berhasil, kami dapat mengganti defaultnya!

@rocallahan hanya untuk mengkonfirmasi, Anda menggunakan tautan emas saat ini, bukan? (sebagai afaik ini lebih cepat dari linker binutils standar). Jika -Z linker-flavor=ld.lld bekerja (dan lebih cepat) maka kita mungkin bisa menstabilkannya! Itu di platform apa?

Secara tidak ilmiah (eyeballing top) setidaknya setengah dari waktu pembuatan kami hanya menjalankan ld.

Itu untuk debug build BTW.

kalian semua menggunakan tautan emas saat ini, bukan? (sebagai afaik ini lebih cepat dari linker binutils standar)

Tidak, itu linker sistem Fedora, linker GNU standar.

Itu di platform apa?

Fedora 27, laptop Skylake quad-core dengan SSD. Saya akan mendapatkan beberapa nomor kinerja.

Ah oke bagus untuk tahu! Pembuatan debug mungkin akan mendapatkan manfaat paling besar dalam waktu tautan dari split dwarf (https://github.com/rust-lang/rust/issues/34651) daripada peningkatan tautan.

Untuk informasi waktu, @rocallahan jika Anda mendapat kesempatan menguji pikiran dengan ld.gold dan ld.lld ?

Tentu. Saya juga harus mengingatkan bahwa masalah #48762 adalah hasil yang sangat rendah untuk mempercepat waktu tautan debug Linux. (Kami sudah menggunakan skrip tautan yang diretas yang menjatuhkan .debug_pubnames / .debug_pubtypes dari yang dapat dieksekusi.)

Split DWARF mungkin bagus tetapi juga dapat menyebabkan masalah bagi pengguna. Saya akan berkomentar dalam masalah itu.

@briansmith apakah Anda sudah menguji LLD untuk musl dan kasus penggunaan Anda? Secara teori, yang perlu Anda lakukan untuk mengujinya adalah dengan lulus -Z linker-flavor=ld.lld, dan jika itu berhasil, kita bisa mengganti defaultnya!

OK, saya akan menguji hal-hal. Mungkin awalnya harus ada jalan tengah antara "default" dan "hanya pada malam hari," beberapa cara memilih untuk menggunakan LLD seperti yang kita bisa dengan -Z , tetapi tanpa menggunakan -Z sehingga berfungsi dalam bangunan yang stabil.

tetapi tanpa menggunakan -Z sehingga berfungsi di build yang stabil.

Anda dapat mencoba RUSTC_BOOTSTRAP=1 RUSTFLAGS="-Z linker-flavor=foo" cargo build

Tolong jangan merekomendasikan flag bootstrap? Saya khawatir jika cukup banyak proyek yang mengandalkannya, semuanya akan menjadi stabil secara de facto, mengalahkan inti dari seluruh mekanisme stabilitas.

Maaf =/

Sebagai titik data, menautkan peti rustc_trans di repo Rust itu sendiri turun drastis dari waktu tautan 78 detik ke waktu tautan 1 detik di mesin lokal saya.

Hasil kinerja saya dari membuat perubahan spasi putih ke peti di dekat bagian bawah hierarki peti kami. Laptop Skylake quad core, RAM 16GB, rustc 1.24.0, LLD 7.0.0, GNU ld 2.29-13. Kami menggunakan skrip tautan khusus yang membuang .debug_pubnames dan .debug_pubtypes ; LLD menggunakan jalur kode yang sangat berbeda ketika skrip tautan ada, sehingga dapat memengaruhi banyak hal.

GNU ld:

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

LLD:

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

Emas tidak berfungsi, itu dimuntahkan pada skrip tautan kami. Hasilnya cukup stabil. LLD tidak terlalu mempengaruhi waktu end-to-end tetapi mengurangi penggunaan CPU secara signifikan; Saya kira itu berarti build kami tidak menghabiskan banyak waktu menunggu lds selesai, tetapi itu menghabiskan banyak waktu CPU untuk menjalankannya.

Lihat #50584 untuk contoh dunia nyata di mana beralih dari GNU ld ke lld membuat beban kerja "perubahan kecil dan pembangunan kembali" yang umum dijalankan lebih dari 2,5x lebih cepat.

Er https://github.com/rust-lang/rust/issues/50584#issuecomment -400918647 lebih tepat di sini:


Langkah selanjutnya untuk menstabilkan LLD adalah mendapatkan tanda, seperti -Z linker-flavor=lld, bekerja untuk semua target (Windows + Mac + Linux). Itu akan melakukan apa pun yang perlu dilakukan untuk bekerja di berbagai platform.

Setelah selesai, kami dapat mengiklankannya ke komunitas, meminta umpan balik. Di sini kita bisa mendapatkan informasi waktu serta laporan bug untuk dikirim ke LLD. Jika semuanya berjalan lancar (yang agak meragukan dengan linker baru, tapi hei Anda tidak pernah tahu!) kita dapat menyalakannya secara default, jika tidak, kita dapat bekerja untuk menstabilkan pemilihan LLD dan kemudian menambahkan opsi ke Cargo. toml sehingga proyek setidaknya dapat ikut serta.

Kami telah beralih ke lld untuk beberapa target: https://rust-embedded.github.io/blog/2018-08-2x-psa-cortex-m-breakage/

Saya percaya untuk wasm juga?

Apakah masalah ini mencakup penautan dengan biner lld eksternal dan penautan dengan dukungan lld internal yang dibangun ke dalam rustc itu sendiri? Atau hanya mantan?

Apakah masalah ini mencakup penautan dengan biner lld eksternal dan penautan dengan dukungan lld internal yang dibangun ke dalam rustc itu sendiri? Atau hanya mantan?

Hanya biner lld eksternal, IIUC.

@nnethercote Apakah ada masalah lain untuk melacak penggunaan tautan internal, atau haruskah saya mengajukan masalah terpisah untuk itu?

Saya belum pernah mendengar tentang ide tautan internal sebelumnya. Saya tidak mengetahui PR untuk itu.

https://github.com/rust-lang/rust/pull/57514 menyiapkan tanah untuk menggunakan LLD untuk menautkan LLVM.

Mungkin awalnya harus ada jalan tengah antara "default" dan "hanya di malam hari", beberapa cara memilih untuk menggunakan LLD seperti yang kita bisa dengan -Z, tetapi tanpa menggunakan -Z sehingga berfungsi di build yang stabil.

https://github.com/rust-lang/rust/pull/56351 menambahkan -C linker-flavor .

Tidak jelas apa yang ingin dilacak oleh masalah ini. Sepertinya akan lebih baik untuk menutup ini demi memiliki masalah tertentu, misalnya "Tautkan dengan LLD untuk target -msvc ketika rantai alat Microsoft tidak tersedia".

Bagi saya, masalah ini adalah tentang mengaktifkan LLD sebagai tautan default untuk semua target. Saya ingin itu karena LLD sangat cepat, dan waktu penautan sering kali merupakan komponen penting dari waktu kompilasi, dan kecepatan kompilasi adalah masalah abadi.

FWIW Saya mengajukan bug untuk mendukung LLD di macOS di BMO. Rupanya itu WONTFIX. Dari komentar di sana tampaknya tidak sesederhana "LLD sangat cepat", karena LLD pada platform yang berbeda adalah program yang berbeda, dan yang ada di macOS rusak dengan pengembangan yang terhenti.

Setuju dengan @briansmith bahwa akan lebih baik untuk memiliki masalah khusus untuk melacak status ini untuk target yang berbeda, meskipun alih-alih menutup ini, kami kemudian dapat mengubah ini menjadi metabug. Jika ada orang yang tahu lebih banyak tentang target apa yang layak untuk dibuka masalah, jangan ragu, karena saya sangat keluar dari lingkaran pada status dukungan LLD.

Apakah menautkan dengan LLD didokumentasikan di mana saja? Saya punya (di Linux) rustc -C linker-flavor=ld.lld hello.rs , tapi saya tidak beruntung. Saya pikir LLD didistribusikan dengan salinan LLVM kami, apakah saya salah? Saya juga sudah mencoba menginstal LLD melalui apt, tetapi rustc masih bingung. Apa saja langkah-langkah yang harus dilakukan untuk mencoba LLD dengan kode Rust hari ini?

@bstrie Anda juga harus meneruskan argumen -C linker=rust-lld .

Apakah itu seharusnya bekerja dengan kargo? Saat ini saya mendapatkan kesalahan berikut ketika mencoba membangun proyek kosong pada bangunan karat dan kargo malam terbaru.

$ 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.

Saya mendapatkan kesalahan yang sama dengan carado. Berhasil "shoehorn" -L /usr/lib ke dalam permintaan tautan tetapi itu hanya mempersingkat daftar lib yang tidak terjawab menjadi -lgcc yang tidak ada di mana pun dalam sistem sebagai libgcc (ada libgcc_s.a ) Saya menduga ini adalah hasil dari beberapa gnu-isme tetapi tidak dapat menemukan cara untuk memperbaikinya.

@almindor coba RUSTFLAGS='-C linker=rust-lld -L /usr/lib -L /usr/lib/gcc/x86_64-pc-linux-gnu/9.1.0' atau yang serupa. Path akan tergantung pada versi distro dan compiler Anda.

Apakah komentar saya di atas merupakan cara yang tepat untuk menggunakan LLD? Saya tidak bisa membuatnya berfungsi, karena setiap program macet dengan 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.

Bagi siapa pun yang berakhir di sini, mantra ajaibnya adalah RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo build jika Anda memiliki GCC 9 atau Dentang sebagai kompiler Anda. Atau, -C linker=clang harus berfungsi terlepas dari versi GCC, jadi mungkin lebih disukai.

Untuk membuatnya permanen, Anda dapat menambahkannya ke ~/.cargo/config atau .cargo/config dalam proyek tertentu:

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

@lnicola perhatikan ini hanya berfungsi saat menggunakan GCC 9 atau Dentang sebagai CC.

@bstrie apakah Anda tahu apa statusnya saat ini? Apa penghalang untuk bergerak maju dengannya?

@ mati865 apakah Anda mengetahui doa alternatif untuk orang-orang dengan GCC yang lebih tua?

@lnicola semua platform saya memiliki Dentang + GCC 9 dan saya belum menyelidiki bagaimana menggunakannya dengan kompiler yang tidak kompatibel.

@jonhoo Saya tidak mengikuti pekerjaan apa pun di area ini, saya kira Anda ingin bertanya kepada tim penyusun.

Saya rasa saya tidak dapat menandai tim, dan saya juga tidak ingin menimbulkan kebisingan yang tidak semestinya untuk mereka. Apa jalan terbaik untuk membuat seseorang dari sana melihat sekilas menurut Anda?

Triase; @rust-lang/compiler adakah yang tahu apa status masalah ini saat ini?

Bagi siapa saja di sini yang berhasil membuat LLD bekerja dengan Rust, dapatkah Anda menambahkan detail tentang platform Anda dan versi spesifik dari semua kompiler yang digunakan? Saya masih melihat orang-orang di alam liar mengalami kesulitan untuk membuatnya bekerja, bahkan dengan saran yang tercantum di sini.

Perintah yang saya posting di atas berfungsi di Linux dengan GCC 9.2.0 dan LLD 9.0.0. Saya pikir itu kadang-kadang juga berfungsi di Windows, tetapi saya telah melihat seseorang dengan GCC 9 untuk Windows yang tidak mendukung -fuse=lld. Di MacOS itu tidak pantas untuk dicoba, menurut beberapa tautan yang diposting di sini.

Bagi siapa saja di sini yang berhasil membuat LLD bekerja dengan Rust, dapatkah Anda menambahkan detail tentang platform Anda dan versi spesifik dari semua kompiler yang digunakan? Saya masih melihat orang-orang di alam liar mengalami kesulitan untuk membuatnya bekerja, bahkan dengan saran yang tercantum di sini.

cat /etc/system-release
Fedora rilis 30 (Tiga Puluh)

cc --versi
cc (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)

ld.lld --version
LLD 8.0.0 (kompatibel dengan linker GNU)

Semoga ini membantu

tetapi saya telah melihat seseorang dengan GCC 9 untuk Windows yang tidak mendukung -fuse=lld

@lnicola
Build Windows GCC 9 mendukung -fuse-ld=lld (kecuali mereka ditambal untuk tidak mendukungnya tetapi mengapa seseorang melakukannya?).
Saya kira komponen rust-mingw telah diinstal dan tautan tidak diganti dalam .cargo/config . Dengan cara itu rustc memilih GCC 6 yang dikirimkannya alih-alih yang sistem.

Masalah lain pada Windows adalah hardcoded linker flag --enable-long-section-names yang tidak didukung oleh LLD 9 dan yang lebih lama (ada rencana untuk mendukungnya di masa mendatang). Untuk menyiasatinya, Anda dapat:

  • buat pembungkus yang menghapus bendera ini
  • patch LLD untuk menerima flag ini sebagai no-op
  • gunakan build Rust lokal yang ditambal yang tidak menggunakan flag ini

Masalah lain pada Windows adalah hardcoded linker flag --enable-long-section-names yang tidak didukung oleh LLD 9 dan yang lebih lama (ada rencana untuk mendukungnya di masa mendatang).

Bagian ini diperbaiki oleh: https://github.com/rust-lang/rust/pull/66257
Pengguna Windows-gnu masih harus melakukan pekerjaan manual untuk menggunakan compiler C yang mendukung -fuse-ld=lld sekalipun.

@bstrie : Ini berfungsi dengan Stabil dan Malam di Windows-MSVC, detail di posting pertama masalah gamedev-wg ini: https://github.com/rust-gamedev/wg/issues/50

Poin data lain: menggunakan RUSTFLAGS="-C link-arg=-fuse-ld=lld" saat membangun rustc itu sendiri, waktu menautkan turun dari 93 detik menjadi 41 detik pada kotak Linux 14-core cepat saya.

@nnethercote : Apakah itu berbeda dari pengaturan linker=lld di (misalnya) bagian [target.x86_64-unknown-linux-gnu] dari config.toml ?

@ Aaron1011 : Dugaan saya adalah dua pendekatan memiliki efek yang sama, tetapi saya belum memeriksanya sendiri.

@ Aaron1011 itu harus dentang, lihat https://github.com/rust-lang/rust/issues/39915#issuecomment -538049306.

@mati865
Sudahkah Anda mencoba membangun rustc di x86_64-pc-windows-gnu dengan LLD sebagai tautan?

Saya mencobanya hari ini dan LLD hang di tengah build dan berhenti melakukan pekerjaan apa pun, atau mengeluh tentang unknown argument: --version-script=... .
Hang juga terjadi jika LLD digunakan untuk menghubungkan LLVM saja, dengan

[llvm]
use-linker = "lld"

Versi alat:

$ 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 ya saya bisa membuatnya dengan beberapa peretasan:

Saya menuliskan beberapa kemungkinan masa depan di sini. Sementara beberapa upaya implementasi diperlukan, saya pikir ini akan membantu memecahkan beberapa masalah lama dalam pengembangan Rust:

  • Alih-alih menggunakan lld yang disediakan eksternal, buat dan gunakan sebagai pustaka statis di dalam rustc. Hal ini memungkinkan integrasi yang lebih erat ke rustc itu sendiri, meningkatkan pengalaman out-of-box, dan membuka kemungkinan masa depan.
  • Alih-alih meneruskan banyak nama jalur ke lld sebagai perintah penghubung, gunakan sistem file virtual, dan teruskan data tersebut dari memori ke memori alih-alih menggunakan disk IO setiap kali ada cukup ruang memori untuk dilakukan. Untuk proyek yang lebih besar, ini dapat menghemat ratusan atau bahkan ribuan megabita disk IO, dan dengan demikian meningkatkan waktu kompilasi.

Alih-alih meneruskan banyak nama jalur ke lld sebagai perintah penghubung, gunakan sistem file virtual, dan teruskan data tersebut dari memori ke memori alih-alih menggunakan disk IO setiap kali ada cukup ruang memori untuk dilakukan. Untuk proyek yang lebih besar, ini dapat menghemat ratusan atau bahkan ribuan megabita disk IO, dan dengan demikian meningkatkan waktu kompilasi.

Ini bukan hanya masalah bandwidth IO. Pada platform seperti Windows, terutama ketika Windows Defender diaktifkan, setiap file yang ingin Anda kerjakan menambahkan penalti waktu yang cukup signifikan, dan model unit codegen Rust berarti peti dipecah menjadi ratusan file objek kecil yang dapat dengan cepat mengumpulkan banyak kompilasi waktu.

Bug ini sedikit berantakan, jadi inilah kesempatan terbaik saya untuk ringkasan singkat dari situasi saat ini, untuk orang-orang yang ingin memajukan ini.

Apa itu lld

Penghubung yang merupakan bagian dari proyek llvm, yang diinginkan karena dua alasan:

  • sangat ramah untuk kompilasi silang (karenanya penekanannya untuk target yang disematkan)
  • ini sangat cepat (sering berjalan dalam separuh waktu sebagai Emas -- penautan dapat memakan waktu beberapa menit untuk proyek besar (rustc, servo, dll.) dan penautan dapat menjadi % besar dari kompilasi dengan build tambahan, jadi mengurangi separuh runtime ini adalah a Masalah besar.)

Hal yang Rust lakukan dengan lld hari ini

  • Rust saat ini mengirimkan salinan lldnya sendiri di sebagian besar platform sebagai biner yang disebut rust-lld
  • rust-lld digunakan secara default pada banyak target bare-metal
  • rust-lld digunakan secara default untuk wasm
  • (?) Anda dapat secara eksplisit meminta rust-lld digunakan dengan menggunakan "-C linker-flavor" (tidak jelas tentang apa sebenarnya yang dilakukan pada platform non-bare-metal, lihat di bawah)

Masalah untuk menggunakan rust-lld di lebih banyak tempat (yaitu desktop linux/mac/windows)

  • Backend macOS (Mach-O) untuk lld rusak dan ditinggalkan

    • penulisan ulang dari awal telah dimulai, tetapi ini masih awal

  • Pada platform linux/unix, Anda tidak seharusnya langsung memanggil ld/lld. Anda seharusnya memanggil linker melalui kompilator c sistem Anda (yaitu gcc), yang bertanggung jawab untuk menemukan simbol sistem seperti crt1.o dan memberikannya ke ld. Ini berarti kita tidak bisa "hanya" menggunakan rust-lld; kita harus memasukkannya ke gcc/clang/whatever. (kami tidak ingin menerapkan logika simbol sistem ini sendiri)

    • Secara umum, Anda tidak dapat memberikan tautan sebagai jalur, Anda harus memasukkannya ke dalam jalur pencarian kompiler C sebagai "ld"

    • Atau, Anda dapat melakukan hal yang sama tetapi menyuntikkannya sebagai "ld.lld", dan meneruskan "-fuse-ld=lld"



      • Ini mungkin penting, tampaknya lld melakukan deteksi nama biner gaya dentang jika dieksekusi sebagai "ld" atau "ld.lld" (perlu penyelidikan)


      • Sayangnya -fuse-ld=lld hanya bagian dari GCC 9, jadi kami mungkin memerlukan deteksi fitur/versi untuk menggunakannya (dentang sudah lama)



  • windows-msvc tampaknya dalam kondisi yang baik, dan tampaknya memiliki beberapa dukungan terbatas untuk menggunakan rust-lld di backend, tetapi saya tidak jelas tentang apa yang perlu dilakukan di sini.
  • windows-mingw tampaknya berada di tempat yang kira-kira sama dengan linux/unix, kecuali Anda bertanggung jawab untuk mendapatkan GCC kuno, dan semuanya agak miring karena pseudo-windows-linux bukanlah konfigurasi yang benar-benar teruji?

Juga secara umum, lld lebih baru, ini bukan default untuk sebagian besar OS, bug compat acak hampir pasti akan muncul jika kita mulai menggunakan ini di lebih banyak tempat.

Saya telah mengajukan dua metabug untuk upaya terfokus menggunakan (karat-)lld secara default pada dua platform:

  • #71515 - x64 Ubuntu 20.04 LTS (dan lebih luas lagi semua platform x64 ELF)
  • #71520 - jendela x64 msvc

windows-msvc tampaknya dalam kondisi yang baik, dan tampaknya memiliki beberapa dukungan terbatas untuk menggunakan rust-lld di backend, tetapi saya tidak jelas tentang apa yang perlu dilakukan di sini.

LLD + windows-msvc dalam keadaan cukup baik, saat ini saya menggunakan pengaturan ini untuk pengembangan rustc .

Semua dukungan yang diperlukan untuk lld-link sudah ada di backend rustc , tetapi ada bug seperti https://github.com/rust-lang/rust/issues/68647.

  • Ini mungkin penting, tampaknya lld melakukan deteksi nama biner gaya dentang jika dieksekusi sebagai "ld" atau "ld.lld" (perlu penyelidikan)

memang, tetapi ld dan ld.lld adalah mode yang sama: https://github.com/rust-lang/llvm-project/blob/rustc/10,0-2020-02-05/lld/tools/lld/lld. cpp (sama sejak 8.0-2019-01-16)

  • Sayangnya -fuse-ld=lld hanya bagian dari GCC 9, jadi kami mungkin memerlukan deteksi fitur/versi untuk menggunakannya (dentang sudah lama)

karena ld.lld sama dengan ld, dan menurut https://patches-gcc.linaro.org/patch/11148/ satu-satunya perubahan dengan -fuse-ld=lld adalah menjalankan ld.lld alih-alih ld, jika kami menggunakan injeksi PATH, seharusnya baik-baik saja. Saya pikir mengunci ini ke gcc 9+ tidak baik: debian stable hanya memiliki 8,3, dan bullseye mungkin tidak akan dirilis hingga 2021.

  • windows-mingw tampaknya berada di tempat yang kira-kira sama dengan linux/unix, kecuali Anda bertanggung jawab untuk mendapatkan GCC kuno, dan semuanya agak miring karena pseudo-windows-linux bukanlah konfigurasi yang benar-benar teruji?

mingw-w64 6.0.0, dirilis 16-09-2018, memiliki gcc 8.3.0, yang tidak memiliki -fuse-ld=lld, tetapi masih cukup baru. mingw-w64 7.0.0, dirilis 11-11-2019, memiliki gcc 9.3.0, yang memang memiliki -fuse-ld=lld. Debian buster (stabil) memiliki 6.0.0, bullseye (pengujian) memiliki 7.0.0. Debian stretch (oldstable) hanya memiliki 5.0.1 dengan gcc 6.3.0, tetapi saya pikir masuk akal untuk meminta debian stable terbaru untuk dukungan lld jika ada masalah signifikan dengan gcc 6.3.

Saya telah mengajukan dua metabug untuk upaya terfokus menggunakan (karat-)lld secara default pada dua platform:

  • #71515 - x64 Ubuntu 20.04 LTS (dan lebih luas lagi semua platform x64 ELF)
  • #71520 - jendela x64 msvc

Tentang port macOS (Mach-O) lld: tampaknya berfungsi, atau setidaknya, berada dalam kondisi yang jauh lebih baik sejak https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211 Sudah ditulis!

Menggunakan komit LLVM ini , saya membuat lld dan menetapkannya sebagai tautan khusus proyek untuk tokio-rs/tracing . Saya kemudian membangun pelacakan terhadap nightly-x86_64-apple-darwin dan menjalankan semua tes dengan sukses. Saya sangat senang dengan waktu pembuatan (debug):

  • Dengan ld , cargo build membutuhkan waktu 35 detik.
  • Dengan lld , cargo build membutuhkan waktu 20 detik.

Perhatikan bahwa:

  • angka performa ini berasal dari MacBook Pro terbaru dengan RAM 32GB dan 8-Core i9, dan
  • ada beberapa masalah luar biasa untuk lld dan Mach-O.

@davidbarsky Keren! Karena penasaran, bagaimana kinerja itu dibandingkan dengan zld ? ( https://github.com/michaeleisel/zld )

Juga, apakah Anda memperhitungkan termal? MBP masuk ke pelambatan termal dengan sangat cepat, terutama dengan profil kecepatan kipas default. Hanya menunggu sampai bagian bawah mesin di dekat engsel dingin saat disentuh sebelum melakukan lari akan membantu konsistensi.

Saya hanya bug seperti itu, di Ubuntu 16 i686

Apakah halaman ini membantu?
0 / 5 - 0 peringkat