จากที่ลองเขียน rust (บอกว่า init demo เถอะ)
โครงสร้างโปรเจกต์ของ Rust นั้นถูกออกแบบมาให้เป็นระเบียบ เรียบง่าย และมีมาตรฐานเดียวกันทั่วโลกผ่านเครื่องมือจัดการอย่าง Cargo ครับ
จากไดเรกทอรีโปรเจกต์ hello_rust ที่คุณแสดง จะเห็นว่า Rust แบ่งโครงสร้างออกเป็น 2 ส่วนหลักชัดเจน คือ ส่วน Source Code (ที่เราเขียน) และ ส่วน Target (ที่คอมไพเลอร์สร้างขึ้น)
โครงสร้างพื้นฐานของโปรเจกต์ Rust
hello_rust/
├── Cargo.toml # ไฟล์ตั้งค่าหลักของโปรเจกต์ (Manifest)
├── Cargo.lock # ไฟล์ล็อกเวอร์ชันของ Dependencies
├── src/ # ไดเรกทอรีเก็บ Source Code
│ └── main.rs # จุดเริ่มต้นของโปรแกรม (Entry point)
└── target/ # ผลลัพธ์จากการคอมไพล์ (สร้างโดย Cargo)
ไฟล์ระดับ Root
Cargo.toml: ไฟล์ตั้งค่าหลักในรูปแบบ TOML เปรียบเสมือนpackage.jsonใน Node.js หรือpom.xmlใน Java ใช้เก็บชื่อโปรเจกต์ เวอร์ชัน และไลบรารีภายนอก (Dependencies) ที่นำมาใช้Cargo.lock: Cargo จะสร้างและดูแลไฟล์นี้ให้อัตโนมัติ เพื่อล็อกเวอร์ชันที่แม่นยำของทุกไลบรารี เพื่อให้มั่นใจว่าเมื่อนำไปรันที่เครื่องอื่น ผลลัพธ์การทำงานจะเหมือนกัน 100%
โฟลเดอร์ src/ (Source Code)
main.rs: จุดเริ่มต้นการทำงานหลักของแอพพลิเคชันประเภท Binary (Executable) ซึ่งต้องมีฟังก์ชันfn main()อยู่ข้างใน- (เพิ่มเติม) หากสร้างโปรเจกต์ประเภท Library จะใช้ชื่อ
src/lib.rsเป็นจุดเริ่มต้นแทน
เจาะลึกโฟลเดอร์ target/ (เกิดอะไรขึ้นเมื่อเราสั่ง cargo build)
เมื่อเราสั่งรันโปรแกรมหรือสร้างไฟล์ Executable ด้วย cargo run หรือ cargo build ตัว Cargo จะสร้างโฟลเดอร์ target/ ขึ้นมาเพื่อเก็บไฟล์ที่คอมไพล์แล้ว รวมถึง cache สำหรับการคอมไพล์รอบถัดไป
target/
├── CACHEDIR.TAG
└── debug/ # build ในโหมด Debug (ค่าเริ่มต้น)
├── hello_rust # Binary Executable ตัวจริงที่พร้อมรัน
├── hello_rust.d # ไฟล์บอก Dependency การคอมไพล์สำหรับระบบ Build
├── build/ # โฟลเดอร์เก็บ Build Scripts (build.rs)
├── deps/ # ไฟล์คอมไพล์ย่อย (.o) และไฟล์ของไลบรารีภายนอก
└── incremental/ # ข้อมูลการคอมไพล์แบบ Incremental Compilation
🛠️ ทำความเข้าใจองค์ประกอบภายใน target/debug/
hello_rust(Executable File)- ไฟล์โปรแกรมหลักที่คอมไพล์เสร็จสมบูรณ์ คุณสามารถนำไฟล์นี้ไปรันผ่าน Terminal ได้ทันที เช่น
./target/debug/hello_rust
- ไฟล์โปรแกรมหลักที่คอมไพล์เสร็จสมบูรณ์ คุณสามารถนำไฟล์นี้ไปรันผ่าน Terminal ได้ทันที เช่น
deps/(Dependencies & Intermediate Artifacts)- เก็บไฟล์วัตถุ (.o / object files) และไฟล์ไลบรารีที่ถูกแบ่งเป็นชิ้นส่วนย่อย ๆ ซึ่งเป็นผลจากการทำงานของ
rustc
- เก็บไฟล์วัตถุ (.o / object files) และไฟล์ไลบรารีที่ถูกแบ่งเป็นชิ้นส่วนย่อย ๆ ซึ่งเป็นผลจากการทำงานของ
incremental/(การคอมไพล์แบบเพิ่มเติ่ม)- จุดเด่นของ Rust: ในการคอมไพล์รอบถัด ๆ ไป ตัว Rust จะไม่คอมไพล์ code ทั้งหมดใหม่ตั้งแต่ต้น แต่จะดูจาก
query-cache.binและdep-graph.binเพื่อคอมไพล์เฉพาะส่วนของ code ที่มีการแก้ไขเท่านั้น ทำให้ช่วยประหยัดเวลาการ Build ลงได้มาก
- จุดเด่นของ Rust: ในการคอมไพล์รอบถัด ๆ ไป ตัว Rust จะไม่คอมไพล์ code ทั้งหมดใหม่ตั้งแต่ต้น แต่จะดูจาก
💡 ข้อแนะนำในการจัดการ Git (.gitignore)
เนื่องจากโฟลเดอร์ target/ มีขนาดใหญ่และเป็นเพียงไฟล์ชั่วคราวที่สร้างใหม่เมื่อไหร่ก็ได้ เราจึงไม่ควร push โฟลเดอร์ target/ ขึ้น Git โดยปกติ Cargo จะสร้างไฟล์ .gitignore ที่ระบุ /target ไว้ให้อัตโนมัติเมื่อเริ่มโปรเจกต์ใหม่
อ่านเพิ่มเติม