2 poin oleh GN⁺ 2023-12-19 | 1 komentar | Bagikan ke WhatsApp
  • gccrs adalah proyek yang dimulai pada 2014 untuk mengimplementasikan compiler Rust di dalam GCC; meski masih jauh dari selesai, proyek ini menunjukkan kemajuan menuju kompilasi standard library dan penyertaan dalam GCC 14
  • Proyek ini menargetkan Rust 1.49 alih-alih terus mengejar Rust terbaru yang berubah cepat, tetapi karena dependensi internal standard library, fitur seperti const generics pada akhirnya tetap harus diimplementasikan
  • Kompilasi core dan alloc masih terhambat oleh resolusi nama makro, decorator macro, compiler intrinsic LLVM yang tidak ada di GCC, serta ketiadaan borrow checker
  • rustc_codegen_gcc adalah pendekatan yang lebih matang, memanfaatkan sebagian rustc dan memakai GCC sebagai backend pembuatan kode; per Oktober 2023, ia dapat mengompilasi Rust for Linux tanpa patch tambahan
  • gccrs memiliki motivasi yang jelas, seperti plugin keamanan GCC, analisis statis, arsitektur yang tidak didukung LLVM, dan Rust for Linux, tetapi kegunaannya secara praktis masih lebih terbatas dibanding rustc_codegen_gcc

Tujuan gccrs dan posisinya saat ini

  • gccrs adalah proyek untuk mengimplementasikan compiler Rust di dalam GNU Compiler Collection(GCC)
  • Proyek ini dimulai pada 2014, dan berdasarkan laporan proyek setelah liputan LWN sebelumnya, telah ada kemajuan
  • Pada 2022, targetnya adalah masuk ke GCC 13, tetapi target itu tidak tercapai; berdasarkan laporan bulanan November 2023, targetnya adalah penyertaan dalam GCC 14
    • GCC 14 dibahas sebagai versi yang kemungkinan dirilis pada pertengahan 2024
  • Pada EuroRust 2023 bulan Oktober 2023, Arthur Cohen menjelaskan pekerjaan kompilasi Rust standard library dan alasan mengapa itu belum dapat dikompilasi dalam presentasi “The road to compiling the standard library with gccrs”

Alasan menargetkan Rust 1.49

  • gccrs menargetkan Rust 1.49, alih-alih terus mengikuti versi terbaru Rust
  • Rust 1.49 dirilis pada akhir 2020, dan merupakan versi terakhir sebelum dukungan const generics tersedia untuk penggunaan umum di Rust 1.50
  • Proyek ini berusaha menghindari const generics, tetapi fitur tersebut sudah digunakan di dalam standard library Rust 1.49 sehingga pada akhirnya tidak dapat diabaikan
  • const generics kemudian telah diimplementasikan sepenuhnya dan tidak lagi menjadi hambatan
  • gccrs tidak bermaksud membuat superset Rust atau bahasa “GNU Rust” terpisah
    • Tujuannya adalah mereproduksi output, bug, hingga perilaku khas rustc
    • Untuk itu, proyek ini menggunakan baik test suite Rust maupun test suite GCC

Bagian yang terhambat dalam kompilasi standard library

  • Rust standard library terdiri dari beberapa crate
  • gccrs sedang mengerjakan dukungan kompilasi untuk dua crate terpenting, yaitu core dan alloc
    • core mengimplementasikan fitur dasar standard library seperti tipe primitif dan makro
    • alloc menangani alokasi memori heap dan berbagai tipe container
  • Saat ini gccrs belum dapat mengompilasi crate-crate ini karena kekurangan fitur berikut
    • Perilaku resolusi nama makro belum benar
    • Dukungan decorator macro belum lengkap
    • Tidak ada borrow checker, sehingga keamanan kode tidak dapat diperiksa dengan semestinya
    • Compiler intrinsic LLVM yang tidak ada di GCC harus diimplementasikan
  • Ketiadaan borrow checker tidak dengan sendirinya menghalangi kompilasi, tetapi membuat pemeriksaan keamanan kode Rust tidak dapat dilakukan dengan benar

Macro prosedural dan pekerjaan integrasi GCC

  • Pada GNU Tools Cauldron bulan September 2023, Pierre-Emmanuel Patry mempresentasikan status penyertaan ke GCC 14 dan pekerjaan terkait macro
  • Cara implementasi procedural macro memerlukan perubahan pada sistem build GCC
  • Procedural macro adalah macro berbasis fungsi yang menghasilkan token stream, bukan sekadar teks sumber seperti macro C atau C++
  • Di Rust, fitur ini diimplementasikan melalui crate bawaan proc_macro
  • Procedural macro sulit diimplementasikan, tetapi memungkinkan fitur-fitur yang kuat
    • Decorator #[attribute]
    • Decorator #[derive()]
    • Pembuatan domain-specific language berbasis evaluasi waktu kompilasi
  • Berdasarkan presentasi GNU Cauldron, gccrs memiliki lebih dari 800 commit yang perlu di-upstream ke GCC

Alasan ingin memanfaatkan ekosistem GCC untuk Rust

  • Salah satu motivasi utama gccrs adalah memanfaatkan plugin keamanan GCC juga untuk kode Rust
  • GCC memiliki beragam plugin yang membantu debugging, analisis statis, dan hardening, dan plugin-plugin ini bekerja pada intermediate representation GCC
  • gccrs ingin mendukung workflow yang memungkinkan developer Rust menggunakan kembali plugin GCC yang sudah ada
  • Cohen memberi contoh bahwa programmer C sudah lama membuat kesalahan tidak menutup file descriptor, sehingga ada banyak plugin untuk menangkap kesalahan tersebut
  • Tujuannya adalah memungkinkan plugin GCC dan static analyzer yang sudah ada dipakai untuk menemukan bug dalam kode unsafe Rust

Area yang sudah mulai digunakan

  • Menurut Cohen, komunitas homebrew Sega Dreamcast menggunakan gccrs untuk membuat game baru bagi konsol game Dreamcast
  • Alasan komunitas Dreamcast tertarik adalah backend LLVM milik rustc tidak mendukung arsitektur Hitachi SH-4 pada konsol tersebut, sedangkan GCC mendukungnya
  • gccrs masih belum selesai, tetapi membantu dalam use case embedded semacam ini
  • Analisis statis terhadap kode Rust unsafe menggunakan plugin GCC juga sudah memungkinkan
  • Dalam proses pengerjaan gccrs, fitur bahasa yang spesifikasinya belum cukup jelas, seperti Deref dan resolusi nama makro, ikut terungkap, dan proyek ini juga dapat berkontribusi pada penambahan spesifikasi Rust
    • Rust saat ini belum memiliki spesifikasi resmi, tetapi pekerjaan spesifikasi sedang berjalan sesuai RFC 3355

Fitur inti yang masih dalam pengembangan

  • gccrs masih kekurangan banyak fitur inti compiler Rust
  • Fitur utama yang belum diimplementasikan atau masih dalam pengembangan adalah sebagai berikut
    • async/await
    • Intrinsic LLVM yang tidak ada di GCC
    • Macro format_args!() yang digunakan oleh macro output seperti println!()
    • Borrow checker yang menegakkan aturan referensi Rust
  • Solusi yang kuat untuk borrow checker adalah proyek terpisah Polonius
  • Cohen mengatakan kemungkinan besar gccrs akan mengintegrasikan Polonius beberapa bulan kemudian
  • Jakub Dupak mencatat kemajuan dalam pekerjaan ini selama beberapa bulan terakhir
  • Polonius adalah library yang mengimplementasikan borrow checker yang secara semantik setara dengan borrow checker rustc saat ini
    • Menggunakan algoritme berbeda untuk menghitung lifetime referensi
    • Dalam jangka panjang, bertujuan mengatasi kekurangan dan corner case pada borrow checker rustc saat ini
    • Jika sudah matang, rustc juga mungkin mengadopsi Polonius di masa depan

Mengapa format_args!() diperlukan

  • Menurut laporan bulanan gccrs November 2023, pekerjaan pada macro format_args!() telah dimulai
  • format_args!() adalah macro pembantu yang menyusun argumen untuk diteruskan ke macro pemformatan string
  • Fitur ini terkait dengan trait Display dan Debug
  • Fitur ini diperlukan untuk menyiapkan argumen yang akan diberikan ke macro seperti format!() dan println!()
  • Tanpa format_args!(), program Rust tidak dapat menghasilkan output terformat
  • Karena itu, fitur ini diperlukan bahkan sebelum gccrs dapat mengompilasi program “Hello, World”
  • Tulisan blog Mara Bos juga dibahas sebagai penjelasan mendalam tentang format_args!()

Perbedaan dengan rustc_codegen_gcc

  • rustc_codegen_gcc adalah proyek Rust berbasis GCC yang berbeda dari gccrs
  • Proyek ini lebih matang daripada gccrs, tetapi cakupannya lebih terbatas
  • Pendekatannya bukan mengimplementasikan compiler Rust sepenuhnya dari awal
  • Ia menggunakan library libgccjit untuk terhubung ke API backend LLVM milik rustc
  • Sebagian besar proses kompilasi dilakukan oleh rustc, lalu GCC digunakan pada tahap berikutnya
  • Meski nama libgccjit mengandung JIT, rustc_codegen_gcc ditujukan untuk kompilasi ahead-of-time
  • Tujuan utamanya adalah memungkinkan pembuatan kode Rust pada platform yang tidak didukung LLVM
  • Per Oktober 2023, rustc_codegen_gcc dapat mengompilasi Rust for Linux tanpa patch tambahan
  • Selama setahun terakhir, dukungan SIMD dan link-time optimization telah ditambahkan
    • Kedua fitur ini sebelumnya disebut sebagai penyebab kegagalan pengujian
  • Dalam presentasi EuroRust, Cohen beberapa kali merekomendasikan agar untuk sementara memakai rustc_codegen_gcc alih-alih gccrs
  • rustc_codegen_gcc sudah masuk upstream ke repositori bahasa Rust

Rust for Linux dan kesenjangan versi

  • Rust for Linux adalah inisiatif untuk menambahkan dukungan Rust ke kernel Linux
  • Cohen menyebut kernel Linux sebagai motivasi utama proyek gccrs
    • Karena banyak pihak terkait kernel lebih memilih kernel dapat dikompilasi hanya dengan toolchain GNU
  • Saat ini proyek Rust for Linux mendokumentasikan rustc atau rustc_codegen_gcc sebagai cara membangun kode Rust kernel
  • Kernel juga memiliki dokumentasi versi minimum yang didukung untuk berbagai build tool
    • rustc diperlakukan bukan sebagai versi minimum, melainkan sebagai versi yang harus persis sama
    • Versi rustc yang saat ini didukung adalah 1.73.0, dirilis pada Oktober 2023
  • Ada kesenjangan besar antara Rust 1.49 yang ditargetkan gccrs dan Rust 1.73.0 yang dibutuhkan Rust for Linux
  • Dukungan Rust for Linux adalah salah satu tujuan eksplisit gccrs, tetapi karena kesenjangan versi ini, jaraknya masih cukup jauh

Evaluasi keseluruhan

  • Repositori gccrs memiliki lebih dari 3.000 commit sejak 1 Januari 2023
  • Selama setahun terakhir, proyek ini menunjukkan kemajuan besar
  • Namun, karena cakupan implementasi compiler Rust penuh dari awal sangat besar, proyek ini belum berada dalam kondisi dapat digunakan untuk hampir semua tujuan praktis
  • rustc_codegen_gcc telah digabungkan ke repositori upstream Rust dan digunakan secara nyata di Rust for Linux
  • Rust belum mencapai tahap ketika ada beberapa implementasi compiler independen untuk bahasa tersebut, tetapi arahnya semakin mendekat ke sana

1 komentar

 
GN⁺ 2023-12-19
Pendapat Hacker News
  • Dari klaim dalam tulisan saja, motivasi gccrs tampak agak lemah
    Plugin keamanan GCC atau preferensi toolchain GNU di sisi kernel Linux memang menjelaskan alasan ingin memakai GCC sebagai backend, tetapi tidak menjelaskan mengapa diperlukan frontend duplikat
    Saya berharap Rust tidak mengulang kesalahan yang membuat pengembangan lintas platform menjadi sulit seperti C++, akibat switch compiler yang berbeda-beda, perbedaan tingkat dukungan bahasa, dan bug spesifik platform
    Jadi akan baik jika dijelaskan mengapa gccrs merupakan pendekatan yang lebih baik daripada rustc_codegen_gcc; yang terakhir tampaknya bisa mencapai tujuan yang sama dengan upaya dan risiko yang jauh lebih kecil

    • Jika ada satu implementasi Rust lagi, itu bisa berperan sebagai audit untuk memverifikasi spesifikasi Rust dan mengurangi perilaku tak terdefinisi
      Jika menemukan bug compiler di MSVC, kita bisa melaporkannya lalu beralih ke GCC untuk melanjutkan pekerjaan, tetapi di Rust saat ini belum ada pilihan seperti itu
    • Rust sudah belajar dari kesalahan C++
      Seperti yang dikutip, kehati-hatian agar tidak menjadi superset Rust adalah salah satu contohnya
      Masalah C/C++ muncul karena para vendor compiler saling bersaing dengan klaim “lebih baik”, sementara beberapa frontend biasanya punya kelebihan dalam mengungkap banyak bug dan implementasi yang keliru
    • Saya tidak mengerti mengapa pertanyaan seperti ini terus muncul
      Rust bukan sesuatu yang sakral sehingga penulisan ulang frontend dilarang, dan melakukan bootstrap Rust di arsitektur baru masih menyakitkan
      Pada arsitektur yang tidak didukung LLVM, tidak ada compiler Rust yang berfungsi
      codegen_rust_gcc juga punya masalah bootstrap yang sama dengan compiler Rust yang ada, dan perlu memasukkan dukungan arsitektur ke berbagai bagian Rust, sesuatu yang selama ini cenderung enggan dilakukan para maintainer Rust
      Jadi jika dalam waktu dekat muncul compiler Rust yang langsung bisa dipakai, sehingga library yang sudah di-Rust-kan bisa kembali dibangun di arsitektur seperti Alpha tanpa banyak rasa sakit, itu akan sangat menggembirakan
    • Dengan logika itu, komunitas LLVM bisa ditanya mengapa mereka tidak terus memakai DragonEgg dan malah membuat Clang, Clang++, libc++, dan sebagainya
      Saat itu sudah ada GCC, G++, libstdc++, dan frontend EDG C++
      GCC, Clang, MSVC, dan compiler lain saling melengkapi, melayani tujuan dan pasar yang berbeda, serta membantu bahasa menjadi kokoh sesuai spesifikasi, bukan sekadar sifat kebetulan dari satu implementasi tunggal
      GNU Toolchain Project, LLVM Project, dan proyek Rust semuanya pernah mengalami masalah, jadi lebih baik tidak bergantung pada satu titik kegagalan; redundansi dan antifragilitas adalah teman
    • Ketika dikatakan Rust harus belajar dari kesalahan C++ dan C, maksudnya belajar dari kesalahan bahasa-bahasa yang paling lama bertahan, paling berpengaruh, dan paling luas didistribusikan dalam sejarah?
      Saya merasa membingungkan jika memandang standar bahasa secara buruk dan lebih suka mengatakan “kode ini berjalan pada biner/sumber rustc dengan hash SHA256 e49d560cd008344edf745b8052ef714b07595808898c835f17f962a10012f964” alih-alih “kode ini adalah C99/C++11”
  • Rust membutuhkan standar bahasa
    https://blog.m-ou.se/rust-standard/
    https://rust-lang.github.io/rfcs/3355-rust-spec.html
    https://github.com/rust-lang/rfcs/pull/3355
    Ada banyak organisasi dan industri yang tidak akan mengadopsi Rust sebelum ada standar
    C, C++, C#, bahkan JavaScript (ECMAScript) memiliki standar bahasa, jadi tidak ada alasan Rust tidak memilikinya
    C: https://www.iso.org/standard/74528.html
    C++: https://isocpp.org/std/the-standard
    C#: https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
    JavaScript / ECMAScript: https://ecma-international.org/publications-and-standards/st...

    • RFC itu sudah disetujui, dan secara nyata sudah mulai berjalan
      Kemajuannya memang sangat lambat sampai mengecewakan, tetapi proyeknya masih hidup, dan ada kemungkinan lajunya meningkat tahun depan
      https://blog.rust-lang.org/inside-rust/2023/11/15/spec-visio...
    • Tulisan blog Mara, yaitu tautan pertama, lebih condong pada pandangan bahwa Rust pada dasarnya tidak membutuhkan standar, karena Rust sudah memiliki cara untuk menambahkan fitur dan menjaga kompatibilitas
    • Berkat spesifikasi Ferrocene, Rust bisa digunakan juga di industri-industri semacam itu
    • Go memiliki spesifikasi yang sangat baik dan beberapa implementasi
      https://go.dev/ref/spec
    • Sebagai sanggahan terhadap pernyataan bahwa banyak organisasi dan industri tidak akan mengadopsi tanpa standar: Rust tetap berjalan baik tanpa organisasi dan industri tersebut
      Saya tidak tahu mengapa kita harus mengubah cara yang sudah berfungsi dengan baik
  • Mengejutkan bahwa ada banyak reaksi negatif terhadap GCC-RS
    Menurut saya, bahasa yang tidak punya beberapa implementasi terlihat cukup menyedihkan

    • Dulu itu dianggap pandangan umum, terutama karena C/C++, tetapi sekarang jauh lebih diperdebatkan
      Konsensus komunitas Rust adalah bahwa cara saat ini—satu compiler yang secara definisi menjadi standar, banyak dokumentasi, spesifikasi minimum untuk industri yang wajib aman, dan spesifikasi sebagian subarea modul—membawa sebagian besar manfaat dari banyak implementasi sambil menghindari kekurangannya
    • Dalam jangka panjang, masalahnya adalah stabilitas sintaks dan pencegahan pembengkakan fitur akibat ekstensi/atribut
      Ini benar-benar terjadi di C, dan C++ sudah hampir tak tertolong karena kompleksitasnya yang absurd dan aneh
      Tanpa ini, implementasi alternatif yang realistis sulit muncul
    • Secara pribadi saya memahami nilai dari banyak implementasi, tetapi masalahnya adalah membangunnya di atas GCC
      Toolchain GNU itu kacau, dan saya benar-benar tidak tahu bagaimana orang mengembangkan sesuatu di atasnya
      Ini bukan soal ideologi; secara harfiah saya tidak paham bagaimana menyiapkan lingkungan pengembangan untuk GCC itu sendiri
      Saya pernah bernasib sial melakukan bootstrap beberapa kali, dan itu adalah perangkat lunak dengan perilaku terburuk yang pernah saya lihat sejauh ini
  • Menyenangkan melihat bagian bahwa komunitas homebrew Sega Dreamcast bisa membuat gim baru dengan gccrs, dan melakukan analisis statis pada kode unsafe Rust dengan plugin GCC
    Arsitektur Hitachi SH-4 pada Dreamcast tidak didukung backend LLVM milik rustc, tetapi didukung GCC, jadi bahkan gccrs yang belum selesai pun berguna untuk pemanfaatan embedded semacam ini

    • Ini agak menyesatkan
      Untuk itu yang dibutuhkan bukan frontend GCC, melainkan cukup backend GCC saja
  • Sekarang tampaknya kita akan bisa melihat dukungan Rust juga di arsitektur seperti Alpha, SuperH, VAX yang tidak didukung LLVM tetapi didukung GCC

    • Itu juga mencakup mips64, yang baru-baru ini dibuang dukungannya oleh rustc setelah gagal menarik dukungan dana/sumber daya dari Loongson
      https://github.com/rust-lang/compiler-team/issues/648
      Masalah terbesar dari cara berpikir LLVM adalah dukungan arsitektur dipakai sebagai alat untuk menarik dukungan dari perusahaan hardware, yaitu posisi developer berbayar
      GNU memang bisa punya standar penggabungan perubahan yang menyebalkan tingginya, tetapi begitu masuk dan didukung, mereka memeliharanya dalam jangka panjang
      Ini seperti perbedaan antara membeli dan menyewa; memasukkan dukungan ke GCC memang memakan waktu pengembangan jauh lebih banyak, tetapi begitu masuk, ia tetap ada
    • Sepertinya akan muncul opsi konfigurasi tambahan juga untuk arsitektur yang sudah didukung
      Misalnya, baru-baru ini saya mengetahui bahwa untuk RISC-V, GCC mendukung target RV32E tetapi LLVM tidak
    • Saya ingin segera melihat kode mesin PDP-11 yang dihasilkan dari Rust
      Terakhir kali saya mengecek, kompilasi C standalone masih berfungsi di GCC
  • Menurut pengalaman saya, bagian bahwa gccrs tidak akan membuat bahasa khusus bernama “GNU Rust” dan justru mencoba mereplikasi output rustc, sampai bug dan keanehannya, adalah kesalahan besar
    Rust tidak punya spesifikasi; ada dokumen referensi, tetapi secara eksplisit tidak normatif
    Bahasa yang tidak terdokumentasi selain satu implementasi referensi punya kelemahan jangka panjang
    Tujuan untuk menjamin kode yang ada berjalan di kedua implementasi memang masuk akal, tetapi jika sampai menjanjikan kompatibilitas bug, itu akan membekukan keputusan buruk dan bug menjadi fosil
    Microsoft mengerahkan banyak tenaga agar program lama tetap berjalan sambil memperbaiki bug keamanan dan keandalan, tetapi Rust tidak perlu memikul beban seperti itu pada awal masa hidupnya
    Jika ingin mengembangkan bahasa, harus menerima penjaminan mutu dan pengendalian mutu
    Kualitas tidak bisa disuntikkan belakangan lewat pengujian; ia harus dibuat bekerja dengan benar—dan jika gagal, gagal ke arah yang benar—melalui proses seperti arsitektur dan desain, serta review desain/kode
    Standar kuat seperti Common Lisp, C++, FORTRAN menerima keyakinan ini, dan bahasa lemah yang secara de facto mendekati standar seperti Python juga bisa populer, tetapi sulit berubah; hal itu terlihat dari transisi panjang Python 2 ke 3 dan sedikitnya jumlah implementasi

    • Kalau menemukan bug besar, sepertinya cukup laporkan ke upstream lalu ubah kedua implementasi
  • Saya terlambat berkomentar di bagian akhir thread ini, tetapi ini belum tentu hal yang baik
    Distribusi sudah kesulitan mengikuti bahasa-bahasa yang merilis versi baru setiap beberapa bulan, sehingga rustc atau Go pun sudah sulit dipakai sebagai paket distribusi
    Sekarang, secara mengejutkan, ada sistem yang tidak lagi membutuhkan GCC sehingga menghapusnya, dan hanya mempertahankan Go serta Rust upstream untuk pembaruan perangkat lunak yang ada
    Beberapa bulan lalu saat memperbarui Go karena CVE, saya melihat aplikasi berbasis Go menyimpan lingkungan Go miliknya sendiri di empat tempat berbeda; itu benar-benar mimpi buruk

  • Linux sudah bisa dikompilasi dengan Clang jika mau, sehingga seluruhnya dapat memakai toolchain berbasis LLVM
    Upaya duplikatif untuk mengembangkan dan memelihara ini demi “kemurnian” GNU tampaknya tidak sepadan

    • Ini bukan masalah kemurnian, melainkan masalah pilihan
      Komunitas ClangBuiltLinux dulu berargumen bahwa Linux tidak boleh bergantung pada satu compiler, tetapi ketika Rust datang, banyak dari orang yang sama tiba-tiba mulai menganggap satu compiler saja juga baik-baik saja
    • Sepertinya ada kesalahpahaman di sini
      Ini bukan untuk mengikat kernel agar khusus GNU, melainkan hanya agar toolchain GNU murni bisa menjadi pilihan