یادداشت‌های در مورد روش‌های چابک اسکرام و تخمین زدن!

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

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

خب انروز بحث اسکرام/روش/ساختار توی گروه شرکت داغ بود منم چندتا مورد که به ذهنم میرسه رو اضافه کردم که گفتم شاید اینجا هم بدردتون بخوره.

اگه نخواستید همش رو بخونید مخلص کلام اینه که: ما اونقدر تجربه نداریم که بخوایم روش از خودمون ایجاد کنیم/بهینه کنیم. روشهای چابک هدفشون مدیریت عدم قطعیت با اولویت تحویل به مشتری هست. اختصاصا اسکرام اومده که زباله و چیزای دست و پا گیر رو در حین انجام حداقل کنه و با کم کردن قضاوت بلندپروازی رو زیاد کنه و تیم بلندپروازی که چیزی دست و پاش رو نگرفته بتونه هرروز بهتر عمل کنه. اما اسکرام به عنوان یکی از پیاده‌سازی‌های روش‌ها چابک الزاما بهترین روش برای همه شرکت/تیم‌ها نیست ولی اگه اسکرام خوب نبود باید یه روش چابک استاندارد دیگه پیدا کنیم. و اضافه کنم که کلا تخمین زدن ما ایراد داره به همین خاطر یه ابزارهای کمکی مثل اسکرام پوکر ایجاد شده که خودش یکی از مصادیق مدیریت عدم قطعیت توی اسکرام هست.

۰ – اینکه من خودم و با اجازه بزرگترها خیلی از ما مهندس‌های نرم‌افزار رو در این حد از نظر احاطه به بحث توسعه فرآیند و ساختار نمیدونم که بتونن یه ساختار/روش کاری ایجاد کنن. پس ایده‌آل ام اینه که به یه روش/ساختار در سطح حلقه/تیم/شرکت به عنوان ریسمان محکم چنگ بزنم و از اون پیروی کنم. «پس به ریسمان محکم الهی چنگ بزنید و متفرق نشوید» آل‌عمران ۱۰۳

۱- به نظر بنده حقیر سراسر تقصیر، تمام روش‌های چابک/اجایل اومدن که دوتا کار کنن. اول عدم قطعیت رو مدیریت کنن. دوم تحویل به مشتری رو بیشینه کنن. پس جایی که ما با عدم قطعیت روبرو نیستیم یا تحویل به مشتری نداریم به نظرم اجایل اصالتا معنی نمیده.

۳ – یه کتاب هست در مورد اسکرام که تلاش کرده روح اسکرام رو بگه، من بخوام خلاصه‌ای که من ازش متوجه شدم رو بگم یعنی این. هدف اصلی اسکرام کاهش زباله است. زباله یعنی هرچیزی که به تحویل دادن کمک نمیکنه و هست. مثلا پلن نکردن کاری که مقدمات حاضر نیست. مثلا مشکل دسترسی که هر از گاهی پیش میاد. مثلا گروه‌های کاری که ممکنه وسط روز تمرکز رو از من بگیره. مثلا ساختارهای قدیمی که همیشه سد راهمونه. مثلا نداشتن ریسورس ذخیره که آدم با خیال راحت بتونه با ریسک کمتر کاری مثل بروزرسانی رو آزمایش کنه. نکته بعدیش اینه که با حذف قضاوت و افزایش کیفیت ارتباط بتونه کارایی آدم‌ها رو به حداکثر برسونه. یعنی من نترسم از اینکه قول بیش از حد بدم و تلاشم رو هم بکنم که با افزایشش کارایی که به دلیلی کم شدن زباله ایجاد شده کار رو برسونم. و اونجا میگه که با همین دوتا مورد کیفیت ظرفیت تیم‌ها افزایش حتی چندبرابری پیدا کرده. من خودم در تیم قبلیم این تجربه رو داشتم که باهمین قدم حذف ذباله و از بین بردن قضاوت یه تیم که ۱ محصول رو داشت تبدیل شد به تیمی که حداقل ۱۶ تا محصول رو داشت توسعه میداد و نگه میداشت.

۲- بازم به نظرم در جاهایی که بیشتر کارهای بیشتر تیم‌هاش از جنس عملیات و نگهداری هست آیا بایستی از اجایل استفاده کنیم؟ به نظرم آره. چون تهش ما هم عدم قطعیت داریم هم تحویل به مشتری. اما آیا اسکرام روش خوبی هست؟ به نظرم در تیم‌هایی که وزن توسعه توشون زیادتره بله. بقیه تیم‌ها چی؟ به نظرم اونها باید چیزی مثل کانبان/اسکامبان که مناسب‌تره استفاده کنن. ولی به نظرم باید بچسبیم به روش و سعی نکنیم مثلا بهبودش بدیم.

۳- و اما میرسیم به بحث جذاب تخمین. از نظر من تخمین درست کار خداست که تونست دنیا رو تو ۷ روز بی‌آفرینه و تازه معلوم نیست اون هفت روز واقعا چند روز بوده و بین علما اختلافه. یعنی چی؟ یعنی به تجربه به من ثابت شده که من و اکثر آدم‌هایی که دیدم نمیتونن درست تخمین بزنن. من خودم اینجوریم که اگه یه کاری از نظرم ۲ ساعت کار داشته باشه در عمل بطور متوسط ۶ ساعت طول کشیده تا انجامش بدم(من بصورت مداومی دارم چیزای مختلف رو میشمارم). و الان هر چی به ذهنم برسه و ضرب در ۳ میکنم. حالا این چه ایرادی داره. این باعث میشه من در هنگام قول دادن(بخونید پلنینگ) اگه بخوام زمان بدم همه چیز رو بدبینانه تخمین میزنم و این یعنی میزان کمتری کار تحویل میدم احتمالا. اما اگه بجای تخمین زمان در مورد بزرگی/سختی کار حرف بزنم و بگم این کار از نظر من واعضای تیم چقدر بزرگه، احتمالا تخمینم دقیق‌تره ولی زمانی هم براش نگفتم که بخوام چندبرابر تخمینم زمان بگم. و اگه چندتا اسپرینت بگذره عملا میتونم بگم من چقدر توان واقعی انجام کار دارم بدون اینکه تخمین زده باشم. نکته بعدی تخمین در آدمیزاد به تجربه ثابت شده که با بزرگ شدن کار بدتر میشه. یعنی من جارو زدن حال رو درست میتونم تخمین بزنم. ولی رفتن به کره ماه رو نه.
به همین خاطر اسکرام پوکر درست شده و از سری فیبوناچی که رشدش زیاده هم توش استفاده شده

فعلا همین!

استفاده از clang برای corss compile

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

خب بعد از مدتها دارم مینویسم و از این که این فرصت پیش اومده خوشحالم. موضوعی که الان میخوام در موردش بنویسم اینه که چطور میشه با استفاده clang که یک کامپالر جدید هست، کدی رو برای یک دستگاه embedded که اتفاقا کامپایلر gcc و کل زندگی خودش رو داره کامپایل کرد.

ممکنه بگید این به نظر غیر ممکن میاد اما مخصوصا توی C میشه یه چنین کاری انجام داد و clang و نسخه‌های جدید gcc قدرت این کار رو دارن که کد رو جوری کامپایل کنن که روی دستگاه‌های قدیمی کار کنه. چیزی که نیاز دارید اینکه اول به مجموعه کامپایلر دسترسی داشته باشید و اون کامپایلر حاوی چیزی به اسم sysroot باشه. کلا منظور از sysroot اینکه کل کتابخانه‌ها و ابزارهای لازم برای ساختن یک سیستم عامل کامل برای اون platform رو داشته باشید. دومین چیزی که نیاز دارید اینه که یه چیزی به نام target رو بدونید. این معمولا یه چیز سه بخشی هست که نشون میده cpu چیه، ساختار فایل اجرایی چیه، سیستم عاملی وجود داره یا نه. مثلا به چند مورد ازشون اینهاست armv7l-linux-gnueabihf یا arm-linux-gnueabihf که هر بخش از این سه گانه میگه چی به چیه.

یکی دیگه از چیزایی که مهم میشه اینه که کجا دنبال کامپایلرهای gcc بگرده که خود رو با اونها تطبیق بده خب اون رو هم باید بگید.

نکته بعدی که مهمه اینه که بگید از چه linker ای استفاده کنه. چرا؟ چون linker هست که زمان اجرا میاد و نرم افزار رو واقعا سر هم میکنه و قابل اجرا میکنه. مثلا اگه قرار باشه یه فایل تست رو کامپایل کنید احتمالا باید یه چنین چیزی رو اجرا کنید.

clang -target arm-brcm-linux-gnueabi --sysroot=/arm-brcm-linux-gnueabi/arm-brcm-linux-gnueabi/sysroot -gcc-toolchain /arm-brcm-linux-gnueabi -fuse-ld=/arm-brcm-linux-gnueabi/bin/arm-brcm-linux-gnueabi-ld hello.c

حالا این تست رو که بتونید روی بردتون اجرا کنید میتونید اون رو با makefile یا CMake هم ترکیب کنید و چیزهای جالبی بدست بیارد

همین!

لذت برنامه نویسی: ذخیره سازی داده

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

مدتی هست که دوست دارم بنویسم و نمیرسم. حالا بعد از مدتها اشتیاق به نوشتن اونقدر زیاد هست که دارم مینویسم.

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

  1. سایز دیتا و فایل متغیر باشه و بشه اون رو اضافه کرد
  2. فیلدهای دیتا قابل اضافه و کم کردن باشه
  3. حجم کد لازم برای این کار کم باشه که بشه روی دستگاه‌های سطح پایین مختلف ازش استفاده کرد.

راه حل‌ها

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

  1. پیاده‌سازی از اول: یعنی وابسته به نیازمون یه ساختار قابل افزایش خوب پیاده‌سازی کنیم
  2. استفاده از فرمت‌های متنی: فرمت‌های متنی که معمولا میشه استفاده کرد ini, xml, cvs, json, yaml هست. ایراد اینها اینه که چون متن هستن حجم زیادی میگیرن و عملا به صرفه نیستن. معمولا میزان پردازش لازم برای parse اونها هم کم نیست.
  3. استفاده از تکنولوژی های serialization مثل protocol buffer, thrift هست که با استفاده از اونها میتونید یه دیتا رو توصیف کنید و همون دیتا رو بصورت آرایه ذخیره کنید. اونها معمولا از schema evolution یعنی تغییر ساختار دیتا هم پشتیبانی می‌کنن.
  4. استفاده از دیتابیس های سبک مانند sqlite
  5. استفاده از کتابخانه‌های ذخیره سازی nosql مثل unqlite یا level db یا berkeley db که هر کدومشون به ما امکان ذخیره سازی دیتای با فرمت نامشخص رو میدن.

انتخاب من

من در پروژه‌هام از یه ساختار با سایز مشخص، ini ، sqlite و unqlite استفاده کردم. الان ترجیحم استفاده از با این اولویت هست:

  1. اول sqlite چون خیلی امکانانت سطح بالایی میده
  2. استفاده از unqlite و یا ini. البته با ini ما به مشکلات زیادی خوردیم اما unqlite رو هم اونقدر توی فیلد تست نکردم
  3. تهش پیاده کردن ساختار با سایز مشخص هست که کلی دردسر داره

همین

زیر پوست داکر چه خبر است

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

در این پست قرار است که به زیرساخت‌هایی که داکر مبتنی بر آن ساخته شده است اشاره شود. هدف نهایی نشان‌دادن این موضوع است که داکر امکانات خود را به چه صورت ارائه می‌کند.

مقدمه

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

کرنل لینوکس

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

  • فضای نام(namespace)ها در لینوکس: فضا‌های نام این امکان را بوجود می‌آورند که بتوانند بخشی از منابع سیستم را بصورت ایزوله به پروسه‌هایی که درون آنها قرار دارند ارائه دهند. این منابع تنها توسط پروسه‌های درون آن قابل روئیت است. فضاهای نامی در داکر مورد استفاده قرار گرفته‌اند عبارتند از
    • فضای‌نام PID: که باعث می‌شود پروسه تنها پروسه‌های درون خود را ببینند
    • فضای‌نام NET: که باعث می‌شود بتوان کارت‌شبکه، پشته شبکه و سایر موارد را بصورت ایزوله ارائه کرد.
    • فضای‌نام IPC: که روندهای ارتباطی بین پروسه‌های مختلف را ایزوله می‌کند.
    • فضای‌نام MNT: که نحوه اتصال(mount) واسط‌های ذخیره سازی را ایزوله می‌کند.
    • فضای‌نام UTS: که نام کامپیوتر(hostname) و دامنه(NIS) را ایزوله می‌کند.
  • گروه‌های کنترلی یا cgroups: کرنل لینوکس این امکان را فراهم می‌اورد که پروسه‌ها در یک ساختار سلسله مراتبی قرار گفته و دسترسی آن به منابع سیستم محدود شود و مورد پایش قرار گیرد. این باعث می‌شود بتوان به عنوان مثال میزان استفاده از سی پی یو یا رم را کنترل کرد.

فایل سیستم

تکنولوژی دیگری که در داکر مورد استفاده قرار گرفته است، استفاده از یک سیستم فایل خاص به ویژگی copy on write است. سیستم فایلهای با این ویژگی را می‌توان بصورت لایه لایه ذخیره کرد و هنگام انتقال در صورت وجود داشتن نسخه قبلی تنها تفاوت‌ها را ارسال نمود. همچنین این امکان به ما این اجازه را میدهد که بتوانیم تغییرات را نسخه متفاوت همانند یک سیستم مدیریت نسخه پیگیری نماییم. سیستم فایلی که داکر از آن استفاده union file system است که ویژگی‌های زیر را دارد:
– بصورت لایه‌ایست
– هر لایه بایستی commit شود
– هر لایه بصورت فقط خواندنی ذخیره می‌شود.
– تنها فایلهای تغییر یافته در آن لایه ذخیره می‌شوند.

اجرا یک کانتینر

برای اجرای کانتیر و مشخص کردن تمام مشخصات آن بایستی این مشخصات را به فرمتی توصیف کرد. در داکر این فرمت container format نام داشته و داکر سعی در استاندارد کردن آن را دارد.

دوپینگ گیط‌ی ;) – دوره کوتاه و فشرده git

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

حدودا ۲ روز پیش با خودم عهد کردم که یه ویدئو کوتاه آموزش درباره git درست کنم به اسم «دوپینگ گیط‌ی ;)». بعد از ۱۰ ساعت کار مفید این ویدئوی ۲۵ دقیقه‌ای در مورد گیت آماده شده که میگذارمش اینجا که ببینید.

مطالبی که توش مطرح میشه اینا هستن:

  • نصب و راه‌اندازی
  • مفاهیم گیت
  • ساختن یک منبع کد محلی
  • اضافه کردن و کامیت!
  • تغییر و کامیت!
  • تاریخچه تغییرات
  • سرور git
  • گرفتن از سرور
  • فرستادن تغییرات
  • شاخه‌ها
  • بروزرسانی و ادغام
  • برچسب‌ها
  • برگردادن تغییرات

سورس فایل ارائه هم مثل سورس این مطلب توی github من در دسترس هست.

ویدئو

در یوتیوب:

در آپارات:

لذت برنامه نویسی: معرفی gerrit

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

خب الان که من فرصت نوشتن بیشتر دارم تصمیم گرفتم یکم در مورد gerrit بنویسم. توی هر شرکتی معمولا یه چیزی به اسم «چرخه حیات توسعه نرم افزار» وجود داره که آدم‌ها ازش بصورت آگاهانه یا به وسیله اونچیزی که فرهنگ اون تیم یا گروه دیکته میکنه ازش استفاده می‌کنند. که اگه عمری بود بیشتر در موردش می‌نویسم. چرخه حیات کارهایی که ما در شرکت انجام می‌دیم به این شکله که:

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

معرفی gerrit

حالا پست امروز یه معرفی کوتاه و از ابزاری هست به اسم gerrit که ما از اون برای merge استفاده می‌کنیم.

روند هم اینه که با امکاناتی که gerrit در اختیار ما قرار میده، بعد از ارسال کد یک مرج محلی اتفاق میفته و کد توسط ci که همون jenkins باشه کنترل و کامپایل میشه. اگه این مرحله درست بود jenkins به gerrit میگه که اگه کسی review کرده میتونه تغییرات رو merge کنه و گرنه تا عدم موفقیت jenkins کسی نمی‌تونه کد رو اشتباهی merge کنه. این تضمین میکنه که دیگه کسی چیز اساسی رو خراب نمی‌کنه. پس از تایید jenkins هم افراد میتونن کد رو بررسی و تغییرات رو merge کنن. همچنین gerrit پلاگین‌هایی داره که کمک میکنه تا ما اون رو به جاهای مختلف مثل jira وصل کنیم و از اینکه یه کار آماده‌است و یا یه کار merge شده با خبر بشیم و حتی وضعیت موارد رو تغییر بدیم.

بعد از بررسی روند کا نوبت به پیش فرضهای هست که توی gerrit وجود داره.

  1. اینکه مدیریت منبع git در کنترل gerrit هست و ازش به عنوان یک git server استفاده می‌شه. یعنی اگه سرور دیگه‌ای مثل github هم وجود داره کپی gerrit هست نه بالعکس
  2. اینکه تغییرات هرچقدر هم که زیاد و مداوم باشن در نهایت در قالب یک commit ارسال میشن. ممکنه بگید که خب اگه من خواستم وسط کارم push کنم چی؟ جواب اینه که هر کامیت یک تغییر هست و تغییر میتونه draft باشه که یعنی هنوز کامل نشده
  3. اینکه gerrit تلاش میکنه که تاریخچه کد خطی بمونه و این در مجموع خوبه. برای خطی نگه داشتن تاریخچه به شدت از rebase استفاده می‌کنه

حالا اگه بخوام بصورت خلاصه مزایا و معایب رو بگم هم اینا به ذهنم میرسه

مزایا و معایب gerrit

مزایا:

  1. تاریخچه خطی
  2. ثبات در عملکرد
  3. وجود ابزار git review برای ارسال به gerrit و راحت کردن استفاده از gerrit
  4. شفافیت روند کاری بررسی کرد
  5. راحتی integrate شدن با ابزارهای دیگه مثل jira و jenkins و gitlab

معایب:

  1. مستندات گنگ. خیلی پیدا کردن چیزهای ساده توی gerrit آسون نیست
  2. زمان زیادی برای یادگیری استفاده از gerrit مورد نیاز هست

در آخر بگم که بگم که روند کاری که هریک از این ابزارها پیشنهاد میدن یک روند دیکته شده است و ممکن به مذاق شما خوش نیاد پس از هر روشی که به مذاقتون خوش میاد استفاده کنید. ما هم یه مدت از gerrit استفاده کردیم بعدش از gitlab و دوباره برگشتیم gerrit چون به نظرمون gerrit بهتر بود

همین!

لذت برنامه نویسی: نحوه کار ما با jenkins

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

خب حدودا سه سال قبل من از جای خالی continues integration نوشتم. حالا حدود بعد از سه سال میخوام دوباره به موضوع رجوع کنم و درباره jenkins بنویسم

توی این سه سال اتفاقات زیادی افتاده. ما روند build رو با استفاده از cmake بهتر کردیم. یادگرفتیم که چی به چیه. حدودا انتهای سال قبل بود که توی شرکت منابع و علم کافی برای پیاده‌سازی روند ci بوجود اومد و ما شروع کردیم به استفاده از jenkins.

نصب و راه‌اندازی jenkins به نسبت آسون و راحت بود. کاری که jenkins برای ما میکرد این بود که به یه دلیلی(بخونید ماشه) شروع به کامپایل کد میکرد. روند کامپایل هم آسون بود. یعنی اینکه یه سری پروژه معمول رو میشناسه مثل cmake, make, gradle, maven داره که کار رو راحت میکنه

ما اول به یه پروژه معمولی که بصورت ساعتی اجرا میشد شروع کردیم فقط نکتش اینه که ما با سخت‌افزارهای مختلف کار میکنیم و این تنها برای یکی از سخت‌افزارهامون کار میکرد. بعدش یه پروژه معمولی دیگه اضافه کردم که با cppcheck کار static analysis رو روی کدمون بصورت ساعتی انجام میداد.

در مرحله بعد با استفاده امکانی از jenkins pipeline تمامی سخت‌افزارها رو باهم کامپایل کردیم و cppcheck هم به عنوان یک مرحله از این خط لوله ما انتخاب شد.

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

در قدم‌های بعدی میخوایم تست اتوماتیک و تست روی سخت‌افزار رو هم پیاده کنیم که اون داستان‌های خودش رو داره. ما آهسته و پیوسته حرکت کردیم تا به این نقطه رسیدیم. شاید کند بودیم شاید هم خوب عمل کردیم ولی خوبیش اینه که راه روشنی پیش رو داریم.

فعلا همین!

openwrt و اضافه کردن یک پکیج جدید

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

توی پست قبل من OpenWrt رو معرفی کردم. بعد از یه مدت متوجه شدم که یه پروژه جدید به نام LEDE ایجاد شده که انگار همونه و الان حدود ۲ سال هست که OpenWrt زیاد بروزرسانی نمی‌شه. حالا با توجه به علاقه‌ام به کارهای نزدیک سخت‌افزار و مسائل مرتبط به cross compile سعی کردم که کل OpenWrt رو کامپایل کنم و سعی کنم یه پکیج جدید بهش اضافه کنم.

البته پکیجی که من دنبالش بودم tun2socks بود که پکیجش بصورت غیر رسمی وجود داشت. کاری که من کردم این بود که آدرس‌ها رو عوض کردم و یادگرفتم که چطور میتونم اون رو برای روترم کامپایل کنم. نتیجه کار من رو میتونید توی گیت‌هاب من پیدا کنید

روند کار به ترتیب اینجوریه که:

  1. اول سورس کد رو با گیت از گیت‌هاب میگیرید
  2. دوم با توجه به راهنمای آنلاین تمام پکیج‌ها رو دانلود میکنید
  3. پکیج رو اضافه می‌کنید
  4. با استفاده از make menuconfig نوع معماری سیستم و نوع دستگاه و پکیج‌ها رو انتخاب می‌کنید
  5. و از ابتدا کامپایلر و کل لینوکس و پکیج رو کامپایل میکنید

پینشهاد میکنم که برای شروع اینها بخونید:

امیدوارم به دردتون خورده باشه!

همین!

دوره گیت: معرفی و مقدمه

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

من یه مدت قبل تصمیم گرفتم که یه درس آموزشی در مورد git برای فرادرس ضبط کنم که دلیل‌های مختلف موفق به ضبط و اتمامش نشدم. فقط تونستم قسمت اول رو ضبط کنم. حالا میخواستم که بصورت کم کم ضبط رو انجام بدم که باز هم می‌بینم در کوتاه مدت نمیشه. پس تصمیم گرفتم این معرفی رو منتشر کنم تا ببینم بازخوردها نسبت بهش چیه.

توی این قسمت یه معرفی و تاریخچه‌ی کوچکی از سیستم‌های کنترل نسخه و git میگم. امیدوارم از نگاه کردن به ویدئو لذت ببرید

بابت اینکه ویدیو رو مشاهده می‌کنید تشکر می‌کنم. در صورتی که نظری داشتید، با من در میان بگذارید.

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

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

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

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

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

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

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

نمونه این کار به این شکل هست که توی CMakeLists.txt یه چنین چیزی نوشتیم
PROJECT(abyz-cmake-test)

CMAKE_MINIMUM_REQUIRED(VERSION 3.0)

SET(customer "a" CACHE STRING "This is customer name")

IF(custome STREQUAL "a")
SET(F1 "TRUE")
SET(F2 "TRUE")
SET(F3 "FALSE")
ENDIF(custome STREQUAL "a")

IF(custome STREQUAL "b")
SET(F1 "TRUE")
SET(F2 "FALSE")
SET(F3 "TRUE")
ENDIF(custome STREQUAL "b")

CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/module.h.in" "${CMAKE_SOURCE_DIR}/module.h")

INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/inc")

SET(appLib_src
src/utility.c
)
ADD_LIBRARY(applibstatic
STATIC
${appLib_src}
)
ADD_EXECUTABLE(abyz-cmake-test
src/main.cpp
)
TARGET_LINK_LIBRARIES(abyz-cmake-test
applibstatic
)
ADD_EXECUTABLE(unittester
tst/main.c
)

TARGET_LINK_LIBRARIES(unittester
applibstatic
)

توی فایل module.h.in هم یه چنین چیزی هست
#ifndef MODULE_H_
#define MODULE_H_

#define F1 ${F1}
#define F2 ${F2}
#define F3 ${F3}

#endif /* MODULE_H_ */

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

برای اجرا کردن هم میشه با این دوتا دستور برای مشتری‌های مختلف کامپایل کرد
$ mkdir build_a
$ cd build_a
$ cmake -G "Unix Makefiles" -Dcustomer:STRING=a ../
$ make
$ cd ..
$ mkdir build_b
$ cd build_b
$ cmake -G "Unix Makefiles" -Dcustomer:STRING=b ../
$ make

همین!