पेड़ के रूप में मेकफाइल में दी गई निर्भरता कैसे प्रदर्शित करें?


18

मुसीबत

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

समान

ऐसे कार्यक्रम हैं जो अन्य स्थितियों के लिए ऐसा करते हैं:

  • पैक्ट्री या डेट्री संबंधित फॉर्मेट में सॉफ्टवेयर पैकेज के लिए निर्भरता प्रदर्शित कर सकते हैं जैसे कि आस्की प्रारूप में या dotग्राफ के रूप में ,
  • gcc -M source_file.c सी स्रोत फ़ाइल की निर्भरता को एक नियम के रूप में प्रदर्शित करता है,
  • pstree प्रक्रिया पेड़ के एक ascii प्रतिनिधित्व प्रदर्शित करता है।

प्रगति

वेब पर सर्च करने पर मुझे थोड़ी मदद मिली । कि मुझे कोशिश करने के लिए नेतृत्व

make --always-make --silent --dry-run some_target | \
  grep --extended-regexp 'Considering target file|Trying rule prerequisite'

लेकिन ऐसा लगता है कि मुझे एक अच्छा पेड़ या ग्राफ़ के रूप में प्रतिनिधित्व करने के लिए पर्ल या अजगर में कुछ और पार्सिंग कोड हैक करना होगा। और मुझे अभी तक नहीं पता है कि क्या मुझे इस तरह से पूर्ण और सही ग्राफ़ मिलेगा।

आवश्यकताएँ

कुछ तरीकों से ग्राफ को सीमित करना अच्छा होगा (कोई बिलियन नियम, केवल एक दिया गया लक्ष्य, केवल कुछ गहराई) लेकिन सबसे अधिक भाग के लिए मैं सिर्फ एक उपकरण की तलाश कर रहा हूं जो मुझे कुछ "उचित" में निर्भरता देगा, मानव -उपलब्ध प्रारूप ("समान" के तहत कार्यक्रमों की तरह)।

प्रशन

  • क्या कोई कार्यक्रम हैं जो ऐसा कर सकते हैं?
  • क्या मुझे पूरी और सही जानकारी मिलेगी make -dnq ...?
  • क्या यह जानकारी प्राप्त करने का कोई बेहतर तरीका है?
  • क्या इस जानकारी को पार्स करने के लिए स्क्रिप्ट / प्रयास पहले से मौजूद हैं?

1
यहाँ समझने के लिए महत्वपूर्ण बात यह है: निर्भरता एक पेड़ नहीं है। वे एक निर्देशित और (उम्मीद है!) एसाइक्लिक ग्राफ - जिसे डीएजी के रूप में भी जाना जाता है । निम्नलिखित के लिए निर्भरता ग्राफ को स्केच करने की कोशिश करें और आप इसे देखेंगे: ए बी पर निर्भर करता है; A, C पर भी निर्भर करता है; बी डी पर निर्भर करता है; C, D पर निर्भर करता है
Wildcard

@Wildcard मुझे पता है लेकिन मेरे उद्देश्य के लिए यह एक पेड़ के रूप में निर्भरता का प्रतिनिधित्व करने के लिए पर्याप्त है । मैं इसे पेड़ बनाने के लिए सबग्राफ (और हलकों में काटने) की नकल करने के साथ ठीक हूं। स्पष्ट नहीं होने के लिए क्षमा करें। आप उदाहरण के लिए मैं के उत्पादन के साथ ठीक हो जाएगा printf 'A\n B\n D\n C\n D\n'। (किसने कहा कि मैं टिप्पणियों में नई बात नहीं डाल सकता? :)
लुकास

यह कैसे अलग होगा "ए बी पर निर्भर करता है? बी डी पर निर्भर करता है; डी सी पर निर्भर करता है? ए डी पर निर्भर करता है"। आप किसी भी DAG पर कोई भी आदेश दे सकते हैं (क्योंकि कोई भी DAG आंशिक आदेश का प्रतिनिधित्व करता है), लेकिन आप DAG को एक पेड़ में नहीं बदल सकते। यह मूल ग्राफ सिद्धांत है। मुझे DAG का ट्री प्रतिनिधित्व बनाने के लिए आपके एल्गोरिदम को देखने में दिलचस्पी होगी, जिसे तब प्रदर्शित किया जा सकता है। इस तरह के एक अंतर्निहित एल्गोरिदम के बिना, किसी भी उपकरण ने जो पेड़ के रूप में निर्भरता प्रदर्शित करने की मांग की थी, वह बहुत हैकरी और त्रुटि-प्रवण होगा।
वाइल्डकार्ड

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

2
RANT: मैं ईमानदारी से थोड़ा निराश हूँ जो इस तरह के आउट-ऑफ-द-बॉक्स की पेशकश नहीं करता है। बनाओ दुनिया में सबसे व्यापक प्रसार वाली निर्माण प्रणालियों में से एक है, और यह सुविधा इतनी अधिक उपयोगी होगी कि यह समझ पाना मुश्किल है कि भगवान के दौरान कितने दशकों तक पता चलता है कि किसी ने ऐसी सुविधा नहीं जोड़ी है। एक स्पष्ट रूप से परिभाषित पाठ्य प्रारूप में इस जानकारी को आउटपुट करना पूरी तरह से पर्याप्त होगा। मैं समझता हूं कि मेक ओपन सोर्स है और मैं हमेशा इस फीचर को खुद से जोड़ सकता हूं। और मेरा विश्वास करो, अगर मूल रूप से मेरे लिए एक ब्लैक बॉक्स नहीं था, तो मैं करूंगा! अधिक शेख़ी मारना।
11:27 पर

जवाबों:


10

Makefile2graph को उसी लेखक से आज़माएँ , जिसके समान एक उपकरण है MakeGraphDependencies केjava बजाय लिखा गया है c

make -Bnd | make2graph | dot -Tsvg -o out.svg

फिर आप की जरूरत है कनेक्शन को उजागर करने के लिए कुछ वेक्टर ग्राफिक्स संपादक का उपयोग करें।


1
मैंने वह टूल आजमाया है। यह भी काम करना शुरू नहीं करता है (कम से कम किसी भी अवतार के लिए जो मैंने इसके साथ कोशिश की थी) नहीं। ज्यादातर समय यह सिर्फ कुछ मेमोरी एक्सेस उल्लंघन के साथ निकल जाता है।
विरोध किया

3

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

getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))


VARIABLE_TARGET_NAME = foobar.txt

all : TopLevelTarget

TopLevelTarget : Target_A Target_D
    $(call getRecipe,\
        @echo Building target $@)

Target_A : Target_B
    $(call getRecipe,\
        @echo Building target $@)

Target_D : Target_C
    $(call getRecipe,\
        @echo Building target $@)

Target_B : $(VARIABLE_TARGET_NAME)
    $(call getRecipe,\
        @echo Building target $@)

Target_C :
    $(call getRecipe,\
        @echo Building target $@)

$(VARIABLE_TARGET_NAME) :
    $(call getRecipe,\
        @echo Building target $@)

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

DEPENDENCY_GRAPH1 के सेट के साथ , यह आउटपुट में होता है:

Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"

जो पार्स करने के लिए काफी आसान होना चाहिए और फिर एक डॉट-ग्राफ़ में परिवर्तित हो जाना चाहिए।

DEPENDENCY_GRAPHसभी पर सेट या 0 पर सेट नहीं होने के साथ , आउटपुट है:

Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget

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

उदाहरण के लिए, अंतिम लक्ष्य बनाने की विधि में, अगर यह कहने के अलावा कि लक्ष्य बनाया जा रहा है, तो मैं वास्तव touchमें फाइल करना चाहता था :

$(VARIABLE_TARGET_NAME) :
    $(call getRecipe,\
        @echo Building target $@\
        touch $@)

makeलगता है कि यह touch $@हिस्सा पिछली पंक्ति में गूंज का हिस्सा है:

Building target foobar.txt touch foobar.txt

अगर मैं पिछली पंक्ति में पीछे चल रही makeशिकायत को छोड़ देता हूं, तो *** unterminated call to functionकॉल की शिकायत करता है ': अनुपलब्ध )'. Stop.यदि किसी को makeअच्छा खेलने के लिए एक विचार है , तो मैं सभी कान हूं। :)

संपादित करें: इस दृष्टिकोण के साथ अन्य समस्या यह है कि यह केवल तभी काम करेगा जब कोई बिल्ड परिणाम पहले से मौजूद न हो, जैसा कि makeस्पष्ट रूप से एक लक्ष्य के बिल्ड नुस्खा को निष्पादित नहीं करता है जो इसे अप-टू-डेट मानता है।


काम करने के लिए टच कमांड के ;बाद जोड़ेंtarget $@
mug896

दूसरी समस्या के लिए, make -Bविकल्प का उपयोग करें जो बिना शर्त सभी लक्ष्यों को बनाते हैं।
मग896

2

मैंने रीमेक - लाभकारी (एक ड्रॉप-इन रिप्लेसमेंट के लिए make) का इस्तेमाल किया, इसने कॉलग्रिंड प्रारूप में एक निर्भरता का पेड़ उत्पन्न किया।

तब gprof2dot लक्ष्य पेड़ की एक छवि उत्पन्न कर सकता है।


क्या मैं दस्तावेज़ को गलत समझता हूं या remake --profileकेवल उस लक्ष्य के लिए निर्भरता ग्राफ को आउटपुट करता है जिसे वह निष्पादित करता है? या यह किसी भी तरह से सभी लक्ष्यों के लिए ग्राफ को आउटपुट कर सकता है?
लुकास

केवल एक ही इसे चलाता है, मुझे डर है। लेकिन आप उन सभी को ड्री-रन के साथ चला सकते हैं
विक्टर सर्जेनको

अरे हाँ, कुछ ऐसा ही remake --targets -r | grep -v %| grep -v '\t*\.'|xargs remake -n --profile -Bहोनहार लग रहा है।
लुकास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.