एक समाधान जिसे मैंने हाल ही में पाया है, मेकफ़ाइल रैपर के साथ आउट-ऑफ-सोर्स बिल्ड अवधारणा को गठबंधन करना है।
अपने शीर्ष स्तर CMakeLists.txt फ़ाइल में, मैं में स्रोत को रोकने के लिए निम्न शामिल हैं बनाता है:
if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt.")
endif()
फिर, मैं एक उच्च-स्तरीय Makefile बनाते हैं, और इस प्रकार हैं:
# -----------------------------------------------------------------------------
# CMake project wrapper Makefile ----------------------------------------------
# -----------------------------------------------------------------------------
SHELL := /bin/bash
RM := rm -rf
MKDIR := mkdir -p
all: ./build/Makefile
@ $(MAKE) -C build
./build/Makefile:
@ ($(MKDIR) build > /dev/null)
@ (cd build > /dev/null 2>&1 && cmake ..)
distclean:
@ ($(MKDIR) build > /dev/null)
@ (cd build > /dev/null 2>&1 && cmake .. > /dev/null 2>&1)
@- $(MAKE) --silent -C build clean || true
@- $(RM) ./build/Makefile
@- $(RM) ./build/src
@- $(RM) ./build/test
@- $(RM) ./build/CMake*
@- $(RM) ./build/cmake.*
@- $(RM) ./build/*.cmake
@- $(RM) ./build/*.txt
ifeq ($(findstring distclean,$(MAKECMDGOALS)),)
$(MAKECMDGOALS): ./build/Makefile
@ $(MAKE) -C build $(MAKECMDGOALS)
endif
डिफ़ॉल्ट लक्ष्य all
को make
टाइप करके बुलाया जाता है, और लक्ष्य ./build/Makefile
को आमंत्रित करता है।
पहली बात यह है लक्ष्य ./build/Makefile
करता है जो mkdir -p
के लिए एक चर रहा है build
निर्देशिका $(MKDIR)
का उपयोग कर, तैयार करना है। निर्देशिका build
वह जगह है जहां हम अपना आउट-ऑफ-सोर्स बिल्ड करेंगे। mkdir
यह सुनिश्चित करने के लिए हम -p
तर्क प्रदान करते हैं जो कि पहले से मौजूद निर्देशिका बनाने की कोशिश करने के लिए चिल्ला नहीं रहा है।
दूसरी बात लक्ष्य ./build/Makefile
निर्देशिका को build
निर्देशिका में बदलना है और cmake
को आमंत्रित करना है।
all
लक्ष्य पर वापस, हम $(MAKE) -C build
, जहां $(MAKE)
एक Makefile चर स्वचालित रूप से make
के लिए उत्पन्न है आह्वान। make -C
कुछ भी करने से पहले निर्देशिका को बदलता है। इसलिए, $(MAKE) -C build
का उपयोग cd build; make
करने के बराबर है।
संक्षेप में, के साथ make all
या make
कर के बराबर है इस Makefile आवरण बुला:
mkdir build
cd build
cmake ..
make
लक्ष्य distclean
invokes cmake ..
, तो make -C build clean
, और अंत में, build
निर्देशिका से सभी सामग्री को निकाल देता है। मेरा मानना है कि यह वही है जो आपने अपने प्रश्न में अनुरोध किया था।
मेकफ़ाइल का अंतिम भाग मूल्यांकन करता है कि उपयोगकर्ता द्वारा प्रदान किया गया लक्ष्य distclean
है या नहीं। यदि नहीं, तो यह इसे आमंत्रित करने से पहले निर्देशिका को build
में बदल देगा। यह बहुत शक्तिशाली है क्योंकि उपयोगकर्ता टाइप कर सकते हैं, उदाहरण के लिए, make clean
, और मेकफ़ाइल इसे cd build; make clean
के समतुल्य रूप में बदल देगा।
निष्कर्ष में, यह मेकफ़ाइल रैपर, अनिवार्य आउट-ऑफ-सोर्स बिल्ड सीएमके कॉन्फ़िगरेशन के साथ संयोजन में, इसे बनाता है ताकि उपयोगकर्ता को कभी भी cmake
कमांड से बातचीत नहीं करनी पड़े। यह समाधान build
निर्देशिका से सभी सीएमके आउटपुट फ़ाइलों को हटाने के लिए एक सुरुचिपूर्ण तरीका भी प्रदान करता है।
पीएस मेकफ़ाइल में, हम शेल कमांड से आउटपुट को दबाने के लिए उपसर्ग @
का उपयोग करते हैं, और शेल कमांड से त्रुटियों को अनदेखा करने के लिए उपसर्ग @-
का उपयोग करते हैं। लक्ष्य के हिस्से के रूप में rm
का उपयोग करते समय, यदि फ़ाइलें मौजूद नहीं हैं तो आदेश एक त्रुटि लौटाएगा (वे पहले से ही rm -rf build
के साथ कमांड लाइन का उपयोग कर हटा दिए गए हैं, या वे पहले स्थान पर कभी नहीं जेनरेट किए गए थे)। यह वापसी त्रुटि हमारे मेकफ़ाइल को बाहर निकलने के लिए मजबूर करेगी। हम इसे रोकने के लिए उपसर्ग @-
का उपयोग करते हैं। यह स्वीकार्य है कि फ़ाइल को पहले ही हटा दिया गया था; हम चाहते हैं कि हमारे मेकफ़ाइल को जारी रखें और बाकी को हटा दें।
ध्यान देने योग्य एक और बात: यदि आप अपनी परियोजना बनाने के लिए सीएमके चर के चर संख्या का उपयोग करते हैं, तो यह मेकफ़ाइल काम नहीं कर सकता है, उदाहरण के लिए, cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar"
। यह मेकफ़ाइल मानता है कि आप cmake ..
टाइप करके या cmake
को लगातार संख्या में तर्क (जिसे आप अपने मेकफ़ाइल में शामिल कर सकते हैं) प्रदान करके, सीएमके को लगातार तरीके से आमंत्रित करते हैं।
अंत में, क्रेडिट जहां क्रेडिट देय है। यह मेकफ़ाइल रैपर C++ Application Project Template द्वारा प्रदान की गई मेकफ़ाइल से अनुकूलित किया गया था।
यह उत्तर मूल रूप से here पोस्ट किया गया था। मैंने सोचा कि यह आपकी स्थिति पर भी लागू होता है।
मेरे पास आपके जैसा ही प्रोजेक्ट आर्किटेक्चर है। मेरा "निर्माण" डीआईआर हमेशा यहाँ है। मैं व्यक्तिगत रूप से यह कहता हूं कि टाइपिंग _cmake .._ इतना बड़ा सौदा नहीं है। – Offirmo