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

mcpp: ابزار ساخت پروژه C++23 با مدیریت خودکار زنجیره ابزار

·۱۷ مرداد ۱۴۰۵۹ دقیقه مطالعه۱ بازدید
ابزار ساخت ماژول‌محور مدرن C++ — نوشته‌شده با ماژول‌های خالص C++23، کاملاً خودمیزبان
ابزار ساخت ماژول‌محور مدرن C++ — نوشته‌شده با ماژول‌های خالص C++23، کاملاً خودمیزبان
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

ادغام کامل مدیریت بسته، نصب خودکار کامپایلر (Toolchain) و موتور ساخت در یک باینری واحد برای C++23؛ چیزی که پیش از این نیازمند ترکیب چندین ابزار مجزا مانند CMake و Conan بود.

تصور کنید تنها با یک دستور، پروژه‌ای در C++23 را بدون نصب هیچ کامپایلری روی سیستم یا درگیر شدن با تنظیمات پیچیده، اجرا کنید. mcpp دقیقاً همین تجربه را فراهم می‌کند؛ ابزاری مدرن و ماژول‌محور که همه چیز، از تأمین زنجیره ابزار (Toolchain) تا حل وابستگی‌ها را در یک محیط ایزوله یا سندباکس (Sandbox) مدیریت می‌کند. به نقل از مستندات گیت‌هاب این پروژه، mcpp کاملاً با استفاده از ماژول‌های C++23 نوشته شده و به‌صورت «خود-میزبانی» (Self-hosted) عمل می‌کند؛ به این معنا که بیش از ۴۳ ماژول C++23، خودِ این ابزار را می‌سازند.

برای دهه‌ها، توسعه‌دهندگان C++ با سیستم‌های ساخت پراکنده و «جهنم وابستگی‌ها» در مدیریت کامپایلرها روی سیستم‌عامل‌های مختلف دست‌وپنجه نرم کرده‌اند. اگرچه استاندارد C++20 ماژول‌ها را برای جایگزینی فایل‌های سرآیند (Header files) معرفی کرد، اما ابزارهای پشتیبان همچنان دشوار بودند. همان‌طور که در تحلیل‌های پیشین ما درباره‌ی تکامل استانداردهای زبان‌های برنامه‌نویسی اشاره کردیم، فاصله میان تعریف استاندارد و ابزارهای عملیاتی همیشه یک چالش بوده است. اکثر برنامه‌نویسان هنوز به پیکربندی‌های پیچیده CMake یا به‌روزرسانی دستی Makefile متکی هستند تا وابستگی‌های ماژول را مدیریت کنند.

اکنون گردش کاری را تصور کنید که در آن فقط دستورات mcpp new hello و mcpp build را اجرا می‌کنید. سیستم به‌طور خودکار سیستم‌عامل شما را شناسایی کرده، نسخه مناسب کامپایلر را دانلود می‌کند و حافظه موقت رابط ماژول باینری (BMI) را بدون آلوده کردن مسیرهای سیستمی شما مدیریت می‌کند. این رویکرد دقیقاً مشابه تجربه توسعه‌دهندگان در زبان Rust با ابزار Cargo است و سطح مشابهی از اتوماسیون را به اکوسیستم C++ می‌آورد.

چرخش به سمت معماری ماژولار

ابزار mcpp به‌طور خاص برای توسعه اول-ماژول در C++23 طراحی شده است. این ابزار امکان استفاده از import std و واحدهای رابط ماژول (.cppm) و همچنین پارتیشن‌های ماژول (Module Partitions) را با تجربه‌ای روان در لینوکس، مک (ARM64) و ویندوز (x86_64) فراهم می‌کند.

برخلاف ابزارهای سنتی، mcpp به‌صورت پیش‌فرض ماژولار است. پروژه‌هایی که از طریق دستور mcpp new ایجاد می‌شوند، مستقیماً از ماژول‌های C++23 استفاده می‌کنند. البته باید توجه داشت که این پروژه در مراحل اولیه توسعه است و احتمال تغییر در رابط‌ها و رفتار آن در نسخه‌های آینده وجود دارد.

مسیرهای نصب و استقرار

توسعه‌دهندگان می‌توانند از روش‌های مختلفی برای نصب استفاده کنند. روش پیشنهادی از طریق xlings و با استفاده از اسکریپت‌های curl (برای لینوکس/مک) یا PowerShell (برای ویندوز) است. کاربران مک و لینوکس همچنین می‌توانند از Homebrew استفاده کنند و با اجرای دستور brew install mcpp-community/mcpp/mcpp-m (که از mcpp-community/homebrew-mcpp استفاده می‌کند) آن را نصب نمایند.

کاربران آرچ لینوکس نیز از طریق AUR به این ابزار دسترسی دارند؛ آن‌ها می‌توانند از yay -S mcpp-bin برای نسخه باینری پیش‌ساخته یا yay -S mcpp-m برای ساخت از سورس استفاده کنند. برای کسانی که از دستیارهای کدنویسی هوش مصنوعی مثل Claude Code، Cursor یا Copilot استفاده می‌کنند، پروژه یک پرامپت خاص برای اتوماسیون نصب و ایجاد پروژه بر اساس راهنمای .agents/skills/mcpp-usage/SKILL.md ارائه داده است. این رویکرد در جهت تسهیل تعامل میان ابزارهای توسعه و مدل‌های زبانی است، مشابه آنچه در تسهیل اتصال مدل‌های زبانی به هسته .NET 9 از طریق پروتکل MCP مشاهده می‌کنیم.

معماری بومی ماژول‌ها

mcpp ماژول‌ها را به‌عنوان شهروند درجه یک می‌شناسد؛ بنابراین import std و import std.compat به‌طور خودکار از طریق پیش‌کامپایل و کشینگ مدیریت می‌شوند. این ابزار از استانداردهای C++20، C++23 و C++26 و همچنین حالت‌های آزمایشی c++latest و c++fly پشتیبانی می‌کند.

طبق مستندات فنی، mcpp یک بهینه‌سازی ساخت افزایشی سه لایه را بر اساس P1689 dyndep پیاده کرده است که شامل موارد زیر است:

  • بررسی‌های سریع Front-end: پرش سریع از فایل‌هایی که تغییر نکرده‌اند.
  • اسکن به‌ازای هر فایل: انجام تحلیل خودکار وابستگی‌های ماژول.
  • BMI restat: استفاده از بررسی «کپی در صورت تفاوت» برای اطمینان از بازکامپایل تنها ماژول‌های تغییریافته.

ابزار ساخت ماژول‌محور مدرن C++ — نوشته‌شده با ماژول‌های خالص C++23، کاملاً خودمیزبان

مدیریت زنجیره ابزار و سندباکس

این ابزار مشکل معروف «روی سیستم من کار می‌کند» را با بسته‌بندی نسخه‌های خاص کامپایلر حل می‌کند. mcpp نسخه‌های GCC 16.1.0 و LLVM/Clang 20.1.7 را فراهم می‌کند که با یک دستور نصب در مسیر ~/.mcpp/registry/ قرار می‌گیرند. این سندباکس ایزوله تضمین می‌کند که محیط جهانی سیستم دست‌نخورده باقی بماند.

پیش‌فرض‌های متناسب با میزبان:

  • لینوکس x86_64: به‌طور پیش‌فرض از GCC بومی glibc استفاده می‌کند.
  • سایر معماری‌های لینوکس: از musl GCC برای تولید باینری‌های کاملاً استاتیک استفاده می‌کند.
  • مک: از LLVM استفاده می‌کند (نیازمند Apple silicon و macOS 14).
  • ویندوز: پیش‌فرض MinGW-w64 GCC (winlibs) برای تجربه‌ای خودکفا است. اگر MSVC قابل استفاده شناسایی شود، پیش‌فرض به x86_64-windows-msvc تغییر می‌کند.

توسعه‌دهندگان می‌توانند چندین نسخه را به‌صورت موازی با دستوراتی مانند mcpp toolchain install gcc 16 یا mcpp toolchain install llvm 20 مدیریت کنند. خط لوله‌های GCC و Clang از طریق یک لایه انتزاعی به نام BmiTraits در سطح یکسان نگه داشته شده‌اند.

ci-linux

منطق وابستگی‌ها و فضای کاری

مدیریت وابستگی‌ها از طریق یک فایل مانیفست mcpp.toml انجام می‌شود. سیستم از نسخه‌بندی معنایی (SemVer) پشتیبانی کرده و محدودیت‌هایی مانند ^ ، ~ ، بازه‌ها و نسخه‌های دقیق را مدیریت می‌کند. همچنین یک فایل mcpp.lock (فرمت v2) تولید می‌کند که شامل یک اسنپ‌شات از ایندکس و فضای نام‌هاست تا بازتولید دقیق ساخت (Reproducible Build) تضمین شود.

مکانیسم حل وابستگی‌ها به این ترتیب است:

  1. ادغام محدودیت‌ها (Constraint merging).
  2. بازگشت به تغییر نام نسخه‌های چندگانه (Multi-version mangling fallback).
  3. حل بر اساس تطبیق دقیق.

برای پروژه‌های بزرگ، mcpp از «فضاهای کاری» (Workspaces) پشتیبانی می‌کند که در بخش [workspace] مانیفست تعریف می‌شوند. این قابلیت اجازه می‌دهد یک فایل lock واحد و مدیریت نسخه یکپارچه برای چندین کتابخانه و اپلیکیشن وجود داشته باشد. پیکربندی‌ها، شامل زنجیره ابزار و فلگ‌های ساخت، از ریشه به اعضای داخلی منتقل می‌شوند. کاربران می‌توانند با دستور mcpp build -p member-name ساخت‌های انتخابی را انجام دهند.

ci-macos

جزئیات مکانیسم سیستم ساخت

  • کش BMI: ابزار از یک کش BMI با اثر انگشت (Fingerprint) استفاده می‌کند که توسط کامپایلر، فلگ‌ها و کتابخانه استاندارد هش شده است؛ این امر اجازه می‌دهد کش بین پروژه‌های مختلف به اشتراک گذاشته شود.
  • بک‌اِند: بهره‌گیری از Ninja برای تولید خودکار build.ninja جهت کامپایل موازی.
  • یکپارچگی با IDE: تولید خودکار compile_commands.json برای سازگاری فوری با سرورهای زبان مانند clangd و ccls.
  • پشتیبانی از C: پشتیبانی درجه یک از زبان C گنجانده شده است؛ فایل‌های .c به‌طور خودکار شناسایی می‌شوند و امکان پروژه‌های ترکیبی C/C++ با cflags ، cxxflags و ldflags تعریف شده توسط کاربر وجود دارد.
  • ساختار پروژه: یک پروژه استاندارد شامل مانیفست mcpp.toml ، پوشه src/ (که در آن main.cpp به‌عنوان هدف باینری در نظر گرفته می‌شود) و پوشه tests/ برای شناسایی خودکار تست‌ها است.

بسته‌بندی و توزیع

دستور mcpp pack چهار حالت انتشار برای لینوکس ارائه می‌دهد: سیستمی (system)، Vendored (پیش‌فرض)، خود-کفا (self-contained) و استاتیک (static). با بهره‌گیری از musl، این ابزار می‌تواند باینری‌های استاتیک تک‌فایلی برای x86_64 و aarch64 تولید کند که بدون وابستگی به glibc روی توزیع‌های مختلف لینوکس اجرا شوند.

ویژگی‌های توزیع اضافی شامل موارد زیر است:

  • mcpp publish: تولید xpkg.lua و انتشار بسته در یک ایندکس.
  • اصلاح RPATH: مدیریت خودکار RPATH در لینوکس از طریق patchelf.
  • ایندکس‌های سفارشی: پشتیبانی از ایندکس‌های بسته سفارشی از طریق مراجع Git یا مسیرهای محلی در بخش [indices] مانیفست.

ci-windows

تجربه توسعه و رابط خط فرمان (CLI)

برای سرعت بخشیدن به کار، mcpp طیف گسترده‌ای از دستورات را ارائه می‌دهد. برای کسانی که اختصار را ترجیح می‌دهند، بسته xlings install mcpp-short-cmd حدود ۳۰ شیم (shim) را ثبت می‌کند. این‌ها از یک قانون نام‌گذاری پیروی می‌کنند: حرف اول هر کلمه به‌جز کلمه آخر، به‌علاوه کلمه آخر به‌صورت کامل (مثلاً mcpp self doctor به msdoctor تبدیل می‌شود).

برخی دستورات کلیدی:

  • mp: دستور ساده mcpp.
  • mnew: همان mcpp new برای ایجاد ساختار پروژه. از --template <pkg>[@ver][:<tmpl>] (مثلاً --template imgui) و --list-templates <pkg> پشتیبانی می‌کند.
  • mbuild: همان mcpp build برای کامپایل پروژه.
  • mrun: همان mcpp run برای ساخت و اجرا. امکان ارسال آرگومان‌ها از طریق mcpp run [-- args] وجود دارد.
  • mtest: همان mcpp test برای شناسایی خودکار تست‌ها در tests/ و اجرای آن‌ها. از فیلتر بر اساس نام، --list ، --timeout <s> و --message-format json پشتیبانی می‌کند.
  • msdoctor: همان mcpp self doctor برای عیب‌یابی خودکار محیط.
  • mexpkg: همان mcpp emit xpkg.
  • msearch: همان mcpp search برای جست‌وجو در ایندکس‌های بسته.
  • madd/mremove/mupdate: دستورات مدیریت وابستگی‌ها.

توسعه‌دهندگان همچنین می‌توانند از mcpp why [toolchain|runtime|deps] برای توضیح تصمیمات اتخاذ شده در ساخت یا mcpp explain E0001 برای توضیحات دقیق کدهای خطا استفاده کنند. برای محیط‌های بدون دسترسی به شبکه (Air-gapped)، دستور mcpp --offline یا متغیر محیطی MCPP_OFFLINE=1 استفاده از وضعیت محلی را اجباری می‌کند.

پشتیبانی از پلتفرم و کامپایل متقاطع

mcpp از یک مدل شناسایی بر اساس دو محور استفاده می‌کند: یک زنجیره ابزار (family@version) و یک هدف (triple arch-os[-env]). کامپایل متقاطع (Cross-compilation) از طریق دستور mcpp build --target <triple> انجام می‌شود که به‌طور خودکار Payload زنجیره ابزار مورد نیاز را حل و نصب می‌کند.

اهداف تأیید شده:

  • x86_64-linux-gnu: GCC یا LLVM.
  • x86_64-linux-musl: GCC 16 (کاملاً استاتیک).
  • aarch64-linux-musl: GCC 16 (کاملاً استاتیک، تأیید شده از طریق qemu).
  • x86_64-windows-gnu: GCC 16 MinGW-w64 (بومی یا تأیید شده از طریق wine).
  • x86_64-windows-msvc: MSVC یا LLVM. توجه: LLVM در ویندوز هدف ABI مربوط به MSVC است و به MSVC BuildTools یا Visual Studio نیاز دارد. اگر یافت نشوند، mcpp به x86_64-windows-gnu باز می‌گردد.
  • aarch64-macos: LLVM.

اهداف برنامه‌ریزی شده شامل riscv64-linux-musl ، aarch64-linux-gnu و x86_64-macos است. همچنین نام‌های قدیمی مانند x86_64-w64-mingw32 یا [email protected] به‌عنوان نام‌های مستعار پذیرفته می‌شوند.

اکوسیستم و یکپارچگی

برای تسریع در پذیرش، جامعه mcpplibs را فراهم کرده است که مجموعه‌ای از کتابخانه‌های ماژول C++23 قابل import است. نمونه‌های فعلی عبارتند از:

  • cmdline: یک فریم‌ورک تحلیل CLI که خود mcpp نیز از آن استفاده می‌کند.
  • tinyhttps: یک کلاینت HTTP/HTTPS مینیمال C++23 با قابلیت SSE streaming.
  • llmapi: یک کلاینت مدرن API برای مدل‌های زبانی بزرگ (LLM) سازگار با OpenAI.
  • imgui-m: کتابخانه Dear ImGui که به‌عنوان یک بسته ماژول C++23 بسته‌بندی شده است.

این تغییر رویکرد به سمت یک ابزار ساخت اول-ماژول، این فرض بنیادی را که C++ به یک ارکستراتور سنگین خارجی مانند CMake نیاز دارد، تغییر می‌دهد. با ادغام زنجیره ابزار، مدیریت بسته و موتور ساخت در یک باینری واحد، mcpp سد ورود به توسعه مدرن C++ را کاهش می‌دهد.

برای توسعه‌دهنده انفرادی، این به معنای زمان کمتر برای فایل‌های .toml یا .cmake و زمان بیشتر برای نوشتن کد واقعی C++23 است. این ابزار به‌طور مؤثر با کامپایلر به‌عنوان یک دارایی نسخه‌بندی شده و یک‌بار مصرف برخورد می‌کند، نه یک نصب دائمی سیستمی.

برای شروع، توسعه‌دهندگان می‌توانند ابزار را از طریق xlings (پیشنهادی)، Homebrew (brew install mcpp-community/mcpp/mcpp-m) یا AUR برای آرچ لینوکس (yay -S mcpp-bin) نصب کنند. پس از نصب، اجرای mcpp new پروژه‌ای با مانیفست mcpp.toml و فایل src/main.cpp ایجاد می‌کند که در آن import std; بلافاصله کار می‌کند.

گام بعدی شما

  • اگر توسعه‌دهنده C++ هستید، mcpp را از طریق xlings یا Homebrew نصب کنید تا سرعت راه‌اندازی پروژه‌های C++23 را تجربه کنید.
  • برای پروژه‌های فعلی خود، بررسی کنید که آیا جایگزینی CMake با یک سیستم ماژول‌محور می‌تواند پیچیدگی‌های ساخت را کاهش دهد یا خیر.
  • کتابخانه‌های mcpplibs را بررسی کنید تا ببینید کدام ابزارهای آماده را می‌توانید در پروژه‌های خود import کنید.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره‌ی تراشه‌های Blackwell مراجعه کنید.

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

این ابزار با حذف اصطکاک‌های محیطی، پذیرش استانداردهای مدرن C++23 را تسریع می‌کند. اعتبار این رویکرد در استفاده از معماری Self-hosted است که ثابت می‌کند ماژول‌های C++23 برای ساخت ابزارهای سیستمی مقیاس‌پذیر آماده‌اند.

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

برای برنامه‌نویسان ایرانی که با محدودیت‌های نصب و پیکربندی ابزارهای سنگین توسعه در محیط‌های مختلف مواجه‌اند، mcpp با ایزوله‌سازی کامپایلرها، فرآیند راه‌اندازی محیط توسعه را بسیار سریع‌تر و خطای آن را کمتر می‌کند.

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

mcpp تلاش می‌کند «تجربه کاربری Rust» را به C++ منتقل کند. حذف وابستگی به CMake و یکپارچه‌سازی کامپایلر در سطح ابزار ساخت، نشان‌دهنده حرکتی به سمت ساده‌سازی رادیکال در زبان‌هایی است که سال‌ها با پیچیدگی‌های محیطی شناخته می‌شدند. این ابزار در واقع کامپایلر را از یک نرم‌افزار سیستمی دائمی به یک دارایی نسخه‌بندی‌شده و مصرفی تبدیل می‌کند.

منابع

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

گفتگو

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

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

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

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

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

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

دات‌هوش

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

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