উত্তর:
ডিফল্টরূপে মেকফিল লক্ষ্যগুলি "ফাইল লক্ষ্য" - এগুলি অন্য ফাইল থেকে ফাইল তৈরি করতে ব্যবহৃত হয়। ধরে নিন তার টার্গেটটি একটি ফাইল, এবং এটি মেকফিলগুলি লিখতে তুলনামূলক সহজ করে তোলে:
foo: bar
create_one_from_the_other foo bar
তবে, কখনও কখনও আপনি চান আপনার মেকফিল এমন কমান্ডগুলি চালিত করুন যা ফাইল সিস্টেমে শারীরিক ফাইলগুলি উপস্থাপন করে না। এর জন্য ভাল উদাহরণগুলি হল সাধারণ লক্ষ্যগুলি "পরিষ্কার" এবং "সমস্ত"। সম্ভাবনাগুলি এমনটি নয়, তবে আপনার মূল ডিরেক্টরিতে আপনার একটি ফাইলের নাম থাকতে পারে clean
। এই ক্ষেত্রে মেক বিভ্রান্ত হবে কারণ ডিফল্টরূপে clean
লক্ষ্যটি এই ফাইলটির সাথে যুক্ত হবে এবং মেক কেবল তখনই চালিত হবে যখন ফাইলটি তার নির্ভরতার সাথে আপ-টু-ডেট হিসাবে উপস্থিত হবে না।
এই বিশেষ লক্ষ্যগুলিকে ফোনি বলা হয় এবং আপনি পরিষ্কারভাবে বলতে পারেন যে তারা ফাইলগুলির সাথে সম্পর্কিত নয়, যেমন:
.PHONY: clean
clean:
rm -rf *.o
make clean
আপনার নামের মতো কোনও ফাইল না থাকলেও এখন আশানুরূপভাবে চলবে clean
।
মেকের ক্ষেত্রে, একটি স্বতন্ত্র লক্ষ্যটি হ'ল একটি লক্ষ্য যা সর্বদা পুরানো make <phony_target>
। কিছু সাধারণ make
লক্ষ্যমাত্রা যে অপ্রকৃত হয়: all
, install
, clean
, distclean
, TAGS
, info
, check
।
আসুন ধরে নেওয়া যাক আপনার install
লক্ষ্য রয়েছে যা মেকফিলগুলিতে খুব সাধারণ। আপনি যদি ব্যবহার না করেন.PHONY
এবং নামের একটি ফাইল install
মেকফিলের মতো একই ডিরেক্টরিতে উপস্থিত থাকে তবে কিছুইmake install
করবে না । এটি কারণ "মাইক্রোসফট " নামটি তৈরির জন্য এই জাতীয় এবং তেমন রেসিপি কার্যকর করার নিয়মটি ব্যাখ্যা করে । যেহেতু ফাইলটি ইতিমধ্যে রয়েছে এবং এর নির্ভরতা পরিবর্তন হয়নি, কিছুই করা হবে না।install
তবে আপনি যদি install
ফোনটি PHONY করেন তবে এটি মেক সরঞ্জামটিকে বলবে যে লক্ষ্যটি কাল্পনিক, এবং সেই মেকের দ্বারা আসল ফাইলটি তৈরি করা আশা করা উচিত নয়। সুতরাং এটি install
ফাইলটি বিদ্যমান কিনা তা খতিয়ে দেখাবে না , অর্থ: ক) ফাইলটি উপস্থিত না থাকলে এর আচরণটি পরিবর্তন করা হবে না এবং খ) অতিরিক্ত stat()
বলা হবে না।
আপনার মেকফিলের সাধারণত সমস্ত টার্গেট যা লক্ষ্য নাম হিসাবে একই নামের সাথে একটি আউটপুট ফাইল তৈরি করে না তার PHONY হওয়া উচিত। এটি বিশেষভাবে অন্তর্ভুক্ত all
, install
, clean
, distclean
, ইত্যাদি।
.sh
বা তাদের .bash
সম্প্রসারণ বাদ দিতে বলে যা তাদের প্রধান ফাংশন যেমন চালায় এবং আপনার অন্তর্ভুক্ত লাইব্রেরিগুলির জন্য একটি এক্সটেনশন যোগ করে ( source mylib.sh
)। আসলে, আমি এই এসও প্রশ্নে পেয়েছি কারণ আমার মেকফিল নামে পরিচিত একই ডিরেক্টরিতে আমার একটি স্ক্রিপ্ট ছিলinstall
.PHONY
সমস্ত সময় ব্যবহার করি ...
.PHONY
সংস্করণ।
দ্রষ্টব্য : মেক টুলটি মেকফিলটি পড়ে এবং একটি নিয়মে ':' চিহ্নের উভয় পাশে ফাইলগুলির সংশোধন সময়-স্ট্যাম্পগুলি পরীক্ষা করে।
একটি ডিরেক্টরিতে 'পরীক্ষায়' নিম্নলিখিত ফাইলগুলি উপস্থিত থাকে:
prerit@vvdn105:~/test$ ls
hello hello.c makefile
মেকফাইলে একটি বিধি নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়:
hello:hello.c
cc hello.c -o hello
এখন ধরে নিন যে ফাইল 'হ্যালো' একটি পাঠ্য ফাইল যা কিছু ডেটা যুক্ত করে যা 'হ্যালো.সি' ফাইলের পরে তৈরি হয়েছিল। সুতরাং 'হ্যালো' -র সংশোধন (বা সৃষ্টি) সময়-স্ট্যাম্প 'হ্যালো.কে' এর চেয়ে নতুন হবে। সুতরাং আমরা যখন কমান্ড লাইন থেকে 'মেক হ্যালো' করব, এটি প্রিন্ট হবে:
make: `hello' is up to date.
এখন 'হ্যালো.সি' ফাইলটি অ্যাক্সেস করুন এবং এতে কিছু সাদা স্পেস রেখে দিন যা কোড সিনট্যাক্স বা যুক্তিকে প্রভাবিত করে না এবং সেভ করে ছাড়ুন। এখন হ্যালো.কের পরিবর্তনের সময়-স্ট্যাম্প 'হ্যালো' এর চেয়ে নতুন। এখন আপনি যদি 'হ্যালো মেক করুন' এর অনুরোধ করেন তবে এটি আদেশগুলি এইভাবে কার্যকর করবে:
cc hello.c -o hello
এবং 'হ্যালো' (পাঠ্য ফাইল) ফাইলটি একটি নতুন বাইনারি ফাইল 'হ্যালো' (উপরের সংকলন কমান্ডের ফলাফল) দিয়ে ওভাররাইট করা হবে।
আমরা যদি মেকফাইলে নিম্নলিখিতভাবে PHPY ব্যবহার করি:
.PHONY:hello
hello:hello.c
cc hello.c -o hello
এবং তারপরে 'মেক হ্যালো' করার অনুরোধ জানানো হবে, এটি পিডব্লিউডি 'পরীক্ষায়' উপস্থিত যে কোনও ফাইলকে উপেক্ষা করবে এবং প্রতিবার কমান্ডটি কার্যকর করবে।
এখন ধরা যাক, 'হ্যালো' টার্গেটটির কোনও নির্ভরতা ঘোষণা করা নেই:
hello:
cc hello.c -o hello
এবং 'হ্যালো' ফাইলটি পিডব্লিউডি 'পরীক্ষায়' ইতিমধ্যে উপস্থিত রয়েছে, তারপরে 'হ্যালো মেক করুন' সর্বদা এটি প্রদর্শিত হবে:
make: `hello' is up to date.
make
এটি সামগ্রিকভাবে অর্থবোধ করে তোলে , এটি সমস্ত ফাইলগুলির সম্পর্কে! এই উত্তরের জন্য আপনাকে ধন্যবাদ।
.PHONY: install
সেরা ব্যাখ্যা হ'ল জিএনইউ নিজেই ম্যানুয়াল তৈরি করুন: 4.6 ফোনি টার্গেটস বিভাগ ।
.PHONY
করতে এর অন্যতম স্পেশাল বিল্ট-ইন উদ্দিষ্ট নাম । আপনার আগ্রহী হতে পারে এমন অন্যান্য টার্গেট রয়েছে, সুতরাং এই উল্লেখগুলির মাধ্যমে এটি স্কিমিংয়ের পক্ষে মূল্যবান।
যখন কোনও .PHONY লক্ষ্য বিবেচনা করার সময় হয়ে যায়, সেই নামের কোনও ফাইল বিদ্যমান কিনা বা তার শেষ-সংশোধন সময়টি কী তা নির্বিশেষে, মেকটি নিঃশর্তভাবে তার রেসিপিটি চালাবে।
আপনি তৈরির স্ট্যান্ডার্ড লক্ষ্যগুলি যেমন all
এবং তে আগ্রহীও হতে পারেন clean
।
".FONY" - এর একটি গুরুত্বপূর্ণ কৌশলও আছে - যখন কোনও শারীরিক লক্ষ্য ফোনি টার্গেটের উপর নির্ভর করে যা অন্য শারীরিক টার্গেটের উপর নির্ভর করে:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> টার্গেট 2
আপনি কেবল প্রত্যাশা করবেন যে আপনি যদি TARGET2 আপডেট করেন তবে TARGET1 টি TARGET1 এর বিপরীতে বাসি হিসাবে বিবেচনা করা উচিত, সুতরাং টারগেট 1 পুনর্নির্মাণ করা উচিত। এবং এটি সত্যিই এইভাবে কাজ করে ।
জটিল অংশটি হল যখন TARGET2 TARGET1 এর বিরুদ্ধে বাসি না হয় - এক্ষেত্রে আপনার প্রত্যাশা করা উচিত যে TARGET1 পুনর্নির্মাণ করা উচিত নয়।
এটি আশ্চর্যজনকভাবে কাজ করে না কারণ: ফোনি টার্গেট যাইহোক চালানো হয়েছিল (ফোনি টার্গেটগুলি সাধারণত হয়) , যার অর্থ ফোনি টার্গেটটি আপডেট হিসাবে বিবেচিত হয়েছিল । এবং যে কারণে TARGET1 কলঙ্কিত লক্ষ্য বিরুদ্ধে বাসি বিবেচনা করা হয় ।
বিবেচনা:
all: fileall
fileall: file2 filefwd
echo file2 file1 >fileall
file2: file2.src
echo file2.src >file2
file1: file1.src
echo file1.src >file1
echo file1.src >>file1
.PHONY: filefwd
.PHONY: filefwd2
filefwd: filefwd2
filefwd2: file1
@echo "Produced target file1"
prepare:
echo "Some text 1" >> file1.src
echo "Some text 2" >> file2.src
আপনি এটি দিয়ে খেলা করতে পারেন:
আপনি দেখতে পাচ্ছেন যে ফাইলল ফাইলের উপরে পরোক্ষভাবে কোনও ফনি টার্গেটের মাধ্যমে নির্ভর করে - তবে এই নির্ভরতার কারণে এটি সর্বদা পুনর্নির্মাণ হয় gets আপনি নির্ভরতা পরিবর্তন করেন তাহলে fileall
থেকে filefwd
থেকে file
, এখন fileall
প্রত্যেক সময় পুনর্নির্মিত পাবেন না, কিন্তু শুধুমাত্র নির্ভরশীল লক্ষ্যমাত্রা যখন কোন ফাইল হিসেবে এটি বিরুদ্ধে সতেজ নয়।
বিশেষ লক্ষ্যটি .PHONY:
নকল লক্ষ্যগুলি ঘোষণার অনুমতি দেয়, যাতে এটি make
প্রকৃত ফাইলের নাম হিসাবে এটি পরীক্ষা করে না: এ জাতীয় ফাইলগুলি বিদ্যমান থাকলেও এটি সর্বদা কাজ করবে।
আপনি বিভিন্ন লাগাতে পারেন .PHONY:
আপনার Makefile
:
.PHONY: all
all : prog1 prog2
...
.PHONY: clean distclean
clean :
...
distclean :
...
নকল লক্ষ্য ঘোষণার আরেকটি উপায় রয়েছে: কেবল '::'
all :: prog1 prog2
...
clean ::
...
distclean ::
...
'::' এর একটি বিশেষ অর্থ রয়েছে: লক্ষ্যগুলি ফনিযুক্ত হয় এবং তারা বেশ কয়েকবার প্রদর্শিত হতে পারে:
clean ::
rm file1
...
clean ::
rm file2
একের পর এক কমান্ড ব্লককে ডাকা হবে।
আমি প্রায়শই এগুলিকে ডিফল্ট লক্ষ্যগুলিতে আগুন না দেওয়ার জন্য বলি।
superclean: clean andsomethingelse
blah: superclean
clean:
@echo clean
%:
@echo catcher $@
.PHONY: superclean
অপ্রকৃত ছাড়া, make superclean
জ্বালান হবে clean
, andsomethingelse
এবং catcher superclean
; কিন্তু PHONY সহ, make superclean
আগুন জ্বালাবে না catcher superclean
।
clean
লক্ষ্যটি PHONY করে দেওয়ার বিষয়ে আমাদের চিন্তা করার দরকার নেই, কারণ এটি সম্পূর্ণ কৌতুকপূর্ণ নয়। যদিও এটি কখনও পরিষ্কার ফাইলটি তৈরি করে না, এতে ফায়ার কমান্ড রয়েছে তাই এটি চূড়ান্ত লক্ষ্য হিসাবে ভাববে।
তবে superclean
লক্ষ্যটি সত্যই কৌতুকপূর্ণ, তাই এটির superclean
লক্ষ্য superclean
নির্ধারণের জন্য ডিপগুলি সরবরাহ করে এমন কোনও কিছু দিয়ে তা সজ্জিত করার চেষ্টা করবে - এর মধ্যে অন্যান্য লক্ষ্য এবং লক্ষ্য অন্তর্ভুক্ত রয়েছে %
।
মনে রাখবেন যে আমরা এ সম্পর্কে andsomethingelse
বা কিছু বলি না blah
, সুতরাং তারা স্পষ্টতই ক্যাচারের কাছে যায়।
আউটপুটটি এরকম কিছু দেখাচ্ছে:
$ make clean
clean
$ make superclean
clean
catcher andsomethingelse
$ make blah
clean
catcher andsomethingelse
catcher blah