-
فرشید پوشنده
1405/05/22
-
22 مرداد 1405
بازگشت به: آموزش برنامه نویسی c++ سی پلاس پلاس
۰.۵ — آشنایی با کامپایلر، لینکر و کتابخانهها
مقدمه
در درس قبلی (۰.۴ — آشنایی با توسعه در C++)، با ۷ مرحله اصلی توسعه نرمافزار آشنا شدید. در این درس، به بررسی دقیقتر مراحل ۴ تا ۷ (کامپایل، لینک، آزمایش و اشکالزدایی) میپردازیم.
گام ۴: کامپایل کردن کد منبع (Compiling)
برای کامپایل فایلهای کد منبع C++، از یک کامپایلر C++ استفاده میکنیم. کامپایلر به ترتیب هر فایل کد منبع (با پسوند .cpp) را در برنامه شما بررسی میکند و دو کار مهم انجام میدهد:
اول: کامپایلر کد C++ شما را بررسی میکند تا مطمئن شود که از قوانین زبان C++ پیروی میکند. اگر چنین نباشد، کامپایلر یک خطا (Error) (به همراه شماره خط مربوطه) به شما میدهد تا مشخص کند چه چیزی نیاز به اصلاح دارد. فرآیند کامپایل تا زمانی که خطا برطرف نشود، متوقف خواهد شد.
دوم: کامپایلر کد C++ شما را به دستورات زبان ماشین ترجمه میکند. این دستورات در یک فایل میانی به نام فایل شیء (Object File) ذخیره میشوند. فایل شیء همچنین شامل دادههای دیگری است که در مراحل بعدی مورد نیاز یا مفید هستند (از جمله دادههای مورد نیاز لینکر در گام ۵ و برای اشکالزدایی در گام ۷).
فایلهای شیء معمولاً با نام name.o یا name.obj نامگذاری میشوند، که name همان نام فایل .cpp است که از آن تولید شده است.
1 program.cpp → program.o (یا program.obj)
2 utils.cpp → utils.o (یا utils.obj)
3 math.cpp → math.o (یا math.obj)
کامپایلرهای C++ برای سیستمعاملهای مختلفی در دسترس هستند. در درسهای آینده نحوه نصب یک کامپایلر را بررسی خواهیم کرد، بنابراین در حال حاضر نیازی به انجام این کار نیست.
گام ۵: لینک کردن فایلهای شیء و کتابخانهها و تولید فایل خروجی (Linking)
پس از اتمام موفقیتآمیز کار کامپایلر، برنامه دیگری به نام لینکر (Linker) وارد عمل میشود. وظیفه لینکر این است که تمام فایلهای شیء را ترکیب کرده و فایل خروجی مورد نظر (مانند یک فایل اجرایی که میتوانید اجرا کنید) را تولید کند. این فرآیند لینک کردن (Linking) نام دارد. اگر هر مرحلهای از فرآیند لینک با شکست مواجه شود، لینکر یک پیام خطا تولید کرده و فرآیند را متوقف میکند.
لینکر سه کار اصلی انجام میدهد:
اول: لینکر هر یک از فایلهای شیء تولیدشده توسط کامپایلر را میخواند و مطمئن میشود که معتبر هستند.
دوم: لینکر اطمینان مییابد که تمام وابستگیهای بین فایلها (Cross-File Dependencies) به درستی برطرف شدهاند. برای مثال، اگر چیزی را در یک فایل .cpp تعریف کنید و سپس در فایل .cpp دیگری از آن استفاده کنید، لینکر این دو را به هم متصل میکند. اگر لینکر نتواند یک ارجاع به چیزی را با تعریف آن متصل کند، با خطای لینکر (Linker Error) مواجه میشوید و فرآیند لینک متوقف میشود.
سوم: لینکر معمولاً یک یا چند فایل کتابخانه (Library Files) را لینک میکند. کتابخانهها مجموعههایی از کدهای از پیش کامپایلشده هستند که برای استفاده مجدد در برنامههای دیگر «بستهبندی» شدهاند.
در نهایت: لینکر فایل خروجی مورد نظر را تولید میکند. به طور معمول، این یک فایل اجرایی (Executable File) خواهد بود که میتوان آن را اجرا کرد (اگرچه اگر پروژه خود را به این صورت تنظیم کرده باشید، میتواند یک فایل کتابخانه نیز باشد).
کتابخانه استاندارد C++ (Standard Library)
C++ همراه با یک کتابخانه گسترده به نام کتابخانه استاندارد C++ (C++ Standard Library) (که معمولاً «کتابخانه استاندارد» نامیده میشود) ارائه میشود که مجموعهای از قابلیتهای مفید را برای استفاده در برنامههای شما فراهم میکند.
یکی از پرکاربردترین بخشهای کتابخانه استاندارد C++، کتابخانه ورودی/خروجی (Input/Output Library) است که اغلب iostream نامیده میشود و شامل قابلیتهایی برای چاپ متن روی صفحهنمایش و دریافت ورودی از صفحهکلید است.
تقریباً هر برنامه C++ نوشتهشده به نوعی از کتابخانه استاندارد استفاده میکند، بنابراین بسیار رایج است که کتابخانه استاندارد C++ به برنامههای شما لینک شود. بیشتر لینکرهای C++ به گونهای پیکربندی شدهاند که کتابخانه استاندارد را بهطور پیشفرض لینک کنند، بنابراین معمولاً نیازی به نگرانی در مورد این موضوع ندارید.
کتابخانههای شخص ثالث (Third-Party Libraries)
شما میتوانید بهصورت اختیاری کتابخانههای شخص ثالث (Third-Party Libraries) را لینک کنید. این کتابخانهها توسط نهادهای مستقل (نه به عنوان بخشی از استاندارد C++) ایجاد و توزیع میشوند.
برای مثال، فرض کنید میخواهید برنامهای بنویسید که صدا پخش کند. کتابخانه استاندارد C++ چنین قابلیتی را ندارد. اگرچه میتوانید کد خود را برای خواندن فایلهای صوتی از دیسک، بررسی معتبر بودن آنها و هدایت دادههای صوتی به سیستمعامل یا سختافزار برای پخش از طریق بلندگو بنویسید — اما این کار بسیار زیادی است! در عوض، به احتمال زیاد یک پروژه نرمافزاری موجود را پیدا میکنید که کتابخانهای دارد که تمام این کارها را برای شما پیادهسازی کرده است.
در بخش ضمیمه (Appendix) نحوه لینک کردن کتابخانهها (و ایجاد کتابخانههای خودتان!) را بررسی خواهیم کرد.
ساختن (Building)
از آنجایی که فرآیند توسعه شامل مراحل متعددی است، اصطلاح ساختن (Building) اغلب برای اشاره به فرآیند کامل تبدیل فایلهای کد منبع به یک فایل اجرایی که میتوان اجرا کرد، استفاده میشود. یک فایل اجرایی خاص که در نتیجه ساختن تولید میشود، گاهی ساخت (Build) نامیده میشود.
برای خوانندگان پیشرفته:
برای پروژههای پیچیده، از ابزارهای خودکارسازی ساخت (Build Automation Tools) مانند make یا build2 استفاده میشود تا به خودکارسازی فرآیند ساخت برنامهها و اجرای تستهای خودکار کمک کنند. اگرچه چنین ابزارهایی قدرتمند و انعطافپذیر هستند، اما از آنجایی که بخشی از زبان اصلی C++ نیستند و برای ادامه مسیر نیازی به استفاده از آنها ندارید، در این مجموعه آموزشی به آنها نخواهیم پرداخت.
گامهای ۶ و ۷: آزمایش و اشکالزدایی (Testing and Debugging)
این بخش، بخش جذاب است! اکنون میتوانید فایل اجرایی خود را اجرا کنید و ببینید که چه کاری انجام میدهد!
هنگامی که میتوانید برنامه خود را اجرا کنید، میتوانید آن را آزمایش (Test) کنید. آزمایش، فرآیند ارزیابی این است که آیا نرمافزار شما همانطور که انتظار میرود کار میکند یا خیر. آزمایش اولیه معمولاً شامل ترکیبهای مختلف ورودی است تا اطمینان حاصل شود که نرمافزار در موارد مختلف به درستی رفتار میکند.
اگر برنامه همانطور که انتظار میرود رفتار نکرد، باید اشکالزدایی (Debugging) انجام دهید. اشکالزدایی فرآیند پیدا کردن و رفع خطاهای برنامهنویسی است.
در فصلهای آینده، نحوه آزمایش و اشکالزدایی برنامههای خود را با جزئیات بیشتری بررسی خواهیم کرد.
محیطهای توسعه یکپارچه (IDEs)
توجه داشته باشید که مراحل ۳، ۴، ۵ و ۷ همگی شامل برنامههای نرمافزاری هستند که باید نصب شوند (ویرایشگر، کامپایلر، لینکر، اشکالیاب). اگرچه میتوانید از برنامههای جداگانه برای هر یک از این فعالیتها استفاده کنید، یک بسته نرمافزاری به نام محیط توسعه یکپارچه (IDE — Integrated Development Environment) تمام این ویژگیها را در کنار هم جمعآوری و یکپارچه میکند. در بخش بعدی، درباره IDEها صحبت کرده و یکی از آنها را نصب خواهیم کرد.
خلاصه درس
کامپایلر (Compiler) کد منبع C++ را به کد ماشین (فایل شیء) تبدیل میکند.
فایل شیء (Object File) یک فایل میانی شامل دستورات زبان ماشین و دادههای دیگر است.
لینکر (Linker) فایلهای شیء را به هم متصل کرده، وابستگیهای بین فایلها را برطرف میکند، کتابخانهها را لینک کرده و فایل اجرایی نهایی را تولید میکند.
کتابخانه استاندارد C++ (Standard Library) مجموعهای از قابلیتهای مفید (مانند ورودی/خروجی) را فراهم میکند.
کتابخانههای شخص ثالث (Third-Party Libraries) کتابخانههایی هستند که توسط نهادهای مستقل ایجاد و توزیع میشوند.
ساختن (Building) به فرآیند کامل تبدیل کد منبع به فایل اجرایی گفته میشود.
آزمایش (Testing) فرآیند بررسی عملکرد صحیح برنامه است.
اشکالزدایی (Debugging) فرآیند پیدا کردن و رفع باگهاست.
محیط توسعه یکپارچه (IDE) تمام ابزارهای مورد نیاز (ویرایشگر، کامپایلر، لینکر، اشکالیاب) را در یک بسته نرمافزاری یکپارچه میکند.
سوالات متداول
سوال: تفاوت بین خطای کامپایلر و خطای لینکر چیست؟
خطای کامپایلر زمانی رخ میدهد که کد شما قوانین زبان C++ را نقض کند (مثلاً فراموش کردن سمیکالن). خطای لینکر زمانی رخ میدهد که لینکر نتواند یک ارجاع را به تعریف آن متصل کند (مثلاً استفاده از یک تابع که تعریف نشده است).
سوال: آیا همه برنامهها از کتابخانه استاندارد استفاده میکنند؟
تقریباً همه برنامههای C++ از کتابخانه استاندارد استفاده میکنند، زیرا قابلیتهای پایهای مانند ورودی/خروجی را فراهم میکند. با این حال، از نظر فنی امکان نوشتن برنامهای بدون استفاده از کتابخانه استاندارد وجود دارد.
سوال: چرا به کتابخانههای شخص ثالث نیاز داریم؟
کتابخانههای شخص ثالث قابلیتهایی را ارائه میدهند که در کتابخانه استاندارد وجود ندارند (مانند پخش صدا، پردازش تصویر، ارتباطات شبکه و غیره). استفاده از آنها باعث صرفهجویی در زمان و کاهش پیچیدگی میشود.
کدنویسم را همراه خود داشته باشید تا در درس بعدی، با نصب کامپایلر و محیط توسعه یکپارچه (IDE) آشنا شوید. 🚀