Rivojlanish jarayonida men kompilyatorlarni o'zgartirishni, rejimlarni, qaramlik versiyalarini yaratishni, statik tahlil qilishni, ishlashni o'lchashni, qamrovni to'plashni, hujjatlarni yaratishni va hokazolarni yoqtiraman. Va men CMake-ni juda yaxshi ko'raman, chunki u menga xohlagan hamma narsani qilishimga imkon beradi.
Ko'pchilik CMake-ni tanqid qiladi va ko'pincha bunga loyiqdir, lekin agar qarasangiz, hamma narsa unchalik yomon emas va yaqinda umuman yomon emas, va rivojlanish yo'nalishi ancha ijobiy.
Ushbu eslatmada men sizga quyidagi funksiyalarni olish uchun CMake tizimida C++ da sarlavhalar kutubxonasini qanday tashkil qilishni aytmoqchiman:
Yig'ish;
Autorun testlari;
Kod qamrovini o'lchash;
O'rnatish;
Avtomatik hujjatlashtirish;
Onlayn sinov muhitini yaratish;
Statik tahlil.
Afzalliklarni va C-makeni tushunadigan har bir kishi buni oddiygina qila oladi Loyiha shablonini yuklab olish va undan foydalanishni boshlang.
Biz asosan CMake skriptlarini qanday tashkil qilish haqida gaplashamiz, shuning uchun ular batafsil muhokama qilinadi. Har kim qolgan fayllarni bevosita ko'rishi mumkin shablon loyihasi sahifasida.
Avvalo, siz CMake tizimining kerakli versiyasini so'rashingiz kerak. CMake rivojlanmoqda, buyruq imzolari va turli sharoitlarda xatti-harakatlari o'zgarib bormoqda. CMake biz undan nimani xohlayotganimizni darhol tushunishi uchun biz unga bo'lgan talablarimizni darhol yozib olishimiz kerak.
cmake_minimum_required(VERSION 3.13)
Keyin biz loyihamizni, uning nomini, versiyasini, ishlatiladigan tillarni va hokazolarni belgilaymiz (qarang. ΠΊΠΎΠΌΠ°Π½Π΄Ρ project).
Bu holda biz tilni ko'rsatamiz CXX (va bu C++ degan ma'noni anglatadi), shuning uchun CMake C tili kompilyatorini izlamaydi va izlamaydi (sukut bo'yicha CMake ikkita tilni o'z ichiga oladi: C va C++).
project(Mylib VERSION 1.0 LANGUAGES CXX)
Bu yerda siz bizning loyihamiz boshqa loyihaga kichik loyiha sifatida kiritilganligini darhol tekshirishingiz mumkin. Bu kelajakda ko'p yordam beradi.
Birinchi variant MYLIB_TESTING β birlik testlarini o'chirish uchun. Sinovlar bilan hamma narsa tartibda ekanligiga ishonchimiz komil bo'lsa, bu kerak bo'lishi mumkin, lekin biz faqat, masalan, loyihamizni o'rnatish yoki paketlashni xohlaymiz. Yoki bizning loyihamiz kichik loyiha sifatida kiritilgan - bu holda loyihamiz foydalanuvchisi bizning testlarimizni o'tkazishdan manfaatdor emas. Siz foydalanadigan bog'liqliklarni sinab ko'rmaysiz, shunday emasmi?
Bundan tashqari, biz alohida variantni qilamiz MYLIB_COVERAGE testlar orqali kod qamrovini o'lchash uchun, lekin u qo'shimcha vositalarni talab qiladi, shuning uchun uni aniq yoqish kerak bo'ladi.
Albatta, biz ajoyib dasturchilarmiz, shuning uchun kompilyatordan kompilyatsiya vaqtidagi diagnostikaning maksimal darajasini istaymiz. Birorta ham sichqonchadan sirg'alib o'tmaydi.
Bizning kutubxonamiz faqat sarlavhali fayllardan iborat, ya'ni bizda statik yoki dinamik kutubxonalar ko'rinishidagi chiqindi yo'q. Boshqa tomondan, kutubxonamizdan tashqarida foydalanish uchun uni o'rnatish kerak, u tizimda aniqlanishi va loyihangizga ulangan bo'lishi kerak va shu bilan birga xuddi shu sarlavhalar, shuningdek, ba'zi qo'shimchalar, xususiyatlari unga biriktirilgan.
Shu maqsadda biz interfeys kutubxonasini yaratamiz.
add_library(mylib INTERFACE)
Biz sarlavhalarni interfeys kutubxonamizga bog'laymiz.
Zamonaviy, moda, yoshlar uchun CMake-dan foydalanish sarlavhalar, xususiyatlar va boshqalarni anglatadi. bitta maqsad orqali uzatiladi. Shuning uchun aytish kifoya target_link_libraries(target PRIVATE dependency), va maqsad bilan bog'langan barcha sarlavhalar dependency, maqsadga tegishli manbalar uchun mavjud bo'ladi target. Va sizga hech narsa kerak emas [target_]include_directories. Bu quyida tahlilda ko'rsatiladi Birlik testlari uchun CMake skripti.
Ushbu buyruq bizga kerak bo'lgan sarlavhalarni interfeys kutubxonamiz bilan bog'laydi va agar kutubxonamiz bir xil CMake ierarxiyasidagi istalgan maqsadga ulangan bo'lsa, katalogdagi sarlavhalar u bilan bog'lanadi. ${CMAKE_CURRENT_SOURCE_DIR}/include, va agar kutubxonamiz tizimga o'rnatilgan bo'lsa va buyruq yordamida boshqa loyihaga ulangan bo'lsa find_package, keyin katalogdagi sarlavhalar u bilan bog'lanadi include o'rnatish katalogiga nisbatan.
Keling, til standartini belgilaylik. Albatta, eng oxirgisi. Shu bilan birga, biz nafaqat standartni o'z ichiga olamiz, balki uni kutubxonamizdan foydalanadiganlar uchun ham kengaytiramiz. Bunga o'rnatilgan xususiyat toifaga ega bo'lganligi sababli erishiladi INTERFACE (Sm. target_compile_features buyrug'i).
Keling, kutubxonamiz uchun taxallus yarataylik. Bundan tashqari, go'zallik uchun u maxsus "nomlar maydonida" bo'ladi. Bu bizning kutubxonamizda turli xil modullar paydo bo'lganda foydali bo'ladi va biz ularni bir-biridan mustaqil ravishda ulashga o'tamiz. Masalan, Bustadagi kabi.
Sarlavhalarimizni tizimga o'rnatish. Bu erda hamma narsa oddiy. Biz barcha sarlavhalari bo'lgan papka katalogga kirishi kerakligini aytamiz include o'rnatish joyiga nisbatan.
Keyinchalik, biz qurish tizimiga uchinchi tomon loyihalarida buyruqqa qo'ng'iroq qilishimiz mumkinligini xabar qilamiz find_package(Mylib) va maqsadga erishing Mylib::mylib.
Keyingi afsunni shu tarzda tushunish kerak. Uchinchi tomon loyihasida biz buyruqni chaqiramiz find_package(Mylib 1.2.3 REQUIRED), va o'rnatilgan kutubxonaning haqiqiy versiyasi versiyaga mos kelmaydi 1.2.3CMake avtomatik ravishda xato hosil qiladi. Ya'ni, versiyalarni qo'lda kuzatishingiz shart emas.
Agar testlar yordamida aniq o'chirilgan bo'lsa mos keladigan variant yoki bizning loyihamiz kichik loyihadir, ya'ni buyruq yordamida boshqa CMake loyihasiga ulanadi add_subdirectory, biz ierarxiya bo'ylab harakat qilmaymiz va testlarni yaratish va ishga tushirish buyruqlarini tavsiflovchi skript oddiygina ishlamaydi.
Avvalo, biz kerakli test tizimiga ega paketni topamiz (sevimli bilan almashtiring).
find_package(doctest 2.3.3 REQUIRED)
Keling, testlar bilan bajariladigan faylimizni yarataylik. Odatda men to'g'ridan-to'g'ri bajariladigan ikkilik faylga faqat funktsiyani o'z ichiga olgan faylni qo'shaman main.
add_executable(mylib-unit-tests test_main.cpp)
Va men testlarning o'zlari keyinroq tasvirlangan fayllarni qo'shaman. Lekin buni qilish shart emas.
Biz bog'liqliklarni bog'laymiz. E'tibor bering, biz faqat o'zimizga kerak bo'lgan CMake maqsadlarini ikkilik tizimimizga bog'ladik va buyruqni chaqirmadik target_include_directories. Sinov tizimidan va bizdan sarlavhalar Mylib::mylib, shuningdek, qurish parametrlari (bizning holatda, bu C++ tili standarti) ushbu maqsadlar bilan birga keldi.
Va nihoyat, biz "qurilishi" ishlaydigan testlarga teng bo'lgan soxta maqsadni yaratamiz va bu maqsadni standart tuzilishga qo'shamiz (atribut bu uchun javobgardir. ALL). Bu shuni anglatadiki, standart tuzilish sinovlarni ishga tushirishni boshlaydi, ya'ni biz ularni bajarishni hech qachon unutmaymiz.
add_custom_target(check ALL COMMAND mylib-unit-tests)
Keyinchalik, tegishli variant ko'rsatilgan bo'lsa, biz kod qamrovini o'lchashni yoqamiz. Men tafsilotlarga kirmayman, chunki ular CMake-dan ko'ra qamrovni o'lchash vositasiga ko'proq tegishli. Shuni ta'kidlash kerakki, natijalar asosida maqsad yaratiladi coverage, uning yordamida qamrovni o'lchashni boshlash qulay.
Keyinchalik, foydalanuvchi til o'zgaruvchisini o'rnatganligini tekshiramiz. Ha bo'lsa, biz unga tegmaymiz, bo'lmasa, rus tilini olamiz. Keyin biz Doxygen tizim fayllarini sozlaymiz. Barcha kerakli o'zgaruvchilar, shu jumladan til, konfiguratsiya jarayonida u erga boradi (qarang. ΠΊΠΎΠΌΠ°Π½Π΄Ρ configure_file).
Keyin biz maqsadni yaratamiz doc, bu hujjatlarni yaratishni boshlaydi. Hujjatlarni yaratish ishlab chiqish jarayonida eng katta ehtiyoj emasligi sababli, maqsad sukut bo'yicha yoqilmaydi; u aniq ishga tushirilishi kerak.
if (Doxygen_FOUND)
if (NOT MYLIB_DOXYGEN_LANGUAGE)
set(MYLIB_DOXYGEN_LANGUAGE Russian)
endif()
message(STATUS "Doxygen documentation will be generated in ${MYLIB_DOXYGEN_LANGUAGE}")
configure_file(Doxyfile.in Doxyfile)
add_custom_target(doc COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
endif ()
Bu erda biz uchinchi Pythonni topamiz va maqsadni yaratamiz wandbox, bu API xizmatiga mos keladigan so'rovni yaratadi Tayoqchalar qutisi, va uni jo'natadi. Javob tayyor sandboxga havola bilan birga keladi.
Birlik sinovini qurish va maqsadni o'chirish imkoniyatini beradi check. Natijada, testlar bilan kod qamrovini o'lchash o'chiriladi (qarang. MYLIB_COVERAGE).
Agar loyiha boshqa loyihaga buyruq yordamida kichik loyiha sifatida ulangan bo'lsa, sinov ham avtomatik ravishda o'chiriladi add_subdirectory.
Buning uchun xizmatdan foydalaniladi Tayoqchalar qutisi. Men ularning serverlari qanchalik moslashuvchanligini bilmayman, lekin menimcha, bu imkoniyatni suiiste'mol qilmaslik kerak.
Aslida, CMake 3.13 versiyasi faqat ushbu yordamda tasvirlangan ba'zi konsol buyruqlarini bajarish uchun talab qilinadi. CMake skriptlarining sintaksisi nuqtai nazaridan, agar generatsiya boshqa yo'llar bilan chaqirilsa, 3.8 versiyasi etarli.
Shundan so'ng, har safar manba kompilyatsiya qilinganda va qayta kompilyatsiya qilinganida statik tahlil avtomatik ravishda ishga tushiriladi. Qo'shimcha hech narsa qilishning hojati yo'q.
Jiringlash
Ajoyib vosita yordamida scan-build Siz qisqa vaqt ichida statik tahlilni ham bajarishingiz mumkin:
CMake - bu har qanday lazzat va rang uchun funksionallikni amalga oshirish imkonini beruvchi juda kuchli va moslashuvchan tizim. Va, garchi sintaksis ba'zida juda ko'p narsani xohlasa ham, shayton hali ham u bo'yalgandek dahshatli emas. Jamiyat va salomatlik manfaati uchun CMake qurish tizimidan foydalaning.