آموزش CMake - قسمت اول
بالاخره طبق قولی که مدت ها پیش داده بودم میخواهم آموزش CMake را شروع کنم. در اولین قسمت این آموزش با مقدمات کار اشنا میشوید و یک پروژه ساده را با CMake میسازید.
در قسمت های بعدی روند کار کمی با کیوت در می آمیزد و پس از پایان این آموزش ها به سراغ ترکیب Qt و QML میرویم.
CMake چیست؟
یک برنامه اتوماسیون ساخت نرم افزار است که مستقل از کامپایلر عمل میکند. از امکانات خوب آن پشتیبانی از ساختار وراثتی دیرکتوری ها (Directory hierarchy) میباشد.
اگر بخواهم به زبان ساده بگویم، یک ابزار برای مدیریت مراحل ساخت پروژه شماست. برنامه خود را بنویسید، محل ذخیره سورس ها، هدر ها و دیگر اجزای برنامه مانند کتابخانه ها را به آن بگویید و هر بار که میخواهید برنامه خود را بسازید (build)، کافی است از CMake بخواهید آن کار را برای شما انجام دهد. دیگر نیازی نیست که یکی یکی دستورات کامپایل و لینک و ... را اجرا کنید، بخاطر تغییر یک فایل وقت خود را صرف کامپایل کل پروژه کنید و نگران مرتب و تمیز بودن دایرکتوری ها باشید. CMake این کار را انجام میدهد.
شروع کار
به جای پرداختن به مباحث تئوری (تاریخچه، ساز و کار، مراحل انجام کار توسط CMake و ...) یکراست میرویم سراغ یک مثال عملی. اگر در مورد اینگونه موارد اطلاعاتی نیاز دارید به مستندات مراجعه کنید (ان شاا... زبانتان که خوب است، نه؟).
لینک دانلود پروژه در انتهای پست موجود است. این فایل فشرده فقط شامل فایل های سورس است و بقیه مراحل را باید همراه من بیایید. فایل را دانلود و استخراج کنید.
پروژه ساده ما از دو پوشه تشکیل شده: src که سورس های برنامه و کلاس ها را نگهداری میکند و include که شامل هدر های کلاس است.
برنامه CMake برای آنکه بفهمد این پروژه را چگونه باید بسازد، فایلی به نام CMakeLists.txt را از دیرکتوری داده شده به عنوان ارگومان میخواند. برای این پروژه ساده ما این فایل را در دیرکتوری ریشه پروژه ایجاد میکنیم:
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)خط اول: تعیین میکند که حداقل نسخه CMake برای ساخت این پروژه چه باشد. اگر برای ساخت از نسخه پایین تر از 3 استفاده شود، عملیات انجام نمیشود.
project(cmake_tutorial)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_executable(CMakeTutorial ${SOURCES})
خط دوم: نام پروژه را تعیین میکند.
خط سوم: دیرکتوری شامل هدرها (در اینجا include)
خط چهارم: میتوانستیم به جای آن بنویسیم:
set(SOURCES src/main.cpp src/simpleMath.cpp)اما عبارتی که ما استفاده کرده ایم کار را راحت تر میکند. در واقع file برای افزودن سورس به پروژه به کار میرود و GLOB هم میتواند لیستی از تمامی فایل های مطابق با عبارت داده شده ("src/*.cpp") ایجاد کند و در متغیر SOURCES ذخیره کند.
خط پنجم: add_executable فایل اجرایی CMakeTutorial را با استفاده از فایل های سورس که در متغیر SOURCES قرار دارند ایجاد میکند.
خب، حالا که این فایل را ایجاد کرده ایم ساختار درختی پروژه به شکل زیر است:
.حتما میپرسید که دیرکتوری build برای چه ایجاد شده؟ برنامه CMake هنگام ساختن پروژه برخی فایل های اضافی مانند MakeFile ها و Cache تولید میکند که ما انها را در این پوشه ذخیره میکنیم تا با بقیه پروژه کاری نداشته باشند. اگر هم برایتان جای سوال است که چگونه بدون اینکه در CMakeLists.txt به برنامه بگوییم انها را اینجا ذخیره کند این کار را انجام میدهد، باید بگویم که: CMake این فایل های اضافی را در دیرکتوری که از آنجا اجرا شده ذخیره میکند.
├── build
├── CMakeLists.txt
├── include
│ └── simpleMath.h
└── src
├── main.cpp
└── simpleMath.cpp
پس ما cmake را در دیرکتوری build اجرا میکنیم و محل ذخیره CmakeLists.txt را به عنوان ارگومان به آن میدهیم.
cd buildپس از پایان کار cmake به ما یک makeFile میدهد که پروژه را میسازد و کافیست مانند همه جای دنیای گنو بنویسیم:
cmake ..
makeو پروژه ساخته میشود. برای اجرا (در لینوکس) میتوانید بنویسید:
./CMakeTutorialنکته: اگر فایلی در پروژه تغییر کرد برای بروز رسانی نسخه ساخته شده کافیست دوباره .. cmake و make را به روشی که گفته شد اجرا کنید. میبینید که زمان ساخت چقدر کاهش یافته!
//جا دارد تشکری کنیم از سایت derekmolloy.ie که من ابتدا از طریق این سایت CMake را یاد گرفتم و روش تدریس این آموزش هم کمی تحت تاثیر آن بود.
Thansk
A good start ;)