ڊولپمينٽ دوران، مان ڪمپلرز کي تبديل ڪرڻ، موڊس ٺاهڻ، انحصار ورزن، جامد تجزيو ڪرڻ، ڪارڪردگي کي ماپڻ، ڪوريج گڏ ڪرڻ، دستاويز تيار ڪرڻ، وغيره ڪرڻ پسند ڪندو آهيان. ۽ مان واقعي CMake سان پيار ڪريان ٿو ڇاڪاڻ ته اها مون کي هر شي ڪرڻ جي اجازت ڏئي ٿي جيڪا مان چاهيان ٿو.
ڪيترائي ماڻهو CMake تي تنقيد ڪن ٿا، ۽ اڪثر ڪري مستحق طور تي، پر جيڪڏهن توهان ان کي ڏسندا، هر شيء ايترو خراب ناهي، ۽ تازو بلڪل خراب ناهي، ۽ ترقي جي هدايت ڪافي مثبت آهي.
هن نوٽ ۾، مان توهان کي ٻڌائڻ چاهيان ٿو ته هيٺ ڏنل ڪارڪردگي حاصل ڪرڻ لاءِ C++ CMake سسٽم ۾ هيڊر لائبريري کي ڪيئن منظم ڪجي:
اسيمبلي؛
خودڪار ٽيسٽ؛
ڪوڊ ڪوريج جي ماپ؛
تنصيب؛
خودڪار دستاويز؛
آن لائين سينڊ باڪس نسل؛
جامد تجزيو.
ڪو به ماڻهو جيڪو اڳ ۾ ئي فائدن کي سمجهي ٿو ۽ C-make ڪري سگهي ٿو پروجيڪٽ ٽيمپليٽ ڊائون لوڊ ڪريو ۽ ان کي استعمال ڪرڻ شروع ڪريو.
اسان بنيادي طور تي ڳالهائينداسين ته ڪيئن منظم ڪجي سي ايمڪ اسڪرپٽ، تنهنڪري انهن تي تفصيل سان بحث ڪيو ويندو. ڪو به ماڻهو باقي فائلن کي سڌو سنئون ڏسي سگهي ٿو ٽيمپليٽ پروجيڪٽ صفحي تي.
سڀ کان پهريان، توهان کي سي ايمڪ سسٽم جي گهربل ورزن جي درخواست ڪرڻ جي ضرورت آهي. CMake ترقي ڪري رهيو آهي، مختلف حالتن ۾ حڪم دستخط ۽ رويي تبديل ٿي رهيا آهن. CMake لاءِ فوري طور تي سمجھڻ لاءِ ته اسان ان مان ڇا ٿا چاهيون، اسان کي ان لاءِ اسان جون ضرورتون فوري طور تي رڪارڊ ڪرڻ گهرجن.
cmake_minimum_required(VERSION 3.13)
پوءِ اسان پنھنجي پروجيڪٽ، ان جو نالو، ورجن، استعمال ٿيل ٻوليون، وغيره مقرر ڪنداسين (ڏسو. команду project).
انهي صورت ۾ اسان ٻولي کي اشارو ڪريون ٿا CXX (۽ ان جو مطلب آهي C++) ته جيئن CMak تنگ نه ٿئي ۽ سي ٻولي ڪمپلر جي ڳولا ڪريو (ڊفالٽ طور، CMak ۾ ٻه ٻوليون شامل آهن: C ۽ C++).
project(Mylib VERSION 1.0 LANGUAGES CXX)
هتي توهان فوري طور تي چيڪ ڪري سگهو ٿا ته ڇا اسان جو منصوبو ڪنهن ٻئي پروجيڪٽ ۾ سب پروجيڪٽ طور شامل آهي. اهو مستقبل ۾ تمام گهڻو مدد ڪندو.
پهريون اختيار آهي MYLIB_TESTING - يونٽ ٽيسٽ کي بند ڪرڻ لاء. اهو ضروري ٿي سگهي ٿو جيڪڏهن اسان کي پڪ آهي ته هر شي ٽيسٽ سان ترتيب ۾ آهي، پر اسان صرف چاهيون ٿا، مثال طور، اسان جي پروجيڪٽ کي انسٽال ڪرڻ يا پيڪيج ڪرڻ. يا اسان جو پروجيڪٽ هڪ ذيلي پروجيڪٽ جي طور تي شامل ڪيو ويو آهي - انهي صورت ۾، اسان جي منصوبي جو استعمال ڪندڙ اسان جي تجربن کي هلائڻ ۾ دلچسپي نه آهي. توهان ان انحصار جي جانچ نٿا ڪريو جيڪي توهان استعمال ڪندا آهيو، ڇا توهان؟
ان کان علاوه، اسان هڪ الڳ اختيار ڪنداسين MYLIB_COVERAGE ٽيسٽ ذريعي ڪوڊ ڪوريج کي ماپڻ لاءِ، پر ان لاءِ اضافي اوزارن جي ضرورت پوندي، تنهنڪري ان کي واضح طور تي فعال ڪرڻ جي ضرورت پوندي.
اسان جي لائبريري صرف هيڊر فائلن تي مشتمل آهي، جنهن جو مطلب آهي ته اسان وٽ جامد يا متحرڪ لائبريرين جي صورت ۾ ڪا به گنجائش نه آهي. ٻئي طرف، اسان جي لائبريري کي ٻاهران استعمال ڪرڻ لاءِ، ان کي انسٽال ڪرڻ جي ضرورت آهي، ان کي سسٽم ۾ ڳولڻ جي ضرورت آهي ۽ توهان جي پروجيڪٽ سان ڳنڍڻ جي ضرورت آهي، ۽ ساڳئي وقت اهي ساڳيا هيڊر، ۽ ممڪن آهي ته ڪجهه اضافي، ان جي ملڪيت سان ڳنڍيل آهن.
هن مقصد لاء، اسان هڪ انٽرفيس لائبريري ٺاهي.
add_library(mylib INTERFACE)
اسان هيڊرز کي اسان جي انٽرفيس لائبريري سان ڳنڍيندا آهيون.
هي ڪمانڊ هيڊرز کي اسان جي انٽرفيس لائبريري سان ڳنڍيندو آهي، ۽ جيڪڏهن اسان جي لائبريري ڪنهن به ٽارگيٽ سان ڳنڍيل آهي ساڳئي CMake هيئرارڪي ۾، پوء ڊاريڪٽري مان هيڊر ان سان لاڳاپيل هوندا. ${CMAKE_CURRENT_SOURCE_DIR}/include، ۽ جيڪڏهن اسان جي لائبريري سسٽم تي نصب ٿيل آهي ۽ ڪمانڊ استعمال ڪندي ٻئي منصوبي سان ڳنڍيل آهي find_package، پوءِ ڊاريڪٽري مان هيڊر ان سان لاڳاپيل هوندا include انسٽاليشن ڊاريڪٽري سان لاڳاپيل.
اچو ته ٻوليءَ جو معيار مقرر ڪريون. يقينا، بلڪل آخري. ساڳئي وقت، اسان نه رڳو معيار کي شامل ڪريون ٿا، پر ان کي انهن تائين وڌايو جيڪي اسان جي لائبريري کي استعمال ڪندا. اهو حاصل ڪيو ويو آهي انهي حقيقت جي ڪري ته سيٽ جي ملڪيت جو هڪ قسم آهي INTERFACE (ڏسو target_compile_features حڪم).
اچو ته اسان جي لائبريري لاء هڪ عرف ٺاهيو. ان کان سواء، خوبصورتي لاء، اهو هڪ خاص "نام جي جڳهه" ۾ هوندو. اهو مفيد ٿيندو جڏهن مختلف ماڊلز اسان جي لائبريري ۾ ظاهر ٿيندا، ۽ اسان انهن کي هڪ ٻئي کان آزاد طور تي ڳنڍڻ لاء وڃون ٿا. جهڙوڪ بسٽا ۾، مثال طور.
اڳيون، اسان تعميراتي نظام کي ڄاڻون ٿا ته اسان ٽئين پارٽي جي منصوبن ۾ حڪم کي سڏڻ جي قابل ٿي چاهيون ٿا find_package(Mylib) ۽ هڪ مقصد حاصل ڪريو Mylib::mylib.
ايندڙ اسپيل کي هن طرح سمجهڻ گهرجي. جڏهن ٽئين پارٽي جي منصوبي ۾ اسان کي حڪم سڏين ٿا find_package(Mylib 1.2.3 REQUIRED)، ۽ نصب ٿيل لائبريري جو حقيقي نسخو نسخي سان مطابقت نه رکندو 1.2.3CMake خودڪار طريقي سان هڪ غلطي پيدا ڪندو. اهو آهي، توهان کي دستي طور تي نسخن کي ٽريڪ ڪرڻ جي ضرورت نه هوندي.
جيڪڏهن ٽيسٽ غير فعال آهن واضح طور تي استعمال ڪندي لاڳاپيل اختيار يا اسان جو پروجيڪٽ هڪ ذيلي پروجيڪٽ آهي، اهو آهي، اهو ڪمانڊ استعمال ڪندي ڪنهن ٻئي CMake پروجيڪٽ سان ڳنڍيل آهي add_subdirectory، اسان اڳتي نه وڌندا آهيون درجه بندي سان، ۽ اسڪرپٽ، جيڪو بيان ڪري ٿو حڪمن کي تيار ڪرڻ ۽ ٽيسٽ هلائڻ لاءِ، بس نه هلندو آهي.
if(NOT MYLIB_TESTING)
message(STATUS "Тестирование проекта Mylib выключено")
elseif(IS_SUBPROJECT)
message(STATUS "Mylib не тестируется в режиме подмодуля")
else()
add_subdirectory(test)
endif()
اسان انحصار کي ڳنڍيندا آهيون. مھرباني ڪري نوٽ ڪريو ته اسان صرف CMake ھدف سان ڳنڍيو آھي اسان کي اسان جي بائنري جي ضرورت آھي ۽ حڪم کي ڪال نه ڪيو target_include_directories. ٽيسٽ فريم ورڪ ۽ اسان جي طرفان عنوان Mylib::mylib، انهي سان گڏ تعميراتي پيرا ميٽرز (اسان جي صورت ۾، هي C++ ٻولي جو معيار آهي) انهن مقصدن سان گڏ آيو.
اڳيون، اسان ڪوڊ ڪوريج جي ماپ کي چالو ڪندا آھيو جيڪڏھن مناسب اختيار بيان ڪيو ويو آھي. مان تفصيل ۾ نه ويندس، ڇاڪاڻ ته اهي CMake جي ڀيٽ ۾ ڪوريج کي ماپڻ لاء هڪ اوزار سان وڌيڪ تعلق رکن ٿا. اهو صرف نوٽ ڪرڻ ضروري آهي ته نتيجن جي بنياد تي هڪ مقصد ٺاهيو ويندو coverage، جنهن سان اهو آسان آهي ڪوريج کي ماپڻ شروع ڪرڻ.
find_program(GCOVR_EXECUTABLE gcovr)
if(MYLIB_COVERAGE AND GCOVR_EXECUTABLE)
message(STATUS "Измерение покрытия кода тестами включено")
target_compile_options(mylib-unit-tests PRIVATE --coverage)
target_link_libraries(mylib-unit-tests PRIVATE gcov)
add_custom_target(coverage
COMMAND
${GCOVR_EXECUTABLE}
--root=${PROJECT_SOURCE_DIR}/include/
--object-directory=${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
check
)
elseif(MYLIB_COVERAGE AND NOT GCOVR_EXECUTABLE)
set(MYLIB_COVERAGE OFF)
message(WARNING "Для замеров покрытия кода тестами требуется программа gcovr")
endif()
اڳيون، اسان چيڪ ڪريون ٿا ته ڇا صارف ٻولي متغير مقرر ڪيو آهي. جيڪڏهن ها، ته پوءِ اسان ان کي هٿ نه ٿا لڳايو، جيڪڏهن نه، ته پوءِ اسان روسي وٺون ٿا. پوء اسان ڊڪسيجن سسٽم فائلن کي ترتيب ڏيو. سڀ ضروري متغير، ٻولي سميت، اتي وڃو ترتيب جي عمل دوران (ڏسو. команду configure_file).
پوء اسان هڪ مقصد ٺاهي doc، جيڪو دستاويز ٺاهڻ شروع ڪندو. جيئن ته ڊولپمينٽ جي عمل ۾ دستاويز تيار ڪرڻ سڀ کان وڏي ضرورت نه آهي، ان ڪري ٽارگيٽ کي ڊفالٽ طور فعال نه ڪيو ويندو؛ ان کي واضح طور تي لانچ ڪرڻو پوندو.
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 ()
حقيقت ۾، CMake نسخو 3.13 صرف هن مدد ۾ بيان ڪيل ڪنسول حڪمن مان ڪجهه هلائڻ جي ضرورت آهي. CMake اسڪرپٽ جي نحو جي نقطي نظر کان، نسخو 3.8 ڪافي آهي جيڪڏهن نسل کي ٻين طريقن سان سڏيو وڃي.
CMake هڪ تمام طاقتور ۽ لچڪدار سسٽم آهي جيڪو توهان کي هر ذائقي ۽ رنگ جي ڪارڪردگي کي لاڳو ڪرڻ جي اجازت ڏئي ٿو. ۽، جيتوڻيڪ نحو ڪڏهن ڪڏهن گهڻو ڪري ڇڏي ٿو گهربل هجي، شيطان اڃا تائين ايترو خوفناڪ نه آهي جيترو هو رنگيل آهي. سماج ۽ صحت جي فائدي لاء CMake تعمير سسٽم استعمال ڪريو.