Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

مرحبًا، Cargo!

إن Cargo هو نظام البناء (build system) ومدير الحزم (package manager) الخاص بلغة Rust. يستخدم معظم مبرمجي Rust (Rustaceans) هذه الأداة لإدارة مشاريعهم لأن Cargo يتولى الكثير من المهام نيابة عنك، مثل بناء الكود الخاص بك، وتنزيل المكتبات التي يعتمد عليها الكود، وبناء تلك المكتبات. (نسمي المكتبات التي يحتاجها الكود الخاص بك بالتبعيات (dependencies)).

أبسط برامج Rust، مثل البرنامج الذي كتبناه حتى الآن، لا تحتوي على أي dependencies. إذا قمنا ببناء مشروع “Hello, world!” باستخدام Cargo، فسيستخدم فقط الجزء من Cargo الذي يتعامل مع بناء الكود الخاص بك. بينما تكتب برامج Rust أكثر تعقيدًا، ستضيف dependencies، وإذا بدأت مشروعًا باستخدام Cargo، فستكون إضافة dependencies أسهل بكثير.

نظرًا لأن الغالبية العظمى من مشاريع Rust تستخدم Cargo، فإن بقية هذا الكتاب تفترض أنك تستخدم Cargo أيضًا. يأتي Cargo مثبتًا مع Rust إذا استخدمت المثبتات الرسمية التي تمت مناقشتها في قسم “Installation”. إذا قمت بتثبيت Rust بوسائل أخرى، فتحقق مما إذا كان Cargo مثبتًا عن طريق إدخال ما يلي في الطرفية (terminal):

$ cargo --version

إذا رأيت رقم إصدار، فأنت تمتلكه! إذا رأيت خطأ، مثل command not found (الأمر غير موجود)، فراجع وثائق طريقة التثبيت الخاصة بك لتحديد كيفية تثبيت Cargo بشكل منفصل.

إنشاء مشروع باستخدام Cargo

دعنا ننشئ مشروعًا جديدًا باستخدام Cargo ونرى كيف يختلف عن مشروع “Hello, world!” الأصلي الخاص بنا. انتقل مرة أخرى إلى دليل المشاريع (projects directory) الخاص بك (أو أي مكان قررت تخزين الكود فيه). ثم، على أي نظام تشغيل، قم بتشغيل ما يلي:

$ cargo new hello_cargo
$ cd hello_cargo

يؤدي الأمر الأول إلى إنشاء دليل ومشروع جديد يسمى hello_cargo. لقد أطلقنا على مشروعنا اسم hello_cargo، ويقوم Cargo بإنشاء ملفاته في دليل يحمل نفس الاسم.

ادخل إلى دليل hello_cargo واعرض قائمة الملفات. سترى أن Cargo قد أنشأ ملفين ودليلاً واحدًا لنا: ملف Cargo.toml ودليل src وبداخله ملف main.rs.

لقد قام أيضًا بتهيئة مستودع Git جديد مع ملف .gitignore. لن يتم إنشاء ملفات Git إذا قمت بتشغيل cargo new داخل مستودع Git موجود؛ يمكنك تجاوز هذا السلوك باستخدام cargo new --vcs=git.

ملاحظة: Git هو نظام شائع للتحكم في الإصدارات (version control system). يمكنك تغيير cargo new لاستخدام نظام تحكم في الإصدارات مختلف أو عدم استخدام نظام تحكم في الإصدارات على الإطلاق باستخدام علم (flag) --vcs. قم بتشغيل cargo new --help لرؤية الخيارات المتاحة.

افتح Cargo.toml في محرر النصوص الذي تختاره. يجب أن يبدو مشابهًا للكود الموجود في القائمة 1-2.

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]

هذا الملف بتنسيق TOML (Tom’s Obvious, Minimal Language)، وهو تنسيق التكوين (configuration format) الخاص بـ Cargo.

السطر الأول، [package]، هو عنوان قسم يشير إلى أن العبارات التالية تقوم بتكوين حزمة (package). بينما نضيف المزيد من المعلومات إلى هذا الملف، سنضيف أقسامًا أخرى.

تحدد الأسطر الثلاثة التالية معلومات التكوين التي يحتاجها Cargo لتجميع (compile) برنامجك: الاسم، والإصدار، وإصدار Rust (edition) المراد استخدامه. سنتحدث عن مفتاح edition في Appendix E.

السطر الأخير، [dependencies]، هو بداية قسم لتدرج فيه أيًا من dependencies الخاصة بمشروعك. في Rust، يشار إلى حزم الكود باسم الصناديق (crates). لن نحتاج إلى أي crates أخرى لهذا المشروع، لكننا سنحتاج إليها في المشروع الأول في الفصل 2، لذا سنستخدم قسم dependencies هذا حينها.

الآن افتح src/main.rs وألقِ نظرة:

Filename: src/main.rs

fn main() {
    println!("Hello, world!");
}

لقد أنشأ Cargo برنامج “Hello, world!” لك، تمامًا مثل البرنامج الذي كتبناه في القائمة 1-1! حتى الآن، الاختلافات بين مشروعنا والمشروع الذي أنشأه Cargo هي أن Cargo وضع الكود في دليل src، ولدينا ملف تكوين Cargo.toml في الدليل العلوي.

يتوقع Cargo أن تعيش ملفات المصدر (source files) الخاصة بك داخل دليل src. دليل المشروع ذو المستوى الأعلى مخصص فقط لملفات README، ومعلومات الترخيص، وملفات التكوين، وأي شيء آخر غير متعلق بالكود الخاص بك. يساعدك استخدام Cargo في تنظيم مشاريعك. هناك مكان لكل شيء، وكل شيء في مكانه.

إذا بدأت مشروعًا لا يستخدم Cargo، كما فعلنا مع مشروع “Hello, world!”، يمكنك تحويله إلى مشروع يستخدم Cargo. انقل كود المشروع إلى دليل src وأنشئ ملف Cargo.toml مناسبًا. إحدى الطرق السهلة للحصول على ملف Cargo.toml هذا هي تشغيل cargo init الذي سيقوم بإنشائه لك تلقائيًا.

بناء وتشغيل مشروع Cargo

الآن دعنا نرى ما هو المختلف عندما نقوم ببناء وتشغيل برنامج “Hello, world!” باستخدام Cargo! من دليل hello_cargo الخاص بك، قم ببناء مشروعك عن طريق إدخال الأمر التالي:

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

يؤدي هذا الأمر إلى إنشاء ملف قابل للتنفيذ (executable file) في target/debug/hello_cargo (أو target\debug\hello_cargo.exe على Windows) بدلاً من دليلك الحالي. نظرًا لأن البناء الافتراضي هو بناء تصحيح أخطاء (debug build)، يضع Cargo الملف الثنائي (binary) في دليل يسمى debug. يمكنك تشغيل الملف القابل للتنفيذ بهذا الأمر:

$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!

إذا سارت الأمور على ما يرام، يجب طباعة Hello, world! في terminal. يؤدي تشغيل cargo build لأول مرة أيضًا إلى قيام Cargo بإنشاء ملف جديد في المستوى الأعلى: Cargo.lock. يتتبع هذا الملف الإصدارات الدقيقة لـ dependencies في مشروعك. لا يحتوي هذا المشروع على dependencies، لذا فإن الملف فارغ قليلاً. لن تحتاج أبدًا إلى تغيير هذا الملف يدويًا؛ يتولى Cargo إدارة محتوياته نيابة عنك.

لقد قمنا للتو ببناء مشروع باستخدام cargo build وتشغيله باستخدام ./target/debug/hello_cargo ولكن يمكننا أيضًا استخدام cargo run لتجميع الكود ثم تشغيل الملف القابل للتنفيذ الناتج في أمر واحد:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

يعد استخدام cargo run أكثر ملاءمة من الاضطرار إلى تذكر تشغيل cargo build ثم استخدام المسار الكامل للملف الثنائي، لذا يستخدم معظم المطورين cargo run.

لاحظ أننا هذه المرة لم نرَ مخرجات تشير إلى أن Cargo كان يقوم بتجميع hello_cargo. أدرك Cargo أن الملفات لم تتغير، لذا لم يقم بإعادة البناء بل قام فقط بتشغيل binary. إذا قمت بتعديل كود المصدر الخاص بك، فسيقوم Cargo بإعادة بناء المشروع قبل تشغيله، وسترى هذا المخرج:

$ cargo run
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/hello_cargo`
Hello, world!

يوفر Cargo أيضًا أمرًا يسمى cargo check. يقوم هذا الأمر بفحص الكود الخاص بك بسرعة للتأكد من أنه يتم تجميعه ولكنه لا ينتج ملفًا قابلاً للتنفيذ:

$ cargo check
   Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

لماذا قد لا ترغب في ملف قابل للتنفيذ؟ غالبًا ما يكون cargo check أسرع بكثير من cargo build لأنه يتخطى خطوة إنتاج ملف قابل للتنفيذ. إذا كنت تتحقق باستمرار من عملك أثناء كتابة الكود، فإن استخدام cargo check سيسرع عملية إخبارك إذا كان مشروعك لا يزال يتم تجميعه! على هذا النحو، يقوم العديد من مبرمجي Rust بتشغيل cargo check بشكل دوري أثناء كتابة برنامجهم للتأكد من أنه يتم تجميعه. ثم يقومون بتشغيل cargo build عندما يكونون مستعدين لاستخدام الملف القابل للتنفيذ.

دعنا نلخص ما تعلمناه حتى الآن عن Cargo:

  • يمكننا إنشاء مشروع باستخدام cargo new.
  • يمكننا بناء مشروع باستخدام cargo build.
  • يمكننا بناء وتشغيل مشروع في خطوة واحدة باستخدام cargo run.
  • يمكننا بناء مشروع دون إنتاج binary للتحقق من الأخطاء باستخدام cargo check.
  • بدلاً من حفظ نتيجة البناء في نفس دليل الكود الخاص بنا، يقوم Cargo بتخزينها في دليل target/debug.

ميزة إضافية لاستخدام Cargo هي أن الأوامر هي نفسها بغض النظر عن نظام التشغيل الذي تعمل عليه. لذا، في هذه المرحلة، لن نقدم تعليمات محددة لنظامي التشغيل Linux و macOS مقابل Windows.

البناء للإصدار (Building for Release)

عندما يكون مشروعك جاهزًا أخيرًا للإصدار، يمكنك استخدام cargo build --release لتجميعه مع التحسينات (optimizations). سيؤدي هذا الأمر إلى إنشاء ملف قابل للتنفيذ في target/release بدلاً من target/debug. تجعل optimizations كود Rust الخاص بك يعمل بشكل أسرع، ولكن تشغيلها يطيل الوقت الذي يستغرقه برنامجك للتجميع. هذا هو السبب في وجود ملفي تعريف (profiles) مختلفين: أحدهما للتطوير، عندما تريد إعادة البناء بسرعة وبشكل متكرر، والآخر لبناء البرنامج النهائي الذي ستعطيه للمستخدم والذي لن يتم إعادة بنائه بشكل متكرر وسيعمل بأسرع ما يمكن. إذا كنت تقوم بقياس أداء (benchmarking) وقت تشغيل الكود الخاص بك، فتأكد من تشغيل cargo build --release والقياس باستخدام الملف القابل للتنفيذ في target/release.

الاستفادة من اتفاقيات Cargo

مع المشاريع البسيطة، لا يوفر Cargo الكثير من القيمة مقارنة بمجرد استخدام rustc ولكنه سيثبت جدارته عندما تصبح برامجك أكثر تعقيدًا. بمجرد أن تنمو البرامج لتشمل ملفات متعددة أو تحتاج إلى dependency، يكون من الأسهل بكثير ترك Cargo ينسق عملية البناء.

على الرغم من أن مشروع hello_cargo بسيط، إلا أنه يستخدم الآن الكثير من الأدوات الحقيقية التي ستستخدمها في بقية حياتك المهنية مع Rust. في الواقع، للعمل في أي مشاريع موجودة، يمكنك استخدام الأوامر التالية لسحب الكود باستخدام Git، والانتقال إلى دليل ذلك المشروع، والبناء:

$ git clone example.org/someproject
$ cd someproject
$ cargo build

لمزيد من المعلومات حول Cargo، راجع وثائقه.

ملخص

لقد بدأت بالفعل بداية رائعة في رحلتك مع Rust! في هذا الفصل، تعلمت كيفية:

  • تثبيت أحدث إصدار مستقر من Rust باستخدام rustup.
  • التحديث إلى إصدار Rust أحدث.
  • فتح الوثائق المثبتة محليًا.
  • كتابة وتشغيل برنامج “Hello, world!” باستخدام rustc مباشرة.
  • إنشاء وتشغيل مشروع جديد باستخدام اتفاقيات Cargo.

هذا وقت رائع لبناء برنامج أكثر جوهرية للتعود على قراءة وكتابة كود Rust. لذا، في الفصل 2، سنبني برنامج لعبة التخمين. إذا كنت تفضل البدء بتعلم كيفية عمل مفاهيم البرمجة الشائعة في Rust، فراجع الفصل 3 ثم عد إلى الفصل 2.