پرش به محتوای اصلی
پرش به محتوای مقاله

ترجمه کامپایلر Rust به ۴۶ میلیون خط کد C؛ راهی برای سخت‌افزارهای منسوخ

·۱۲ تیر ۱۴۰۵۶ دقیقه مطالعه
لوگوی GitHub و عنوان پروژه: «crustc» - کل کامپایلر rustc به زبان C ترجمه شده.
لوگوی GitHub و عنوان پروژه: «crustc» - کل کامپایلر rustc به زبان C ترجمه شده.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

برای نخستین بار، کل کامپایلر Rust به زبان C ترجمه شده تا وابستگی به بک‌اندهای LLVM حذف شود. این یک تغییر ساختاری در نحوه هدف‌گذاری سخت‌افزاری Rust است، نه یک به‌روزرسانی ساده در نسخه کامپایلر.

تصور کنید می‌خواهید مدرن‌ترین زبان برنامه‌نویسی جهان را روی تراشه‌هایی اجرا کنید که پیش از تولد شما ساخته شده‌اند. اکنون با ظهور ابزار Cilly، این رویای مهندسی به واقعیت تبدیل شده و Rust را از وابستگی مطلق به زیرساخت‌های پیچیده نجات داده است.

به نقل از مستندات پروژه، این ابزار توانسته است کامپایلر rustc را به ۴۶ میلیون خط کد C ترجمه کند. این حجم عظیم از کد، در واقع پلی است برای اجرای Rust روی سخت‌افزارهایی که پیش‌تر «منسوخ» تلقی می‌شدند. پروژه‌ای که با نام crustc در گیت‌هاب میزبانی می‌شود، یک کامپایلر کاربردی است که کاملاً با GCC و make ساخته شده و بر اساس بیلد نایتلای ۱۶ ژوئن ۲۰۲۶ (نسخه v1.98.0، کامیت c712ea946) اجرا می‌شود.

برای سال‌ها، وابستگی شدید Rust به LLVM (یک زیرساخت بهینه‌ساز کد) مانند دیواری بلند بود که توسعه‌دهندگان را از سیستم‌های قدیمی جدا می‌کرد. اگر سخت‌افزاری بک‌اند LLVM نداشت، Rust عملاً روی آن قابل اجرا نبود. همان‌طور که در تحلیل‌های پیشین ما درباره‌ی اکوسیستم زبان‌های برنامه‌نویسی اشاره کردیم، این موضوع همواره نقطه ضعف اصلی Rust در مقایسه با زبان C ذکر می‌شد؛ چراکه کامپایلرهای C حتی در تاریک‌ترین و قدیمی‌ترین گوشه‌های سخت‌افزاری دنیا و روی مبهم‌ترین پلتفرم‌ها هم حضور دارند. هدف بنیادین این پروژه، حذف کامل این مشکل است تا کاربران بتوانند هر کامپایلر C مورد نیاز خود را برای یک هدف (Target) خاص تعریف کنند.

سازوکار Cilly

قلب تپنده این دستاورد، ابزار Cilly است که پس از ۱۴ تلاش ناموفق توسعه‌دهنده‌اش برای حل مسئله کامپایل Rust به C به ثمر رسیده است. این مسیر شامل چندین تلاش عمومی و خصوصی پیشین، از جمله پروژه rustc_codegen_clr بود. Cilly در واقع یک کتابخانه Rust برای تولید کد C است که به عنوان یک پلاگین برای بک‌اند کامپایلر عمل کرده و این ترجمه را ممکن می‌سازد.

تفاوت کلیدی Cilly با تلاش‌های قبلی در این است که محیط هدف را ثابت نمی‌بیند. در عوض، خود را با هر کامپایلر C و هر پلتفرمی که با آن روبرو شود، تطبیق می‌دهد. این ابزار به گونه‌ای طراحی شده است که حتی یک «کامپایلر C شمینکی برای سیستم‌عامل Blorbo» را نیز راضی کند؛ و این کار را از طریق استعلام ویژگی‌های خاص محیط انجام می‌دهد.

برای رسیدن به این انعطاف‌پذیری، Cilly برنامه‌های «شاهد» (Witness) تولید می‌کند تا قابلیت‌های کامپایلر میزبان را بسنجد. برای مثال، قطعات کوچکی از کد می‌نویسد تا بررسی کند آیا کامپایلر از _Thread_local پشتیبانی می‌کند یا خیر؛ این کار با بررسی کدی شبیه به _Thread_local int KEYWORD_TLS_SUPPORTED; انجام می‌شود. همچنین با استفاده از دستور assert(sizeof(float) == sizeof(double)); بررسی می‌کند که آیا اندازه داده‌های اعشاری (float و double) در آن پلتفرم یکسان است یا نه.

این ابزار موارد زیر را در پلتفرم هدف استعلام و تطبیق می‌دهد:

  • تمام چیدمان‌ها (Layouts)، اندازه‌ها و ترازهای نوع داده (Type Alignments).
  • رمزگذاری‌های نویسه (به‌ویژه ASCII).
  • فرمت‌های اعداد صحیح (complement دو یا Two's complement).

اگر ویژگی‌ای در پلتفرم هدف نباشد، Cilly سعی می‌کند راهکارهای جایگزین (Fallbacks) را پیاده کند. هدف توسعه‌دهنده، انطباق سخت‌گیرانه با استاندارد ANSI C است، که شامل راهکارهای جایگزین برای مشکلاتی در استانداردهای مدرن C، مانند «تخصیص نام مستعار سخت‌گیرانه» (Strict Aliasing) می‌شود. با این حال، این بدان معناست که خروجی نهایی کاملاً وابسته به کامپایلر است؛ یعنی کد C تولید شده برای Arm64 روی riscv32 اجرا نمی‌شود، هرچند تولید یک خروجی مجزا برای riscv32 امکان‌پذیر است.

مدیریت مقیاس و حجم کد

حجم خروجی این فرآیند خیره‌کننده است. ترجمه rustc نسخه ۱.۹۸.۰-nightly منجر به تولید ۴۶ میلیون خط کد C شد (و تعدادی Wrapperهای C++ برای LLVM که برای در دسترس قرار دادن تنظیمات خاص LLVM استفاده شده‌اند). با این حال، طبق گزارش توسعه‌دهنده، ساخت (Build) این پروژه بدون بهینه‌سازی، روی یک ایستگاه کاری لینوکس ARM64 تنها چند دقیقه زمان می‌برد.

در آزمایش‌های ثبت شده با دستور make -j20:

  • زمان کاربر (user): ۹۳۷.۹۸ ثانیه
  • زمان سیستم (system): ۱۲۳.۷۷ ثانیه
  • استفاده از CPU: ۱۳۵۲٪
  • زمان کل: ۱ ساعت و ۱۸ دقیقه و ۴۸ ثانیه

به دلیل اینکه بهینه‌سازی‌های سنگین ممکن است باعث شکست در فرآیند ساخت شود یا باعث شود کامپایلر در مواجهه با فایل‌های غول‌پیکر Rust «خفه شود»، شدیداً توصیه شده است که بهینه‌سازی‌ها غیرفعال باشند.

مشخصات فنی دقیق بیلد:

  • کامپایلر C: GCC 13.3.0 (Ubuntu 24.04.1).
  • لینکر: Ubuntu LLD 18.1.3.
  • سیستم‌عامل: Linux spark-2773 6.17.0-1021-nvidia (aarch64).
  • وابستگی: نیاز به فایل libLLVM.so.22.1-rust-1.98.0-nightly. کاربر باید مسیر LLVM_LIB_DIR را ارائه دهد، مثلاً: ~/.rustup/toolchains/nightly-2026-06-16-aarch64-unknown-linux-gnu/lib.

حل پارادوکس بوت‌استرپ

یکی از نوآوری‌های Cilly، شفافیت شبکه است. این ابزار می‌تواند از طریق پروتکل TCP یا حتی UART با کامپایلرهای C ارتباط برقرار کند. این ویژگی «پارادوکس بوت‌استرپ» را برای پلتفرم‌هایی که فاقد کامپایلر متقاطع (Cross-compiler) هستند، حل می‌کند.

در این گردش‌کار، توسعه‌دهنده یک سرور C کوچک روی سیستم‌عامل هدف (مثلاً Blorbo OS) اجرا می‌کند و rustc را روی یک ماشین لینوکسی استاندارد می‌راند. سپس Cilly از طریق شبکه دستورات را می‌فرستد تا کامپایل را انجام دهد. این روش با موفقیت برای کامپایل برنامه‌های Rust برای ماشین‌های مجازی x86 Plan9 از روی میزبان Arm64 لینوکس آزمایش شد. باینری‌های حاصل از طریق ابزار nm تأیید شدند و حضور نماد rust_begin_unwind در آن‌ها مشاهده شد (به عنوان مثال: 1020 T _RNvCshfEkAwg4zv6_7___rustc17rust_begin_unwind).

قابلیت‌های مدیریتی پیشرفته دیگر:

  • تولید Makefile: Cilly می‌تواند نشانگرهایی (Markers) را در فایل‌های آبجکت جاسازی کرده و IR را در یک پوشه کش ذخیره کند. سپس این نشانگرها را می‌خواند تا توابع و متغیرهای جهانی را بر اساس مکان تعریفشان تقسیم کرده و مجموعه‌ای از Makefileها را تولید کند.
  • سفارشی‌سازی هدف: کاربران می‌توانند اهداف را در قالب JSON تعریف کنند و در آن فایل اجرایی محلی (مثلاً /usr/bin/sdcc) و آرگومان‌های پایه (مثلاً -mz180 یا --std-c89 یا -c) را مشخص کنند.

محدودیت‌ها و شکاف‌های ABI

این پروژه فعلا یک «نمایش کوتاه» (Teaser) است و هنوز برای مصرف عمومی آماده نشده است. توسعه‌دهنده این ابزار را «ناپخته» توصیف کرده و به چندین مانع حیاتی اشاره کرده است:

  • سازگاری ABI: اگرچه سیستم تا حد زیادی سازگار است، اما شکاف‌هایی در پلتفرم‌هایی مثل Arm64 وجود دارد. به‌طور مشخص، rustc از اشاره‌گرهای بازگشتی استراکچر (sret) استفاده می‌کند که C نمی‌تواند به‌طور بومی آن‌ها را نمایش دهد. در حالی که Arm64 اغلب این مورد را با پاس دادن اشاره‌گر در همان رجیسترِ اولین آرگومان مدیریت می‌کند، اما این کار را برای استراکچرهای کوچک (کمتر از ۱۶ بایت) انجام نمی‌دهد و این موضوع باعث بروز مشکل می‌شود.
  • خطاهای مسیردهی: به دلیل دلایل عجیب در استانداردسازی مسیرها (Path-canonicalization)، crustc اگر در همان دایرکتوری که بیلد شده (ریشه مخزن) اجرا شود، ممکن است کرش کند. این برنامه زمانی به طور عادی کار می‌کند که از مکان‌های دیگر اجرا شود.
  • کتابخانه استاندارد: کاربران باید کتابخانه std را به‌صورت جداگانه بیلد کنند تا بتوانند برنامه‌ها را کامپایل کنند. تلاش برای اجرای main.rs بدون نصب هدف (Target)، منجر به خطای E0463 (عدم یافتن crate برای std) می‌شود.

با وجود این باگ‌ها و عدم دسترسی فعلی توسعه‌دهنده به دلیل تعهدات دانشگاهی و آسیب دیدن دستش در اثر یک حادثه با نرم‌افزار Blender، اثبات مفهوم (Proof-of-Concept) کامل شده است. تبدیل Rust به C در واقع استدلال‌های سخت‌افزاری علیه Rust را از بین می‌برد. با تبدیل C به یک «زبان اسمبلی قابل حمل»، ایمنی و ارگونومی Rust حالا می‌تواند به هر تراشه‌ای برسد که یک کامپایلر ساده C دارد.

معنای این اتفاق برای دنیای برنامه‌نویسی، جداسازی Rust از انحصار LLVM است. در حالی که LLVM بهینه‌سازی‌های فوق‌العاده‌ای ارائه می‌دهد، توانایی هدف قرار دادن یک «کامپایلر C شمینکی برای سیستم‌عامل Blorbo»، راه را برای ورود Rust به عمیق‌ترین لایه‌های سیستم‌های نهفته (Embedded) و باستان‌شناسی دیجیتال باز می‌کند.

گام بعدی شما

  • اگر روی سیستم‌های قدیمی یا Embedded کار می‌کنید، مخزن crustc را برای بررسی سازگاری با کامپایلرهای محلی خود دنبال کنید.
  • مستندات مربوط به تعریف اهداف (Targets) در قالب JSON را مطالعه کنید تا متوجه شوید چگونه کامپایلر خود را به Cilly معرفی کنید.
  • منتظر انتشار نسخه‌های پایدارتر برای حل مشکل ABI در معماری Arm64 باشید.

اما این تنها بخشی از نبرد برای رهایی از LLVM است؛ برای درک اینکه چرا مدل‌های زبانی بزرگ نیز در حال گذار به معماری‌های غیرمتمرکز هستند، تحلیل ما درباره لبه‌های رایانش را بخوانید.

چرا این موضوع مهم است؟

این دستاورد بر پایه تخصص در مهندسی کامپایلر، انحصار LLVM را در زنجیره تولید Rust می‌شکند. نتیجه این است که Rust اکنون می‌تواند در محیط‌هایی که فقط کامپایلرهای C ابتدایی دارند، جایگزین C++ شود.

تأثیر برای ایران

این ابزار برای توسعه‌دهندگان ایرانی در حوزه سیستم‌های نهفته (Embedded) و سخت‌افزارهای صنعتی قدیمی که دسترسی به ابزارهای مدرن LLVM ندارند، فرصت استفاده از ایمنی زبان Rust را فراهم می‌کند.

·نگاه ما
تحریریه دات‌هوش

این پروژه در واقع «دموکراسی‌سازی» دسترسی به Rust است. با تبدیل C به یک لایه واسط (Intermediate Layer)، Rust دیگر محتاج تایید یا پشتیبانی LLVM برای هر تراشه جدید نیست. این حرکت، استراتژی Rust را از «تسلط از طریق ابزار» به «نفوذ از طریق سازگاری» تغییر می‌دهد و احتمالاً راه را برای پذیرش گسترده‌تر Rust در سیستم‌های Critically Embedded هموار می‌کند.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.