कोड को संकलित करने के लिए Makefile और CMake का उपयोग करने के बीच अंतर


288

मैं C / C ++ पर कोड करता हूं और कोड को संकलित करने के लिए (GNU) मेकफाइल का उपयोग करता हूं। मैं सीएमके के साथ एक ही कर सकता हूं और मेकफाइल प्राप्त कर सकता हूं। हालाँकि, कोड को संकलित करने के लिए Makefile और CMake का उपयोग करने में क्या अंतर है?


2
cmake निंजा का उपयोग करने के लिए फाइल भी बना सकता है
B canови

जवाबों:


403

बनाओ (या बल्कि Makefile) एक बिल्ड सिस्टम है - यह आपके कोड को बनाने के लिए कंपाइलर और अन्य बिल्ड टूल को ड्राइव करता है।

सीएमके बिल्डडिस्ट्स का एक जनरेटर है। यह मेकफाइल्स का उत्पादन कर सकता है, यह निंजा बिल्ड फ़ाइलों का उत्पादन कर सकता है, यह केडीविलेड या एक्सकोड परियोजनाओं का उत्पादन कर सकता है, यह विजुअल स्टूडियो समाधानों का उत्पादन कर सकता है। एक ही शुरुआती बिंदु से, एक ही CMakeLists.txt फ़ाइल। इसलिए यदि आपके पास एक प्लेटफ़ॉर्म-इंडिपेंडेंट प्रोजेक्ट है, तो सीमेक इसे बिल्ड-सिस्टम-इंडिपेंडेंट बनाने का एक तरीका है।

यदि आपके पास विज़ुअल स्टूडियो और यूनिक्स डेवलपर्स का उपयोग किया जाता है जो GNU मेक द्वारा कसम खाते हैं, तो सीएमके जाने का तरीका है।

यदि आप अपनी परियोजना को बहु-मंच या व्यापक रूप से उपयोग करने योग्य बनाने का इरादा रखते हैं, तो मैं हमेशा सीएमके (या किसी अन्य बिल्डसिस्टम जनरेटर का उपयोग करने की सलाह दूंगा, लेकिन सीएमके मेरी व्यक्तिगत प्राथमिकता है)। सीएमके खुद भी निर्भरता का पता लगाने, पुस्तकालय इंटरफ़ेस प्रबंधन, या CTest, CDash और CPack के साथ एकीकरण जैसी कुछ अच्छी सुविधाएँ प्रदान करता है।

एक बिल्डसिस्टम जनरेटर का उपयोग करना आपके प्रोजेक्ट को अधिक भविष्य का सबूत बनाता है। यहां तक ​​कि अगर आप केवल जीएनयू-मेक-अप कर रहे हैं, तो क्या होगा यदि आप बाद में अन्य प्लेटफार्मों (यह विंडोज या कुछ एम्बेडेड हो) का विस्तार करने का फैसला करते हैं, या सिर्फ एक आईडीई का उपयोग करना चाहते हैं?


5
@ आरिश हां, वह जिस्ट है। हालाँकि, नोट करें कि Makefiles की तुलना में लिनक्स पर प्रोग्राम करने के और भी तरीके हैं - उदाहरण के लिए QtCreator, KDEvelop, Ninja। इनमें से प्रत्येक के लिए, यह या तो "एक परियोजना बनाएं और इसे मेकफाइल के साथ सिंक में रखें," या "सीमेक को फिर से चलाएं।" और, जैसा कि उत्तर का उल्लेख है, सीएमके में अन्य कार्यक्षमता भी है, जैसे कि निर्भरता खोज (जैसे find_package()) या परीक्षण / पैकेजिंग समर्थन।
Angew को अब SO

3
मैंने पढ़ा कि CMake गैर-पुनरावर्ती मेकफाइल्स नहीं बना सकता। क्या यह अब भी सच है?
मैक्सिम इगोरुशिन

1
@Angew गैर-पुनरावर्ती वह है जब मेक को एक बार पूर्ण प्रोजेक्ट निर्भरता ट्री के साथ लागू किया जाता है। जब एक शीर्ष स्तर मेकफाइल कुछ क्रम में उप-प्रोजेक्ट मेकफाइल्स को आमंत्रित करता है, तो पुनरावर्ती के विपरीत ।
मैक्सिम इगोरुस्किन

3
यह CMake की एक महत्वपूर्ण कमजोरी है - GNU मेक की अपनी झुर्रियाँ हैं, लेकिन अगर आप इसे सीखने में समय लेते हैं, तो यह बेहद शक्तिशाली और बहुमुखी है, और भारी मात्रा में प्लेटफार्मों पर काम करता है। विश्लेषण के लिए पूरी तरह निर्भरता का पेड़ न होना एक बड़ा दोष है, बस 'पुनरावर्ती को हानिकारक माना जाता है'।
एरिक अलापा

1
@ ErikAlapää मैं लेख को विस्तार से पढ़ूंगा, लेकिन पहली नज़र से - वे पुनरावर्ती बनाने के बारे में बात कर रहे हैं जहां पुनरावृत्ति की गहराई डेटा-चालित है (यानी स्रोत निर्देशिका गहराई आदि पर निर्भर करता है)। सीएमके के साथ ऐसा नहीं है: प्रोजेक्ट संरचना की परवाह किए बिना, इनवोकेशन की कुल गहराई हमेशा 3 होती है। यह सिर्फ इतना है कि कुछ बिट्स को एक में सभी के बजाय एक सबमेकफाइल को सौंप दिया जाता है, लेकिन यह किसी भी तरह से प्रोजेक्ट संरचना को प्रतिबिंबित नहीं करता है । इसके अलावा, सबमेकफाइल्स वास्तव में "स्व-निहित" नहीं हैं, इसलिए वे निर्भरता समस्या से अधिक / पीड़ित नहीं हैं।
Angew को अब SO

39

सीएमके के "बिल्ड जनरेटर" के बारे में बयान एक आम गलत धारणा है।

यह तकनीकी रूप से गलत नहीं है; यह सिर्फ यह बताता है कि यह कैसे काम करता है, लेकिन यह क्या नहीं करता है।

प्रश्न के संदर्भ में, वे एक ही काम करते हैं: C / C ++ फ़ाइलों का एक गुच्छा लें और उन्हें बाइनरी में बदल दें।

तो, वास्तविक अंतर क्या है?

  • CMake बहुत अधिक उच्च-स्तरीय है। यह C ++ को संकलित करने के लिए तैयार है, जिसके लिए आप बहुत कम बिल्ड कोड लिखते हैं, लेकिन इसका उपयोग सामान्य उद्देश्य बिल्ड के लिए भी किया जा सकता है। makeकुछ अंतर्निहित C / C ++ नियम भी हैं, लेकिन वे ज्यादातर बेकार हैं।

  • CMakeएक दो कदम का निर्माण करता है: उस में एक निम्न स्तर के निर्माण स्क्रिप्ट उत्पन्न करता है ninjaया makeया कई अन्य जनरेटर, और फिर आप इसे चलाते हैं। सभी शेल स्क्रिप्ट के टुकड़े जो आम तौर पर ढेर होते Makefileहैं, उन्हें केवल पीढ़ी स्तर पर निष्पादित किया जाता है। इस प्रकार, CMakeबिल्ड तेजी के परिमाण के आदेश हो सकते हैं।

  • CMakeबाहरी उपकरण के लिए मेक की तुलना में समर्थन के लिए व्याकरण बहुत आसान है ।

  • एक बार makeएक कलाकृति बनाने के बाद, यह भूल जाता है कि इसे कैसे बनाया गया था। यह किन स्रोतों से बनाया गया था, कौन से कंपाइलर झंडे? CMakeइसे ट्रैक करता है, makeइसे आपके ऊपर छोड़ता है। यदि लाइब्रेरी स्रोत में से एक को पिछले संस्करण से हटा दिया गया था Makefile, makeतो इसे फिर से नहीं बनाया जाएगा।

  • आधुनिक CMake(संस्करण 3.something के साथ शुरू) "लक्ष्य" के बीच निर्भरता के संदर्भ में काम करता है। एक लक्ष्य अभी भी एक एकल ओटपुट फ़ाइल (दुख की बात है), लेकिन सकर्मक ("सार्वजनिक" / "इंटरफ़ेस" सीएमके शब्दों में) निर्भरता हो सकती है। ये सकर्मक निर्भरताएँ आश्रित पैकेजों से उजागर या छिपाई जा सकती हैं। CMakeआपके लिए निर्देशिकाओं का प्रबंधन भी करेगा। इसके साथ make, आप फ़ाइल-दर-फ़ाइल और प्रबंधन-निर्देशिका-दर-स्तर स्तर पर अटक जाते हैं।

आप makeअंतिम दो अंतराल को कवर करने के लिए ध्वज फ़ाइलों का उपयोग करने में कुछ कोड कर सकते हैं, लेकिन आप अपने दम पर हैं। makeइसमें ट्यूरिंग पूरी भाषा (यहां तक ​​कि दो, कभी-कभी तीन गिनने वाली गील ) होती है, और ये सभी भयानक हैं।

सच कहूं तो, यह वही है जो आम है CMakeऔर makeउनकी भाषाएं बहुत भयानक हैं:

  • उनके पास कोई प्रकार नहीं है;
  • कोई सरणियाँ, केवल अंतरिक्ष-अलग तार, इस प्रकार नरक से बच;
  • आप आमतौर पर वैश्विक चर सेट करके कार्यों के लिए तर्क देते हैं; (यह आधुनिक सीएमके में निपटाया जा रहा है - चर में अब एक नाम स्थान हो सकता है; एक लक्ष्य अपने नाम के लिए एक नाम स्थान है)
  • एक अपरिभाषित चर का जिक्र चुपचाप डिफ़ॉल्ट रूप से अनदेखा कर दिया जाता है;

साथ शुरू करने के लिए।

लेकिन CMakeआप कोड की बहुत कम पंक्तियाँ लिखते हैं।


1
यहाँ कुछ अच्छी जानकारी है, लेकिन एक टिप्पणी पूरी तरह से गलत है: cmake में एक LIST प्रकार होता है, जिसमें उचित LIST फ़ंक्शन होते हैं जो बहुत सारे बिल्ड-सिस्टम कार्यों के लिए महत्वपूर्ण होते हैं, थोड़ा अंतर: cmake.org/cmake/help/git-master/command /list.html
सॉल्यूशनJ

मैं इसे "पूरी तरह से" गलत नहीं कहूंगा, लेकिन सुधार के लिए धन्यवाद।
विक्टर सर्जियनको
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.