لذت برنامه‌نویسی: ساختن header فایل در cmake

اینم یه تجربه پراکنده دیگه!

با توجه به شلوغی‌های روز افزون زندگی، دارم سعی میکنم که به حد یک نوشته در ماه برسم. قبلا در مورد cmake نوشتم و حالا خواستم یه مورد دیگه که شاید به درد کسی بخوره رو بنویسم.

ما توی کارهایی که انجام می‌دیم سعی کردیم که ویژگی‌های مختلف نرم‌افزارمون قابل فعال و غیر فعالسازی باشه. هر مشتری هم نیازهای خاص خودش رو داره و یه زیرمجموعه از ویژگی‌ها رو تحویل میگیره. کاری که انجام داده بودیم استفاده از پیش‌پردازندهها برای این کار بود. بدین شکل که هر ویژگی یه پیش پردازنده مخصوص خودش داشت که فعال یا غیر فعال میشد.

این روند فعال و غیر فعال سازی همیشه با مشکلات جدی همراه بود بدین صورت که همکارها به علت زیاد بودن و متغیر بودن ویژگی‌ها برای مشتری‌ها بایستی این فایل رو زیاد تغییر میدادن و این تغییرات زیاد باعث می‌شد که خطای انسانی داشته باشن و یه چیزایی یادشون بره و یا اضافه کامپایل کنند و به مشتری بدن

کاری که ما کردیم این بود که این هدر خاص که همه این تعاریف توش بود رو بجای دستی ساختن به کمک cmake ساختیم به این شکل که

  1. یه متغیر از نوع cached تعریف کردیم که بشه به عنوان پارامتر زمان کامپایل اضافه بشه
  2. بر اساس اون متغیر برای هریک از ویژگی‌ها یک مقدار فعال و غیر فعال تخصیص دادیم
  3. از اون متغیرها استفاده کردیم و فایل اصلی رو ساختیم

نمونه این کار به این شکل هست که توی CMakeLists.txt یه چنین چیزی نوشتیم

توی فایل

هم یه چنین چیزی هست

و به این شکل این فایل بصورت اتوماتیک ساخته میشه و قابل استفاده است

برای اجرا کردن هم میشه با این دوتا دستور برای مشتری‌های مختلف کامپایل کرد

همین!

لذت برنامه نویسی: ساختار یک پروژه در cmake

اینم یه تجربه پراکنده دیگه!

متاسفانه یه مدت میشه که سرم بیش از اندازه شلوغ شده و نرسیدم وبلاگ بنویسم. قبلا در مورد cmake نشوتم و حالا خواستم یکم بیشتر بنویسم.

خب توی این پست سعی میکنم که بگم که توی دنیای واقعی من از cmake چطور میتونم استفاده کنم. توی دنیای واقعی معمولا پروژه از این بخش‌ها تشکیل شده:

  1. یه سری سورس که اصل منطق برنامه اونجا پیاده سازی شده
  2. یه فایل اصلی یا main که تابع اصلی نرم افزار اونجا قرار گرفته
  3. احتمالا یه سری تست که نرم افزار رو بصورت اتوماتیک مورد تست قرار میدن
  4. احتمالا یه سری کتابخانه که بصورت static یا dynamic به کد اضافه میشن.

یه خورده توضیح بدم که توی مcmake معمولا یه چیزی داریم به عنوان خروجی که میتونه از جنس فایل اجرایی باشه یا از جنس کتابخانه. ما با ترکیب کتابخانه‌ها و سورس کدهای موجود فایل اجرایی نهایی رو درست میکنیم. روند کار هم معمولا به این صورته که:
۱٫ سورسهای اصلی بصورت یه کتابخانه static کامپایل میشه
۲٫ فایل اصلی برنامه بصورت یک فایل اجرایی کامپایل شده و به کتابخانه سورس‌های اصلی لینک میشه
۳٫ تست کیسها بصوت یک فایل اجرایی کامپایل شده و به کتابخانه سورس‌هاس اصلی لینک میشه.
۴٫ کتابخانه ها هم به فایل اجرایی اضافه میشن.

حالا اگه مثال بخوایم یه پروژه رو مثال بزنم که ساختار کدش به شکل زیره


		

فایل CMakeLists.txt این پروژه یه چیزی شبیه این خواهد بود


		

شامل یک کتابخانه static و دو فایل اجرایی یکی اصل برنامه و دیگری تست برنامه.

همین!

cmake diagram

لذت برنامه نویسی: معرفی مقدماتی cmake

اینم یه تجربه پراکنده دیگه!

متاسفانه یه مدت میشه که سرم بیش از اندازه شلوغ شده و نرسیدم خوب وبلاگ بنویسم. اما این هفته یه کار خوبی انجام دادم که گفتم اینجا مستندش کنم.

خب همونطور که ممکنه بدونید من توسعه اصلی کارهام در زبان‌های c و c++ هست. یکی از ویژگی‌هایی که این زبان‌ها دارن این هست که شما بایستی برای کامپایل شدن برنامه همیشه از یک IDE استفاده کنی یا از ابزارهایی مثل make برای لینوکس یا مثلا nmake در ویندوز. خب وقتی شما بخوای یه کد رو بین پلتفروم‌های مختلف و برنامه نویس‌های مختلف به اشتراک بگذاری همیشه این سوال وجود داره که دقیقا چطور میشه روند build رو یه جوری از وابستگی به سیستم عامل و حتی پلتفرم آزاد کرد. یه موضوع دیگه‌هم اینه که چطور میشه برای برنامه نویسان این آزادی رو ایجاد کرد که از IDE مورد علاقه‌شون استفاده کنند.

برای جواب به این سوالات و خیلی سوالات دیگه جامعه متن باز پروژه‌ای به نام cmake ایجاد کرده که ویژگی‌های خیلی خوبی داره و همچنین یادگیریش به نسبت آسونه!

ویژگی‌های cmake

خب اگه بگم ویژگی‌های cmake رو بصورت خلاصه بگم اینها هستن

  • امکان کامپایل‌کردن کد بدون در نظر گرفتن محل کد
  • امکان کامپایل‌کردن کد روی سیستم‌عاملهای مختلف
  • امکان تشخیص محل فایل‌ها، کتابخانه‌ها
  • مدیریت وابستگی ها
  • امکان تولید فایل‌های make برای سیستم‌های مختلف و تولید پروژه برای IDEهای مختلف

کاری که من با cmake انجام دادم

کاری که من با کم cmake انجام دادم رو سعی میکنم براتون توضیح بدم. خب ما یه کد داشتیم که برای سه تا پلتفرم سخت افزاری مختلف با سه تا کامپایلر مختلف به سه دسته کتابخانه مختلف کامپایل و لینک میشد. کد تمام این پروژه‌ها یکسان بود اما فقط توسط کامپایلرهای مختلف توی محیط netbeans کامپایل میشد. کاری که انجام دادم این بود:

  • ابتدا پروژه فعلی رو تنها برای یک پلتفرم به cmake تبدیل کردم
    • کامپایلر استاندارد رو به کامپایلر دلخواه تبدیل کردم
    • آدرس کتابخانه‌ها و header فایلهای استاندارد رو عوض کردم
    • بصورت اتوماتیک لیست تمام فایلهای پروژه استخراج میشه
  • با استفاده از پارامترها و ساختار منطقی که cmake ساپورت میکنه دو تا پلتفرم دیگه رو اضافه کردم
    • یه متغیر کنترلی تعریف کردم
    • با استفاده از متغیر کنترلی و if همه موارد بالا رو برای هر پلتفرم تعریف کردم
    • اسم خروجی باینری و فولدر اون رو بر اساس متغیر کنترلی تعیین کردم.

حالا با این حال من تنها یک فایل دارم که باهاش کار سه تا پروژه رو انجام میدم که خب این خیلی جالب و جذابه

همین!