CMake का परिचय

छवि सीएमके स्वचालित रूप से स्रोत कोड से एक कार्यक्रम के निर्माण के लिए एक क्रॉस-प्लेटफॉर्म उपयोगिता है। उसी समय, सीएमके खुद ही सीधे निर्माण नहीं करता है, लेकिन एक फ्रंट-एंड है। मेक और निंजा के विभिन्न संस्करण बैक-एंड के रूप में कार्य कर सकते हैं। CMake आपको CodeBlocks, Eclipse, KDevelop3, MS VC ++ और Xcode के लिए प्रोजेक्ट बनाने की अनुमति देता है। यह ध्यान देने योग्य है कि अधिकांश परियोजनाएं मूल रूप से नहीं बनाई गई हैं, लेकिन सभी एक ही बैक-एंड के साथ हैं।

सीमेक का उपयोग करके एक परियोजना बनाने के लिए, आपको स्रोत पेड़ की जड़ में CMakeLists.txt फ़ाइल को रखने की आवश्यकता है, जो विधानसभा के नियमों और लक्ष्यों को संग्रहीत करता है, और कुछ सरल कदम उठाता है।
आइए उदाहरणों को देखें।

उदाहरण 1. नमस्कार, विश्व:


शुरू करने के लिए, हम सरलतम विश्वशब्द लिखेंगे और परियोजना संरचना बनाएँगे:
main.cpp
#include <iostream> int main(int argc, char** argv) { std::cout << "Hello, World!" << std::endl; return 0; } 


CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . add_executable(main main.cpp) #      main #   main.cpp 



CMake का सिंटैक्स बैश के सिंटैक्स के समान है, "#" वर्ण के बाद सब कुछ एक टिप्पणी है और कार्यक्रम द्वारा संसाधित नहीं किया जाएगा। सीमेक अस्थायी फ़ाइलों के साथ स्रोत के पेड़ को अव्यवस्थित नहीं करने की अनुमति देता है - यह बहुत सरल है और अतिरिक्त इशारों के बिना, विधानसभा को "आउट-ऑफ-सोर्स" किया जाता है।

अस्थायी फ़ाइलों के लिए एक खाली निर्देशिका बनाएं और वहां जाएं।
fshp @ पैनिका-डेस्कटॉप: ~ $ mkdir tmp
fshp @ पनिका-डेस्कटॉप: ~ $ cd tmp /
fshp @ पनिका-डेस्कटॉप: ~ / tmp $

अब cmake कमांड को रन करें, इसे सोर्स फोल्डर के लिए एक पैरामीटर के रूप में पास करें:
fshp @ पैनिका-डेस्कटॉप: ~ / tmp $ cmake ~ / cmake / example_1 /
...
- बिल्ड फ़ाइलों को लिखा गया है: / घर / fshp / tmp
fshp @ पनिका-डेस्कटॉप: ~ / tmp $
fshp @ पैनिका-डेस्कटॉप: ~ / tmp $ ls
CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
fshp @ पनिका-डेस्कटॉप: ~ / tmp $

हम देखते हैं कि प्रोजेक्ट के निर्माण के लिए आवश्यक कई अस्थायी फाइलें फ़ोल्डर में दिखाई दीं।
अब आप सीधे बना सकते हैं:
fshp @ panica-desktop: ~ / tmp $ मेक
लक्ष्य मुख्य की स्कैनिंग निर्भरताएँ
[100%] CXX ऑब्जेक्ट CMakeFiles / main.dir / main.cpp.o का निर्माण
जोड़ने CXX निष्पादन योग्य मुख्य
[१००%] निर्मित मुख्य लक्ष्य
fshp @ पनिका-डेस्कटॉप: ~ / tmp $ ./main
नमस्ते विश्व!
fshp @ पनिका-डेस्कटॉप: ~ / tmp $

इसलिए, हमारा कार्यक्रम इकट्ठा हो गया है।
स्रोत को तोड़ने के जोखिम के बिना tmp फ़ोल्डर को साफ / हटाया जा सकता है। यदि CMakeLists.txt को बदल दिया गया है, तो एक कॉल स्वचालित रूप से cmake शुरू कर देगा। यदि स्रोतों को स्थानांतरित किया गया था, तो आपको अस्थायी निर्देशिका को खाली करने और मैन्युअल रूप से सेमीकेक चलाने की आवश्यकता है।

उदाहरण 2. पुस्तकालय:


यदि आपकी परियोजना में एक पुस्तकालय है, तो सीएमके बिना किसी समस्या के इसका निर्माण करेगा।
ऐसा करने के लिए, हम उदाहरण को जटिल करते हैं।
foo.h
 void hello_world(); 


foo.cpp
 #include <iostream> void hello_world() { std::cout << "Hello, World!" << std::endl; } 


main.cpp
 #include "foo.h" int main(int argc, char** argv) { hello_world(); return 0; } 


CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . project(hello_world) #   set(SOURCE_EXE main.cpp) #         set(SOURCE_LIB foo.cpp) #  ,    add_library(foo STATIC ${SOURCE_LIB}) #      foo add_executable(main ${SOURCE_EXE}) #      main target_link_libraries(main foo) #     



चर रिक्त स्थान / टैब / हाइफ़न द्वारा अलग किए गए मानों की सूची संग्रहीत कर सकते हैं:
 set(SOURCE main.cpp foo.cpp) set(HEADER main.h foo.h) 

दोनों विकल्प सही हैं।
एक चर का मूल्य पाने के लिए, हम निर्माण का उपयोग करते हैं:
 ${var_name} 

तो, हमारी परियोजना के इस संस्करण में स्रोत से संकलित एक स्थिर पुस्तकालय शामिल है। यदि हम “STATIC” को “SHARED” से बदल देते हैं, तो हमें एक गतिशील पुस्तकालय मिलता है। यदि लाइब्रेरी का प्रकार निर्दिष्ट नहीं है, तो डिफ़ॉल्ट रूप से इसे स्थिर के रूप में इकट्ठा किया जाएगा।
लिंक करते समय, सभी आवश्यक पुस्तकालयों का संकेत दिया जाता है:
 target_link_libraries(main foo ogg vorbis) 

मैनुअल संकलन के साथ, पुस्तकालय के नाम मानक "लिबास" उपसर्ग के बिना निर्दिष्ट किए जाते हैं।
इसलिए, सीएमके के साथ लाइब्रेरी का निर्माण करने में कोई समस्या नहीं होती है, जबकि लाइब्रेरी का प्रकार केवल एक पैरामीटर के साथ स्थिर / गतिशील परिवर्तन होता है।

उदाहरण 3. सबप्रोजेक्ट:


यदि आपका कार्यक्रम कई पुस्तकालयों में विभाजित है या परियोजना में कई कार्यक्रम शामिल हैं तो उपप्रोजेक्ट बहुत सुविधाजनक हैं।
प्रत्येक उपप्रोजेक्ट अनिवार्य रूप से एक पूर्ण विकसित परियोजना है और इसका उपयोग स्वतंत्र रूप से किया जा सकता है।
अब हमारे पास "foo" उपनिर्देशिका में स्थित है और CMakeLists.txt उपप्रोजेक्ट भी वहां स्थित है।
CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . project(hello_world) #   set(SOURCE_EXE main.cpp) #      include_directories(foo) #    add_executable(main ${SOURCE_EXE}) #      main add_subdirectory(foo) #  ,    target_link_libraries(main foo) #     


main.cpp
 #include "foo.h" int main(int argc, char** argv) { hello_world(); return 0; } 


foo / CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . project(foo) #   set(SOURCE_LIB foo.cpp) #      add_library(foo STATIC ${SOURCE_LIB})#    


foo / foo.h
 void hello_world(); 


foo / foo.cpp
 #include <iostream> void hello_world() { std::cout << "Hello, World!" << std::endl; } 



सबप्रोजेक्ट फ़ाइल में आपके लिए कुछ भी नया नहीं है। और यहाँ मुख्य फाइल में नए कमांड हैं:

 include_directories(foo) 
main.cpp हमने नहीं बदला, लेकिन foo.h ने स्थानांतरित कर दिया। कमांड कंपाइलर को बताता है कि हेडर फ़ाइलों को कहां देखना है। इसे कई बार कहा जा सकता है। हेडर सभी निर्दिष्ट निर्देशिकाओं में खोजा जाएगा।

 add_subdirectory(foo) 
निर्देशिका को उपप्रोजेक्ट के साथ निर्दिष्ट करें, जिसे एक स्वतंत्र के रूप में इकट्ठा किया जाएगा।
निष्कर्ष: सीएमके पर परियोजनाओं को बल्कि जटिल पदानुक्रमित संरचनाओं में जोड़ा जा सकता है, और वास्तविकता में प्रत्येक उपप्रोजेक्ट एक स्वतंत्र परियोजना है, जो बदले में खुद उपप्रोजेक्ट शामिल कर सकती है। यह आपके प्रोग्राम को अलग-अलग मॉड्यूल की आवश्यक संख्या में विभाजित करना आसान बनाता है। इस दृष्टिकोण का एक उदाहरण केडीई है।

उदाहरण 4. पुस्तकालयों की खोज:


CMake ने स्थापित पुस्तकालयों की खोज के लिए काफी विकसित साधन बनाए हैं, हालांकि वे बिल्ट-इन नहीं हैं, लेकिन अलग मॉड्यूल के रूप में कार्यान्वित किए जाते हैं। मानक वितरण में काफी मॉड्यूल हैं, लेकिन कुछ परियोजनाएं (उदाहरण के लिए, ओग्रे) अपनी आपूर्ति करती हैं। वे सिस्टम को एक परियोजना को जोड़ने के लिए आवश्यक पुस्तकालयों की उपलब्धता का स्वचालित रूप से पता लगाने की अनुमति देते हैं।
डेबियन पर, मॉड्यूल /usr/share/cmake-2.8/Modules/ में स्थित हैं (आपका संस्करण भिन्न हो सकता है)। FindNAME.cmake नामक लाइब्रेरी लाइब्रेरी खोज के लिए ज़िम्मेदार है, जहाँ NAME लाइब्रेरी का नाम है।
 find_package(SDL REQUIRED) if(NOT SDL_FOUND) message(SEND_ERROR "Failed to find SDL") return() else() include_directories(${SDL_INCLUDE_DIR}) endif() ########################################################## find_package(LibXml2 REQUIRED) if(NOT LIBXML2_FOUND) message(SEND_ERROR "Failed to find LibXml2") return() else() include_directories(${LIBXML2_INCLUDE_DIR}) endif() ########################################################## find_package(Boost COMPONENTS thread-mt REQUIRED) if(NOT Boost_FOUND) message(SEND_ERROR "Failed to find boost::thread-mt.") return() else() include_directories(${Boost_INCLUDE_DIRS}) endif() ########################################################## target_link_libraries(${TARGET} ${SDL_LIBRARY} ${LIBXML2_LIBRARIES} ${Boost_LIBRARIES}) 

मुझे लगता है कि अर्थ स्पष्ट होना चाहिए। पहला और दूसरा ब्लॉक एक पुस्तकालय खोज है। यदि सिस्टम में एक नहीं है, तो एक त्रुटि संदेश प्रदर्शित होता है और cmake पूरा होता है। तीसरा ब्लॉक समान है, लेकिन यह पुस्तकालयों के पूरे पैकेज की तलाश नहीं है, लेकिन केवल आवश्यक घटक है। प्रत्येक ऐसी स्वचालित खोज कम से कम 3 चर के निष्पादन के बाद निर्धारित करती है:
SDL_FOUND, LIBXML2_FOUND, Boost_FOUND - एक पुस्तकालय की उपस्थिति का संकेत;
SDL_LIBRARY, LIBXML2_LIBRARIES, Boost_LIBRARIES - लिंक करने के लिए लाइब्रेरी नाम;
SDL_INCLUDE_DIR, LIBXML2_INCLUDE_DIR, Boost_INCLUDE_DIRS - हेडर फ़ाइलों के पथ।
यदि पूर्व अधिक या कम स्पष्ट है, तो उत्तरार्द्ध और तीसरे ने मुझे बहुत परेशानी दी है - आधे में एकवचन में नाम हैं, आधे में बहुवचन। लेकिन यह ट्रैक करना आसान हो गया। प्रत्येक मॉड्यूल में, शुरुआत में टिप्पणियां होती हैं, परिभाषित चर वहां वर्णित हैं। उदाहरण के लिए देखें /usr/share/cmake-2.8/Modules/FindLibXml2.cmake
जैसा कि आप देख सकते हैं, सीएमके आवश्यक पुस्तकालयों और हेडर फ़ाइलों की उपस्थिति और स्थान निर्धारित करने में सक्षम है। सिद्धांत रूप में, कोई भी स्वचालित विधानसभा प्रणाली ऐसा करने में सक्षम होना चाहिए, अन्यथा इसमें कोई बिंदु है?

उदाहरण 5. बाहरी लाइब्रेरी और ऑब्जेक्ट फ़ाइलें:


यदि आप "चाचा" के लिए लिखते हैं, और दुष्ट "चाचा" स्व-लिखित पुस्तकालयों से प्यार करता है और स्रोत कोड साझा नहीं करना चाहता है, इसलिए वह तैयार पुस्तकालय भेजता है, तो आप पते पर हैं।
सीएमके में ऑब्जेक्ट फाइलें स्रोत के बराबर हैं - बस संकलन के लिए फाइलों की सूची में ऑब्जेक्ट को शामिल करें।
पुस्तकालयों के साथ सख्त। जैसा कि आप जानते हैं, एक स्थैतिक पुस्तकालय एक आर्क-आर्काइव से ज्यादा कुछ नहीं है, जिसके अंदर साधारण वस्तुएं हैं जो किसी भी तरह से जुड़ी नहीं हैं। आपने शायद पहले ही अनुमान लगा लिया था कि मैंने पहले कैसे अभिनय किया। हां, मैंने सिर्फ पुस्तकालय को देखा। लेकिन तब एक और सुंदर तरीका पाया गया:
 add_library(netutil STATIC IMPORTED) set_property(TARGET netutil PROPERTY IMPORTED_LOCATION Binary/game_client/libnetutil.a) 

"आयातित" शब्द इंगित करता है कि पुस्तकालय बाहर से लिया गया है।
CMake में, प्रत्येक लक्ष्य में पैरामीटर हैं, और set_property आपको उन्हें बदलने की अनुमति देता है।
ऐसा पुस्तकालय मानक के रूप में जुड़ा हुआ है:
 target_link_libraries(${TARGET} netutil) 

गतिशील पुस्तकालयों के लिए, सब कुछ समान है, केवल प्रकार "साझा" है, विस्तार ".so" है।
दुर्भाग्य से, गैर-सिस्टम पुस्तकालयों के लिए समर्थन थोड़ा crutally कार्यान्वित किया जाता है। शायद मुझे सिर्फ सही विकल्प का पता नहीं है, इसलिए मुझे खुशी होगी अगर आप "थूथन को पोक करेंगे।" दूसरी ओर, यह जीवन समर्थन प्रणाली के साथ एक फैंसी एक्सोस्केलेटन नहीं है, बल्कि दो लाइनों का एक सरल बैसाखी है।

जनरेटर:


जैसा कि शुरुआत में कहा गया है, सीएमके कई अलग-अलग प्रकार की परियोजनाएं उत्पन्न कर सकता है। यह सुविधाजनक है और आपको लगभग किसी भी लोकप्रिय आईडीई के लिए सीएमके का उपयोग करने की अनुमति देता है।
यदि आप बिना मापदंडों के cmake चलाते हैं, तो उपलब्ध जनरेटर अंत में वर्णित होंगे। इस तरह का उपयोग करें:
fshp @ panica-desktop: ~ / tmp $ cmake ~ / cmake / example_3 / -G "KDevelop3 - Unix Makefiles"

निष्कर्ष:


यह मैनुअल का अनुवाद नहीं है, लेकिन एक व्यावसायिक परियोजना में सीएमके का उपयोग करने का परिणाम है। मुझे खुशी होगी अगर लेख कम से कम एक व्यक्ति की मदद करे - रूसी में इस तरह के प्रलेखन बहुत छोटा है।

मुझे व्यक्तिगत रूप से CMake पसंद है:

उदात्त पाठ के लिए, एक प्लगइन है जो CMake सिंटैक्स हाइलाइटिंग को जोड़ता है, इसे "CMake" कहा जाता है।
उदाहरण

Source: https://habr.com/ru/post/In155467/


All Articles