2011-12-21 11 views
9

मेरे पास एक बड़ा-आश कोडबेस है जो कई दर्जन मुक्ति और कई निष्पादन योग्य बनाता है।सीएमके "प्रोजेक्ट" निर्देश का उचित उपयोग क्या है

कोडबेस को पदानुक्रमित रूप से तोड़ दिया गया है और पुस्तकालयों को हर स्तर पर काफी अधिक बनाया गया है।

मैं प्रत्येक लाइब्रेरी बनाने के लिए प्रत्येक निर्देशिका में एक CMakeLists.txt फ़ाइल चला गया है और रखा है।

प्रत्येक CMakeLists.txt में मैंने "प्रोजेक्ट (xxx)" निर्देश का उपयोग किया है। इसने मुझे PROJECT_NAME, PROJECT_SOURCE_DIR और PROJECT_BINARY_DIR वेरिएबल्स के लिए परिभाषित किया है जिन्हें मैं न्यायसंगत उपयोग करता हूं।

हालांकि, टीम में से एक इस दृष्टिकोण से नाखुश है क्योंकि उसे ऐसा करने वाले किसी और के असली दुनिया के उदाहरण नहीं मिल रहे हैं। वह अक्सर इस दृष्टिकोण का उपयोग न करने के रूप में किटवेयर उदाहरणों का हवाला देते हैं और इसलिए हमें भी नहीं चाहिए।

वैकल्पिक दृष्टिकोण वह वकालत कर रहा है जो प्रत्येक मेकफ़ाइल में इन चर को सेट करना है जो "प्रोजेक्ट" आपको पसंद करता है।

मैं वास्तव में उसका मुद्दा नहीं देख सकता और अन्यथा उसे विश्वास दिलाने में थोड़ा रास्ता बना रहा हूं। क्या कोई इस तरह से परियोजना निर्देश का उपयोग करने के डाउनसाइड्स पर कोई प्रकाश डाल सकता है।

मैं अपने सामूहिक ज्ञान पर खुद को फेंक देता हूं?

+0

आप 'PROJECT_NAME',' PROJECT_SOURCE_DIR' और 'PROJECT_BINARY_DIR' चर का उपयोग कैसे करते हैं? और क्या ये पुस्तकालय स्वतंत्र हैं या वे मुख्य पुस्तकालय/आवेदन के कुछ हिस्सों हैं? –

+0

मै मैक्रोज़ के अंदर इन चर का उपयोग करता हूं जो स्रोत कोड उत्पन्न करता है। मैं $ {PROJECT_NAME} _SPDEF नामक एक शीर्ष स्तरीय लक्ष्य बनाता हूं जो अन्य परियोजनाएं इनकी पीढ़ी के बल पर निर्भर करती हैं। मैं जेनरेट कोड को उचित स्थान पर रखने के लिए _DIR चर का भी उपयोग करता हूं। – ScaryAardvark

उत्तर

12

सबसे पहले, यह आपको <projectName>_BINARY_DIR और <projectName>_SOURCE_DIR का उपयोग करने में सक्षम बनाता है, लेकिन यह मुख्य लाभ नहीं है। यदि आप सीएमके को एक परियोजना का नाम देते हैं तो यह प्रत्येक उप-परियोजनाओं के लिए अपनी निर्देशिका में निर्माण लक्ष्य उत्पन्न करेगा। इसका मतलब यह है कि क्या आप जीएनयू मेक, ग्रहण सीडीटी, एक्सकोड, या अन्य समर्थित जेनरेटर का उपयोग कर रहे हैं, आप अलग-अलग उप-परियोजनाओं का निर्माण कर सकते हैं। उदाहरण के लिए जीएनयू के साथ प्रत्येक उप-प्रोजेक्ट की अपनी खुद की निर्देशिका से अपनी पूर्ण बिल्ड सिस्टम बनाएं।

आप PROJECT_NAME के माध्यम से वर्तमान प्रोजेक्ट नाम तक पहुंच सकते हैं, और रूट प्रोजेक्ट का नाम CMAKE_PROJECT_NAME द्वारा कर सकते हैं।

संपादित करें: मुझे अभी पता चला है कि नीचे दिए गए किसी भी निर्माण लक्ष्य के लिए मानक सीएमके व्यवहार होगा चाहे वे परियोजनाएं हों या नहीं। मैं इसे सामान्य जानकारी के लिए यहां रखूंगा लेकिन यह उत्तर के लिए प्रासंगिक नहीं है:

मान लें कि मेरे पास सी ++ लाइब्रेरी है, और मैं तीन बाइनरी निष्पादन योग्य उत्पन्न कर सकता हूं; Main और tests/test1, और examples/ex1। मैं या तो निर्देशिका में बना सकता हूं जिसे मैंने सीएमके को सभी लक्ष्यों से बुलाया है, make ex1 चलाएं, या मैं निर्देशिका को examples/ पर बदल सकता हूं और उस निर्देशिका से make के साथ उदाहरण बना सकता हूं। यह सभी निर्भर परियोजनाओं और पुस्तकालयों का निर्माण करेगा, भले ही वे निर्देशिका संरचना में कहीं और हों लेकिन Main या tests/test1 या किसी भी पुस्तकालय जो examples/ex1 पर निर्भर नहीं हैं, निर्माण नहीं करेंगे। यदि मैं फिर मुख्य निर्देशिका से चलाता हूं, तो यह किसी भी पुस्तकालय का पुनर्निर्माण नहीं करेगा जो examples/ex1 तब तक निर्भर करता है जब तक उनका स्रोत बदल नहीं जाता है।

+1

बिल्ड पदानुक्रम के किसी भी स्तर पर "सीडी" करने में सक्षम होने की क्षमता और "सब कुछ करें" और इस स्तर से सभी कलाकृतियों का निर्माण मेरे लिए एक बड़ी जीत है। धन्यवाद। – ScaryAardvark

+0

@ScaryAardvark विभिन्न कंप्यूटर्स के लिए अलग-अलग कमांड चलाने की क्षमता और अलग-अलग ऑपरेटिंग सिस्टम के साथ अलग-अलग कोड शामिल करना वास्तव में अच्छा है, साथ ही कोड की कुछ पंक्तियों के साथ काफी उन्नत संचालन करना बहुत आसान है। मैं सीएमके के साथ 'ज़िप' के साथ संपत्तियों को संपीड़ित करता हूं, जो कि किसी भी मंच/आईडीई/टूलचेन पर ठीक काम करता है। यह एआरएम आदि के लिए क्रॉस-कंपाइल करना भी बहुत आसान बनाता है। आपको सीएमके के टेस्ट सिस्टम में निर्मित, [सीटीएस्ट] (http://www.vtk.org/Wiki/CMake_Testing_With_CTest) भी देखना चाहिए। जेनकींस जैसे सीआई सिस्टम के लिए सीएमके प्लगइन्स भी हैं। –

+0

हां, मैं इससे परिचित हूं। एक सवाल यह था कि सेमेक एक ही कंपाइलर के विभिन्न संस्करण को कैसे संभालता है ... यानी हमारे पास हमारे प्रोजेक्ट ट्री का एक सेक्शन है जिसे केवल सनस्टूडियो 11 के तहत संकलित किया जा सकता है और इसमें से अधिकांश को सनस्टूडियो 12 की आवश्यकता होती है। मुझे लगता है कि मैं इसके बारे में एक और सवाल उठाऊंगा, लेकिन धन्यवाद :) – ScaryAardvark

0

यदि पुस्तकालय वास्तव में स्वतंत्र परियोजनाएं हैं तो project कमांड का उपयोग करना समझ में आता है। हालांकि अगर वे नहीं हैं तो मैं उन्हें अपनी रूट CmakeLists.txt में उपनिर्देशिका के रूप में जोड़ दूंगा। यदि आप वर्तमान में संसाधित होने वाली निर्देशिकाओं को जानना चाहते हैं तो आप चर CMAKE_CURRENT_SOURCE_DIR और CMAKE_CURRENT_BINARY_DIR चर का उपयोग कर सकते हैं।

+0

क्या कोई CMAKE_CURRENT_PROJECT है। यदि वहां है तो मैं आपका बिंदु देख सकता हूं, हालांकि अगर मुझे इस चर (या कुछ समान) बनाने के लिए सेट() का उपयोग करना है तो फिर "प्रोजेक्ट" का उपयोग क्यों न करें और मेरे लिए बनाए गए सभी चर हैं। – ScaryAardvark

0

मुझे आज इस तरह का एक अच्छा उपयोग उदाहरण मिला: डॉक्सिजन दस्तावेज जोड़ना।

मैं अपनी व्यक्तिगत सी ++ परियोजनाओं का निर्माण करने के लिए सीएमके (और निंजा) का उपयोग करता हूं। मैंने अपने बहुत सारे पूर्ण लेकिन अनियंत्रित प्रयासों में से एक को कुछ डॉक्सीजन दस्तावेज जोड़ने की इच्छा पर फैसला किया। मैंने यह भी सोचा कि इसे अन्य परियोजनाओं में जोड़ने के लिए भी साफ होगा, जैसे ही मैं इसे यथासंभव सामान्य बनाने के लिए काम करता हूं।

आरंभ करने के लिए, मैंने एक मानक डॉक्सीजन टेम्पलेट जेनरेट किया और इसका नाम बदल दिया।

cd my_projects/projectx 
doxygen -g Doxyfile 
mv Doxyfile Doxyfile.in 

.in एक्सटेंशन पर ध्यान दें। शायद मैं जरूरी नहीं लेकिन परंपरागत, अगर मैं सही ढंग से समझता हूं।

अगला, मैंने अपने लक्ष्य को परिभाषित करने से ठीक पहले, मेरे CMakeLists.txt फ़ाइल में निम्न कोड ब्लॉक जोड़ा (सुनिश्चित नहीं है कि यह महत्वपूर्ण है लेकिन सीएमके कभी-कभी कुछ आदेशों के अनुक्रम के बारे में चिंतित होता है)।

FIND_PACKAGE(Doxygen) 
IF("${DOXYGEN_FOUND}" MATCHES "^YES$") 
    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 
        ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
        @ONLY) 
    ADD_CUSTOM_TARGET( doc ALL 
         COMMAND ${DOXYGEN_EXECUTABLE} 
         ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
         WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 
         COMMENT "Doxygenating..." 
         VERBATIM) 
ENDIF() 

यह दस्तावेज़ नामक एक नया लक्ष्य बनाता है। सभी निर्दिष्ट करना इसे डिफ़ॉल्ट "सभी" लक्ष्य में जोड़ता है, लेकिन यह वैकल्पिक है। @ONLY निर्दिष्ट करना सुनिश्चित करता है कि किसी भी "$ {variable}" प्रकार चर को CONFIGURE_FILE द्वारा विस्तारित नहीं किया जाएगा, केवल "@ चर @ @ प्रकार। कुछ हद तक भ्रमित (कम से कम मेरे लिए), CMAKE_CURRENT_SOURCE_DIR प्रोजेक्ट निर्देशिका और CMAKE_CURRENT_BINARY_DIR को बिल्ड निर्देशिका में संदर्भित करता है।

अंत में, और यह वह जगह है जहां PROJECT_NAME et al आते हैं, मैंने Doxyfile.in संपादित किया।

यह मेरा नया Doxyfile.in की शुरुआत है:

DOXYFILE_ENCODING  = UTF-8 
PROJECT_NAME   = "@[email protected]" 
PROJECT_NUMBER   = @[email protected] 
PROJECT_BRIEF   = 
PROJECT_LOGO   = @[email protected]/res/doc_logo-200x55.png 
OUTPUT_DIRECTORY  = @[email protected]/doc 

आप अंदाजा हो, मुझे लगता है। एक बार यह पूरी तरह से जेनेरिक हो जाता है (क्या यह एक शब्द है?) मैं इसे अपनी अन्य परियोजनाओं में कॉपी कर सकता हूं और जब तक मैं अपना कोड टैग करता हूं, तब तक मेरे पास हर जगह अच्छा दस्तावेज होगा।

नोटिस PROJECT_BRIEF निर्दिष्ट नहीं है। मैंने इसके साथ समाप्त नहीं किया है और मेरे बारे में सोचने के लिए अभी भी कुछ रिक्त स्थान हैं। उदाहरण के लिए PROJECT_VERSION_TWEAK में वास्तव में कुछ भी शामिल नहीं है। मुझे वहां अपना निर्माण नंबर प्राप्त करने का एक तरीका खोजना होगा।

संबंधित मुद्दे