makepp_cookbook - क्लाउड में ऑनलाइन

यह कमांड मेकप_कुकबुक है जिसे हमारे कई मुफ्त ऑनलाइन वर्कस्टेशन जैसे कि उबंटू ऑनलाइन, फेडोरा ऑनलाइन, विंडोज ऑनलाइन एमुलेटर या मैक ओएस ऑनलाइन एमुलेटर का उपयोग करके ऑनवर्क्स फ्री होस्टिंग प्रदाता में चलाया जा सकता है।

कार्यक्रम:

नाम


मेकप_कुकबुक - विभिन्न स्थितियों के लिए मेकफाइल्स सेट करने का सबसे अच्छा तरीका

वर्णन


मैंने पाया कि व्यावहारिक रूप से कोई भी मेक टूल के लिए मैनुअल नहीं पढ़ता है, क्योंकि स्पष्ट रूप से
वास्तव में निर्माण प्रक्रिया में किसी की रुचि नहीं है--हम केवल परिणामों में रुचि रखते हैं।
इसलिए इस रसोई की किताब को इस उम्मीद में एक साथ रखा गया था कि लोगों को उनकी ज़रूरत की चीज़ें मिल सकेंगी
मैनुअल को पढ़े बिना उदाहरणों से शीघ्रता से। यह दिखाता है कि कैसे टाइप करना है
प्रश्न, जबकि इंस्टॉलेशन निर्देश और बाधाएँ इसमें मिलेंगी
अक्सर पूछे जाने वाले प्रश्न।

इमारत पुस्तकालयों
Do इसलिए आप वास्तव में आवश्यकता a पुस्तकालय?

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

कई मामलों में, मुझे लगता है कि लाइब्रेरी का उपयोग करने के बजाय, एक बेहतर तरीका है। पुस्तकालय
यदि प्रत्येक मॉड्यूल का किसी अन्य में पुन: उपयोग नहीं किया जा सकता है या नहीं किया जाएगा तो ये वास्तव में सही समाधान नहीं हैं
कार्यक्रम, क्योंकि तब आपको पुस्तकालयों की सभी कमियाँ मिलेंगी और कुछ भी नहीं
फायदे. पुस्तकालय निम्नलिखित मामलों में उपयोगी हैं:

1. जब आपके पास सबरूटीन्स का एक समूह होता है जिसे कई अलग-अलग लोगों के साथ जोड़ा जाना होता है
प्रोग्राम, और कोई भी प्रोग्राम वास्तव में 100% सबरूटीन्स का उपयोग नहीं करता है - प्रत्येक प्रोग्राम एक का उपयोग करता है
भिन्न उपसमुच्चय. इस मामले में, संभवतः स्थैतिक लाइब्रेरी (ए) का उपयोग करना एक अच्छा विचार है
.a फ़ाइल, या एक संग्रह फ़ाइल)।

2. जब आपके पास एक मॉड्यूल हो जिसे कई अलग-अलग प्रोग्रामों से जोड़ा जाना चाहिए, और आप
इसे गतिशील रूप से लोड करना चाहते हैं ताकि प्रत्येक प्रोग्राम की एक अलग प्रतिलिपि न हो
पुस्तकालय। गतिशील लाइब्रेरीज़ निष्पादन योग्य फ़ाइल स्थान को बचा सकती हैं और कभी-कभी बढ़ा सकती हैं
सिस्टम प्रदर्शन क्योंकि सभी के लिए लाइब्रेरी की केवल एक प्रति लोड की गई है
विभिन्न प्रोग्राम जो इसका उपयोग करते हैं।

3. जब आपका लिंक समय अत्यधिक लंबा हो, तो बड़े टुकड़ों के लिए साझा लाइब्रेरी का उपयोग करें
प्रोग्राम लिंक को काफी तेज़ कर सकता है।

स्थैतिक पुस्तकालयों का उपयोग करने का एक मुख्य नुकसान है: कुछ प्रणालियों (उदाहरण के लिए लिनक्स) पर, ऑर्डर
जिसमें आप पुस्तकालयों को जोड़ते हैं वह अत्यंत महत्वपूर्ण है। लिंकर पुस्तकालयों को संसाधित करता है
इसकी कमांड लाइन पर निर्दिष्ट क्रम में। यह वह सब कुछ ले लेता है जिसकी उसे आवश्यकता होती है
प्रत्येक पुस्तकालय, फिर अगले पुस्तकालय की ओर बढ़ता है। यदि कोई अनुवर्ती लाइब्रेरी a को संदर्भित करती है
प्रतीक जिसे अभी तक पिछली लाइब्रेरी से शामिल नहीं किया गया है, लिंकर नहीं करता है
वापस जाना और पिछली लाइब्रेरी से इसे प्राप्त करना जानते हैं। परिणामस्वरूप, यह आवश्यक हो सकता है
लिंकर कमांड लाइन पर लाइब्रेरी को कई बार सूचीबद्ध करने के लिए। (मैंने एक प्रोजेक्ट पर काम किया
जहाँ हमें पुस्तकालयों की पूरी सूची तीन बार दोहरानी पड़ी। यह प्रोजेक्ट वही बना है
मैं नीचे सुझाए गए वैकल्पिक दृष्टिकोण, वृद्धिशील लिंकिंग को प्राथमिकता देता हूं।)

गतिशील पुस्तकालयों का उपयोग करने के कई नुकसान हैं। सबसे पहले, आपका प्रोग्राम थोड़ा सा हो सकता है
यदि लाइब्रेरी का उपयोग पहले से ही किसी अन्य प्रोग्राम द्वारा नहीं किया जा रहा है, तो प्रारंभ करने में धीमी गति होगी, क्योंकि
इसे ढूंढना और लोड करना होगा। दूसरा, सारी गतिशीलता प्राप्त करना एक वास्तविक परेशानी हो सकती है
सही स्थानों पर स्थापित पुस्तकालय; आप केवल निष्पादनयोग्य प्रोग्राम की प्रतिलिपि नहीं बना सकते,
आपको यह भी सुनिश्चित करना होगा कि आप इसकी सभी लाइब्रेरी की प्रतिलिपि बनाएँ। तीसरा, कुछ प्रणालियों पर, यह
साझा लाइब्रेरीज़ के अंदर कोड को डीबग करना कठिन है क्योंकि डीबगर्स समर्थन नहीं करते हैं
वो अच्छा।

यदि आपका मॉड्यूल कभी भी किसी अन्य प्रोग्राम में उपयोग नहीं किया जाएगा, तो उपयोग करने का कोई कारण नहीं है
एक पुस्तकालय: आपको पुस्तकालयों का उपयोग करने के सभी नुकसान मिलते हैं और कोई लाभ नहीं।
मेरी पसंद की तकनीक वृद्धिशील लिंकिंग का उपयोग करना है, जहां यह उपलब्ध है।

यहां बताया गया है कि आप लिनक्स पर यह कैसे कर सकते हैं:

my_module.o : $(filter_out my_module.o, $(वाइल्डकार्ड *.o))
एलडी -आर -ओ $(आउटपुट) $(इनपुट)

यह जो करेगा वह दूसरा बनाना है .o फ़ाइल कहा जाता है my_module.o, जिसमें शामिल होंगे
के सभी .o इस उपनिर्देशिका में फ़ाइलें। लिंकर इनमें से कई का समाधान करेगा
जितना संभव हो उतना संदर्भ दें, और शेष संदर्भों को हल करने के लिए छोड़ देंगे
लिंक करने का अगला चरण. शीर्ष स्तर पर, जब आप अंततः अपना प्रोग्राम बनाते हैं,
के साथ जोड़ने के बजाय libmy_module.a or libmy_module.so, आप बस इसके साथ लिंक करेंगे
my_module.o. जब आप लिंक करते हैं .o फ़ाइलें, आपको ऑर्डर-निर्भरता की समस्या नहीं है
लिंकर कमांड लाइन।

दे मेकप्प आंकड़ा आउट कौन कौन से पुस्तकालय मॉड्यूल रहे जरूरत

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

यदि आपकी लाइब्रेरी उस परिपाटी का कड़ाई से पालन करती है जिसमें सभी फ़ंक्शन या कक्षाएं घोषित की जाती हैं
एक पंक्ति xyz.h संकलित स्रोत फ़ाइल में पूरी तरह से कार्यान्वित किया जाता है xyz.o (अर्थात, आप
कार्यान्वयन को विभाजित न करें xyz1.o और xyz2.o), तो आप इसका उपयोग कर सकते हैं
"$(infer_objects)" फ़ंक्शन मेकप को केवल प्रासंगिक मॉड्यूल को बाहर निकालने के लिए कहता है
पुस्तकालय। यह दर्जनों सम्मिलित फ़ाइलों वाले पुस्तकालयों के लिए भी आश्चर्यजनक रूप से अच्छा काम कर सकता है।
मूल रूप से, "$(infer_objects)" की सूची की जांच करता है .h फ़ाइलें जो शामिल हैं, और दिखती हैं
संगत के लिए .o फ़ाइलें. यदि आप तेजी से एक पुस्तकालय और एक कार्यक्रम विकसित कर रहे हैं
साथ में, यह संकलन समय बचा सकता है, क्योंकि आप कभी भी मॉड्यूल संकलित करने की जहमत नहीं उठाते
वह लाइब्रेरी जिसका प्रोग्राम उपयोग नहीं करता है.

मैं इसका उपयोग कैसे करता हूं इसका एक उदाहरण यहां दिया गया है:

मेरा_प्रोग्राम: $(infer_objects *.o, $(LIB1)/*.o $(LIB2)/*.o)
$(CXX) $(इनपुट) -o $(आउटपुट) $(SYSTEM_LIBRARIES)

"$(infer_objects )" फ़ंक्शन अपना पहला तर्क देता है (वाइल्डकार्ड करने के बाद)।
इस पर विस्तार), और इसके दूसरे तर्क में फ़ाइलों की सूची को भी देखता है
फ़ाइलें जिनका नाम किसी के नाम के समान है .h किसी भी फ़ाइल द्वारा उसके पहले में शामिल फ़ाइलें
तर्क। यदि ऐसी कोई फ़ाइलें पाई जाती हैं, तो इन्हें सूची में जोड़ दिया जाता है।

इमारत a स्थिर पुस्तकालय

यदि आप आश्वस्त हैं कि आपको वास्तव में एक लाइब्रेरी की आवश्यकता है और वृद्धिशील लिंकिंग उपलब्ध नहीं है या
यह वह नहीं है जो आप करना चाहते हैं, इसे करने के कुछ तरीके हैं। सबसे पहले, यहाँ एक उदाहरण है
जहां सभी फ़ाइलें स्पष्ट रूप से सूचीबद्ध हैं:

LIBRARY_FILES = abcde

libmin.a: $(LIBRARY_FILES).o
और आरएम-एफ $ (आउटपुट)
$(AR) करोड़ $(आउटपुट) $(इनपुट)
ranlib $(आउटपुट) # आपके ओएस के आधार पर आवश्यक नहीं हो सकता है।

&rm मेकप का अंतर्निहित "आरएम" कमांड है। यदि आप मेकफ़ाइल्स लिखने के आदी हैं, तो हो सकता है
इस आदेश से थोड़ा आश्चर्य हुआ; आपको इस तरह की और किसी चीज़ की आदत हो सकती है:

libmin.a: $(LIBRARY_FILES).o
$(AR) ru $@ $? # सिफारिश नहीं की गई!!!!!!!
रैनलिब $(आउटपुट)

कहाँ $? (जिसे "$(changed_inputs)" के नाम से भी जाना जाता है) एक स्वचालित वैरिएबल है जिसका अर्थ किसी भी फाइल से है
जो पिछली बार लाइब्रेरी के निर्माण के बाद से बदल गया है, और $@ लगभग वही है
"$(आउटपुट)" के रूप में।

यह दृष्टिकोण कई कारणों से अनुशंसित नहीं है:

· मान लीजिए कि आप वर्तमान निर्देशिका से एक स्रोत फ़ाइल हटाते हैं। यह अभी भी अंदर है
लाइब्रेरी, क्योंकि आपने लाइब्रेरी को शुरू से दोबारा नहीं बनाया है। परिणामस्वरूप, कुछ भी
इस लाइब्रेरी से जुड़े लिंक पुराने हो जाएंगे .o फ़ाइल, और वह आपकी गड़बड़ कर सकती है
बनाता है. (जब मैं डेड कोड हटाने का प्रयास कर रहा था तो एक बार मैं इससे पूरी तरह भ्रमित हो गया था
एक प्रोजेक्ट से: मैं फ़ाइलें हटाता रहा और यह अभी भी लिंक थी, इसलिए मैंने सोचा कि कोड था
मृत। हालाँकि, जब किसी और ने प्रोजेक्ट को नए सिरे से बनाया, तो उसने कोई भी लिंक नहीं किया
अधिक! समस्या यह थी कि पुराना .o फ़ाइलें अभी भी संग्रह में थीं।)

इसके अलावा, "ar" के आपके विकल्पों और "ar" के आपके कार्यान्वयन पर निर्भर करता है (उदाहरण के लिए, यदि आप
"आर" के बजाय "क्यू" विकल्प का उपयोग करें, आपके पास इसके कई संस्करण हो सकते हैं
वही .o अंदर .a फ़ाइल। यदि अलग-अलग संस्करण अलग-अलग ग्लोबल्स को परिभाषित करते हैं, तो
लिंकर उन दोनों को खींचने का प्रयास कर सकता है। यह शायद एक बुरी बात है.

यही कारण है कि हम पहले लाइब्रेरी फ़ाइल को हटाते हैं, और इसे स्क्रैच से बनाते हैं। यह करेगा
किसी लाइब्रेरी में मॉड्यूल अपडेट करने में थोड़ा अधिक समय लगता है, लेकिन अधिक नहीं; पर
एक आधुनिक कंप्यूटर, इसमें लगने वाले समय की मात्रा ar कार्यक्रम तुलना में बहुत छोटा है
सी कंपाइलर एक सामान्य बिल्ड में क्या लेता है, इसलिए यह चिंता करने लायक नहीं है
के बारे में।

· मेकप जिन तरीकों से सही निर्माण की गारंटी देने का प्रयास करता है उनमें से एक यह है कि वह ऐसा करेगा
यदि किसी दिए गए लक्ष्य को बनाने की कमांड लाइन बदल गई है तो स्वचालित रूप से पुनर्निर्माण करें। लेकिन
$ का उपयोग कर रहे हैं? वैरिएबल समस्याएँ पैदा कर सकता है, क्योंकि हर बार लाइब्रेरी को अपडेट किया जाता है,
बिल्ड कमांड अलग है. (आप इसका उपयोग करके इसे दबा सकते हैं
":बिल्ड_चेक इग्नोर_एक्शन"; विवरण के लिए makepp_build_check देखें।)

· संग्रह को दोबारा बनाने के बजाय उसे अद्यतन करने से मेकप के लिए इसे असंभव बना दिया जाएगा
फ़ाइल को बिल्ड कैश में ठीक से डालें (विवरण के लिए makepp_build_cache देखें)।

कभी-कभी आपको लग सकता है कि सभी फाइलों को सूचीबद्ध करना थोड़ा कष्टकारी है, खासकर यदि
परियोजना तेजी से विकास के दौर से गुजर रही है और फाइलों की सूची लगातार बदल रही है। यह
वाइल्डकार्ड का उपयोग करके लाइब्रेरी बनाना आसान हो सकता है, जैसे:

libmin.a: $(only_targets *.o)
&rm $(आउटपुट)
$(AR) करोड़ $(आउटपुट) $(इनपुट)

यह सब डालता है .o वर्तमान निर्देशिका की फ़ाइलें लाइब्रेरी में। वाइल्डकार्ड
किसी से मेल खाता है .o फ़ाइल मौजूद है या बनाई जा सकती है, इसलिए फ़ाइलें न होने पर भी यह काम करेगी
अभी भी मौजूद है.

"only_targets" फ़ंक्शन का उपयोग बहिष्कृत करने के लिए किया जाता है .o ऐसी फ़ाइलें जिनमें संगतता नहीं है
स्रोत फ़ाइलें अब और नहीं। मान लीजिए कि आपके पास एक फ़ाइल बुलाई गई है xyz.c जो आप अपने में डालते थे
पुस्तकालय। इसका मतलब यह है कि वहाँ एक है xyz.o फ़ाइल इधर उधर पड़ी है. अब आप डिलीट कर दीजिए xyz.c
क्योंकि यह अप्रचलित है, लेकिन आप हटाना भूल जाते हैं xyz.o. "केवल_लक्ष्य" के बिना
समारोह, xyz.o की सूची में अभी भी शामिल किया जाएगा .o लाइब्रेरी में शामिल फ़ाइलें.

इमारत a गतिशील पुस्तकालय

गतिशील पुस्तकालयों के निर्माण की प्रक्रिया पूरी तरह से सिस्टम पर निर्भर है। मैं अत्यधिक चाहूँगा
गतिशील लाइब्रेरी बनाने के लिए libtool का उपयोग करने की अनुशंसा करें (देखें)।
<http://www.gnu.org/software/libtool/>), इसलिए आपको यह पता लगाने की ज़रूरत नहीं है कि इसे कैसे करना है
आपका प्लेटफ़ॉर्म, और ताकि जब आप स्विच करें तब भी आपकी मेकफ़ाइल काम करती रहेगी
अलग ओएस. विवरण के लिए libtool दस्तावेज़ देखें। यहाँ एक नमूना मेकफ़ाइल है:

लिबटूल := लिबटूल

libflick.la : $(only_targets *.lo)
$(LIBTOOL) --मोड=लिंक $(CC) $(इनपुट) -o $(आउटपुट)

%लो : %c
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(INCLUDES) -c $(इनपुट) -o $(आउटपुट)

इमारत on कई विभिन्न मशीनों or नेटवर्क
मेकफ़ाइल्स के साथ सबसे कष्टप्रद समस्याओं में से एक यह है कि वे लगभग कभी भी आपके काम नहीं करते हैं
किसी भिन्न मशीन या भिन्न नेटवर्क पर स्विच करें। यदि आपके मेकफ़ाइल्स पर काम करना है
ग्रह पर हर संभव मशीन, तो आपको संभवतः किसी प्रकार के कॉन्फिगर की आवश्यकता होगी
लिखी हुई कहानी। लेकिन अगर आपको केवल कुछ अलग-अलग मशीनों पर काम करना है, तो कई तरीके हैं
आप इस समस्या से संपर्क कर सकते हैं:

उपयोग a विभिन्न शामिल पट्टिका in सब la वातावरण

प्रत्येक मेकफ़ाइल की शुरुआत में, आप इस तरह एक पंक्ति शामिल कर सकते हैं:

system_defs.mk शामिल करें

फ़ाइल system_defs.mk सामान्यतः प्रत्येक के लिए एक अलग स्थान पर स्थित होगा
पर्यावरण। यदि आप चाहते हैं कि आपकी बिल्ड निर्देशिका सभी मशीनों पर समान हो, तो डालें
system_defs.mk बिल्ड निर्देशिकाओं के ऊपर एक निर्देशिका में, या फिर एक सम्मिलित पथ प्रदान करें
"-I" कमांड लाइन विकल्प का उपयोग करके मेकप करने के लिए।

ऐसा करना आम तौर पर कष्टदायक होता है, लेकिन अगर बड़ी संख्या में हों तो यह अच्छा काम करता है
मतभेद।

उपयोग if बयान

ऐसा करने का यह सबसे ख़राब तरीका है, लेकिन यह आमतौर पर काम करेगा।

ifsys i386
सीसी := जीसीसी
अन्यथा ifsys sun4u
सीसी := सीसी
अन्यथा ifsys hpux11
सीसी = सी89
endif

यदि आपको बस कुछ प्रोग्राम या लाइब्रेरी ढूंढना है या अलग-अलग फ़ाइलों को शामिल करना है
स्थान, बेहतर तरीके हो सकते हैं (नीचे देखें)।

खोज_प्रोग्राम, प्रथम_उपलब्ध, फ़ाइल ढूंढे

ये फ़ंक्शन आपके सिस्टम में विभिन्न विभिन्न निर्देशिकाओं को खोज सकते हैं
उपयुक्त फ़ाइलें. बेशक, यह कॉन्फिगर स्क्रिप्ट जितना शक्तिशाली नहीं है, लेकिन मुझे यह लगता है
उपयोगी। उदाहरण के लिए, मैं निम्नलिखित कार्य करता हूँ:

CXX ;= $(find_program g++ c++ pg++ cxx CC aCC)
# पहला C++ कंपाइलर चुनें जो PATH में उपलब्ध है।
# (संयोग से, यदि आप CXX को बिल्कुल भी परिभाषित नहीं करते हैं, तो यह
# इसे परिभाषित करने का तरीका है।)
TCL_INCLUDE ;= -I$(dir_noslash $(findfile tcl.h,
/usr/local/stow/tcl-8.4.5-nothread/include
/usr/include/tcl8.4 /usr/include/tcl
/net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))
# $(findfile ) प्रत्येक संकेत में tcl.h ढूंढता है
# निर्देशिकाएँ और पूरा पथ लौटाता है। ये तो तब है
# को अलग करके एक संकलन विकल्प में परिवर्तित किया गया
# फ़ाइल नाम (निर्देशिका को छोड़कर) और -I के साथ उपसर्ग लगाएं।
%.o : %.सीपीपी
$(CXX) $(CXXFLAGS) $(TCL_INCLUDE) $(इनपुट) -o $(आउटपुट)

TCL_LIB ;= $((first_available
/usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so
/usr/lib/libtcl8.4.so /usr/lib/libtcl.so
/नेट/na1/tcl8.4a3/lib/libtcl8.4.a
/नेट/na1/tcl8.4a3/lib/libtcl8.4.sl))
# पता लगाएं कि टीसीएल लाइब्रेरी कहां है। यह तो स्पष्ट रूप से है
# लिंक कमांड पर सूचीबद्ध:
मेरा_प्रोग्राम : *.ओ
$(CXX) $(CXXFLAGS) $(इनपुट) -o $(आउटपुट) $(TCL_LIB)

लेना लाभ of पर्ल के विन्यास करें-

यदि आपको कुछ अतिरिक्त जानकारी की आवश्यकता है तो उपरोक्त तकनीकें पर्याप्त नहीं हो सकती हैं
आपका सिस्टम, जैसे कि क्या कोई लंबा डबल मौजूद है, या बाइट ऑर्डर क्या है। तथापि,
पर्ल ने पहले ही इन चीजों की गणना कर ली है, इसलिए आप इसके उत्तरों का उपयोग कर सकते हैं।

पर्ल की ऑटोकॉन्फ़िगर स्क्रिप्ट इसके सभी कॉन्फ़िगरेशन जानकारी को उपलब्ध कराती है
%कॉन्फिग हैश. मेकप में सीधे पर्ल हैश तक पहुंचने के लिए कोई सिंटैक्स नहीं है, लेकिन आप ऐसा कर सकते हैं
पर्ल में ड्रॉप करें और स्केलर वैरिएबल सेट करें, जो मेकप से सीधे पहुंच योग्य हैं:

perl_begin
# कॉन्फ़िगरेशन हैश से मान प्राप्त करें।
कॉन्फिग का उपयोग करें;
$सीसी = $कॉन्फिग{'सीसी'}; # सी कंपाइलर जिसका उपयोग पर्ल ने किया था;
$byteorder_flags = "-DBYTEORDER=$Config{'byteorder'}";
$longdouble_Defined = $Config{'d_longdbl'} eq 'define';
$CFLAGS_for_shared_libs = $Config{'cccdlflags'};
$LDFLAGS_for_shared_libs = $Config{'ccdlflags'};
perl_end

इसके अलावा, एक बार जब आप 'यूज कॉन्फिग' कर लेते हैं, तो आप "$(perl )" स्टेटमेंट का उपयोग कर सकते हैं, जैसे
इस:

SHARED_LIB_EXTENSION := $(perl $Config{'dlext'})

%Config हैश के माध्यम से कौन सी जानकारी उपलब्ध है यह देखने के लिए "perldoc config" टाइप करें।

पूर्णांक प्रकार, बाइट के बारे में जानकारी प्राप्त करने के लिए पर्ल का कॉन्फ़िगरेशन एक अच्छी जगह है
ऑर्डर, और अन्य चीजें जिनका पता लगाने के लिए आमतौर पर एक अलग कॉन्फिग स्क्रिप्ट की आवश्यकता होती है। कुछ
इसकी जानकारी जो फ़ाइल सिस्टम में चीज़ों की उपस्थिति से संबंधित है, वह नहीं हो सकती है
वैध। उदाहरण के लिए, $Config{'cc'} उस C कंपाइलर को संदर्भित करता है जिसके साथ पर्ल बनाया गया था,
जो शायद वही C कंपाइलर नहीं है जिसका आप उपयोग करना चाहते हैं। वास्तव में, इसका अस्तित्व भी नहीं हो सकता है
आपके सिस्टम पर, चूँकि संभवतः आपने पर्ल को बाइनरी पैकेज के माध्यम से स्थापित किया है।

टिप्स एसटी का उपयोग वाइल्डकार्ड
मिलान सब फ़ाइलों सिवाय a कुछ सबसेट

मेकप्प के वाइल्डकार्ड के पास फिलहाल सभी फाइलों के मिलान का कोई तरीका नहीं है सिवाय एक निश्चित
सेट करें, लेकिन आप इसे फ़ंक्शंस के संयोजन के साथ कर सकते हैं।

उदाहरण के लिए, मान लीजिए कि आपके पास लाइब्रेरी में प्रत्येक मॉड्यूल के लिए एक परीक्षण कार्यक्रम है, लेकिन आपके पास नहीं है
लाइब्रेरी में परीक्षण कार्यक्रम शामिल करना चाहते हैं. यदि सभी परीक्षण कार्यक्रम प्रारंभ होते हैं
परीक्षण, तो आप उन्हें इस तरह बाहर कर सकते हैं:

libproduction.a: $(फ़िल्टर_आउट टेस्ट*, $(वाइल्डकार्ड *.o))

"$(फ़िल्टर )" और "$(फ़िल्टर_आउट )" फ़ंक्शंस फ़िल्टर का एक बहुत शक्तिशाली सेट हैं
सभी प्रकार के सेट इंटरसेक्शन और अंतर संचालन। उदाहरण के लिए,

SUBDIRS ;= $(filter_out *test* *$(ARCH)*, $(shell find . -type d -print))
# उन सभी उपनिर्देशिकाओं को लौटाता है जिनमें यह नहीं है
# उनमें "परीक्षण" या $(ARCH)।

$(फ़िल्टर $(patsubst test_dir/test_%.o, %o, $(वाइल्डकार्ड test_dir/*.o)),
$(वाइल्डकार्ड *.o))
# वर्तमान में .o फ़ाइलों की एक सूची लौटाता है
# निर्देशिका जिसके लिए एक संगत है
# test_*.o फ़ाइल test_dir उपनिर्देशिका में।
$(filter_out $(patsubst man/man3/%.3, %o, $(वाइल्डकार्ड man/man3/*.3)),
$(वाइल्डकार्ड *.o))
# वर्तमान में .o फ़ाइलों की एक सूची लौटाता है
# निर्देशिका जिसके लिए कोई मैन्युअल पेज नहीं है
# man/man3 उपनिर्देशिका में समान फ़ाइल नाम के साथ।

का प्रयोग la "$(only_targets )" समारोह सेवा मेरे को खत्म करने बासी .o फ़ाइलों

मान लीजिए कि आप इस तरह बिल्ड कमांड के साथ एक प्रोग्राम या लाइब्रेरी बना रहे हैं:

कार्यक्रम: *.ओ
$(CC) $(इनपुट) -o $(आउटपुट)

मान लीजिए कि अब आप एक स्रोत फ़ाइल हटाते हैं। यदि आप संबंधित को हटाना भूल जाते हैं .o फ़ाइल,
यह अभी भी जुड़ा रहेगा भले ही इसे बनाने का कोई तरीका नहीं है। में
भविष्य में, मेकप संभवतः इस स्थिति को स्वचालित रूप से पहचान लेगा और इसे बाहर कर देगा
वाइल्डकार्ड सूची, लेकिन वर्तमान में, आपको इसे मैन्युअल रूप से बाहर करने के लिए कहना होगा:

कार्यक्रम: $(only_targets *.o)
$(CC) $(इनपुट) -o $(आउटपुट)

मेकप्प को बासी बनाने का कोई तरीका नहीं पता .o कोई और फ़ाइल करें क्योंकि इसकी स्रोत फ़ाइल है
चला गया, इसलिए "$(only_targets )" फ़ंक्शन इसे निर्भरता सूची से बाहर कर देगा।

टिप्स एसटी विभिन्न निर्देशिकाओं
मेकप लिखने का एक मुख्य कारण मल्टीपल के संचालन को सरल बनाना था
निर्देशिकाएँ मेकप एकाधिक मेकफाइल्स से बिल्ड कमांड को संयोजित करने में सक्षम है, इसलिए यह कर सकता है
एक मेकफ़ाइल में एक नियम से ठीक से निपटें जो एक फ़ाइल पर निर्भर करता है जिसे a द्वारा बनाया गया है
अलग मेकफ़ाइल.

क्या सेवा मेरे do in जगह of पुनरावर्ती बनाना

Makepp पश्चगामी संगतता के लिए पुनरावर्ती मेक का समर्थन करता है, लेकिन इसकी अत्यधिक अनुशंसा की जाती है
कि आप नहीं इसका इस्तेमाल करें। यदि आप नहीं जानते कि यह क्या है, तो अच्छा है।

आप ऐसा क्यों नहीं करना चाहते इसके विवरण के लिए मेकप में "पदानुक्रमित निर्माण के लिए बेहतर प्रणाली" देखें
पुनरावर्ती मेक का उपयोग करें, अन्यथा वेब पर "पुनरावर्ती मेक को हानिकारक माना जाता है" खोजें।

प्रत्येक मेकफ़ाइल में "सभी" लक्ष्य बनाने के लिए पुनरावर्ती मेक करने के बजाय, यह है
आमतौर पर मेकप को यह पता लगाने देना आसान होता है कि वास्तव में कौन से लक्ष्य बनाने की आवश्यकता होगी।
इसके अलावा, यदि आप अपना सब कुछ डाल देते हैं .o और लाइब्रेरी फ़ाइलों को उसी निर्देशिका में रखें
मेकफाइल्स, फिर मेकप स्वचालित रूप से पता लगाएगा कि कौन सी मेकफाइल्स की भी आवश्यकता है -
केवल एक चीज जो आवश्यक है वह यह है कि अपने शीर्ष स्तर पर उन फाइलों की सूची बना लें जिनकी जरूरत है
अंतिम लिंकिंग चरण के लिए. नीचे दिए गए उदाहरण देखें.

एक makefile एसटी से प्रत्येक निर्देशिका: साथ में अंतर्निहित लोड हो रहा है

एकाधिक निर्देशिकाओं को संभालने का सबसे आम तरीका प्रत्येक निर्देशिका में एक मेकफ़ाइल डालना है
जो बताता है कि उस निर्देशिका में या उससे सब कुछ कैसे बनाया जाए। यदि आप डालते हैं .o फाइलों में
स्रोत फ़ाइलों के समान निर्देशिका, फिर अंतर्निहित लोडिंग ("अंतर्निहित लोडिंग" देखें)।
makepp_build_algorithm) स्वचालित रूप से सभी मेकफ़ाइलें ढूंढ लेगा। यदि आप अपना .o
एक अलग निर्देशिका में फ़ाइलें (उदाहरण के लिए, एक आर्किटेक्चर-निर्भर उपनिर्देशिका में), फिर आप
संभवतः सभी प्रासंगिक मेकफ़ाइलों को "load_makefile" कथन का उपयोग करके लोड करना होगा।

यहां निर्देशिका पदानुक्रम के लिए एक नमूना शीर्ष-स्तरीय मेकफ़ाइल है जो अंतर्निहित लोडिंग का उपयोग करता है
एक प्रोग्राम बनाने के लिए जिसमें कई साझा लाइब्रेरी शामिल हैं (लेकिन देखें "क्या आपको वास्तव में इसकी आवश्यकता है
लाइब्रेरी?" makepp_cookbook में, क्योंकि साझा लाइब्रेरीज़ के एक समूह से एक प्रोग्राम बनाना
जरूरी नहीं कि यह एक अच्छा विचार हो):

# शीर्ष स्तर की मेकफाइल:
कार्यक्रम: main.o **/*.la # सभी उपनिर्देशिकाओं से साझा पुस्तकालयों में लिंक।
$(LIBTOOL) --मोड=लिंक $(CC) $(CFLAGS) $(इनपुट) -o $(आउटपुट) $(LIBS)

शीर्ष स्तरीय मेकफ़ाइल में आपको बस इतना ही चाहिए। प्रत्येक उपनिर्देशिका में, आप
संभवतः ऐसा कुछ करेगा:

# प्रत्येक उपनिर्देशिका में मेकफ़ाइल:
मानक_defs.mk शामिल करें # खोजें ., .., ../ .., आदि जब तक यह
# संकेतित सम्मिलित फ़ाइल ढूंढता है।
# यहां कुछ परिवर्तनीय परिभाषाओं को ओवरराइड करें
SPECIAL_FLAGS := -कुछ_कुछ_अलग_करो

यदि लक्ष्य बनाने के लिए आदेश दिए जाएं तो प्रत्येक मेकफ़ाइल संभवतः लगभग समान हो सकती है
काफी समान हैं.

अंत में, आप निम्नलिखित को इसमें डालेंगे मानक_defs.mk फ़ाइल (जो संभवतः होनी चाहिए
शीर्ष-स्तरीय निर्देशिका में स्थित हो):

# सभी निर्देशिकाओं के लिए सामान्य चर सेटिंग्स और नियम बनाएं।
CFLAGS := -g -O2
INCLUDE_DIR := $(find_upwards शामिल है)
# खोजें ., .., ../ .., आदि किसी फ़ाइल के लिए या
# निर्देशिका को शामिल कहा जाता है, इसलिए यदि आप डालते हैं
# आपकी सभी फ़ाइलें वहां मौजूद होंगी, ऐसा होगा
# उन्हें लगता है।
शामिल है := -I$(INCLUDE_DIR)

%लो : %c
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(INCLUDES) -c $(इनपुट) -o $(आउटपुट)

lib$(relative_to ., ..).la: $(only_targets *.lo)
$(LIBTOOL) --मोड=लिंक $(CC) $(CFLAGS) -o $(आउटपुट) $(इनपुट)
# $(relative_to ., ..) वर्तमान का नाम लौटाता है
# ऊपरी स्तर के सापेक्ष उपनिर्देशिका
# उपनिर्देशिका. तो यदि यह मेकफ़ाइल xyz/Makefile है,
# यह नियम xyz/libxyz.la बनाएगा.

# सार्वजनिक रूप से शामिल फ़ाइलों को शीर्ष-स्तरीय शामिल निर्देशिका में प्रकाशित करें:
$(INCLUDE_DIR)/public_%.h : public_%.h
:build_check symlnk
&ln -fr $(इनपुट) $(आउटपुट)

एक makefile एसटी से प्रत्येक निर्देशिका: स्पष्ट लोड हो रहा है

यदि आप अपना सब कुछ लगाना चाहते हैं .o फिर एक आर्किटेक्चर-निर्भर उपनिर्देशिका में फ़ाइलें
उपरोक्त उदाहरण को कुछ इस प्रकार संशोधित किया जाना चाहिए:

# शीर्ष स्तर की मेकफाइल:
MAKEFILES := $(वाइल्डकार्ड **/Makeppfile) # सभी उपनिर्देशिकाओं की सूची
# से मेकफ़ाइलें प्राप्त करें।

Load_makefile $(MAKFILES) # उन सभी को लोड करें।

मानक_defs.mk शामिल करें # main.o के लिए कंपाइल कमांड प्राप्त करें।

कार्यक्रम: $(ARCH)/main.o */**/$(ARCH)/*.la
$(LIBTOOL) --मोड=लिंक $(CC) $(CFLAGS) $(इनपुट) -o $(आउटपुट) $(LIBS)
# */**/$(ARCH) उपनिर्देशिका को बाहर करता है
# $(ARCH), जहां हम निर्माण नहीं करना चाहते
# एक साझा लाइब्रेरी.

प्रत्येक मेकफ़ाइल बिल्कुल पहले जैसा ही होगा:

# प्रत्येक उपनिर्देशिका में मेकफ़ाइल:
मानक_defs.mk शामिल करें
#...वेरिएबल यहां ओवरराइड करता है

और अंत में, मानक_defs.mk इसमें निम्नलिखित जैसा कुछ होगा:

# सभी निर्देशिकाओं के लिए सामान्य चर सेटिंग्स और नियम बनाएं।
ARCH ;= $(खोल अनाम -s)-$(खोल अनाम -m)-$(खोल अनाम -r)
# कभी-कभी लोग केवल $(shell uname -m) का उपयोग करते हैं, लेकिन
# यह FreeBSD और Linux के लिए समान होगा
# एक x86. लिनक्स पर -r वास्तव में उपयोगी नहीं है,
# लेकिन अन्य OSes के लिए महत्वपूर्ण है: बायनेरिज़ के लिए
# SunOS 5.8 आमतौर पर SunOS 5.7 पर नहीं चलेगा।
&mkdir -p $(ARCH) # सुनिश्चित करें कि आउटपुट निर्देशिका मौजूद है।
CFLAGS := -g -O2
INCLUDE_DIR := $(find_upwards शामिल है)
# खोजें ., .., ../ .., आदि किसी फ़ाइल के लिए या
# निर्देशिका को शामिल कहा जाता है, इसलिए यदि आप डालते हैं
# आपकी सभी फ़ाइलें वहां मौजूद होंगी, ऐसा होगा
# उन्हें लगता है।
शामिल है := -I$(INCLUDE_DIR)

$(ARCH)/%lo : %c
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(INCLUDES) -c $(इनपुट) -o $(आउटपुट)

$(आर्क)/ दायित्व$(सापेक्ष_से ., ..).la: $(only_targets *.lo)
$(LIBTOOL) --मोड=लिंक $(CC) $(CFLAGS) -o $(आउटपुट) $(इनपुट)
# $(relative_to ., ..) वर्तमान का नाम लौटाता है
# ऊपरी स्तर के सापेक्ष उपनिर्देशिका
# उपनिर्देशिका. तो यदि यह मेकफ़ाइल xyz/Makefile है,
# यह नियम xyz/$(ARCH)/libxyz.la का निर्माण करेगा।

# सार्वजनिक रूप से शामिल फ़ाइलों को शीर्ष-स्तरीय निर्देशिका में कॉपी करें:
$(INCLUDE_DIR)/public_%.h : public_%.h
और सीपी $ (इनपुट) $ (आउटपुट)

स्वतः कमाना और la मेकफ़ाइल्स

यदि आपकी सभी मेकफ़ाइलें बेहद समान हैं (जैसा कि उपरोक्त उदाहरण में है), तो आप Makepp को बता सकते हैं
यदि वे मौजूद नहीं हैं तो उन्हें स्वचालित रूप से बनाने के लिए। बस निम्नलिखित को अपने शीर्ष-स्तर पर जोड़ें
मेकफ़ाइल:

SUBDIRS := $(फ़िल्टर_आउट अवांछित_dir1 अवांछित_dir2, $(वाइल्डकार्ड */**))
$(foreach)/Makeppfile: : foreach $(SUBDIRS)
&echo "standard_defs.mk शामिल करें" -o $(आउटपुट)
&echo "_include everything_defs.mk" -o >>$(आउटपुट)
# यदि फ़ाइल अतिरिक्त_defs.mk मौजूद है, तो
# इसे शामिल किया जाएगा, लेकिन यदि यह अस्तित्व में नहीं है,
# _शामिल कथन को नजरअंदाज कर दिया जाएगा।

अब मेकफ़ाइलें स्वयं स्वचालित रूप से निर्मित हो जाएंगी।

एक makefile केवल at la ऊपर का स्तर

यदि आपकी सभी मेकफ़ाइलें समान हैं, तो आप पूछ सकते हैं: मुझे प्रत्येक में मेकफ़ाइल क्यों होनी चाहिए
स्तर? यह सब शीर्ष-स्तरीय मेकफ़ाइल में क्यों नहीं डाला गया?

हाँ, ये किया जा सकता है. मुख्य नुकसान यह है कि इसे निर्दिष्ट करना कठिन हो जाता है
प्रत्येक उपनिर्देशिका के लिए अलग-अलग निर्माण विकल्प। दूसरा नुकसान यह है कि आपका
मेकफ़ाइल को पढ़ना संभवतः थोड़ा कठिन हो जाएगा।

ऐसा करने का एक उदाहरण यहां दिया गया है:

# निर्देशिका पदानुक्रम के लिए शीर्ष-स्तरीय मेकफ़ाइल। प्रोग्राम बनाता है
# उदाहरण के तौर पर साझा पुस्तकालयों के एक सेट से बाहर। (ऊपर चेतावनी देखें
# आप वृद्धिशील लिंकिंग या किसी अन्य का उपयोग क्यों करना चाहते हैं
साझा पुस्तकालयों के बजाय # दृष्टिकोण।)
makepp_percent_subdirs := 1 # % को एकाधिक निर्देशिकाओं से मिलान करने की अनुमति दें।
SUBDIRS := $(filter_out *CVS* अन्य-अवांछित_dirs $(वाइल्डकार्ड **))
CFLAGS := -g -O2
सम्मिलित है := -शामिल है

%.लो: %.सी
$(LIBTOOL) --मोड=संकलन $(CC) $(शामिल है) $(CFLAGS) -c $(इनपुट) -o $(आउटपुट)

$(foreach)/ दायित्व$(notdir $(foreach)).la: $(foreach)/*.lo : foreach $(SUBDIRS)
$(LIBTOOL) --मोड=लिंक $(CC) $(CFLAGS) -o $(आउटपुट) $(इनपुट)
# सभी पुस्तकालय बनाने का नियम.

कार्यक्रम: main.o **/*.la
$(LIBTOOL) --मोड=लिंक $(CC) $(CFLAGS) -o $(आउटपुट) $(इनपुट)

include/$(notdir $(foreach)) : $(foreach): foreach **/public_*.h
और सीपी $ (इनपुट) $ (आउटपुट)
#सार्वजनिक रूप से नकल करने का नमूना नियम
# .h फ़ाइलों को सही स्थान पर पहुँचाएँ।

A स्वच्छ लक्ष्य

पारंपरिक मेकफ़ाइल्स में एक साफ़ लक्ष्य होता है, जो कि जो कुछ भी था उसे हटाने की अनुमति देता है
बनाना। ऐसे तीन कारण हैं जिनकी वजह से आपको मेकप के साथ ऐसा नहीं करना चाहिए:

1. मेकप्प सही निर्माण सुनिश्चित करने के लिए हर संभव प्रयास करता है। तो हताश "मैं नहीं करता
जानें क्या गलत है", आपको शून्य से शुरुआत करने के लिए प्रेरित करना अतीत की बात है।

2. लोग कभी-कभी एक साथ दो विरोधाभासी काम करके समय बचाने की कोशिश करेंगे:
"सब साफ़ करो"। यह मेकप के स्मार्ट वाइल्डकार्ड सिस्टम को भ्रमित कर सकता है, क्योंकि ऐसा होगा
कुछ भी करने से पहले तथ्य जान लें। इसके बाद स्वच्छ क्रिया आती है, जो होती है
मेकप को यह न बताएं कि यह क्या करता है (वास्तव में यह नहीं कर सकता, क्योंकि यह कुछ को पूर्ववत करता है -)।
बिल्ड टूल किसके लिए है इसके विपरीत)। फिर आता है "सभी", लेकिन अद्यतित फ़ाइलें,
जो वहां रहस्यमय तरीके से गायब हो गए हैं।

3. "makeppclean" कमांड है, जो वही काम करता है, और अधिक कुशलता से।

फिर भी हमने इस ऐतिहासिक खंड को बरकरार रखा है, क्योंकि यह आपको इसके बारे में कुछ बताता है
मेकप कैसे काम करता है: "क्लीन" नामक एक नकली लक्ष्य केवल कमांड के एक सेट का नाम है
मेक प्रक्रिया के परिणामस्वरूप उत्पन्न होने वाली सभी फ़ाइलें हटा दें। आमतौर पर साफ़ लक्ष्य दिखता है
कुछ इस तरह:

$ (फोनी क्लीन):
&rm -fm $(वाइल्डकार्ड *.o .makepp_log)
# -m और .makepp_log मेकप्प के सभी जंक से छुटकारा दिलाता है।

जिन फ़ाइलों को आप हटाना चाहते हैं उन्हें स्पष्ट रूप से सूचीबद्ध करने के बजाय, आप मेकप को भी बता सकते हैं
वह सब कुछ हटा दें जो वह जानता है कि कैसे बनाना है, इस तरह:

$ (फोनी क्लीन):
&rm -fm .makepp_log $(only_targets *)

इसका यह लाभ है कि यदि आपकी कोई भी स्रोत फ़ाइल अन्य फ़ाइलों से बनाई जा सकती है,
उन्हें भी हटा दिया जाएगा; दूसरी ओर, बासी .o फ़ाइलें (फ़ाइलें जो हुआ करती थीं
निर्माण योग्य लेकिन जिसकी स्रोत फ़ाइल हटा दी गई है) हटाई नहीं जाएगी।

यदि आपके पास एक ऐसा निर्माण है जिसमें कई अलग-अलग निर्देशिकाओं में मेकफ़ाइलें शामिल हैं, तो आपका शीर्ष-
लेवल मेकफ़ाइल "स्वच्छ" लक्ष्य (या किसी अन्य नकली लक्ष्य) को अलग तरीके से संदर्भित कर सकता है
मेकफ़ाइल:

# शीर्ष-स्तरीय मेकफ़ाइल
सबडिर्स := सब1 सब2

# यहां नियम बनाएं

# निर्माण के बाद सफाई करें:
$(फनी क्लीन): $(SUBDIRS)/क्लीन
&rm -fm .makepp_log $(only_targets *)

वैकल्पिक रूप से, आप अपना "स्वच्छ" लक्ष्य केवल शीर्ष-स्तरीय मेकफ़ाइल में रख सकते हैं, और इसे प्राप्त कर सकते हैं
सभी निर्देशिकाओं को इस प्रकार संसाधित करें:

$ (फोनी क्लीन):
&rm -fm $(only_targets **/*)

का प्रयोग क्यू.टी एमओसी पूर्वप्रक्रमक
यह उदाहरण एक उपयोगिता के लिए मेकफ़ाइल दिखाता है जो नोकिया की क्यूटी जीयूआई लाइब्रेरी का उपयोग करता है (देखें)।
<http://qt.nokia.com>). इसमें एकमात्र चीज जो थोड़ी असामान्य है, वह है आप
विजेट परिभाषाओं वाली अधिकांश ".h" फ़ाइलों पर "moc" नामक प्रीप्रोसेसर अवश्य चलाना चाहिए,
लेकिन आप किसी भी ".h" फ़ाइल पर "moc" नहीं चलाना चाहते जो "Q_OBJECT" मैक्रो का उपयोग नहीं करती हैं।

स्वतः निर्धारित करने कौन कौन से फ़ाइलों आवश्यकता एमओसी फ़ाइलों

बेशक, आप उन सभी ".h" फ़ाइलों को सूचीबद्ध कर सकते हैं जिन पर "moc" चलाने की आवश्यकता है।
हालाँकि, यदि आप तेजी से नए विजेट विकसित कर रहे हैं, तो यह कुछ हद तक परेशानी भरा हो सकता है
मेकफ़ाइल में सूची को अद्यतन करते रहें। आप मॉक को सूचीबद्ध करने की आवश्यकता से निजात पा सकते हैं
मॉड्यूल स्पष्ट रूप से कुछ इस तरह से:

एमओसी := $(क्यूटीडीआईआर)/बिन/एमओसी
मॉड्यूल:= आपके प्रोग्राम में जो भी मॉड्यूल हैं
MOC_MODULES := $(patsubst .h, moc_%, $(&grep -l /Q_OBJECT/ *.h))
# Q_OBJECT मैक्रो के लिए सभी .h फ़ाइलों को स्कैन करता है।

मेरा_प्रोग्राम: $(MODULES).o $(MOC_MODULES).o
$(CXX) $(इनपुट) -o $(आउटपुट)

moc_%cxx: %h # .h फ़ाइलों से moc फ़ाइलें बनाता है।
$(MOC) $(इनपुट) -ओ $(आउटपुट)

%o: %cxx
$(CXX) $(CXXFLAGS) -c $(इनपुट) -o $(आउटपुट)

यह दृष्टिकोण आपके प्रत्येक को स्कैन करता है .h हर बार जब मेकप चलाया जाता है तो फ़ाइलें ढूंढी जाती हैं
"Q_OBJECT" मैक्रो. यह महँगा लगता है, लेकिन संभवतः इसमें अधिक समय नहीं लगेगा। (द .h
फ़ाइलों को संकलन प्रक्रिया द्वारा वैसे भी डिस्क से लोड करना होगा, इसलिए वे करेंगे
कैश किया जाए.)

# शामिल la .मोसी पट्टिका

दूसरा तरीका आपके विजेट में "moc" प्रीप्रोसेसर से आउटपुट को "#include" करना है
कार्यान्वयन फ़ाइल. इसका मतलब है कि आपको "#include" लिखना याद रखना होगा, लेकिन ऐसा हो गया है
लाभ यह है कि संकलन करने के लिए कम मॉड्यूल हैं, और इसलिए संकलन तेजी से होता है।
(अधिकांश C++ संकलन के लिए, अधिकांश समय हेडर फ़ाइलों को पढ़ने में व्यतीत होता है, और
प्रीप्रोसेसर के आउटपुट में लगभग आपके विजेट जितनी फ़ाइलें शामिल होनी चाहिए
वैसे भी।) उदाहरण के लिए:

//my_widget.h
कक्षा MyWidget : सार्वजनिक QWidget {
Q_वस्तु
// ...
}

//my_widget.cpp

#"my_widget.h" शामिल करें
#include "my_widget.moc" // my_widget.moc इसका आउटपुट है
// एमओसी प्रीप्रोसेसर।
// अन्य कार्यान्वयन चीजें यहां।
MyWidget::MyWidget(QWidget * पैरेंट, स्थिरांक चार * नाम) :
QWidget(अभिभावक, नाम)
{
// ...
}

अब आपको सभी ".moc" फ़ाइलें बनाने के लिए अपनी मेकफ़ाइल में एक नियम रखना होगा, जैसे:

एमओसी := $(क्यूटीडीआईआर)/बिन/एमओसी
# .moc फ़ाइलें बनाने का नियम:
%.मोक: %.एच
$(MOC) $(इनपुट) -ओ $(आउटपुट)

मेकप्प इतना समझदार है कि उसे यह एहसास है कि यदि ऐसा नहीं होता है तो उसे "my_widget.moc" बनाने की आवश्यकता है
पहले से मौजूद है, या यदि यह पुराना है।

यह दूसरा दृष्टिकोण वह है जिसका मैं आमतौर पर उपयोग करता हूं क्योंकि यह संकलन को गति देता है।

प्रतिस्थापन एसटी पदावनत बनाना मुहावरों
लक्ष्य बनाएं

कभी-कभी लोगों के मेकफ़ाइल में नियम इस बात पर निर्भर करते हैं कि वे किस लक्ष्य का निर्माण कर रहे हैं,
विशेष चर "MAKECMDGOALS" का उपयोग करना। उदाहरण के लिए, कोई कभी-कभी ऐसी चीजें देखता है
इस:

ifneq ($(फ़िल्टर उत्पादन, $(MAKECMDGOALS)),)
CFLAGS := -O2
अन्य
CFLAGS := -जी
endif

यह मेकप के साथ ठीक काम करेगा। हालाँकि, मैं ऐसे के लिए "MAKECMDGOALS" का उपयोग न करने की सलाह देता हूँ
मामले (और इसी तरह जीएनयू मैनुअल बनाता है)। बेहतर होगा कि आप अपना अनुकूलित और लगाएं
डिबग-संकलित .o अलग-अलग निर्देशिकाओं में फ़ाइलें, या उन्हें अलग-अलग उपसर्ग देना या
उन्हें अलग रखने के लिए प्रत्यय, या रिपॉजिटरी का उपयोग करना।

संभवतः एकमात्र समय जब आप वास्तव में "MAKECMDGOALS" का संदर्भ देना चाहेंगे
आपकी मेकफ़ाइल्स को लोड करने में लंबा समय लगता है, और आपको अपने "स्वच्छ" लक्ष्य के लिए इसकी आवश्यकता नहीं है
(लेकिन आपको साफ़ लक्ष्य की आवश्यकता नहीं है)। उदाहरण के लिए,

ifneq ($(MAKECMDGOALS),स्वच्छ)
लोड_मेकफाइल $(वाइल्डकार्ड **/मेकपफाइल)
अन्य
no_implicit_load . # किसी भी अन्य मेकफ़ाइल की स्वचालित लोडिंग को रोकें।
endif

$ (फोनी क्लीन):
&rm -f $(वाइल्डकार्ड **/*.o)

पुनरावर्ती बनाना सेवा मेरे निर्माण in विभिन्न निर्देशिकाओं

makepp_cookbook में "एकाधिक निर्देशिकाओं के लिए युक्तियाँ" देखें।

पुनरावर्ती बनाना सेवा मेरे परिवर्तन मूल्य of a परिवर्तनशील

कुछ मेकफ़ाइलें किसी वेरिएबल के भिन्न मान के साथ स्वयं को पुनः सक्रिय करती हैं, उदाहरण के लिए, डिबग
निम्नलिखित मेकफ़ाइल खंड में लक्ष्य

.फोनी: सभी डिबग

अनुकूलित:
$(MAKE) प्रोग्राम CFLAGS=-O2

डिबग:
$(MAKE) प्रोग्राम CFLAGS=-g

कार्यक्रम: एओ बो
$(सीसी) $(CFLAGS) $^ -o $@

%.ओ:%.सी
$(CC) $(CFLAGS) -c $< -o $@

यदि उपयोगकर्ता "डीबग बनाएं" टाइप करता है, तो यह डिबग सक्षम होने के साथ डिफ़ॉल्ट मोड में प्रोग्राम बनाता है
अनुकूलन के बजाय.

ऐसा करने का एक बेहतर तरीका दो अलग-अलग सेटों के साथ दो अलग-अलग प्रोग्राम बनाना है
ऑब्जेक्ट फ़ाइलें, इस तरह:

CFLAGS := -O2
DEBUG_FLAGS := -जी
मॉड्यूल := एबी

प्रोग्राम: $(मॉड्यूल).o
$(CC) $(CFLAGS) $(इनपुट) -o $(आउटपुट)

डिबग/प्रोग्राम: डिबग/$(मॉड्यूल).o
$(CC) $(DEBUG_FLAGS) $(इनपुट) -o $(आउटपुट)

%.ओ:%.सी
$(CC) $(CFLAGS) -c $(इनपुट) -o $(आउटपुट)

डीबग/%o : %c
$(CC) $(DEBUG_FLAGS) -c $(इनपुट) -o $(आउटपुट)

$(फोनी डीबग): डीबग/प्रोग्राम

इसे इस तरह से करने का फायदा यह है कि (ए) आपको हर चीज को फिर से बनाने की जरूरत नहीं है
डिबग से अनुकूलित पर स्विच करें और फिर से वापस आएं; (बी)

उपरोक्त को रिपॉजिटरी का उपयोग करके कुछ अधिक संक्षिप्त रूप से लिखा जा सकता है। निम्नलिखित
मेकफ़ाइल बिल्कुल समतुल्य है:

रिपॉजिटरी डिबग=. # डिबग उपनिर्देशिका को एक प्रति की तरह बनाता है
# वर्तमान उपनिर्देशिका.
लोड_मेकफ़ाइल डिबग CFLAGS=-g
# डिबग उपनिर्देशिका में लागू होने पर CFLAGS को ओवरराइड करें
CFLAGS := -O2 # इस उपनिर्देशिका में लागू होने पर CFLAGS का मान

कार्यक्रम: एओ बो
$(सीसी) $(CFLAGS) $^ -o $@

%.ओ:%.सी
$(CC) $(CFLAGS) -c $< -o $@

$(फोनी डीबग): डीबग/प्रोग्राम
# यदि उपयोगकर्ता "मेकएप डिबग" टाइप करता है, तो बिल्ड होता है
# प्रोग्राम के बजाय डिबग/प्रोग्राम.

कई तरह का सुझावों
कैसे do I निर्माण एक भाग अलग ढंग से केवल एक बार?

मेकप्प ने ऐसा करना कठिन बना दिया है क्योंकि परिणाम नियमों के संबंध में असंगत है।
लेकिन ऐसी स्थितियां हैं जहां आपको इसकी आवश्यकता हो सकती है, उदाहरण के लिए केवल एक मॉड्यूल संकलित करना
भारी डिबगिंग जानकारी. आप इसे पहले निर्माण करके दो चरणों में प्राप्त कर सकते हैं
निर्भरता को अलग से, और फिर इसे लिंक चरण से बाहर करना:

मेकप्प DEBUG=3 buggy.o # इसे अन्य विकल्प के साथ बनाएं।
makepp --dont-build=buggy.o buggy # "गलत" बिल्ड विकल्प के बावजूद इसका उपयोग करें।

कैसे do I बनाना निश्चित my उत्पादन निर्देशिकाओं मौजूद?

आप आउटपुट निर्देशिका बनाने के लिए एक नियम निर्दिष्ट कर सकते हैं, फिर सुनिश्चित करें कि प्रत्येक फ़ाइल
आउटपुट डायरेक्टरी में जाना इस पर निर्भर करता है। लेकिन आमतौर पर ऐसा कुछ करना आसान होता है
इस:

#शास्त्रीय तरीका
डमी := $(शेल टेस्ट -d $(OUTPUT_DIRECTORY) || mkdir -p $(OUTPUT_DIRECTORY))
# यह आमतौर पर सभी फ़ाइलों पर निर्भर होने से आसान है
# $(OUTPUT_DIRECTORY) और इसे बनाने का एक नियम है।
# ध्यान दें कि आपको इसे बाध्य करने के लिए = के बजाय := का उपयोग करना होगा
# तुरंत अमल करें.
# एक वैकल्पिक दृष्टिकोण: पर्ल कोड, OUTPUT_DIRECTORY स्थानीय संस्करण का उपयोग करना
perl_begin
-d $OUTPUT_DIRECTORY या mkdir $OUTPUT_DIRECTORY;
perl_end
# आधुनिक तरीका, मौजूदा निर्देशिकाओं के लिए कुछ नहीं करता
&mkdir -p $(OUTPUT_DIRECTORY)

इनमें से एक कथन आपके मेकफ़ाइल के शीर्ष के पास होना चाहिए, ताकि उन्हें निष्पादित किया जा सके
किसी भी चीज़ से पहले जिसे संभवतः निर्देशिका की आवश्यकता हो सकती है।

कैसे do I मजबूर a आदेश सेवा मेरे निष्पादित on प्रत्येक निर्माण?

सबसे आसान तरीका नियम तंत्र का बिल्कुल भी उपयोग नहीं करना है, बल्कि बस इसे निष्पादित करना है, जैसे
इस:

डमी := $(शेल दिनांक > Last_build_timestamp)

या इसे पर्ल ब्लॉक में रखें, इस तरह:

perl_begin
सिस्टम ("निष्पादित करने के लिए आदेश");
perl_end

इस दृष्टिकोण का नुकसान यह है कि असंबंधित लक्ष्य होने पर भी इसे निष्पादित किया जाएगा
चलाया जा रहा है.

दूसरा तरीका यह है कि फ़ाइल को नकली लक्ष्य घोषित किया जाए, भले ही वह वास्तविक फ़ाइल हो।
यह मेकप को हर बार इसे बनाने के लिए कमांड को दोबारा निष्पादित करने के लिए मजबूर करेगा, लेकिन केवल तभी
कुछ नियम की निर्भरता सूची में प्रकट होता है।

कैसे do I छोटा करना la दिखाया गया है निर्माण आदेश?

प्राय: आदेशों को संकलित करने के लिए इतने सारे विकल्प होते हैं कि उस पर क्या प्रदर्शित होता है
स्क्रीन अपठनीय है. आप डिस्प्ले को दबाकर जो प्रदर्शित हो रहा है उसे बदल सकते हैं
संपूर्ण कमांड, और फिर कमांड के दिलचस्प भाग को स्पष्ट रूप से प्रिंट करें। इसका
"$(filter_out )" का उपयोग करके कमांड के केवल प्रासंगिक भाग को प्रिंट करना आसान है
इस:

ALL_CFLAGS = $(CFLAGS) $(शामिल है) $(ADDL_CXX_FLAGS) $(DEBUG_FLAGS)

%.ओ:%.सी
@&echo $(notdir $(CC)) ...
$(filter_out -I* $(ADDL_CXX_FLAGS), $(ALL_CFLAGS))
-सी $(इनपुट)
@$(CC) $(ALL_CFLAGS) -c $(इनपुट) -o $(आउटपुट)

(कमांड के सामने "@" कमांड को प्रिंट करने से रोकता है।)

यह आपको अधिकांश दिलचस्प विकल्प देखने की अनुमति देगा लेकिन सभी प्रदर्शित नहीं करेगा
निर्देशिकाएँ शामिल करें (जिनमें से अक्सर बहुत सारे होते हैं!)। यदि आप जिस भाग में रुचि रखते हैं
in आपके आदेश में सन्निहित है, आप "प्रिंट" फ़ंक्शन का भी उपयोग कर सकते हैं (जो एक जोड़ता है)।
न्यूलाइन, इसलिए आप उनमें से कई नहीं चाहते हैं):

को लक्ष्य:
@...$(दिलचस्प हिस्सा छापें)...

कैसे do I बदलना a पट्टिका में निर्भरताएँ?

कुछ अस्पष्ट फ़ाइल स्वरूपों के लिए स्कैनर लागू करना उचित नहीं है। एक प्रोजेक्ट में
मान लीजिये, हमारे पास xml फ़ाइलें हैं foobar.xml जिसमें निर्भरताएँ शामिल हैं foobar.out:



बी
सी


हमने इस सरल लेआउट का पालन करने का निर्णय लिया, इसलिए हमें xml को पार्स करने की आवश्यकता नहीं है। साथ
बिल्टिन एंड सेड, यहां बताया गया है कि हम तीन प्रकार के तीन सरल प्रतिस्थापनों के साथ क्या करते हैं
लाइनों:

%d: %xml
&sed 's! !$(stem).out: \\! || एस! (.+) !$$1 \\! || एस! !# खाली!'
$(इनपुट) -o $(आउटपुट)

foobar.d शामिल करें

इसे शामिल करने का प्रयास करने पर, पहले "foobar.d" उत्पन्न होता है:

foobar.बाहर:
a
b
c
# खाली

खाली (सिर्फ एक टिप्पणी या वास्तव में खाली) पंक्ति पीछे रहने के बारे में चिंता करने से बचाती है
बैकस्लैश मल्टीलाइन सूची तैयार करने वाला एक विकल्प है:

%d: %xml
&sed 's! !$(stem).out: \$$((! || s! !))! || एस!<.+?>!!जी'
$(इनपुट) -o $(आउटपुट)

foobar.d शामिल करें

यह एक समतुल्य उत्पन्न करता है:

फ़ोबार.आउट: $((
a
b
c
))

यदि आपको अधिक जटिल पुनर्लेखन करना है, तो मेकफ़ाइल के भीतर या किसी फ़ंक्शन को परिभाषित करें
मॉड्यूल जिसे आप शामिल करते हैं। उदाहरण के लिए $_ को अपरिभाषित करने से इनपुट लाइनें छूट जाएंगी:

उप मायफ़िल्टर {
अपरिभाषित $_ वापस लौटें यदि /
मेरा $stem = f_stem;
एस! !$stem.out: \$((! || s! !))! || s!<.+?>!!g;
}

%d: %xml
&sed 's! !$(stem).out: \$$((! || s! !))! || एस!<.+?>!!जी'
$(इनपुट) -o $(आउटपुट)

foobar.d शामिल करें

onworks.net सेवाओं का उपयोग करके ऑनलाइन makepp_cookbook का उपयोग करें



नवीनतम Linux और Windows ऑनलाइन प्रोग्राम