আপনি কিভাবে একটি মেকফিলের লক্ষ্যগুলি তালিকা পেতে পারেন?


202

আমি রেকটিকে কিছুটা ব্যবহার করেছি (একটি রুবি মেক প্রোগ্রাম), এবং এটিতে উপলভ্য সমস্ত লক্ষ্যমাত্রার একটি তালিকা পাওয়ার বিকল্প রয়েছে যেমন,

> rake --tasks
rake db:charset      # retrieve the charset for your data...
rake db:collation    # retrieve the collation for your da...
rake db:create       # Creates the databases defined in y...
rake db:drop         # Drops the database for your curren...
...

তবে মনে হয় জিএনইউ মেক করার ক্ষেত্রে এটি করার কোনও বিকল্প নেই।

স্পষ্টতই কোডটি এর জন্য প্রায় 2007 এর মতই রয়েছে - http://www.mail-archive.com/help-make@gnu.org/msg06434.html

যাইহোক, আমি একটি মেকফিল থেকে লক্ষ্যগুলি নিষ্কাশন করতে সামান্য হ্যাক করেছি, যা আপনি একটি মেকফিলের মধ্যে অন্তর্ভুক্ত করতে পারেন।

list:
    @grep '^[^#[:space:]].*:' Makefile

এটি আপনাকে নির্ধারিত লক্ষ্যগুলির একটি তালিকা দেবে। এটি কেবল একটি সূচনা - এটি নির্ভরতাগুলি ফিল্টার করে না, উদাহরণস্বরূপ।

> make list
list:
copy:
run:
plot:
turnin:

2
আমি দ্রুত উত্তরগুলি পড়ি, যা আকর্ষণীয়, তবে এখনও পর্যন্ত আমি এটিকে একটি উপনাম (আমার .bashrc) এর সাহায্যে সরল, সরল এবং পোর্টেবল রাখতে পছন্দ করি: alias makefile-targets='grep "^[^#[:space:]].*:" Makefile' বেশিরভাগ ক্ষেত্রে আমার কেবল বর্তমান মেকফাইল পরীক্ষা করা দরকার, এবং ব্যাশের সমাপ্তি প্রসারিত হয় আমার উপনাম
রকিরোড


4
এটা খুব তুচ্ছ ঠিক হয়: grep : Makefile?
cibercitizen1

উত্তর:


130

এটি নীচে @ নবারের দুর্দান্ত পদ্ধতির উন্নতি করার চেষ্টা :

  • টার্গেটের নামগুলি বের করার জন্য আরও শক্তিশালী কমান্ড ব্যবহার করে, যা প্রত্যাশা করে যে কোনও মিথ্যা ইতিবাচক প্রতিরোধ করে (এবং অপ্রয়োজনীয়তাও সরিয়ে দেয় sh -c)
  • বর্তমান ডিরেক্টরিতে অবিচ্ছিন্নভাবে মেকফিলটিকে লক্ষ্য করে না ; শ্রদ্ধার সাথে মেকফিলগুলি স্পষ্টভাবে নির্দিষ্ট করে-f <file>
  • গোপন লক্ষ্যগুলি বাদ দেয় - কনভেনশন অনুসারে, এগুলি এমন টার্গেট যাঁর নাম অক্ষর বা অঙ্ক দিয়ে শুরু হয় না
  • একটি একক কল্পনা লক্ষ্য সঙ্গে কাজ করে
  • কমান্ডটি @প্রয়োগের পূর্বে প্রতিধ্বনিত হতে আটকাতে প্রিফিক্স করে

কৌতূহলজনকভাবে, makeজিএনইউর কোনও মেকফিলে সংজ্ঞায়িত টার্গেটের নামের তালিকা তৈরির কোনও বৈশিষ্ট্য নেই। -pবিকল্প আউটপুট যে সব লক্ষ্যমাত্রা অন্তর্ভুক্ত উত্পাদন করে, কিন্তু তাদের অন্যান্য তথ্য অনেক লুকিয়ে রাখে।

জিএনইউতে makeএকটি টার্গেট বাস্তবায়নের জন্য একটি মেকফিলের মধ্যে নিম্নলিখিত নিয়মটি রাখুন যার listনাম বর্ণানুক্রমিক ক্রমে সমস্ত টার্গেটের নাম তালিকাভুক্ত করা হয় - যেমন: অনুরোধ করুনmake list :

.PHONY: list
list:
    @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'

গুরুত্বপূর্ণ : এটি আটকানোর সময়, নিশ্চিত হয়ে নিন যে শেষ লাইনটি ঠিক 1 প্রকৃত ট্যাব চর দ্বারা সূচিত হয়েছে (স্পেস কাজ করে না )

লক্ষ্য করুন বাছাই লক্ষ্যমাত্রা ফলে তালিকা, সবচেয়ে ভাল বিকল্প যেহেতু না বাছাই যে ক্রমে লক্ষ্যমাত্রা Makefile মধ্যে প্রদর্শিত হয় একটি সহায়ক ক্রম উত্পাদন না না সংরক্ষিত।
এছাড়াও, একাধিক লক্ষ্য নিয়ে গঠিত একটি নিয়মের উপ-লক্ষ্যগুলি অদৃশ্যভাবে পৃথকভাবে আউটপুট হয় এবং তাই বাছাইয়ের কারণে, সাধারণত একে অপরের পাশে উপস্থিত হয় না ; উদাহরণস্বরূপ, কোনও নিয়ম দিয়ে শুরু হওয়াতে লক্ষ্যমাত্রা a z:থাকবে নাa এবং আউটপুটে একে অপরের পাশেz তালিকাভুক্ত করা হবে , যদি অতিরিক্ত লক্ষ্যবস্তু থাকে।

বিধি ব্যাখ্যা :

  • PHONY: list
    • টার্গেট লিস্টকে একটি ফনি টার্গেট ঘোষণা করে, অর্থাত্ কোনও ফাইলকে উল্লেখ করে না , যার ফলে এর রেসিপিটি নিঃশর্তভাবে আহ্বান করা উচিত
  • $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null

    • মেকফাইল makeথেকে প্রাপ্ত ডেটাবেস মুদ্রণ এবং পার্স করার জন্য আবার অনুরোধ করুন:
      • -p ডাটাবেস মুদ্রণ
      • -Rr অন্তর্নির্মিত নিয়ম এবং ভেরিয়েবল অন্তর্ভুক্তি দমন করে
      • -qকেবলমাত্র কোনও টার্গেটের আপ-টু-ডেট-স্ট্যাটাস পরীক্ষা করে (কোনও কিছুই পুনর্বিবেচনা ছাড়াই), তবে এটি নিজে থেকেই সমস্ত ক্ষেত্রে রেসিপি আদেশের প্রয়োগকে আটকাতে পারে না; অত: পর:
      • -f $(lastword $(MAKEFILE_LIST))এটি নিশ্চিত করে যে এটি একই মেকফিলটিকে মূল অনুরোধের মতো লক্ষ্যবস্তু করা হয়েছে, তা নির্বিশেষে বা স্পষ্টতই লক্ষ্যবস্তু ছিল তা নির্বিশেষে -f ...
        ক্যাভেট : আপনার মেকফাইলে includeনির্দেশ থাকলে এটি ভেঙে যাবে ; এটিকে সমাধান করতে, কোনও নির্দেশাবলীর THIS_FILE := $(lastword $(MAKEFILE_LIST)) আগে পরিবর্তনশীল সংজ্ঞায়িত করুন includeএবং -f $(THIS_FILE)পরিবর্তে ব্যবহার করুন।
      • :একটি হল ইচ্ছাকৃতভাবে অবৈধ লক্ষ্য যে বোঝানো হয় তা নিশ্চিত কোনো কমান্ড মৃত্যুদন্ড কার্যকর করা হয় ; 2>/dev/nullফলাফল ত্রুটি বার্তা দমন করে। দ্রষ্টব্য: এটি -pতথাপি ডাটাবেস মুদ্রণের উপর নির্ভর করে , এটি জিএনইউ-র 3.82 হিসাবে তৈরি make দুঃখজনকভাবে, এর গনুহ করতে অফার কোন সরাসরি বিকল্প মাত্র ডাটাবেসের মুদ্রণ ছাড়া এছাড়াও ডিফল্ট (অথবা দেওয়া হয়) কাজের নির্বাহ; আপনার যদি কোনও নির্দিষ্ট মেকফিলকে টার্গেট করার দরকার না হয় তবে আপনি পৃষ্ঠায় make -p -f/dev/nullসুপারিশ অনুসারে ব্যবহার করতে পারেন man
  • -v RS=

    • এটি একটি জাঁকজমক আইডিয়ম যা সংহত খালি খালি লাইনের ব্লকে ইনপুটটিকে ভেঙে দেয়।
  • /^# File/,/^# Finished Make data base/
    • আউটপুটে রেখার পরিসীমা মেলে যা সমস্ত লক্ষ্যবস্তু রাখে (জিএনইউ হিসাবে সত্য 3.82 তৈরি করে) - এই ব্যাপ্তিতে পার্সিং সীমাবদ্ধ করে, অন্য আউটপুট বিভাগগুলির মিথ্যা ধনাত্মক মোকাবেলা করার দরকার নেই।
  • if ($$1 !~ "^[#.]")
    • নির্বাচিতভাবে ব্লকগুলি উপেক্ষা করুন:
      • # ... অ-লক্ষ্যগুলি উপেক্ষা করে, যার ব্লকগুলি দিয়ে শুরু হয় # Not a target:
      • . ... বিশেষ লক্ষ্যগুলি উপেক্ষা করে
    • অন্যান্য সমস্ত ব্লকের প্রত্যেকটি কেবল একটি স্পষ্টভাবে সংজ্ঞায়িত টার্গেটের নামের পরে একটি লাইন দিয়ে শুরু করা উচিত :
  • egrep -v -e '^[^[:alnum:]]' -e '^$@$$' আউটপুট থেকে অযাচিত লক্ষ্যগুলি সরিয়ে দেয়:
    • '^[^[:alnum:]]'... গোপন লক্ষ্যগুলি বাদ দেয় , যা - কনভেনশন অনুসারে - এমন লক্ষ্যগুলি যা কোনও চিঠি বা অঙ্ক দিয়ে শুরু হয় না।
    • '^$@$$'... listলক্ষ্য নিজেই বাদ দেয়

make listতারপরে চালানো সমস্ত লক্ষ্যবস্তু মুদ্রিত করে, প্রতিটি তার নিজস্ব লাইনে; xargsপরিবর্তে একটি স্থান দ্বারা পৃথক তালিকা তৈরি করতে আপনি পাইপ করতে পারেন ।


এটি একটি দুর্দান্ত উত্তর, তবে আমি কীভাবে প্রতিটি কাজের বিবরণ পেতে পারি? বর্তমানে, আমি এটিকে টাস্ক সংজ্ঞা উপরে একটি মন্তব্য হিসাবে সংরক্ষণ করছি। নিশ্চিত না যে এটির মতো এটি তালিকাতে অন্তর্ভুক্ত করা সম্ভব rake --tasksকিনা?
পাইটর কুকিজেনস্কি

1
@ পাইওত্রেকুজেনস্কি: আকর্ষণীয় প্রশ্ন, তবে আমি আপনাকে এটি একটি নতুন প্রশ্ন হিসাবে পোস্ট করার পরামর্শ দিচ্ছি (রেফারেন্সের জন্য এটির দিকে ইঙ্গিত করে)।
mklement0

"দুঃখের বিষয়, জিএনইউ মেকিং কেবলমাত্র ডাটাবেস মুদ্রণের জন্য কোনও সরাসরি বিকল্প দেয় না।" একটি -nবিকল্প আছে।
বুলেটম্যাগনেট

@ বুলেটমেগনেট: -nবিকল্পটির উদ্দেশ্য হ'ল "যে আদেশগুলি কার্যকর করা হবে তা মুদ্রণ করা ..." - অন্য কথায়: একটি শুকনো-চালিত বৈশিষ্ট্য। এছাড়াও আপনার উদ্ধৃতি শব্দের italicization অনুপস্থিত যে শুধু : make -pনিজে করে ডাটাবেসের প্রিন্ট কিন্তু সবসময় ডিফল্ট টাস্ক সঞ্চালিত হয় ; ম্যানুয়ালটি make -p -f/dev/nullএড়ানোর জন্য চতুরটিকে সুপারিশ করে ।
mklement0

1
কোনও .PHONY টার্গেটগুলিও তালিকাভুক্ত করবে, সুতরাং আপনার কাছে নেই তা নিশ্চিত করুন.PHONY: *
টেকুমার

189

বাশের অধীনে (কমপক্ষে), ট্যাব সমাপ্তির সাথে এটি স্বয়ংক্রিয়ভাবে করা যেতে পারে:

make spacetabtab


1
পরীক্ষিত: বাশ - রূপান্তর = 4.2.45 (1) -প্রথম। Make --version = 3.81।
নোবার

53
+1, তবে মনে রাখবেন যে এটি কোনও ব্যাশ বৈশিষ্ট্য নয়, তবে এটি আপনার প্ল্যাটফর্মের উপর নির্ভর করে । প্ল্যাটফর্মগুলি তিনটি বিভাগে বিভক্ত: এই সমাপ্তিটি যেখানে ডিফল্টরূপে ইনস্টল করা হয় (যেমন, ডেবিয়ান 7, ফেডোরা 20), আপনি যেখানে option চ্ছিকভাবে এটি ইনস্টল করতে পারেন (যেমন, উবুন্টু 14, সহ . /etc/bash_completion) এবং যেগুলি একেবারেই সমর্থন করে না (উদাঃ, ওএসএক্স 10.9)
mklement0

8
এটি ওএস এক্স 10.10 (ব্যাশের সাথে নয় তবে zsh এর সাহায্যে) কাজ করে।
ফ্লোরিয়ান ওসওয়াল্ড

4
দুর্দান্ত টিপ তবে bash-completionপ্যাকেজও দরকার। ফেডোরায় পাওয়া গেছে, আরএইচইএল, জেন্টু, ect।
নোয়েলপ্রফ

4
এটি কর্মসূচী অনুসারে তৈরি এএএএফসিটি লক্ষ্যগুলি নিয়ে কাজ করে না, যেমন$(RUN_TARGETS): run-%: ...
ম্যাথিয়ায়াস

31

এটি অবশ্যই বেশিরভাগ ক্ষেত্রে কাজ করবে না, তবে যদি আপনার Makefileসিএমকে তৈরি করা হয় তবে আপনি চালাতে সক্ষম হতে পারেন make help

$ make help
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... install
etc

এটি পেতে আপনার সিএমকেলিস্টে চালু করার কোনও বিকল্প আছে কি? আমি সিএমকে তৈরি একটি মেকফাইল পেয়েছি এবং সিউডো সহায়তা লক্ষ্য উপলব্ধ নেই
জাভিয়ের টি।

নাঃ। কমপক্ষে সাম্প্রতিক সিএমকে নিয়ে ওএসএক্সে (আমি আসলে রাত্রে ব্যবহার করছি তবে আমি বিশ্বাস করি যে আমি যখন এটি লিখলাম তখন আমি ৩.৩ ব্যবহার করছিলাম), কেবল চালান touch CMakeLists.txt && cmake . && make helpএবং এটি কাজ করা উচিত। আমি কেবল অনুমান করতে পারি আপনি একটি প্রাচীন চাগল ব্যবহার করছেন, বা ইউনিক্স মেকফিলস জেনারেটরটি ব্যবহার করছেন না?
টিম্ম্ম্ম

আমি উইন্ডোজটিতে ইউনিক্স জেনারেটরের সাথে সিএমকে ৩. 3..২ ব্যবহার করছি। আমি ব্যাখ্যা খোঁজার জন্য চারপাশে খনন করব কারণ এটি সুবিধাজনক বলে মনে হচ্ছে।
জাভিয়ার টি।

26

আমি এই দুটি উত্তর একত্রিত করেছি: https://stackoverflow.com/a/9524878/86967 এবং https://stackoverflow.com/a/7390874/86967 এবং কিছু পালাতে পেরেছি যাতে এটি কোনও মেকফিলের অভ্যন্তর থেকে ব্যবহার করা যায়।

.PHONY: no_targets__ list
no_targets__:
list:
    sh -c "$(MAKE) -p no_targets__ | awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {split(\$$1,A,/ /);for(i in A)print A[i]}' | grep -v '__\$$' | sort"

$ make -s list
build
clean
default
distclean
doc
fresh
install
list
makefile ## this is kind of extraneous, but whatever...
run

10
আমি এটিও (সম্প্রতি) আবিষ্কার করেছি যে বাশের অধীনে ট্যাব-সমাপ্তি উপলব্ধ লক্ষ্যবস্তু তালিকাভুক্ত করবে।
নোবার

1
একটি দুর্দান্ত পদ্ধতির জন্য +1, তবে কয়েকটি উন্নতি করা যেতে পারে: (ক) স্পষ্টভাবে নির্দিষ্ট করে দেওয়া sh -c "…"অপ্রয়োজনীয়, কারণ এটিই makeডিফল্টরূপে রেসিপি কমান্ড আহ্বান করতে ব্যবহার করে; (খ) আপনি যে আদেশটি ব্যবহার করছেন তা খুব সরল, ফলস্বরূপ মিথ্যা ধনাত্মক (যেমন আপনি লক্ষ্য করুন); (গ) আপনি যদি কমান্ডটি উপস্থাপন করেন তবে @এটি কার্যকর করার আগে স্টাডাউটের প্রতিধ্বনি করা হবে না, অনুরোধের জন্য প্রয়োজনীয় ব্যবহারকে বাধ্য করা -sহবে।
mklement0

1
আপনি যে যুক্ত করতে পারেন তার চেয়ে সহজ সরল লক্ষ্য রয়েছে: তালিকা: বিড়াল মেকফিল | গ্রেপ "^ [আজ]]" | awk '{মুদ্রণ $$ 1}' | সেড "এস /: // জি | সাজান"
থেমস্টার

2
বিড়াল / সেড পদ্ধতির বিভিন্ন স্তরে ব্যর্থতা। এটি ভেরিয়েবলগুলি প্রসারিত করে না, এবং লক্ষ্যগুলি তালিকাভুক্ত করতে ব্যর্থ হয় যা অন্যান্য ফাইলগুলি অন্তর্ভুক্তের ফলাফল।
ট্রয় ড্যানিয়েল

1
@ এমকিলেটমেন্ট ০: আমি মেকফিলের সাথে কমান্ডের প্রাকফিক্স না করে make -s(বাশ ওরফে মাধ্যমে) ব্যবহার করতে পছন্দ করি @। কিছু ক্ষেত্রে রয়েছে যেখানে কার্যকর @হতে পারে, বিশেষত echoকমান্ডগুলির উপসর্গ হিসাবে (যেখানে কমান্ডের প্রদর্শনটি অতিরিক্ত কাজ হবে), তবে সাধারণভাবে আমি এটি ব্যবহার করতে পছন্দ করি না। এইভাবে, আমি যখন প্রয়োজন (তখন ব্যবহার না করে -s) প্রয়োজন হয় তবে আমি "রেসিপিগুলি" দেখতে পাই , তবে সাধারণত না। সম্পর্কিত ডকুমেন্টেশন এখানে: জিএনইউ মেকুয়াল, 5.2 রেসিপি প্রতিধ্বনি
নবার

14

আপনার কাছে makeইনস্টল করার জন্য যদি বাশ সমাপ্তি হয় তবে সমাপ্তি স্ক্রিপ্ট একটি ফাংশন সংজ্ঞায়িত করবে _make_target_extract_script। এই ফাংশনটি এমন একটি sedস্ক্রিপ্ট তৈরি করার উদ্দেশ্যে যা লক্ষ্য হিসাবে লক্ষ্যগুলি অর্জন করতে ব্যবহার করা যায়।

এটি এর মতো ব্যবহার করুন:

# Make sure bash completion is enabled
source /etc/bash_completion 

# List targets from Makefile
sed -nrf <(_make_target_extract_script --) Makefile

3
সহায়ক, তবে মনে রাখবেন যে সমস্ত প্ল্যাটফর্মের স্ক্রিপ্ট /etc/bash_completionএবং / অথবা ফাংশন নেই _make_target_extract_script- আপনি উবুন্টু> 12 তে উপস্থিত রয়েছেন বলে মনে করেন আপনি যদি /usr/share/bash-completion/completions/makeপরিবর্তে লক্ষ্যবস্তু করেন তবে আপনার পদ্ধতির অতিরিক্ত প্ল্যাটফর্মগুলিতে কাজ করবে যেমন ফেডোরা 20 There রয়েছে (পুরানো) প্ল্যাটফর্মগুলি রয়েছে এই ফাইলটি, তবে ফাংশনটি নয় (যেমন, দেবিয়ান 7 এবং উবুন্টু 12); অন্যান্য প্ল্যাটফর্মগুলি, যেমন ওএসএক্স, মোটেও ট্যাব সমাপ্তির সাথে আসে না make। সম্ভবত আসল ফাংশন সংজ্ঞা পোস্ট করা সহায়ক হবে।
mklement0

1
আপনার মন্তব্যের জন্য ধন্যবাদ. এটি অনেক প্রশংসা করা হয়। হ্যাঁ, আমি এটি উবুন্টু 14.04
hek2mgl

11

হিসাবে mklement0 পয়েন্ট আউট , জিএনইউ-মেক থেকে সমস্ত মেকফিল লক্ষ্যমাত্রাগুলি তালিকাভুক্ত করার একটি বৈশিষ্ট্য অনুপস্থিত এবং তার উত্তর এবং অন্যরা এটি করার উপায় সরবরাহ করে।

যাইহোক, মূল লেখাটি উল্লেখ মই দিয়া আহরণ করা , যার কর্ম সুইচ কিছু মাত্র rakefile সমস্ত কর্ম তালিকা চেয়ে কিছুটা ভিন্ন না। রাক কেবল আপনাকে সেই কাজের একটি তালিকা দেবে যা সম্পর্কিত বিবরণ যুক্ত করে। বিবরণ ছাড়া কার্য তালিকাভুক্ত করা হবে না । এটি লেখককে উভয়কে কাস্টমাইজড সহায়তা বিবরণ সরবরাহ করার এবং নির্দিষ্ট লক্ষ্যগুলির জন্য সহায়তা বাদ দেওয়ার ক্ষমতা দেয়।

আপনি যদি রেকের আচরণ অনুকরণ করতে চান, যেখানে আপনি প্রতিটি লক্ষ্যের জন্য বিবরণ সরবরাহ করেন , এটি করার জন্য একটি সহজ কৌশল রয়েছে: আপনি তালিকাভুক্ত প্রতিটি টার্গেটের জন্য মন্তব্যগুলিতে বিবরণ এম্বেড করুন।

আপনি বিবরণটি লক্ষ্যবস্তুটির পাশে রাখতে পারেন বা আমি প্রায়শই লক্ষ্য হিসাবে উপরে একটি PHONY স্পেসিফিকেশনের পাশে রাখতে পারি:

.PHONY: target1 # Target 1 help text
target1: deps
    [... target 1 build commands]

.PHONY: target2 # Target 2 help text
target2:
    [... target 2 build commands]

...                                                                                                         

.PHONY: help # Generate list of targets with descriptions                                                                
help:                                                                                                                    
    @grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20

যা ফলন করবে

$ make help
target1             Target 1 help text
target2             Target 2 help text

...
help                Generate list of targets with descriptions

আপনি এই টুকরোটিতে এবং এখানেও একটি সংক্ষিপ্ত কোড উদাহরণ খুঁজে পেতে পারেন ।

আবার, এটি একটি মেকফাইলে সমস্ত লক্ষ্যগুলি তালিকাভুক্ত করার সমস্যার সমাধান করে না। উদাহরণস্বরূপ, আপনার যদি এমন একটি বড় মেকফিল থাকে যা সম্ভবত উত্পন্ন হয়েছিল বা অন্য কেউ লিখেছিল এবং আপনি এটির লক্ষ্য না রেখে তার লক্ষ্যগুলি তালিকাভুক্ত করার জন্য দ্রুত উপায় চান তবে এটি কোনও লাভ করবে না।

তবে, আপনি যদি কোনও মেকফিল লেখেন এবং আপনি যদি একটি সামঞ্জস্যপূর্ণ, স্ব-ডকুমেন্টিং উপায়ে সহায়তা পাঠ্য উত্পন্ন করার উপায় চান তবে এই কৌশলটি কার্যকর হতে পারে।


এটি একটি দুর্দান্ত কৌশল - দুর্দান্ত এবং সহজ তবে বর্ণনাও দেয়!
ব্রায়ান বার্নস

দুর্দান্ত কৌশল। echoকমান্ডের বিবরণ ( stackoverflow.com/a/52059487/814145 ) হিসাবে কমান্ডটি ব্যবহার করতে আমি এটি কিছুটা পরিবর্তন করেছি ।
পেঙ্গে গেঞ্জ

পোস্ট পেঙ্গেজেং পোস্টের জন্য ধন্যবাদ। আমি পরিষ্কার করতে চাই যে এটি @echo "Target 1"কেবল একটি স্থানধারক এবং "বিবরণ প্রতিধ্বনি কমান্ড" নয়। উত্পন্ন সহায়তা পাঠ্যটি এর থেকে আসে না @echo। একটি বাস্তব মেকফাইলে, এগুলি echoএকটি বিল্ড কমান্ড বা অন্য কোনও দ্বারা প্রতিস্থাপন করা হবে। আরও স্পষ্ট করার জন্য আমি পোস্টটি সম্পাদনা করব।
jsp

4

@ নোবারের উত্তরটি মেকফিলের লক্ষ্যগুলি তালিকাভুক্ত করতে ট্যাব সমাপ্তি কীভাবে ব্যবহার করবেন তা সহায়কভাবে দেখায় ।

  • এটি প্ল্যাটফর্মগুলির জন্য দুর্দান্ত কাজ করে যা ডিফল্টরূপে এই কার্যকারিতা সরবরাহ করে (যেমন, দেবিয়ান, ফেডোরা )।

  • অন্যান্য প্ল্যাটফর্মগুলিতে (উদাঃ উবুন্টু ) আপনাকে অবশ্যই এই কার্যকারিতাটি স্পষ্টভাবে লোড করতে হবে , @ হেক ২ এমজিএল এর উত্তর দ্বারা সূচিত :

    • . /etc/bash_completion এর জন্য একটি সহ কয়েকটি ট্যাব-সমাপ্তির কার্যাদি ইনস্টল করে make
    • বিকল্পভাবে, কেবলমাত্র ট্যাব সমাপ্তির জন্য ইনস্টল করতে make:
      • . /usr/share/bash-completion/completions/make
  • জন্য প্ল্যাটফর্মের যে সব সময়ে এই কার্যকারিতা প্রস্তাব না , যেমন ওএসএক্স , আপনি পারেন উৎস নিম্নলিখিত কমান্ড (থেকে adapated এখানে ) এটি বাস্তবায়ন:
_complete_make() { COMPREPLY=($(compgen -W "$(make -pRrq : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' | egrep -v '^[^[:alnum:]]' | sort | xargs)" -- "${COMP_WORDS[$COMP_CWORD]}")); }
complete -F _complete_make make
  • দ্রষ্টব্য: এটি লিনাক্স ডিস্ট্রিবিউশনগুলির সাথে উপস্থিত ট্যাব-সমাপ্তির কার্যকারিতাটির মতো পরিশীলিত নয়: উল্লেখযোগ্যভাবে, কমান্ড লাইনটি ভিন্ন মেকফাইলকে লক্ষ্য করে হলেও, এটি বর্তমান ডিরেক্টরিটিতে মেকফাইলটিকে লক্ষ্যবস্তু করে-f <file>

4

এর আমার প্রিয় উত্তরটি ক্রিস ডাউন পোস্ট করেছেন ইউনিক্স এবং লিনাক্স স্ট্যাক এক্সচেঞ্জে। আমি উদ্ধৃতি দিব।

এর জন্য বাশ সমাপ্তি মডিউলটি makeতার তালিকাটি পেয়েছে:

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

এটি পেজিং ছাড়াই লক্ষ্যগুলির একটি নতুনলাইন-সীমাবদ্ধ তালিকা প্রিন্ট করে।

ব্যবহারকারী ব্রেনস্টোনsort -u সদৃশ এন্ট্রিগুলি সরাতে পাইপিংয়ের পরামর্শ দেয় :

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

উত্স: কীভাবে সমস্ত লক্ষ্যমাত্রা তৈরি করতে হয়? (ইউনিক্স এবং লিনাক্স এসই)


4

কোনও মেক টার্গেট বর্ণনা করার জন্য একটি সহজ বাক্য গঠনগুলিতে ফোকাস করা, এবং একটি পরিষ্কার আউটপুট থাকার কারণে, আমি এই পদ্ধতিটি বেছে নিয়েছি:

help:
    @grep -B1 -E "^[a-zA-Z0-9_-]+\:([^\=]|$$)" Makefile \
     | grep -v -- -- \
     | sed 'N;s/\n/###/' \
     | sed -n 's/^#: \(.*\)###\(.*\):.*/\2###\1/p' \
     | column -t  -s '###'


#: Starts the container stack
up: a b
  command

#: Pulls in new container images
pull: c d 
    another command

make-target-not-shown:

# this does not count as a description, so leaving
# your implementation comments alone, e.g TODOs
also-not-shown:

সুতরাং উপরেরটিকে একটি Makefile হিসাবে আচরণ করা এবং এটি চালানো আপনাকে এরকম কিছু দেয়

> make help
up          Starts the container stack
pull        Pulls in new container images

কমান্ডের শৃঙ্খলার জন্য ব্যাখ্যা:


খুব সুন্দর সমাধান। আমি এটি কয়েক বছর ধরে ব্যবহার করেছি: লক্ষ্য হিসাবে একই লাইনে মন্তব্য awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort করার ##আগে। তবে আমি মনে করি আপনার সমাধান পাঠযোগ্যতার আগে মঞ্জুরি দেয়।
থারোক

grep: parentheses not balancedআমার ওএসএক্স 10.15 মেশিনে প্রথম দুটি লাইনের প্রতিবেদনগুলির সমন্বয়ে একটি মেকফিল রয়েছে ।
ম্যালকম ক্রাম

@ ক্রিমি দুঃখিত, আমার ভুল এটা ইশারা জন্য ধন্যবাদ। ঠিক কর. মেইকের ডলার সংকেতগুলি পালাতে হবে যা ভেরিয়েবলের নাম শুরু করার কথা নয়।
রিচার্ড কেফার

দেখুন, উপরের কোড বিভাগগুলি প্রদর্শন করার সময় স্ট্যাকওভারফ্লো ট্যাবগুলিকে স্পেসে রূপান্তরিত করে, তবে মেকফিলগুলি ট্যাবগুলির প্রয়োজন। আপনি পোস্টটি সম্পাদনা করতে পারেন এবং বিভাগগুলি অনুলিপি করতে পারেন, তাই ট্যাবগুলি ধরে রাখা যায় ed
রিচার্ড কিফার

2

এখানে প্রচুর পরিশ্রমযোগ্য সমাধান, তবে আমি যেমনটি বলতে চাই, "যদি এটি একবার করার মতো হয় তবে তা আবার করা ভাল।" আমি (ট্যাব) (ট্যাব) ব্যবহারের জন্য উত্সাহকে উত্সাহিত করেছি, তবে কেউ কেউ উল্লেখ করেছেন যে আপনার সম্পূর্ণরূপে সমর্থন নাও থাকতে পারে, বা আপনার যদি অনেকগুলি ফাইল অন্তর্ভুক্ত থাকে তবে আপনি কোথায় লক্ষ্য নির্ধারণ করা হয়েছে তা জানার একটি সহজ উপায় চাইবেন।

আমি সাব-মেক দিয়ে নীচে পরীক্ষা করিনি ... আমার মনে হয় এটি কার্যকর হবে না। যেমনটি আমরা জানি, পুনরাবৃত্তি ক্ষতিকারক হিসাবে বিবেচিত হয়।

.PHONY: list ls
ls list :
    @# search all include files for targets.
    @# ... excluding special targets, and output dynamic rule definitions unresolved.
    @for inc in $(MAKEFILE_LIST); do \
    echo ' =' $$inc '= '; \
    grep -Eo '^[^\.#[:blank:]]+.*:.*' $$inc | grep -v ':=' | \
    cut -f 1 | sort | sed 's/.*/  &/' | sed -n 's/:.*$$//p' | \
    tr $$ \\\ | tr $(open_paren) % | tr $(close_paren) % \
; done

# to get around escaping limitations:
open_paren := \(
close_paren := \)

যা আমি পছন্দ করি কারণ:

  • অন্তর্ভুক্ত ফাইল অন্তর্ভুক্ত তালিকা লক্ষ্য।
  • আউটপুট কাঁচা গতিশীল লক্ষ্য সংজ্ঞা (মডুলোর সাথে পরিবর্তনশীল ডিলিমিটারগুলি প্রতিস্থাপন করে)
  • একটি নতুন লাইনে প্রতিটি লক্ষ্য আউটপুট
  • পরিষ্কার মনে হয় (বিষয়গত মতামত)

ব্যাখ্যা:

  • MAKEFILE_LIST এ পূর্বাভাস ফাইল
  • ফাইলের নাম আউটপুট
  • কোলনযুক্ত গ্রেপ রেখাগুলি, যা ইন্টেন্টেড নয়, মন্তব্য নয়, এবং কোনও সময়ের সাথে শুরু হয় না
  • অবিলম্বে নিয়োগের এক্সপ্রেশনগুলি বাদ দিন (: =)
  • নিয়ম-নির্ভরতা কাটা, সাজান, ইনডেন্ট করুন এবং কাটা দিন (কোলনের পরে)
  • সম্প্রসারণ রোধ করতে পরিবর্তনশীল ডিলিমিটারদের মুঞ্জ করে নিন

নমুনা আউটপুট:

 = Makefile = 
  includes
  ls list
 = util/kiss/snapshots.mk = 
  rotate-db-snapshots
  rotate-file-snapshots
  snap-db
  snap-files
  snapshot
 = util/kiss/main.mk = 
  dirs
  install
   %MK_DIR_PREFIX%env-config.php
   %MK_DIR_PREFIX%../srdb

1

এইটি আমার পক্ষে সহায়ক ছিল কারণ আমি তৈরি লক্ষ্য দ্বারা প্রয়োজনীয় বিল্ড টার্গেটগুলি (এবং তাদের নির্ভরতা) দেখতে চেয়েছিলাম। আমি জানি যে লক্ষ্যগুলি তৈরি করা একটি "দিয়ে শুরু করা যায় না।" অক্ষর। কোন ভাষাগুলি সমর্থিত তা আমি জানি না, তাই আমি egrep এর বন্ধনী এক্সপ্রেশন দিয়ে চলেছি।

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

1

এটি পরিষ্কার থেকে অনেক দূরে, তবে কাজটি আমার পক্ষে হয়েছিল।

make -p 2&>/dev/null | grep -A 100000 "# Files" | grep -v "^$" | grep -v "^\(\s\|#\|\.\)" | grep -v "Makefile:" | cut -d ":" -f 1

আমি ব্যবহার make -pকরি যা আভ্যন্তরীণ ডাটাবেস ডাম্প, স্টাডার খনন করে, grep -A 100000আউটপুটটির নীচে রাখতে একটি দ্রুত এবং ময়লা ব্যবহার করে । তারপরে আমি আউটপুটটি কয়েকটি দিয়ে পরিষ্কার করি grep -vএবং শেষ পর্যন্ত cutকোলনের আগে যা হয় তা লক্ষ্যগুলি অর্জন করতে ব্যবহার করি।

এটি আমার বেশিরভাগ মেকফিলগুলিতে আমার সহায়ক স্ক্রিপ্টগুলির জন্য যথেষ্ট।

সম্পাদনা: grep -v Makefileএটি একটি অভ্যন্তরীণ নিয়ম added


1

এটি জেএসপির খুব সহায়ক উত্তরের একটি পরিবর্তন ( https://stackoverflow.com/a/45843594/814145 )। আমি কেবল টার্গেটের একটি তালিকা নয় তাদের বিবরণও পেতে চাই getting jsp এর মেকফিল বিবরণটিকে মন্তব্য হিসাবে রাখে, যা আমি প্রায়শই লক্ষ্য করেছিলাম লক্ষ্য বর্ণনার ইকো কমান্ডে পুনরাবৃত্তি হবে। সুতরাং পরিবর্তে, আমি প্রতিটি টার্গেটের জন্য ইকো কমান্ড থেকে বর্ণনাটি বের করি।

উদাহরণ Makefile:

.PHONY: all
all: build
        : "same as 'make build'"

.PHONY: build
build:
        @echo "Build the project"

.PHONY: clean
clean:
        @echo "Clean the project"

.PHONY: help
help:
        @echo -n "Common make targets"
        @echo ":"
        @cat Makefile | sed -n '/^\.PHONY: / h; /\(^\t@*echo\|^\t:\)/ {H; x; /PHONY/ s/.PHONY: \(.*\)\n.*"\(.*\)"/    make \1\t\2/p; d; x}'| sort -k2,2 |expand -t 20

এর আউটপুট make help:

$ make help
Common make targets:
    make all        same as 'make build'
    make build      Build the project
    make clean      Clean the project
    make help       Common make targets

মন্তব্য:

  • জেএসপি হিসাবে একই এর উত্তর, শুধুমাত্র অপ্রকৃত লক্ষ্যমাত্রা, তালিকাভুক্ত করা হতে পারে যা বা থাকতে পারি আপনার ক্ষেত্রে জন্য কাজ না
  • তদতিরিক্ত, এটি কেবলমাত্র সেই PHONY টার্গেটগুলি তালিকাভুক্ত করে যা রেসিপিটির প্রথম কমান্ড হিসাবে একটি আদেশ echoবা :কমান্ড রয়েছে। :"কিছুই করবেন না" এর অর্থ। উপরোক্ত টার্গেটের মতো কোনও প্রতিধ্বনি প্রয়োজন নেই এমন লক্ষ্যগুলির জন্য আমি এখানে এটি ব্যবহার করছি all
  • helpলক্ষ্যমাত্রার জন্য make helpআউটপুটে ":" যুক্ত করার জন্য একটি অতিরিক্ত কৌশল রয়েছে ।

0

তবুও উপরে আরও একটি অতিরিক্ত উত্তর।

টার্মিনালটিতে কেবল বিড়াল এবং কর্ক ব্যবহার করে ম্যাকোএসএক্সে পরীক্ষা করা হয়েছে

cat Makefile | awk '!/SHELL/ && /^[A-z]/ {print $1}' | awk '{print substr($0, 1, length($0)-1)}'

নীচের মত মেক ফাইল আউটপুট হবে:

target1

target2

target3

মেকফাইলে এটি একই বক্তব্য হওয়া উচিত, নিশ্চিত হয়ে নিন যে আপনি ভেরিয়েবলের পরিবর্তে $$ ভেরিয়েবল ব্যবহার করে ভেরিয়েবল ব্যবহার করে পালাতে পারেন।

ব্যাখ্যা

বিড়াল - বিষয়বস্তু আউট spits

| - পাইপ পরের সপ্তাহে আউটপুট পার্স করে

awk - "শেল" বাদ দিয়ে এবং "" Az "রেখাগুলি গ্রহণ করে রেইগেক্স চালায় তারপরে $ 1 প্রথম কলামটি প্রিন্ট করে

awk - তবুও তালিকা থেকে শেষ অক্ষরটিকে ":" সরিয়ে দেয়

এটি মোটামুটি আউটপুট এবং আপনি কেবলমাত্র এডাব্লুকে দিয়ে আরও মজাদার স্টাফ করতে পারেন। বিএসডি ভেরিয়েন্টে যেমন সামঞ্জস্যপূর্ণ না হয় সেহেতু এড়াতে চেষ্টা করুন অর্থাত্ * নিক্সে কিছু কাজ করে তবে ম্যাকোএসএক্সের মতো বিএসডিগুলিতে ব্যর্থ হয়।

অধিক

আপনার তৈরির জন্য একটি ফাইলটিতে এটি (পরিবর্তনগুলির সাথে) যুক্ত করতে সক্ষম হওয়া উচিত ডিফল্ট বাশ-সমাপ্তি ফোল্ডারে /usr/local/etc/bash-completion.d/ এর অর্থ যখন আপনি " ট্যাব ট্যাব তৈরি করেন " .. এটি সম্পূর্ণ হবে ওয়ান লাইন স্ক্রিপ্টের উপর ভিত্তি করে লক্ষ্যগুলি।


আপনি বিড়ালের চেয়ে মেক-কিপিও ব্যবহার করতে পারেন। সুতরাং এটি মেক-কি.পি. হয়ে যাবে | awk '/: / &&! /: = / && / ^ [এজেড] / ওএডি / / প্যাথ / এবং & , দৈর্ঘ্য ($ 0) -1) | "বাছাই করুন"
জিমি এমজি লিম

0

আমি সাধারণত:

গ্রেপ ইনস্টল_তারেকেট মেকফিল

এটি এমন কিছু নিয়ে ফিরে আসবে:

install_targets = install-xxx1 install-xxx2 ... etc

আশা করি এটা কাজে লাগবে


0

বাশ স্ক্রিপ্টের জন্য

এটি করার জন্য এখানে একটি খুব সহজ উপায় bash- উপরের @ সিবারসিটিজন 1 এর মন্তব্যের ভিত্তিতে :

grep : Makefile | awk -F: '/^[^.]/ {print $1;}'

@ মার্ক ২৩377 এর আরও প্রামাণিক উত্তরও দেখুন , যা বাশ সমাপ্তি মডিউলটি makeএটি করে কীভাবে বলে ।


-4

আগের উত্তরটি কেন এত জটিল ছিল তা নিশ্চিত নয়:

list:
    cat Makefile | grep "^[A-z]" | awk '{print $$1}' | sed "s/://g" 

8
পূর্ববর্তী উত্তর তাই হয়, জটিল, কারণ এটি সব পরিস্থিতিতে যে আপনার উত্তর কাভার করে না জুড়ে: (ক) মাধ্যমে সংজ্ঞায়িত লক্ষ্যমাত্রা অন্তর্ভুক্তি ভেরিয়েবল (যেমন, $(SHELLS): ...), (খ) লক্ষ্যমাত্রা যে কোনো সংখ্যা দিয়ে শুরু, (গ) অন্তর্ভুক্তি অ- পরিবর্তনশীল সংজ্ঞা অন্তর্ভুক্তি , (d) যদি makeএকটি সুস্পষ্ট মেকফিল পথ নির্দিষ্ট করে নির্দিষ্ট মেকফিলকে লক্ষ্য করে । (ক) অত্যন্ত জটিলতা: আপনি যদি নির্ভরযোগ্যভাবে সঠিক মেকফিলটিকে লক্ষ্য করেও থাকেন , তবে ভেরিয়েবল প্রসারণের অভাবে কাঁচা ফাইল পার্স করা সাধারণ ক্ষেত্রে কাজ করবে না।
mklement0

6
একটি সরাইয়া হিসাবে, পুনরায় জটিল: আপনার কমান্ড অনুসরণ সরলীকৃত করা যেতে পারে - কিন্তু মূল বিন্দু এটি শক্তসমর্থ যথেষ্ট না হয় : awk -F: '/^[A-z]/ {print $$1}' Makefile। পরিশেষে, একটি বৃহত্তর একাডেমিক পয়েন্ট: এর [A-z]পরিবর্তে ব্যবহার করার [:alpha:]অর্থ আপনি বিদেশী চরিত্রের সাথে শুরু হওয়া লক্ষ্যগুলি মিস করবেন á
mklement0

@ mklement0 আপনার প্রথম awk কমান্ডটি দুর্দান্তভাবে কাজ করে এবং এটি এখন পর্যন্ত সবচেয়ে সহজ, যদিও [: alpha:] ব্যবহার করে এটি কোনও কারণে ভেঙে যাচ্ছে বলে মনে হচ্ছে - এটি একটি পরীক্ষার ফাইলে কিছু লক্ষ্য হারিয়েছে।
ব্রায়ান বার্নস 21

@ bburns.km: আমার খারাপ: আমার [[:alpha:]]চেয়ে বরং বলা উচিত ছিল [:alpha:]( অক্ষর শ্রেণীর অভ্যন্তরে[:alpha:] বর্ণের স্থানীয়-সচেতন সেটকে উপস্থাপন করা ) ( ), সুতরাং ডাবল / । এর কার্যকর প্রয়োজন[...] [[]]
mklement0

4
এই উত্তর এত জটিল কেন ? আপনি এই সংক্ষিপ্ত স্নিপেটে বেশ কয়েকটি অকেজো পাপ সংগ্রহ করতে পরিচালনা করুন । awk -F: '/^[A-Za-z]/ { print $$1 }' Makefileএকটি একক প্রক্রিয়া ব্যবহার করে এবং আশা করা যায় যে আরও সঠিক নিয়মিত অভিব্যক্তি (যদিও আপনি অবশ্যই আন্ডারস্কোর, সংখ্যা ইত্যাদির সাথে লক্ষ্য রাখতে পারেন, আগের মন্তব্যে উল্লিখিত হিসাবে)।
ট্রিপলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.