makefile ट्यूटोरियल
मेकफाइल के साथ शुरुआत करना
खोज…
टिप्पणियों
एक मेकफाइल एक पाठ फ़ाइल है जो make
प्रोग्राम के संचालन को नियंत्रित करती है। make
प्रोग्राम का उपयोग आम तौर पर उनके स्रोत फ़ाइलों से कार्यक्रमों के निर्माण का प्रबंधन करने के लिए किया जाता है, लेकिन इसका उपयोग आमतौर पर किसी भी प्रक्रिया को संभालने के लिए किया जा सकता है जहां फ़ाइलों (या लक्ष्य ) को अन्य फ़ाइलों (या पूर्वापेक्षाओं ) के बाद पुनर्जीवित करने की आवश्यकता होती है। मेकफाइल लक्ष्य और पूर्वापेक्षाओं के बीच संबंध का वर्णन करता है, और जब एक या अधिक आवश्यक शर्तें बदल गई हैं, तो लक्ष्य को अप-टू-डेट लाने के लिए आवश्यक आदेशों को भी निर्दिष्ट करता है। एक ही तरीका है कि make
को निर्धारित करता है "तिथि सत्ता से बाहर" लक्ष्य फ़ाइलों और उनके आवश्यक शर्तें के संशोधन समय की तुलना करके है।
Makefiles कुछ मायनों में कुछ अनोखे हैं जो शुरू में भ्रमित कर सकते हैं।
सबसे पहले, एक मेकफाइल में एक ही फाइल में दो पूरी तरह से अलग प्रोग्रामिंग भाषाएं होती हैं। फ़ाइल के थोक एक भाषा में लिखा गया है कि make
समझ सकते हैं: इस चर काम और विस्तार, कुछ पूर्वप्रक्रमक क्षमताओं (अन्य फ़ाइलें, फ़ाइल के वर्गों की सशर्त पार्स, आदि सहित) के साथ ही लक्ष्य की परिभाषा और प्रदान करता है उनके आवश्यक शर्तें। इसके अलावा, प्रत्येक लक्ष्य के साथ एक नुस्खा जुड़ा हो सकता है जो यह निर्दिष्ट करता है कि कौन से आदेशों को लागू किया जाना चाहिए ताकि लक्ष्य को अद्यतित किया जा सके। नुस्खा एक शेल स्क्रिप्ट के रूप में लिखा गया है (POSIX sh डिफ़ॉल्ट रूप से)। make
प्रोग्राम इस स्क्रिप्ट को पार्स नहीं करता है: यह एक शेल चलाता है और स्क्रिप्ट को रन करने के लिए पास करता है। तथ्य यह है कि व्यंजनों को make
द्वारा पार्स नहीं किया जाता है, बल्कि एक अलग शेल प्रक्रिया द्वारा नियंत्रित किया जाता है, यह मेकफाइल्स को समझने में केंद्रीय है।
दूसरा, एक मेकफाइल एक स्क्रिप्ट की तरह एक प्रक्रियात्मक भाषा नहीं है: जैसा make
मेसफाइल make
यह आंतरिक रूप से एक निर्देशित ग्राफ का निर्माण करता है जहां लक्ष्य ग्राफ के नोड होते हैं और पूर्वापेक्षा संबंध किनारों होते हैं। सभी मेकफाइल्स के पूरी तरह से पार्स हो जाने के बाद ही और ग्राफ पूरा make
एक नोड (लक्ष्य) चुनेंगे और इसे अप टू डेट लाने का प्रयास करेंगे। लक्ष्य सुनिश्चित करने के लिए, पहले यह सुनिश्चित करना चाहिए कि लक्ष्य के पूर्वापेक्षा में से प्रत्येक अद्यतित हो और इसी तरह पुनरावर्ती हो।
संस्करण
नाम | के रूप में भी जाना जाता है | प्रारंभिक संस्करण | संस्करण | रिलीज़ की तारीख |
---|---|---|---|---|
POSIX बनाते हैं | 1992 | IEEE Std 1003.1-2008, 2016 संस्करण | 2016/09/30 | |
NetBSD बनाते हैं | bmake | 1988 | 20160926 | 2016/09/26 |
जीएनयू बनाते हैं | gmake | 1988 | 4.2.1 | 2016/06/10 |
सनप्रो बनाते हैं | dmake | 2006 | 2015/07/13 | |
MSVS nmake | 2003 | 2015p3 | 2016/06/27 |
बेसिक मेकफाइल
एक "हैलो वर्ल्ड" लिखने पर विचार करें! सी में कार्यक्रम। कहते हैं कि हमारा स्रोत कोड source.c नामक एक फ़ाइल में है, अब हमारे प्रोग्राम को चलाने के लिए हमें इसे संकलित करने की आवश्यकता है, आमतौर पर लिनक्स पर (जीसीसी का उपयोग करके) हमें $> gcc source.c -o output
टाइप करने की आवश्यकता होगी जहां आउटपुट उत्पन्न होने वाले निष्पादन योग्य का नाम है। एक बुनियादी कार्यक्रम के लिए यह अच्छी तरह से काम करता है लेकिन जैसे-जैसे कार्यक्रम अधिक जटिल होते जाते हैं हमारी संकलन कमांड भी अधिक जटिल हो सकती है। यह वह जगह है जहां एक मेकफाइल आता है, मेकफाइल्स हमें नियमों के एक काफी जटिल सेट को लिखने की अनुमति देता है कि कैसे एक कार्यक्रम को संकलित करें और फिर इसे कमांड लाइन पर मेक टाइप करके संकलित करें। उदाहरण के लिए यहाँ एक संभावित उदाहरण है हेलो वेल्ड उदाहरण ऊपर।
बेसिक मेकफाइल
आओ हम एक मूल Makefile बनाते हैं और इसे हमारे सिस्टम में उसी निर्देशिका में सहेजते हैं जैसे हमारे स्रोत कोड को Makefile नाम दिया गया है । ध्यान दें कि इस फ़ाइल का नाम मेकफाइल होना चाहिए, हालांकि कैपिटल एम वैकल्पिक है। कहा कि कैपिटल एम का उपयोग करना अपेक्षाकृत मानक है।
output: source.c
gcc source.c -o output
ध्यान दें कि दूसरी पंक्ति पर gcc कमांड से पहले एक टैब है (यह मेकफाइल्स में महत्वपूर्ण है)। एक बार जब यह मेकफाइल हर बार लिखा जाता है तो उपयोगकर्ता प्रकार (मेकफाइल के समान निर्देशिका में) बनाते हैं, यह देखने के लिए जांच करेंगे कि क्या स्रोत.c को संशोधित किया गया है (समय टिकट की जांच करता है) यदि इसे आउटपुट से अधिक हाल ही में संशोधित किया गया है तो यह चलेगा निम्नलिखित पंक्ति पर संकलन नियम।
मेकफाइल्स में चर
परियोजना के आधार पर आप अपनी फ़ाइल में कुछ चर पेश कर सकते हैं। यहां एक उदाहरण मेकफाइल है जिसमें चर मौजूद हैं।
CFLAGS = -g -Wall
output: source.c
gcc $< $(CFLAGS) -o $@
अब यहां क्या हुआ आइए देखें। पहली पंक्ति में हमने सीएफएलएजीएस नामक एक चर घोषित किया जिसमें कई आम झंडे हैं जो आप संकलक को पास करना चाह सकते हैं, ध्यान दें कि आप इस चर में जितने झंडे गाड़ सकते हैं। फिर हमारे पास वही लाइन है जो पहले बताएं कि चेक सोर्स सी। सी। देखें कि क्या इसे आउटपुट की तुलना में हाल ही में बदल दिया गया है, यदि यह संकलन नियम चलाता है। हमारा संकलन नियम ज्यादातर पहले जैसा ही है लेकिन इसे चर का उपयोग करके छोटा कर दिया गया है, $<
चर को बनाया गया है (एक स्वचालित चर के रूप में संदर्भित https://www.gnu.org/software/make/manual/ html_node / Automatic-Variables.html ) और यह हमेशा स्रोत के लिए खड़ा होता है इसलिए इस मामले में source.c । $(CFLAGS)
हमारा वैरिएबल है जिसे हमने पहले परिभाषित किया था, लेकिन ध्यान दें कि हमें इस $(someVariable)
जैसे $ के साथ एक कोष्ठक में वैरिएबल $(someVariable)
। यह आपके द्वारा पहले टाइप किए गए चर का विस्तार करने के लिए मेक को बताने के लिए वाक्य रचना है। अंत में हमारे पास $ @ प्रतीक है, एक बार फिर यह एक वैरिएबल है जिसे मेक इन बनाया गया है, और यह बस संकलन कदम के लक्ष्य के लिए खड़ा है, इसलिए इस मामले में यह आउटपुट के लिए खड़ा है।
स्वच्छ
मेक क्लीन, फाइल बनाने के बारे में जानने के लिए एक और उपयोगी अवधारणा है। ऊपर से मेकफाइल को संशोधित करने देता है
CFLAGS = -g -Wall
TARGETS = output
output: source.c
gcc $< $(CFLAGS) -o $@
clean:
rm $(TARGETS)
जैसा कि आप देख सकते हैं कि हमने अपने Makefile में बस एक और नियम जोड़ा है, और एक अतिरिक्त चर जिसमें हमारे सभी लक्ष्य शामिल हैं। यह मेकफाइल्स में होने वाला एक सामान्य नियम है क्योंकि यह आपको केवल $> make clean
टाइप करके अपने द्वारा उत्पादित सभी बायनेरिज़ $> make clean
। मेक क्लीन लिखकर आप मेक प्रोग्राम को क्लीन रूल चलाने के लिए कहें और फिर अपने सभी टारगेट को डिलीट करने के लिए rm कमांड चलाएंगे।
मुझे उम्मीद है कि मेक का उपयोग करने का यह संक्षिप्त अवलोकन आपको अपने वर्कफ़्लो को गति देने में मदद करता है, मेकफाइल्स बहुत जटिल हो सकता है, लेकिन इन विचारों के साथ आपको मेक का उपयोग शुरू करने में सक्षम होना चाहिए और अन्य प्रोग्रामर मेकफाइल्स में क्या चल रहा है इसकी बेहतर समझ है। एक उत्कृष्ट संसाधन बनाने के बारे में अधिक जानकारी के लिए https://www.gnu.org/software/make/manual/ है ।
नियमों को परिभाषित करना
जल्दी शुरू
एक नियम बताता है कि कब और कैसे कुछ फाइलें (नियम के लक्ष्य ) बनाए जाते हैं। यह लक्ष्य फ़ाइल को अपडेट करने के लिए भी सेवा दे सकता है यदि इसके निर्माण के लिए आवश्यक फ़ाइलों में से कोई भी (लक्ष्य की आवश्यकताएं ) लक्ष्य से नई हैं।
नियम नीचे दिए गए सिंटैक्स का अनुसरण करते हैं: (ध्यान दें कि नियम का पालन करने वाले कमांड टैब द्वारा इंडेंट किए जाते हैं)
targets: prerequisites
<commands>
जहाँ लक्ष्य और पूर्वापेक्षाएँ फ़ाइल नाम या विशेष आरक्षित नाम और आदेश हैं (यदि मौजूद हैं) एक शेल द्वारा निष्पादित / लक्षित लक्ष्यों को बनाने या फिर से बनाने के लिए निष्पादित किए जाते हैं।
एक नियम को निष्पादित करने के लिए एक टर्मिनल में make
कमांड केवल उसी निर्देशिका से चला सकता है जहां मेकफाइल रहता है। रनिंग make
लक्ष्य निर्धारित किए बिना ही, पहला नियम Makefile में परिभाषित निष्पादित करेंगे। सम्मेलन द्वारा, मेकफाइल में पहले नियम को प्रायः सभी या डिफ़ॉल्ट कहा जाता है, आमतौर पर सभी वैध निर्माण लक्ष्यों को किसी और चीज के रूप में सूचीबद्ध किया जाता है।
make
अर्थ या तो यह मौजूद नहीं है या उसके संशोधन समय अपने आवश्यक शर्तें के किसी भी अधिक पुराना है केवल शासन को निष्पादित करता है, तो लक्ष्य आउट-ऑफ-तिथि है। यदि किसी और चीज की सूची खाली है, तो नियम को तभी क्रियान्वित किया जाएगा, जब लक्ष्य बनाने के लिए पहले आह्वान किया गया हो। हालाँकि, जब नियम फ़ाइल नहीं बनाता है और लक्ष्य एक डमी चर है, तो नियम हमेशा निष्पादित किया जाएगा।
पैटर्न नियम
कई नियमों को निर्दिष्ट करने और लक्ष्य नामों से पूर्वापेक्षित नामों के निर्माण के लिए पैटर्न नियमों का उपयोग किया जाता है। वे सामान्य नियमों की तुलना में अधिक सामान्य और अधिक शक्तिशाली होते हैं क्योंकि प्रत्येक लक्ष्य की अपनी पूर्वापेक्षाएँ हो सकती हैं। पैटर्न नियमों में, एक लक्ष्य और एक शर्त के बीच एक संबंध उपसर्गों के आधार पर निर्मित होता है जिसमें पथ नाम और प्रत्यय, या दोनों शामिल होते हैं।
कल्पना कीजिए कि हम क्रमशः C स्क्रिप्ट, foo.c
और bar.c
को संकलित करके foo.o
और bar.o
को लक्ष्य बनाना चाहते हैं। यह नीचे दिए गए सामान्य नियमों का उपयोग करके किया जा सकता है:
foo.o: foo.c
cc -c $< -o $@
bar.o: bar.c
cc -c $< -o $@
जहां स्वचालित चर $<
पहली शर्त का नाम है और $@
लक्ष्य का नाम है (स्वचालित चर की पूरी सूची यहां पाई जा सकती है )।
हालाँकि, जैसा कि लक्ष्य एक ही प्रत्यय साझा करते हैं, उपरोक्त दो नियम अब निम्नलिखित पैटर्न नियम द्वारा प्रतिस्थापित किए जा सकते हैं:
%.o: %.c
cc -c $< -o $@
निहित नियम
निहित नियम यह बताते make
कि कुछ प्रकार की लक्ष्य फ़ाइलों के निर्माण के लिए प्रथागत विधियों का उपयोग कैसे किया जाता है, जिनका उपयोग बहुत बार किया जाता है। make
निर्धारित करने के लिए कि किस अंतर्निहित नियम को लागू करने के लिए लक्ष्य फ़ाइल नाम का उपयोग करें।
पैटर्न नियम उदाहरण हम पिछले अनुभाग में देखा, वास्तव में एक Makefile में घोषित करने के रूप में की जरूरत नहीं है make
सी संकलन के लिए एक अंतर्निहित नियम है। इस प्रकार, निम्नलिखित नियम में, आवश्यक शर्तें foo.o
और bar.o
का निर्माण foo
संकलन से पहले C संकलन के लिए निहित नियम का उपयोग करके किया जाएगा।
foo : foo.o bar.o
cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
निहित नियमों और उनके द्वारा उपयोग किए गए चर की एक सूची यहां पाई जा सकती है ।
एक फ़ाइल को gzip करने के लिए सामान्य नियम
यदि किसी निर्देशिका में 2 फाइलें हैं:
$ ls
makefile
example.txt
और makefile
में निम्न पाठ होता है
%.gz: %
gzip $<
तो आप शेल में टाइप करके example.txt.gz
प्राप्त कर सकते हैं
$ make -f makefile example.txt.gz
मेकफाइल में केवल एक नियम होता है, जो निर्देश देता है कि एक फ़ाइल कैसे बनाई जाए जिसका नाम .gz के साथ समाप्त होता है अगर एक ही नाम वाली फ़ाइल है लेकिन .gz प्रत्यय है।
makefile हैलो वर्ल्ड
C: \ makefile:
helloWorld :
[TAB]echo hello world
परिणाम चलाएँ:
C:\>make
echo hello world
hello world
नोट: [TAB] को वास्तविक टैब द्वारा प्रतिस्थापित किया जाना चाहिए, स्टैकओवरफ़्लो टैब को रिक्त स्थान के साथ बदल देता है, और रिक्त स्थान का उपयोग मेकफाइल में टैब के समान नहीं किया जाता है।