जीएनयू में सूची लक्ष्यों / लक्ष्यों को बनाएं जो उनकी परिभाषा में चर होते हैं


100

मेरे पास एक काफी बड़ा मेकफाइल है जो चर से नामों की गणना करके मक्खी पर कई लक्ष्य बनाता है। (जैसे foo $ (VAR): $ (PREREQS))। क्या कोई ऐसा तरीका है जिससे कि ग्नू मेक इन लक्ष्यों का विस्तार करने के बाद लक्ष्यों की एक सूची बनाने के लिए आश्वस्त हो सकता है?

मैं एक उचित makefile के लिए लक्ष्य प्राप्त करने में सक्षम होना चाहते हैं। मैं अपने शेल के लिए एक पूर्ण कार्य लिखने की कोशिश कर रहा हूं।

जवाबों:


79

क्या आप make -pn(यानी make --print-data-base --dry-run) से आउटपुट पार्स कर सकते हैं ? यह सभी चर, नियम, निहित नियमों को प्रिंट करता है और कौन से आदेश श्रमसाध्य विस्तार में चलाए जाएंगे।


यह उत्तर दूसरे की तुलना में बहुत अच्छा लगता है।
मैट जॉइनर

मैं मानता हूं कि यह बहुत अच्छा है। अभी भी मुझे आशा से अधिक काम है, लेकिन मैं इसे उत्तर के रूप में चिह्नित करने जा रहा हूं क्योंकि कुछ भी उचित नहीं लगता है और जीएनयू मेक को मेरे लिए एक सुविधाजनक झंडा नहीं है।
BitShifter

6
ध्यान रखें कि आउटपुट आपके द्वारा निर्दिष्ट लक्ष्य पर निर्भर हो सकता है, यदि आपका Makefile गतिशील रूप से लक्ष्य बनाता है। आउटपुट पर्यावरण चर के मूल्यों पर निर्भर हो सकता है या मेक कमांड के साथ निर्दिष्ट चर बना सकता है।
रीयरियरपोस्ट

6
मुझे संक्षिप्तता पसंद है। +1 जोड़ा गया अपना स्वयं का स्पिन (नीचे एक उत्तर में वर्णित):make -pn | sed -rn '/^[^# \t\.%].*:[^=]?/p'
जेमी

सुझाव दें make -pnr-rअंतर्निहित नियमों को हटा।
sjbx

114
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'     

मेक एर्ग पूरा होने से लिया गया, जो एक आकर्षण की तरह काम करता है।


2
मैंने इसके लिए एक उपनाम बनाने की कोशिश की, इसे दोहरे उद्धरण चिह्नों में डाल दिया, लेकिन यह केवल पहले अल्पविराम पर एक वाक्यविन्यास त्रुटि होने के परिणामस्वरूप होता है ... शेल (बैश) उपनाम के लिए इसे सही ढंग से कैसे निकालना है?
drfrogsplat

3
मुझे लगता है कि जहां यह परिभाषित है, उसके साथ कुछ करना है। मुझे लगता है कि अगर इसे एक उपनाम के रूप में परिभाषित किया जाता है तो इसकी कार्यशील निर्देशिका वह निर्देशिका बन जाती है जहां इसे परिभाषित किया जाता है, और जाहिर है कि awk भाग को छिपी निर्देशिकाओं में डॉट पसंद नहीं है। एक फ़ंक्शन को परिभाषित करना काम करता है।
इब्राहिम

मैंने सिर्फ ~/binएक उपनाम का उपयोग करने के बजाय इसे एक शेल स्क्रिप्ट में डाल दिया । बहुत अच्छा काम करता है; धन्यवाद!
एमपॉन्टिलो

3
उर्फ alias mkl="make -qp | awk -F':' '/^[a-zA-Z0-9][^\$#\/\t=]*:([^=]|\$)/ {split(\$1,A,/ /);for(i in A)print A[i]}' | sort"जो आपको 2 मिनट के खेल को बचाने के लिए बचाएगा :-)
सिरो संतिली which save save save 六四 事件

1
| sort -uअधिक उपयोगी लगता है :)
sherpya

14

मुझे यकीन नहीं है कि यह केवल एक ग्नू बनाने की चीज़ है, लेकिन यह अच्छी तरह से काम करता है:

make help


यह बहुत आसान है, अन्य तरीकों में से एक के लिए कस्टम उपनाम से याद रखना बहुत आसान है।
इब्राहिम

8
जीएनयू मेक 3.81 पर वास्तव में काम नहीं कर रहा है, शायद आप मेकफाइल्स में एक लक्ष्य: "बनाओ: ***` मदद 'करने के लिए कोई नियम नहीं है। बंद करो "
a1an

8
यह सिर्फ मेकफाइल में "मदद" लक्ष्य को लागू करता है। यदि यह मौजूद है, तो यह कुछ प्रिंट करेगा ( लक्ष्यों की पूरी सूची नहीं ), यदि यह मौजूद नहीं है (विशिष्ट स्थिति), तो यह जमानत कर देगा।
pfalcon

2
अच्छी खबर है cmake लगता है "मदद" लक्ष्य को पढ़ने के लिए एक अच्छा आसान उत्पन्न करता है।
स्टीफन

यह कमाल का है! :) गो सेमी
जीफ

10

कई उत्तरदाताओं ने उपयोग करने का सुझाव दिया है make -pn, जो नियमों के डेटाबेस को प्रिंट करेगा, लेकिन कुछ भी निष्पादित नहीं करेगा - अधिक या कम। इस दृष्टिकोण के साथ समस्या यह है कि -nअभी भी सभी पुनरावर्ती बनाता है, और यह अभी भी आवश्यकता से अधिक काम करता है, क्योंकि यह हर आदेश को प्रिंट करता है जिसे उसने एक नियमित निर्माण में लगाया होगा। एक अधिक कुशल समाधान इन सामग्रियों के साथ एक तुच्छ मेकफाइल, डमी। Mk बनाना होगा:

__all_targets__: ; #no-op

अब जैसा बना रहे हो make -p -f Makefile -f dummy.mk __all_targets__। किसी भी पर्याप्त निर्माण पर, मेक द्वारा उत्पन्न आउटपुट की मात्रा में अंतर महत्वपूर्ण है। उदाहरण के लिए:

$ gmake -pn | wc
 138985 2632330 69612711
$ gmake -f Makefile -f /tmp/dummy.mk -pn __all_targets__ | wc
  21673   93437  878985

निष्पादन का समय नाटकीय रूप से बेहतर था - पहले संस्करण के लिए 2.063, दूसरे के लिए 0.059।


1
नीट विचार, हर कोई जो विशाल बिल्ड सिस्टम के साथ काम करता है वह इसकी सराहना करेगा। Android जिंजरब्रेड पेड़ के लिए आँकड़े (पुनरावर्ती उपयोग नहीं करते हैं, इसलिए बचत बहुत बड़ी नहीं है, बस अच्छा है): " time make -pn | wc -l": 1338738 real 0m47.754s." time make -f Makefile -f dummy.mk -pn __all_targets__ | wc -l": 938621 real 0m40.219s
pfalcon

अच्छी बात। ऐसा makeलगता है कि आदमी पेज कुछ इसी तरह के अनुकूल लगता है, लेकिन इसका नाम हैmake -p -f/dev/null
डेविड

@ काम है कि काफी काम नहीं करेगा: निर्दिष्ट करने से नियमित रूप से मेकअप करने से -f /dev/nullरोका जाएगा make, इसलिए आपको केवल अंतर्निहित नियमों का एक प्रिंटआउट मिलेगा। इसलिए मेरा समाधान निर्दिष्ट है -f Makefile -f dummy.mk। लेकिन यह पर्याप्त नहीं है, क्योंकि इसके साथ -n, makeआगे बढ़ेंगे और वास्तव में मेकफाइल में नियमों को निष्पादित करना शुरू कर देंगे। दुर्भाग्य से मुझे किसी भी संशोधन की जानकारी नहीं है जो मूल रूप से प्रस्तुत समाधान को सरल बना सकता है।
एरिक मेल्स्की

बेशक आप ठीक हैं। हालांकि मेक मैन पेज में एक बग है, क्योंकि यह बताता है: "किसी भी फाइल का रीमेक बनाने की कोशिश किए बिना डेटा बेस को प्रिंट करने के लिए, मेकअप -p / dev / null का उपयोग करें"
Davide

मेरी पिछली टिप्पणी में थोड़ा सुधार: इसे "... क्योंकि बिना -n ..." पढ़ना चाहिए
एरिक मेल्स्की


7

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

#!/bin/bash

SCRIPT='
  /^# Make data base/,/^# Files/d             # skip until files section
  /^# Not a target/,+1          d             # following target isnt
  /^\.PHONY:/                   d             # special target
  /^\.SUFFIXES:/                d             # special target
  /^\.DEFAULT:/                 d             # special target
  /^\.PRECIOUS:/                d             # special target
  /^\.INTERMEDIATE:/            d             # special target
  /^\.SECONDARY:/               d             # special target
  /^\.SECONDEXPANSION/          d             # special target
  /^\.DELETE_ON_ERROR:/         d             # special target
  /^\.IGNORE:/                  d             # special target
  /^\.LOW_RESOLUTION_TIME:/     d             # special target
  /^\.SILENT:/                  d             # special target
  /^\.EXPORT_ALL_VARIABLES:/    d             # special target
  /^\.NOTPARALLEL:/             d             # special target
  /^\.ONESHELL:/                d             # special target
  /^\.POSIX:/                   d             # special target
  /^\.NOEXPORT:/                d             # special target
  /^\.MAKE:/                    d             # special target

# The stuff above here describes lines that are not
#  explicit targets or not targets other than special ones
# The stuff below here decides whether an explicit target
#  should be output.

  /^[^#\t:=%]+:([^=]|$)/ {                    # found target block
    h                                         # hold target
    d                                         # delete line
  }
  /^# File is an intermediate prerequisite/ { # nope
    s/^.*$//;x                                # unhold target
    d                                         # delete line
  }
  /^([^#]|$)/ {                               # end of target block
    s/^.*$//;x                                # unhold target
    s/:.*$//p                                 # write current target
    d                                         # hide any bugs
  }
'

make -npq .DEFAULT 2>/dev/null | sed -n -r "$SCRIPT" \
  | sort | uniq

यह डेबियन बैश समापन स्क्रिप्ट की तुलना में बहुत अधिक पूर्ण स्क्रिप्ट है क्योंकि यह उत्पन्न नियमों के लिए परिणाम प्रदान करता है जो कि सवाल पूछता है और शीर्ष मतदान जवाब (डेबियन गिट सर्वर पर डेबियन बैश पूरा स्क्रिप्ट) बहुत दूर नहीं जाता है।

यह मूल स्क्रिप्ट नहीं है जिसे मैंने लिंक किया है, लेकिन यह बहुत सरल है और एक स्पर्श तेज है।


BTW, mods, अगर यह उत्तर पूरी तरह से पाठ की बारीकियों के कारण सभी नीतियों के अनुरूप नहीं है, तो कृपया हटाने से पहले टिप्पणी करें। मैं किसी भी क़ानूनी समायोजन को आवश्यक बनाऊंगा ताकि इस प्रश्न का वास्तव में पूर्ण और मान्य उत्तर मिल सके।
कोडेशोट

एक त्वरित परीक्षण के रूप में मैंने gcc स्रोत कोड को पकड़ा और भाग गया। /configure && time ~ / makecomp.sh | wc -l जहाँ ~ / makecomp.sh मेरा उत्तर है। ... कॉन्फ़िगर आउटपुट ... config.status: Makefile 3312 असली 0m0.401s उपयोगकर्ता 0m0.412s sys 0m0.028s
कोडेशॉट

एक अन्य परीक्षण के रूप में मैंने कोडशॉट . blogspot.co.uk/2012/08/… पर डेमो मेकफाइल का इस्तेमाल किया, जो यूनिट-टेस्ट पास बनाने और जाँचने के लिए छद्म नियम बनाता है। यह उदाहरण एक विशिष्ट क्रॉस-प्लेटफ़ॉर्म ऑटोकॉन्फ़ प्रोजेक्ट की तुलना में मेक की अधिक सुविधाओं का उपयोग करता है इसलिए इस उत्तर में स्क्रिप्ट 14 वास्तविक लक्ष्य देता है जबकि उबंटू पर बनाने के लिए पूरा होने वाले बैश केवल दो उपयोगी नियम और फिर 5 स्रोत फ़ाइलें देता है।
कोडेशोट

4

यह टॉड होड्स समाधान पर आधारित उपनाम के लिए कोड है

alias mtargets='make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"'



2

लगता है कि मुझे इस पार्टी में थोड़ी देर हो गई है, लेकिन यदि आप एक विशिष्ट आदेश की तलाश कर रहे हैं तो आप कोशिश कर सकते हैं

make -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'

यह ज्यादातर काम करता है, हालांकि इसमें अभी भी कुछ गैर-लक्षित सामान जैसे vpathनिर्देश शामिल हो सकते हैं । यदि आप makeनिर्मित नियमों पर निर्भर नहीं हैं , तो आप make -qpRपाइपलाइन में पहले कमांड के रूप में उपयोग कर सकते हैं ।


मैंने इसे freetz (.org) के साथ आज़माया। बहुत सारे शामिल किए गए मेकफाइल्स को सूचीबद्ध करता है और सभी लक्ष्यों को सूचीबद्ध नहीं करता है।
रॉबर्ट सिएमर

1

रूबी समाधान:

`make -qp`.split("\n").select{|l| l =~ /^\w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'')}

1

मैं सोलारिस 10a टर्बो सी शेल पर काम कर रहा हूं। दिए गए समाधान मेरे मेकफाइल प्रोजेक्ट के लिए काम नहीं करते हैं। ऊपर के कमांड लाइन को tcsh सिंटैक्स में बदलने के बाद भी। हालांकि, मुझे पता चला कि आप एक आसान समाधान का उपयोग कर सकते हैं

remake --tasks | grep -v "clean some static output or just grep tabs on start of line" | awk ´{print $1}´

रीमेक संस्करण:

remake --version

है

GNU Make 3.82+dbg0.8
Built for sparc-sun-sparc2-9

और कुछ अन्य महत्वहीन संस्करण डेटा


0

मैं उसी प्रश्न की तलाश में था और इस स्पिन के साथ आया:

make -pn | sed -rn '/^[^# \t\.%].*:/p'

यह सभी टिप्पणी लाइनों, पैटर्न नियमों (टैब से शुरू होने वाली रेखाएं), सभी आंतरिक (उदाहरण .c.oऔर %.o: %.cपैटर्न) को हटा देता है ।


स्वीकार किए गए उत्तर से टिप्पणी नहीं पढ़ी: जैक के जवाब के लिए +1 ... gist.github.com/777954 - pvandenberk 13 जनवरी को 14:47 पर
जेमी

0

इस समाधान को एक और सूत्र में मिला:

sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\""

आप इसे अपने लिए भी जोड़ सकते हैं Makefile:

list:
    sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\\""

और निष्पादित करें make list


-1

यकीन है, लेकिन जब आप यह चाहते हैं कि उन्हें बाहर थूकना है?

लक्ष्य का नाम रिपोर्ट करने के लिए, जब वह नियम चलाता है, नियम में एक पंक्ति डालें:

foo$(VAR): $(PREREQS)
    @echo now making the foo target: $@
    do_other_stuff...

एक बार में उन सभी को बाहर निकालने के लिए, आप एक अलग PHONY लक्ष्य बना सकते हैं:

.PHONY: show_vars
show_vars:
    @echo foo$(VAR)
    @echo bar$(PARAM) blah$(FLAG)
    # and so on

और इसे आपके डिफ़ॉल्ट लक्ष्य की शर्त बनाया जा सकता है:

all: show_vars
    ...

संपादित करें:
आप एक मनमाना मेकफिल के सभी संभावित लक्ष्यों को दिखाने का एक तरीका चाहते हैं, जो मुझे लगता है कि इसका मतलब गैर-घुसपैठ है। कुंआ...

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

सरल नियमों के लक्ष्यों को देखने के लिए, आप एक मेकफाइल लिख सकते हैं जो एक मेकफाइल स्कैनर के रूप में काम करेगा, जो मनमाने ढंग से मेकफाइल पर काम कर रहा है:

  1. Sed का उपयोग करते हुए makefile से सभी लक्षित नाम प्राप्त करें।
  2. `चर शामिल करने के लिए इसका इस्तेमाल करने के लिए मेकफाइल को शामिल करें।
  3. `Show_% का उपयोग करें:; सभी लक्ष्यों को मुद्रित करने के लिए $ $ * प्रतिध्वनि करें

यह एक प्रभावशाली कृति होगी। क्या आप सुनिश्चित हैं कि लक्ष्य प्रयास के लायक है?


जो मैं चाहता हूं वह बिलकुल नहीं। मैं एक मनमाने ढंग से किए गए बदलाव के लिए लक्ष्य की एक सूची बनाने में सक्षम होना चाहूंगा जो मेरे पास हो सकता है। मैं अपने शेल के लिए एक तर्क पूर्ण कार्य लिखने की कोशिश कर रहा हूं और मैं किसी भी समझदार मदद करने वाले मेकअप पर भरोसा नहीं कर सकता।
बिटशिफ़र

-4
grep ^[a-z].*\:$ Makefile | sed s,:,,g

1
-1: यह दृष्टिकोण साधारण चर असाइनमेंट ( :=) के लिए भी झूठी सकारात्मकता पैदा करता है ।
तेरह

आपको पहले इसका परीक्षण करना चाहिए था। यह अच्छा है कि आप कोशिश करें, हालांकि।
कोनराड विन्टर्स्टन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.