makepp_cookbook - ক্লাউডে অনলাইন

এটি হল makepp_cookbook কমান্ড যা আমাদের একাধিক বিনামূল্যের অনলাইন ওয়ার্কস্টেশন যেমন উবুন্টু অনলাইন, ফেডোরা অনলাইন, উইন্ডোজ অনলাইন এমুলেটর বা MAC OS অনলাইন এমুলেটর ব্যবহার করে OnWorks ফ্রি হোস্টিং প্রদানকারীতে চালানো যেতে পারে।

কার্যক্রম:

NAME এর


makepp_cookbook -- বিভিন্ন পরিস্থিতিতে মেকফাইল সেট আপ করার সেরা উপায়

বর্ণনাঃ


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

ভবন লাইব্রেরি
Do আপনি সত্যিই প্রয়োজন a গ্রন্থাগার?

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

অনেক ক্ষেত্রে, আমি মনে করি একটি লাইব্রেরি ব্যবহার করার পরিবর্তে, একটি ভাল পদ্ধতি আছে। লাইব্রেরি
যদি প্রতিটি মডিউল অন্য কোনো মডিউলে পুনঃব্যবহার করা যায় না বা করা যায় না তবে এটি সত্যিই সঠিক সমাধান নয়
প্রোগ্রাম, কারণ তারপর আপনি লাইব্রেরির সমস্ত ত্রুটিগুলি পাবেন এবং এর কোনটিই পাবেন না
সুবিধাদি. লাইব্রেরি নিম্নলিখিত ক্ষেত্রে দরকারী:

1. যখন আপনার কাছে একগুচ্ছ সাবরুটিন থাকে যা বিভিন্ন সাথে লিঙ্ক করতে হবে
প্রোগ্রাম, এবং কোন প্রোগ্রাম আসলে 100% সাবরুটিন ব্যবহার করে না--প্রতিটি প্রোগ্রাম একটি ব্যবহার করে
বিভিন্ন উপসেট। এই ক্ষেত্রে, একটি স্ট্যাটিক লাইব্রেরি ব্যবহার করা সম্ভবত একটি ভাল ধারণা (a
.a ফাইল, বা একটি সংরক্ষণাগার ফাইল)।

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

3. যখন আপনার লিঙ্কের সময় নিষেধজনকভাবে দীর্ঘ হয়, তখন বড় অংশের জন্য ভাগ করা লাইব্রেরি ব্যবহার করে
প্রোগ্রাম উল্লেখযোগ্যভাবে লিঙ্ক গতি বাড়াতে পারে.

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

ডায়নামিক লাইব্রেরি ব্যবহার করার বেশ কিছু অসুবিধা রয়েছে। প্রথমত, আপনার প্রোগ্রাম সামান্য হতে পারে
যদি লাইব্রেরিটি ইতিমধ্যে অন্য কোনও প্রোগ্রাম দ্বারা ব্যবহার করা না হয় তবে শুরু করার জন্য ধীরগতি, কারণ
এটা খুঁজে পাওয়া এবং লোড করা আছে. দ্বিতীয়ত, সমস্ত গতিশীল পেতে এটি একটি বাস্তব ঝামেলা হতে পারে
সঠিক অবস্থানে লাইব্রেরি ইনস্টল করা; আপনি শুধু প্রোগ্রাম এক্সিকিউটেবল কপি করতে পারবেন না,
আপনাকে নিশ্চিত করতে হবে যে আপনি এর সমস্ত লাইব্রেরি কপি করেছেন। তৃতীয়ত, কিছু সিস্টেমে, এটি
ভাগ করা লাইব্রেরির ভিতরে কোড ডিবাগ করা কঠিন কারণ ডিবাগার সমর্থন করে না
তাদের ভাল।

যদি আপনার মডিউল অন্য কোন প্রোগ্রামে ব্যবহার করা না হয়, তাহলে ব্যবহার করার সামান্য কারণ আছে
একটি লাইব্রেরি: আপনি লাইব্রেরি ব্যবহার করার সমস্ত অসুবিধাগুলি পান এবং কোন সুবিধা পান না।
আমি যে কৌশলটি পছন্দ করি তা হল ইনক্রিমেন্টাল লিঙ্কিং ব্যবহার করা, যেখানে এটি উপলব্ধ।

লিনাক্সে আপনি কীভাবে এটি করতে পারেন তা এখানে:

my_module.o : $(filter_out my_module.o, $(wildcard*.o))
ld -r -o $(আউটপুট) $(ইনপুট)

এই কি করবে আরেকটি তৈরি করতে হবে .o ফাইল বলা হয় my_module.o, যা গঠিত হবে
সবগুলো .o এই সাবডিরেক্টরিতে ফাইল। লিঙ্কার অনেক হিসাবে সমাধান করবে
রেফারেন্সগুলি যতটা সম্ভব, এবং অবশিষ্ট রেফারেন্সগুলিকে ক-এ সমাধান করার জন্য ছেড়ে দেবে
লিঙ্কিং পরবর্তী পর্যায়ে। শীর্ষ স্তরে, যখন আপনি অবশেষে আপনার প্রোগ্রাম তৈরি করবেন,
সাথে লিঙ্ক করার পরিবর্তে libmy_module.a or libmy_module.so, আপনি সহজভাবে সঙ্গে লিঙ্ক হবে
my_module.o. আপনি যখন লিঙ্ক .o ফাইল, আপনার অর্ডার-নির্ভরতার সাথে সমস্যা নেই
লিঙ্কার কমান্ড লাইন।

লেটিং makepp ব্যক্তিত্ব বাইরে যে লাইব্রেরি মডিউল হয় প্রয়োজন

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

যদি আপনার লাইব্রেরি কঠোরভাবে কনভেনশন পালন করে যে সমস্ত ফাংশন বা ক্লাস ঘোষণা করা হয়েছে
একটি নথি xyz.h একটি উৎস ফাইলে সম্পূর্ণরূপে প্রয়োগ করা হয় যা কম্পাইল করে xyz.o (অর্থাৎ, আপনি
মধ্যে বাস্তবায়ন বিভক্ত করবেন না xyz1.o এবং xyz2.o), তারপর আপনি ব্যবহার করতে পারেন
"$(infer_objects)" ফাংশন মেকপপকে বলতে বলতে শুধুমাত্র প্রাসঙ্গিক মডিউলগুলি থেকে বের করতে
লাইব্রেরি এটি এমনকি কয়েক ডজন ফাইল অন্তর্ভুক্ত সহ লাইব্রেরির জন্য আশ্চর্যজনকভাবে ভাল কাজ করতে পারে।
মূলত, "$(infer_objects)" এর তালিকা পরীক্ষা করে .h ফাইল যে অন্তর্ভুক্ত করা হয়, এবং চেহারা
অনুরূপ জন্য .o নথি পত্র. আপনি যদি দ্রুত একটি লাইব্রেরি এবং একটি প্রোগ্রাম বিকাশ করছেন
একসাথে, এটি সংকলনের সময় বাঁচাতে পারে, কারণ আপনি কখনই এর মডিউল কম্পাইল করতে বিরক্ত করবেন না
লাইব্রেরি যা প্রোগ্রাম ব্যবহার করে না।

আমি যেভাবে এটি ব্যবহার করি তার একটি উদাহরণ এখানে:

my_program: $(infer_objects *.o, $(LIB1)/*.o $(LIB2)/*.o)
$(CXX) $(ইনপুট) -o $(আউটপুট) $(SYSTEM_LIBRARIES)

"$(infer_objects )" ফাংশনটি তার প্রথম আর্গুমেন্ট ফেরত দেয় (ওয়াইল্ডকার্ড করার পরে
এটিতে সম্প্রসারণ), এবং এর দ্বিতীয় আর্গুমেন্টে ফাইলগুলির তালিকাও দেখে, জন্য
ফাইল যার নাম যেকোন নামের মত .h ফাইল যেকোন ফাইলের প্রথমটিতে অন্তর্ভুক্ত
যুক্তি. যদি এই ধরনের কোনো ফাইল পাওয়া যায়, এই তালিকায় যোগ করা হয়.

ভবন a স্থির লাইব্রেরি

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

LIBRARY_FILES = abcde

libmine.a: $(LIBRARY_FILES).o
&rm -f $(আউটপুট)
$(AR) cr $(আউটপুট) $(ইনপুট)
ranlib $(output) # আপনার OS এর উপর নির্ভর করে প্রয়োজনীয় নাও হতে পারে।

&rm হল makepp এর বিল্টইন "rm" কমান্ড। আপনি যদি মেকফাইল লিখতে অভ্যস্ত হন তবে আপনি হতে পারেন
এই আদেশ দ্বারা একটু বিস্মিত; আপনি এই মত আরো কিছু অভ্যস্ত হতে পারে:

libmine.a: $(LIBRARY_FILES).o
$(AR) ru $@ $? # প্রস্তাবিত নয়!!!!!!!
ranlib $(আউটপুট)

কোথায় $? ("$(changed_inputs)" নামেও পরিচিত) একটি স্বয়ংক্রিয় পরিবর্তনশীল যার অর্থ যেকোন ফাইল
যা শেষবার লাইব্রেরি তৈরি হওয়ার পর থেকে পরিবর্তিত হয়েছে এবং $@ মোটামুটি একই
"$(আউটপুট)" হিসাবে।

এই পদ্ধতিটি বিভিন্ন কারণে সুপারিশ করা হয় না:

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

এছাড়াও, আপনার "ar" বিকল্পের উপর নির্ভর করে এবং আপনার "ar" বাস্তবায়নের উপর নির্ভর করে (যেমন, যদি আপনি
"r" এর পরিবর্তে "q" বিকল্পটি ব্যবহার করুন), আপনি এর বিভিন্ন সংস্করণ থাকা বন্ধ করতে পারেন
একই .o ভিতরে .a ফাইল যদি বিভিন্ন সংস্করণ বিভিন্ন গ্লোবালকে সংজ্ঞায়িত করে,
লিঙ্কার তাদের উভয়ই টানার চেষ্টা করতে পারে। এটি সম্ভবত একটি খারাপ জিনিস।

এই কারণেই আমরা প্রথমে লাইব্রেরি ফাইল মুছে ফেলি, এবং এটি স্ক্র্যাচ থেকে তৈরি করি। এটা হবে
একটি লাইব্রেরিতে শুধু মডিউল আপডেট করার চেয়ে একটু বেশি সময় নেয়, কিন্তু বেশি সময় নেয় না; চালু
একটি আধুনিক কম্পিউটার, এর দ্বারা ব্যবহৃত সময়ের পরিমাণ ar প্রোগ্রামটি তুলনামূলকভাবে কম
সি কম্পাইলার একটি সাধারণ বিল্ডে যা গ্রহণ করে, তাই এটি উদ্বেগজনক নয়
সম্বন্ধে.

· মেকপপ সঠিক বিল্ডের গ্যারান্টি দেওয়ার একটি উপায় হল এটি হবে
একটি নির্দিষ্ট লক্ষ্য নির্মাণের কমান্ড লাইন পরিবর্তিত হলে স্বয়ংক্রিয়ভাবে পুনর্নির্মাণ। কিন্তু
$ ব্যবহার করে? পরিবর্তনশীল সমস্যা সৃষ্টি করতে পারে, কারণ প্রতিবার লাইব্রেরি আপডেট করা হয়,
বিল্ড কমান্ড ভিন্ন। (আপনি এটি ব্যবহার করে দমন করতে পারেন
":build_check ignore_action"; বিস্তারিত জানার জন্য makepp_build_check দেখুন।)

· পুনঃনির্মাণের পরিবর্তে সংরক্ষণাগারটি আপডেট করা মেকপিপের পক্ষে এটিকে অসম্ভব করে তুলবে
ফাইলটি সঠিকভাবে একটি বিল্ড ক্যাশে রাখুন (বিশদ বিবরণের জন্য makepp_build_cache দেখুন)।

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

libmine.a: $(only_targets*.o)
&rm $(আউটপুট)
$(AR) cr $(আউটপুট) $(ইনপুট)

এই সব রাখে .o লাইব্রেরিতে বর্তমান ডিরেক্টরির ফাইলগুলি। ওয়াইল্ডকার্ড
যে কোনো মেলে .o ফাইল যা বিদ্যমান বা নির্মিত হতে পারে, তাই ফাইলগুলি না থাকলেও এটি কাজ করবে
এখনো বিদ্যমান।

"only_targets" ফাংশনটি বাদ দিতে ব্যবহৃত হয় .o ফাইল যা সংশ্লিষ্ট নেই
সোর্স ফাইল আর কোন. ধরুন আপনি একটি ফাইল কল ছিল xyz.c যে আপনি আপনার মধ্যে রাখা ব্যবহৃত
লাইব্রেরি এর মানে একটি আছে xyz.o ফাইল চারপাশে পড়ে আছে। এখন আপনি মুছে ফেলুন xyz.c
কারণ এটি অপ্রচলিত, কিন্তু আপনি মুছে ফেলতে ভুলে গেছেন xyz.o. "শুধু_লক্ষ্য" ছাড়া
ফাংশন, xyz.o এখনও তালিকায় অন্তর্ভুক্ত করা হবে .o লাইব্রেরিতে অন্তর্ভুক্ত ফাইল।

ভবন a প্রগতিশীল লাইব্রেরি

গতিশীল গ্রন্থাগার নির্মাণের প্রক্রিয়া সম্পূর্ণরূপে সিস্টেম নির্ভর। আমি অত্যন্ত হবে
একটি ডায়নামিক লাইব্রেরি তৈরি করতে libtool ব্যবহার করার সুপারিশ করুন (দেখুন
<http://www.gnu.org/software/libtool/>), তাই আপনাকে এটি কীভাবে করতে হবে তা খুঁজে বের করতে হবে না
আপনার প্ল্যাটফর্ম, এবং যাতে আপনি a এ স্যুইচ করলেও আপনার মেকফাইল কাজ করতে থাকবে
বিভিন্ন ওএস। বিস্তারিত জানার জন্য libtool ডকুমেন্টেশন দেখুন। এখানে একটি নমুনা মেকফাইল:

লিবটুল := লিবটুল

libflick.la : $(only_targets *.lo)
$(LIBTOOL) --mode=link $(CC) $(ইনপুট) -o $(আউটপুট)

%.lo : %.c
$(LIBTOOL) --mode=কম্পাইল $(CC) $(CFLAGS) $(ইনক্লুডস) -c $(ইনপুট) -o $(আউটপুট)

ভবন on বিভিন্ন বিভিন্ন মেশিন or নেটওয়ার্ক
মেকফাইলগুলির সাথে সবচেয়ে বিরক্তিকর সমস্যাগুলির মধ্যে একটি হ'ল তারা প্রায় কখনই কাজ করে না যখন আপনি
একটি ভিন্ন মেশিন বা একটি ভিন্ন নেটওয়ার্কে স্যুইচ করুন। যদি আপনার makefiles কাজ করতে হবে
গ্রহের প্রতিটি সম্ভাব্য মেশিন, তাহলে আপনার সম্ভবত কিছু ধরণের কনফিগার প্রয়োজন
লিপি. কিন্তু যদি আপনাকে শুধুমাত্র কয়েকটি ভিন্ন মেশিনে কাজ করতে হয়, তবে বিভিন্ন উপায় রয়েছে
আপনি এই সমস্যার কাছে যেতে পারেন:

ব্যবহার a বিভিন্ন অন্তর্ভুক্ত করা ফাইল in সব দ্য পরিবেশের

প্রতিটি মেকফাইলের শুরুতে, আপনি এইরকম একটি লাইন অন্তর্ভুক্ত করতে পারেন:

system_defs.mk অন্তর্ভুক্ত করুন

ফাইল system_defs.mk সাধারণত প্রতিটি জন্য একটি ভিন্ন জায়গায় অবস্থিত হবে
পরিবেশ আপনি যদি চান যে আপনার বিল্ড ডিরেক্টরিগুলি সমস্ত মেশিনে অভিন্ন হতে পারে, তাহলে রাখুন
system_defs.mk বিল্ড ডিরেক্টরির উপরে একটি ডিরেক্টরিতে, বা অন্যথায় একটি অন্তর্ভুক্ত পথ সরবরাহ করুন
"-I" কমান্ড লাইন বিকল্প ব্যবহার করে makepp করতে।

এটি করা সাধারণত এক ধরণের বেদনাদায়ক, তবে যদি প্রচুর সংখ্যক থাকে তবে এটি ভাল কাজ করে
পার্থক্য

ব্যবহার if বিবৃতি

এটি করার সবচেয়ে কুৎসিত উপায়, তবে এটি সাধারণত কাজ করবে।

ifsys i386
CC:= gcc
অন্যথা ifsys sun4u
CC := cc
অন্যথা ifsys hpux11
CC = c89
যদি শেষ

যদি আপনাকে যা করতে হবে তা হল কয়েকটি প্রোগ্রাম বা লাইব্রেরি খুঁজে বের করা বা বিভিন্ন ফাইল অন্তর্ভুক্ত করা
জায়গা, আরও ভাল উপায় থাকতে পারে (নীচে দেখুন)।

খুঁজুন_প্রোগ্রাম, প্রথম_উপলব্ধ, ফাইল টি খুজো

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

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 : %.cpp
$(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
/net/na1/tcl8.4a3/lib/libtcl8.4.a
/net/na1/tcl8.4a3/lib/libtcl8.4.sl))
# Tcl লাইব্রেরি কোথায় আছে তা খুঁজুন। এই তাহলে স্পষ্টভাবে
# লিঙ্ক কমান্ডে তালিকাভুক্ত:
my_program : *.o
$(CXX) $(CXXFLAGS) $(ইনপুট) -o $(আউটপুট) $(TCL_LIB)

গ্রহণ করা সুবিধা of পার্লের কনফিগ তথ্য

আপনার যদি কিছু অতিরিক্ত তথ্যের প্রয়োজন হয় তবে উপরের কৌশলগুলি যথেষ্ট নাও হতে পারে
আপনার সিস্টেম, যেমন একটি দীর্ঘ ডবল বিদ্যমান কিনা, বা বাইট অর্ডার কি। যাহোক,
পার্ল ইতিমধ্যে এই জিনিসগুলি গণনা করেছে, তাই আপনি কেবল এর উত্তরগুলি ব্যবহার করতে পারেন।

পার্লের স্বয়ংক্রিয় কনফিগার স্ক্রিপ্ট এর মাধ্যমে এর সমস্ত কনফিগারেশন তথ্য উপলব্ধ করে
% কনফিগার হ্যাশ. মেকপপে সরাসরি পার্ল হ্যাশ অ্যাক্সেস করার জন্য কোনও সিনট্যাক্স নেই, তবে আপনি করতে পারেন
পার্লে ড্রপ করুন এবং স্কেলার ভেরিয়েবল সেট করুন, যা সরাসরি makepp থেকে অ্যাক্সেসযোগ্য:

perl_begin
# কনফিগার হ্যাশ থেকে মান আনুন।
কনফিগ ব্যবহার করুন;
$CC = $Config{'cc'}; # সি কম্পাইলার যা পার্ল ব্যবহার করেছে;
$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 কিছু উপসেট

Makepp এর ওয়াইল্ডকার্ডে বর্তমানে সমস্ত ফাইল মেলানোর কোন উপায় নেই ছাড়া একটি নির্দিষ্ট
সেট, কিন্তু আপনি ফাংশন একটি সংমিশ্রণ সঙ্গে এটি করতে পারেন.

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

libproduction.a: $(filter_out test*, $(wildcard*.o))

"$(ফিল্টার )" এবং "$(filter_out )" ফাংশনগুলি ফিল্টারগুলির একটি অত্যন্ত শক্তিশালী সেট
সেট ছেদ এবং পার্থক্য অপারেশন সব ধরণের. উদাহরণ স্বরূপ,

SUBDIRS ;= $(filter_out *পরীক্ষা*$(ARCH)*, $(শেল খুঁজুন। -টাইপ d -প্রিন্ট))
# নেই এমন সব সাবডিরেক্টরি ফেরত দেয়
তাদের মধ্যে # "পরীক্ষা" বা $(ARCH)।

$(ফিল্টার $(patsubst test_dir/test_%.o, %.o, $(wildcard test_dir/*.o)),
$(ওয়াইল্ডকার্ড *.o))
# বর্তমান .o ফাইলগুলির একটি তালিকা প্রদান করে
# ডিরেক্টরি যার জন্য একটি সংশ্লিষ্ট আছে
test_dir সাবডিরেক্টরিতে # test__*.o ফাইল।
$(filter_out $(patsubst man/man3/%.3, %.o, $(wildcard man/man3/*.3)),
$(ওয়াইল্ডকার্ড *.o))
# বর্তমান .o ফাইলগুলির একটি তালিকা প্রদান করে
# ডিরেক্টরি যার জন্য একটি ম্যানুয়াল পৃষ্ঠা নেই
# man/man3 সাবডিরেক্টরিতে একই ফাইলের নাম সহ।

ব্যবহার দ্য "$(only_targets )" ক্রিয়া থেকে বাছা মামুলি .o নথি পত্র

ধরুন আপনি এইরকম একটি বিল্ড কমান্ড সহ একটি প্রোগ্রাম বা একটি লাইব্রেরি তৈরি করছেন:

প্রোগ্রাম: *.o
$(CC) $(ইনপুট) -o $(আউটপুট)

ধরুন আপনি এখন একটি উৎস ফাইল মুছে ফেলছেন। আপনি সংশ্লিষ্ট মুছে ফেলতে ভুলবেন না .o ফাইল,
এটি এখনও সংযুক্ত করা হবে যদিও এটি আর নির্মাণ করার কোন উপায় নেই। মধ্যে
ভবিষ্যতে, makepp সম্ভবত এই পরিস্থিতি স্বয়ংক্রিয়ভাবে চিনবে এবং এটি থেকে বাদ দেবে
ওয়াইল্ডকার্ড তালিকা, কিন্তু বর্তমানে, আপনাকে এটিকে ম্যানুয়ালি বাদ দিতে বলতে হবে:

প্রোগ্রাম: $(only_targets *.o)
$(CC) $(ইনপুট) -o $(আউটপুট)

মেকেপ বাসি গড়ার কোন উপায় জানে না .o ফাইল এর সোর্স ফাইল থেকে আর কোনো ফাইল
চলে গেছে, তাই "$(only_targets )" ফাংশন এটিকে নির্ভরতা তালিকা থেকে বাদ দেবে।

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

কি থেকে do in জায়গা of পুনরাবৃত্তি করা

Makepp পশ্চাদগামী সামঞ্জস্যের জন্য পুনরাবৃত্তিমূলক মেক সমর্থন করে, তবে এটি অত্যন্ত সুপারিশ করা হয়
ওটাই তুমি না এটা ব্যবহার করো. যদি আপনি এটি কি জানেন না, ভাল.

আপনি কেন করতে চান না তার বিশদ বিবরণের জন্য makepp-এ "হায়ারার্কিক্যাল বিল্ডগুলির জন্য আরও ভাল সিস্টেম" দেখুন
রিকার্সিভ মেক ব্যবহার করুন, অন্যথায় ওয়েবে অনুসন্ধান করুন "পুনরাবৃত্ত মেক ক্ষতিকারক বলে বিবেচিত"।

প্রতিটি মেকফাইলে "সমস্ত" টার্গেট তৈরি করার জন্য একটি পুনরাবৃত্তিমূলক মেক করার পরিবর্তে, এটি
সাধারণত কোন টার্গেটগুলি তৈরি করতে হবে তা নির্ধারণ করা makeppকে দেওয়া সহজ।
উপরন্তু, আপনি যদি আপনার সব করা .o এবং লাইব্রেরি ফাইলগুলি একই ডিরেক্টরিতে
makefiles, তারপর makepp স্বয়ংক্রিয়ভাবে বুঝতে পারবে কোন মেকফাইলগুলি খুব প্রয়োজন--
শুধুমাত্র যে জিনিসটি প্রয়োজন তা হল আপনার শীর্ষ স্তরে প্রয়োজনীয় ফাইলগুলির তালিকা তৈরি করা
চূড়ান্ত লিঙ্কিং ধাপের জন্য। নীচের উদাহরণ দেখুন.

এক মেকফাইল উন্নত প্রতি ডিরেক্টরি: সঙ্গে অন্তর্নিহিত বোঝাই

একাধিক ডিরেক্টরি পরিচালনা করার সবচেয়ে সাধারণ উপায় হল প্রতিটি ডিরেক্টরিতে একটি মেকফাইল রাখা
যেটি বর্ণনা করে কিভাবে সেই ডিরেক্টরিতে বা থেকে সবকিছু তৈরি করতে হয়। রাখলে .o ফাইলগুলি
সোর্স ফাইলগুলির মতো একই ডিরেক্টরি, তারপর অন্তর্নিহিত লোডিং (এ "ইমপ্লিসিট লোডিং" দেখুন
makepp_build_algorithm) স্বয়ংক্রিয়ভাবে সমস্ত মেকফাইল খুঁজে পাবে। আপনি যদি আপনার করা .o
একটি ভিন্ন ডিরেক্টরিতে ফাইল (যেমন, একটি আর্কিটেকচার-নির্ভর সাবডিরেক্টরিতে), তারপর আপনি
সম্ভবত "load_makefile" বিবৃতি ব্যবহার করে সমস্ত প্রাসঙ্গিক মেকফাইল লোড করতে হবে।

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

# শীর্ষ স্তরের মেকফাইল:
প্রোগ্রাম: main.o **/*.la # সমস্ত সাবডিরেক্টরি থেকে শেয়ার করা লাইব্রেরিতে লিঙ্ক।
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(ইনপুট) -o $(আউটপুট) $(LIBS)

উপরের স্তরের মেকফাইলে আপনার যা দরকার তা প্রায়। প্রতিটি সাবডিরেক্টরিতে, আপনি
সম্ভবত এই মত কিছু করবে:

# প্রতিটি সাবডিরেক্টরিতে মেকফাইল:
standard_defs.mk # অনুসন্ধানগুলি অন্তর্ভুক্ত করুন ., .., ../ .., ইত্যাদি পর্যন্ত এটি
# নির্দেশিত অন্তর্ভুক্ত ফাইল খুঁজে পায়।
# এখানে কিছু পরিবর্তনশীল সংজ্ঞা ওভাররাইড করুন
বিশেষ_ফ্ল্যাগস := -করো_কিছু_বিভিন্ন

প্রতিটি মেকফাইল সম্ভবত প্রায় একই হতে পারে যদি লক্ষ্যগুলি তৈরি করার কমান্ডগুলি
বেশ অনুরূপ।

অবশেষে, আপনি নিম্নলিখিত করা হবে standard_defs.mk ফাইল (যা সম্ভবত করা উচিত
শীর্ষ-স্তরের ডিরেক্টরিতে অবস্থিত হবে):

# সাধারণ পরিবর্তনশীল সেটিংস এবং সমস্ত ডিরেক্টরির জন্য নিয়ম তৈরি করুন।
CFLAGS := -g -O2
ইনক্লুড_ডিআইআর := $(ফাইন্ড_উপরের দিকে অন্তর্ভুক্ত)
# অনুসন্ধান ., .., ../ .., ইত্যাদি একটি ফাইলের জন্য বা
# ডাইরেক্টরিতে বলা হয়, তাই যদি আপনি রাখেন
# আপনার সমস্ত ফাইল সেখানে অন্তর্ভুক্ত, এটি হবে
# তাদেরকে খোঁজো.
অন্তর্ভুক্ত := -I$(INCLUDE_DIR)

%.lo : %.c
$(LIBTOOL) --mode=কম্পাইল $(CC) $(CFLAGS) $(ইনক্লুডস) -c $(ইনপুট) -o $(আউটপুট)

lib$(relative_to ., ..).la: $(only_targets *.lo)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS)-o $(আউটপুট) $(ইনপুট)
# $(আপেক্ষিক_টু ., ..) কারেন্টের নাম প্রদান করে
উপরের স্তরের সাথে সম্পর্কিত # সাবডিরেক্টরি
# সাবডিরেক্টরি। সুতরাং যদি এই মেকফাইলটি xyz/Makefile হয়,
# এই নিয়ম xyz/libxyz.la তৈরি করবে।

# শীর্ষ-স্তরের অন্তর্ভুক্ত ডিরেক্টরিতে সর্বজনীন অন্তর্ভুক্ত ফাইলগুলি প্রকাশ করুন:
$(INCLUDE_DIR)/public_%.h : public_%.h
:build_check symlnk
&ln -fr $(ইনপুট) $(আউটপুট)

এক মেকফাইল উন্নত প্রতি ডিরেক্টরি: স্পষ্ট বোঝাই

আপনি আপনার সব লাগাতে চান .o একটি আর্কিটেকচার-নির্ভর সাবডিরেক্টরিতে ফাইল, তারপর
উপরের উদাহরণটি এরকম কিছু হতে সংশোধন করা উচিত:

# শীর্ষ স্তরের মেকফাইল:
MAKEFILES := $(wildcard **/Makeppfile) # সমস্ত সাবডিরেক্টরির তালিকা
# থেকে makefiles পান।

load_makefile $(MAKEFILES) # সবগুলো লোড করুন।

standard_defs.mk অন্তর্ভুক্ত করুন # main.o এর জন্য কম্পাইল কমান্ড পান।

প্রোগ্রাম: $(ARCH)/main.o */**/$(ARCH)/*.la
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(ইনপুট) -o $(আউটপুট) $(LIBS)
# */**/$(ARCH) সাবডিরেক্টরি বাদ দেয়
# $(ARCH), যেখানে আমরা নির্মাণ করতে চাই না
# একটি শেয়ার্ড লাইব্রেরি।

প্রতিটি মেকফাইল ঠিক আগের মতোই হবে:

# প্রতিটি সাবডিরেক্টরিতে মেকফাইল:
standard_defs.mk অন্তর্ভুক্ত
# ... পরিবর্তনশীল এখানে ওভাররাইড করে

এবং পরিশেষে, standard_defs.mk নিম্নলিখিত মত কিছু থাকবে:

# সাধারণ পরিবর্তনশীল সেটিংস এবং সমস্ত ডিরেক্টরির জন্য নিয়ম তৈরি করুন।
ARCH ;= $(শেল uname -s)-$(শেল uname -m)-$(শেল uname -r)
# কখনও কখনও লোকেরা শুধুমাত্র $(শেল uname -m) ব্যবহার করে, কিন্তু
# এটি ফ্রিবিএসডি এবং লিনাক্স অনের জন্য একই হবে
# একটি x86। লিনাক্সে -r সত্যিই দরকারী নয়,
# কিন্তু অন্যান্য ওএসের জন্য গুরুত্বপূর্ণ: বাইনারিগুলির জন্য
# SunOS 5.8 সাধারণত SunOS 5.7 এ চলবে না।
&mkdir -p $(ARCH) # নিশ্চিত করুন যে আউটপুট ডিরেক্টরি বিদ্যমান।
CFLAGS := -g -O2
ইনক্লুড_ডিআইআর := $(ফাইন্ড_উপরের দিকে অন্তর্ভুক্ত)
# অনুসন্ধান ., .., ../ .., ইত্যাদি একটি ফাইলের জন্য বা
# ডাইরেক্টরিতে বলা হয়, তাই যদি আপনি রাখেন
# আপনার সমস্ত ফাইল সেখানে অন্তর্ভুক্ত, এটি হবে
# তাদেরকে খোঁজো.
অন্তর্ভুক্ত := -I$(INCLUDE_DIR)

$(ARCH)/%.lo : %.c
$(LIBTOOL) --mode=কম্পাইল $(CC) $(CFLAGS) $(ইনক্লুডস) -c $(ইনপুট) -o $(আউটপুট)

$(ARCH)/ lib$(আপেক্ষিক_টু ., ..).la: $(only_targets *.lo)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS)-o $(আউটপুট) $(ইনপুট)
# $(আপেক্ষিক_টু ., ..) কারেন্টের নাম প্রদান করে
উপরের স্তরের সাথে সম্পর্কিত # সাবডিরেক্টরি
# সাবডিরেক্টরি। সুতরাং যদি এই মেকফাইলটি xyz/Makefile হয়,
# এই নিয়মটি xyz/$(ARCH)/libxyz.la তৈরি করবে।

# সর্বজনীন অন্তর্ভুক্ত ফাইলগুলিকে শীর্ষ-স্তরের অন্তর্ভুক্ত ডিরেক্টরিতে অনুলিপি করুন:
$(INCLUDE_DIR)/public_%.h : public_%.h
&cp $(ইনপুট) $(আউটপুট)

স্বয়ংক্রিয়ভাবে তৈরীর দ্য মেকফাইলস

যদি আপনার মেকফাইলগুলি সবই একই রকম হয় (উপরের উদাহরণের মতো), আপনি মেকপকে বলতে পারেন
তাদের অস্তিত্ব না থাকলে স্বয়ংক্রিয়ভাবে তৈরি করতে। শুধু আপনার শীর্ষ স্তরে নিম্নলিখিত যোগ করুন
makefile:

SUBDIRS := $(filter_out unwanted_dir1 unwanted_dir2, $(ওয়াইল্ডকার্ড */**))
$(foreach)/Makeppfile: : foreach $(SUBDIRS)
&echo "include standard_defs.mk" -o $(আউটপুট)
&echo "_include additional_defs.mk" -o >>$(আউটপুট)
# যদি extra_defs.mk ফাইলটি বিদ্যমান থাকে, তাহলে
# এটি অন্তর্ভুক্ত করা হবে, কিন্তু যদি এটি বিদ্যমান না থাকে,
# _include বিবৃতি উপেক্ষা করা হবে।

এখন মেকফাইলগুলি স্বয়ংক্রিয়ভাবে তৈরি হবে।

এক মেকফাইল কেবল at দ্য শীর্ষ স্তর

যদি আপনার সমস্ত মেকফাইল অভিন্ন হয়, আপনি জিজ্ঞাসা করতে পারেন: কেন আমার প্রতিটিতে একটি মেকফাইল থাকা উচিত
স্তর? কেন যে সব শীর্ষ স্তরের মেকফাইল মধ্যে রাখা না?

হ্যাঁ, এই কাজ করা যেতে পারে। প্রধান অসুবিধা হল যে এটি নির্দিষ্ট করা কঠিন হয়ে যায়
প্রতিটি সাবডিরেক্টরির জন্য বিভিন্ন বিল্ড বিকল্প। একটি দ্বিতীয় অসুবিধা হল যে আপনার
makefile সম্ভবত পড়া একটু কঠিন হয়ে যাবে।

এখানে শুধু এটি করার একটি উদাহরণ:

# ডিরেক্টরি অনুক্রমের জন্য শীর্ষ-স্তরের মেকফাইল। প্রোগ্রাম তৈরি করে
# একটি উদাহরণ হিসাবে ভাগ করা লাইব্রেরির একটি সেটের মধ্যে। (উপরে সতর্কতা দেখুন
# কেন আপনি ইনক্রিমেন্টাল লিঙ্কিং বা অন্য কিছু ব্যবহার করতে চাইতে পারেন
ভাগ করা লাইব্রেরির পরিবর্তে # পদ্ধতি।)
makepp_percent_subdirs := 1 # %-কে একাধিক ডিরেক্টরির সাথে মেলাতে অনুমতি দিন।
SUBDIRS := $(filter_out *CVS* অন্যান্য-অবাঞ্ছিত_dirs $(ওয়াইল্ডকার্ড **))
CFLAGS := -g -O2
অন্তর্ভুক্ত := -অন্তর্ভুক্ত

%.lo: %.c
$(LIBTOOL) --mode=কম্পাইল $(CC) $(Includes) $(CFLAGS)-c $(ইনপুট) -o $(আউটপুট)

$(প্রগামী)/ lib$(notdir $(foreach)).la: $(foreach)/*.lo : foreach $(SUBDIRS)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS)-o $(আউটপুট) $(ইনপুট)
# সব লাইব্রেরি করার নিয়ম।

প্রোগ্রাম: main.o**/*.la
$(LIBTOOL) --mode=link $(CC) $(CFLAGS)-o $(আউটপুট) $(ইনপুট)

অন্তর্ভুক্ত/$(notdir $(foreach)): $(foreach): foreach **/public_*.h
&cp $(ইনপুট) $(আউটপুট)
# সর্বজনীনভাবে অনুলিপি করার জন্য নমুনা নিয়ম
# অ্যাক্সেসযোগ্য .h ফাইল সঠিক জায়গায়।

A পরিষ্কার লক্ষ্য

ঐতিহ্যগত মেকফাইলগুলিতে একটি পরিষ্কার লক্ষ্য থাকে, যা যা ছিল তা সরিয়ে ফেলার অনুমতি দেয়
নির্মিত মেকপিপের সাথে আপনার এটি করা উচিত নয় এমন তিনটি কারণ রয়েছে:

1. মেকপ একটি সঠিক বিল্ড নিশ্চিত করতে অনেক দৈর্ঘ্যে যায়। তাই মরিয়া "আমি না
জানি কি ভুল", আপনাকে স্ক্র্যাচ থেকে শুরু করতে চাওয়াটা অতীতের বিষয়।

2. মানুষ কখনও কখনও একবারে দুটি বিপরীত কাজ করে সময় বাঁচানোর চেষ্টা করবে:
"সব পরিষ্কার করুন"। এটি makepp এর স্মার্ট ওয়াইল্ডকার্ড সিস্টেমকে বিভ্রান্ত করতে পারে, কারণ এটি হবে
কিছু করার আগে আগে ঘটনা জেনে নিন। তারপর পরিষ্কার কর্ম আসে, যা করে
মেকপ্পকে বলবেন না এটি কী করে (প্রকৃতপক্ষে এটি পারে না, কারণ এটি কিছুকে পূর্বাবস্থায় ফিরিয়ে আনে --
একটি বিল্ড টুল কি জন্য বিপরীত). তারপর "সমস্ত" আসে, কিন্তু আপ টু ডেট ফাইল,
যেখানে রহস্যজনকভাবে চলে গেছে।

3. "makeppclean" কমান্ড আছে, যা একই কাজ করে এবং আরও দক্ষতার সাথে।

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

$(ফনি ক্লিন):
&rm -fm $(ওয়াইল্ডকার্ড *.o .makepp_log)
# -m এবং .makepp_log মেকপ এর সমস্ত জাঙ্ক থেকে মুক্তি পায়।

আপনি যে ফাইলগুলি মুছতে চান তা স্পষ্টভাবে তালিকাভুক্ত করার পরিবর্তে, আপনি makepp কে বলতে পারেন
এটি কীভাবে তৈরি করতে জানে তার সমস্ত কিছু সরান, যেমন:

$(ফনি ক্লিন):
&rm -fm .makepp_log $(only_targets*)

এটির সুবিধা রয়েছে যে যদি আপনার কোনো সোর্স ফাইল অন্য ফাইল থেকে তৈরি করা যায়,
তারাও মুছে ফেলা হবে; অন্যদিকে, বাসি .o ফাইল (যে ফাইলগুলি ব্যবহার করা হত
নির্মাণযোগ্য কিন্তু যার উত্স ফাইলটি মুছে ফেলা হয়েছে) মুছে ফেলা হবে না।

আপনার যদি এমন একটি বিল্ড থাকে যাতে বিভিন্ন ডিরেক্টরিতে মেকফাইল জড়িত থাকে, আপনার শীর্ষ-
লেভেল মেকফাইল "ক্লিন" টার্গেট (বা অন্য কোন নকল টার্গেট) আলাদাভাবে উল্লেখ করতে পারে
makefile:

# টপ-লেভেল মেকফাইল
SUBDIRS := sub1 sub2

# এখানে নিয়ম তৈরি করুন

# নির্মাণের পরে পরিষ্কার করুন:
$(ফনি ক্লিন): $(SUBDIRS)/ক্লিন
&rm -fm .makepp_log $(only_targets*)

বিকল্পভাবে, আপনি আপনার "পরিষ্কার" লক্ষ্যমাত্রা শুধুমাত্র শীর্ষ-স্তরের মেকফাইলে রাখতে পারেন এবং এটি রাখতে পারেন
সমস্ত ডিরেক্টরি প্রক্রিয়া করুন, যেমন:

$(ফনি ক্লিন):
&rm -fm $(only_targets**/*)

ব্যবহার Qt এর ক্ষমতা প্রিপ্রসেসর
এই উদাহরণটি এমন একটি ইউটিলিটির জন্য একটি মেকফাইল দেখায় যা Nokia এর Qt GUI লাইব্রেরি ব্যবহার করে (দেখুন
<http://qt.nokia.com>)। এই সম্পর্কে সামান্য অস্বাভাবিক যে শুধুমাত্র জিনিস আপনি হয়
উইজেট সংজ্ঞা রয়েছে এমন বেশিরভাগ ".h" ফাইলে "moc" নামক একটি প্রিপ্রসেসর চালাতে হবে,
কিন্তু আপনি "Q_OBJECT" ম্যাক্রো ব্যবহার করে না এমন কোনো ".h" ফাইলে "moc" চালাতে চান না।

স্বয়ংক্রিয়ভাবে নির্ণয় যে নথি পত্র প্রয়োজন ক্ষমতা নথি পত্র

আপনি, অবশ্যই, শুধুমাত্র ".h" ফাইলগুলির তালিকা করতে পারেন যেগুলির উপর "moc" চালানোর প্রয়োজন৷
আপনি যদি দ্রুত নতুন উইজেট তৈরি করেন, তবে, এটি একটি বিরক্তিকর কিছু হতে পারে
মেকফাইলে তালিকা আপডেট করতে থাকুন। আপনি moc তালিকা প্রয়োজন কাছাকাছি পেতে পারেন
এই মত কিছু সঙ্গে স্পষ্টভাবে মডিউল:

MOC := $(QTDIR)/bin/moc
মডিউল := আপনার প্রোগ্রামে যে মডিউল থাকুক না কেন
MOC_MODULES := $(patsubst %.h, moc_%, $(&grep -l /Q_OBJECT/ *.h))
# Q_OBJECT ম্যাক্রোর জন্য সমস্ত .h ফাইল স্ক্যান করে।

my_program: $(MODULES).o $(MOC_MODULES).o
$(CXX) $(ইনপুট) -o $(আউটপুট)

moc_%.cxx: %.h # .h ফাইল থেকে moc ফাইল তৈরি করে।
$(MOC) $(ইনপুট) -o $(আউটপুট)

%.o: %.cxx
$(CXX) $(CXXFLAGS)-c $(ইনপুট) -o $(আউটপুট)

এই পদ্ধতি আপনার প্রতিটি স্ক্যান .h ফাইল প্রতিবার makepp চালানো হয়, খুঁজছেন
"Q_OBJECT" ম্যাক্রো। এটি ব্যয়বহুল শোনাচ্ছে, তবে এটি সম্ভবত খুব বেশি সময় নেবে না। (দ্য .h
ফাইলগুলিকে কম্পাইলেশন প্রক্রিয়ার মাধ্যমে যেকোনোভাবেই ডিস্ক থেকে লোড করতে হবে, তাই তারা করবে
ক্যাশে করা হবে।)

# অন্তর্ভুক্ত দ্য .moc ফাইল

আরেকটি পদ্ধতি হল আপনার উইজেটের "moc" প্রিপ্রসেসর থেকে আউটপুট "#include" করা
বাস্তবায়ন ফাইল। এর মানে আপনাকে "#include" লিখতে মনে রাখতে হবে, কিন্তু এটা আছে
সুবিধা হল কম্পাইল করার জন্য কম মডিউল আছে, এবং তাই সংকলন দ্রুত হয়।
(বেশিরভাগ C++ সংকলনের জন্য, বেশিরভাগ সময় হেডার ফাইল পড়তে ব্যয় করা হয়, এবং
প্রিপ্রসেসরের আউটপুটে আপনার উইজেটের মতো প্রায় অনেকগুলি ফাইল অন্তর্ভুক্ত করতে হবে
যাই হোক।) যেমন:

// my_widget.h
ক্লাস MyWidget : সর্বজনীন QWidget {
Q_OBJECT
// ...
}

// my_widget.cpp

# "my_widget.h" অন্তর্ভুক্ত করুন
#include "my_widget.moc" // my_widget.moc থেকে আউটপুট
// moc প্রিপ্রসেসর।
// অন্যান্য বাস্তবায়ন জিনিস এখানে.
MyWidget::MyWidget(QWidget * parent, const char * name):
QWidget (অভিভাবক, নাম)
{
// ...
}

এখন সমস্ত ".moc" ফাইল তৈরি করার জন্য আপনার মেকফাইলে একটি নিয়ম থাকতে হবে, যেমন:

MOC := $(QTDIR)/bin/moc
# .moc ফাইল তৈরি করার নিয়ম:
%.moc: %.h
$(MOC) $(ইনপুট) -o $(আউটপুট)

Makepp যথেষ্ট স্মার্ট এটা বুঝতে পারে যে এটি "my_widget.moc" তৈরি করতে হবে যদি এটি না করে
ইতিমধ্যেই বিদ্যমান, অথবা যদি এটি পুরানো হয়।

এই দ্বিতীয় পদ্ধতিটি আমি সাধারণত ব্যবহার করি কারণ এটি সংকলনের গতি বাড়ায়।

প্রতিস্থাপন উন্নত অবচিত করা বাগধারার
MAKECMDGOALS

কখনও কখনও লোকেদের তাদের মেকফাইলে নিয়ম থাকে তারা কোন টার্গেট তৈরি করছে তার উপর নির্ভর করে,
বিশেষ পরিবর্তনশীল "MAKECMDGOALS" ব্যবহার করে। উদাহরণস্বরূপ, এক কখনও কখনও মত জিনিস দেখে
এই:

ifneq ($(ফিল্টার উত্পাদন, $(MAKECMDGOALS)),)
CFLAGS := -O2
আর
CFLAGS := -g
যদি শেষ

এটি makepp এর সাথে ভাল কাজ করবে। যাইহোক, আমি এই ধরনের জন্য "MAKECMDGOALS" ব্যবহার না করার পরামর্শ দিই
কেস (এবং তাই GNU ম্যানুয়াল তৈরি করে)। আপনি আপনার অপ্টিমাইজ করা বন্ধ ভাল এবং
ডিবাগ-সংকলিত .o আলাদা ডিরেক্টরিতে ফাইল, বা তাদের বিভিন্ন উপসর্গ দেওয়া বা
প্রত্যয়, বা সংগ্রহস্থল ব্যবহার করে, তাদের আলাদা রাখতে।

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

ifneq ($(MAKECMDGOALS),পরিষ্কার)
load_makefile $(ওয়াইল্ডকার্ড **/Makeppfile)
আর
কোন_ইমপ্লিসিট_লোড # অন্য কোনো মেকফাইল স্বয়ংক্রিয়ভাবে লোড হওয়া প্রতিরোধ করুন।
যদি শেষ

$(ফনি ক্লিন):
&rm -f $(ওয়াইল্ডকার্ড**/*.o)

রিকার্সিভ করা থেকে নির্মাণ করা in বিভিন্ন ডিরেক্টরি

makepp_cookbook-এ "একাধিক ডিরেক্টরির জন্য টিপস" দেখুন।

রিকার্সিভ করা থেকে পরিবর্তন মূল্য of a পরিবর্তনশীল

কিছু মেকফাইল একটি ভেরিয়েবলের ভিন্ন মান দিয়ে নিজেদেরকে পুনরায় চালু করে, যেমন, ডিবাগ
নিম্নলিখিত মেকফাইল খণ্ডে লক্ষ্য

.PHONE: সব ডিবাগ

অপ্টিমাইজ করা:
$(মেক) প্রোগ্রাম CFLAGS=-O2

ডিবাগ:
$(মেক) প্রোগ্রাম CFLAGS=-g

প্রোগ্রাম: ao bo
$(CC) $(CFLAGS) $^ -o $@

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

ব্যবহারকারী যদি "মেক ডিবাগ" টাইপ করে, তবে এটি ডিবাগ সক্ষম করে ডিফল্ট মোডে প্রোগ্রাম তৈরি করে
অপ্টিমাইজেশানের পরিবর্তে।

এটি করার একটি ভাল উপায় হল দুটি ভিন্ন ভিন্ন সেটের সাথে দুটি ভিন্ন প্রোগ্রাম তৈরি করা
অবজেক্ট ফাইল, এই মত:

CFLAGS := -O2
DEBUG_FLAGS := -g
মডিউল:= ab

প্রোগ্রাম: $(মডিউল).o
$(CC) $(CFLAGS) $(ইনপুট) -o $(আউটপুট)

debug/program: debug/$(MODULES).o
$(CC) $(DEBUG_FLAGS) $(ইনপুট) -o $(আউটপুট)

%.o : %.c
$(CC) $(CFLAGS)-c $(ইনপুট) -o $(আউটপুট)

ডিবাগ/%.o : %.c
$(CC) $(DEBUG_FLAGS)-c $(ইনপুট) -o $(আউটপুট)

$(ফনি ডিবাগ): ডিবাগ/প্রোগ্রাম

এইভাবে এটি করার সুবিধা হল (ক) যখন আপনি সবকিছু পুনর্নির্মাণের প্রয়োজন নেই
ডিবাগ থেকে অপ্টিমাইজে স্যুইচ করুন এবং আবার ফিরে যান; (খ)

ভান্ডার ব্যবহার করে উপরেরটি আরও সংক্ষিপ্তভাবে লেখা যেতে পারে। পরবর্তী
makefile ঠিক সমতুল্য:

সংগ্রহস্থল ডিবাগ=. # ডিবাগ সাবডিরেক্টরিটিকে এর একটি অনুলিপির মতো দেখায়৷
# বর্তমান সাবডিরেক্টরি।
load_makefile ডিবাগ CFLAGS=-g
# ডিবাগ সাবডিরেক্টরিতে আহ্বান করা হলে CFLAGS ওভাররাইড করুন
CFLAGS := -O2 # CFLAGS-এর মান যখন এই সাব-ডিরেক্টরিতে চালু করা হয়

প্রোগ্রাম: ao bo
$(CC) $(CFLAGS) $^ -o $@

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

$(ফনি ডিবাগ): ডিবাগ/প্রোগ্রাম
# যদি ব্যবহারকারী টাইপ করে "makepp debug", বিল্ড করে
প্রোগ্রামের পরিবর্তে # ডিবাগ/প্রোগ্রাম।

বিবিধ পরামর্শ
কিভাবে do I নির্মাণ করা এক অংশ ভিন্নভাবে মাত্র একদা?

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

makepp DEBUG=3 buggy.o # অন্য বিকল্প দিয়ে এটি তৈরি করুন।
makepp --dont-build=buggy.o buggy # "ভুল" বিল্ড বিকল্প থাকা সত্ত্বেও এটি ব্যবহার করুন।

কিভাবে do I করা নিশ্চিত my আউটপুট ডিরেক্টরি বিদ্যমান?

আপনি আউটপুট ডিরেক্টরি তৈরি করার জন্য একটি নিয়ম নির্দিষ্ট করতে পারেন, তারপর নিশ্চিত করুন যে প্রতিটি ফাইল
আউটপুট ডিরেক্টরিতে যায় এটির উপর নির্ভর করে। কিন্তু সাধারণত এরকম কিছু করা সহজ
এই:

# শাস্ত্রীয় উপায়
ডামি := $(শেল টেস্ট -d $(OUTPUT_DIRECTORY) || mkdir -p $(OUTPUT_DIRECTORY))
# এটি সাধারণত সমস্ত ফাইল নির্ভর করার চেয়ে সহজ
# $(OUTPUT_DIRECTORY) এবং এটি তৈরি করার একটি নিয়ম রয়েছে।
# মনে রাখবেন যে আপনি অবশ্যই := এর পরিবর্তে = এটিকে জোর করে ব্যবহার করতে হবে
# অবিলম্বে কার্যকর করুন।
# একটি বিকল্প পদ্ধতি: পার্ল কোড ব্যবহার করে, OUTPUT_DIRECTORY স্থানীয় var
perl_begin
-d $OUTPUT_DIRECTORY বা mkdir $OUTPUT_DIRECTORY;
perl_end
# আধুনিক উপায়, বিদ্যমান ডিরেক্টরিগুলির জন্য কিছুই করে না
&mkdir -p $(OUTPUT_DIRECTORY)

এই বিবৃতিগুলির মধ্যে একটি আপনার মেকফাইলের শীর্ষের কাছে থাকা উচিত, তাই সেগুলি কার্যকর করা হয়
সম্ভবত ডিরেক্টরির প্রয়োজন হতে পারে এমন কিছুর আগে।

কিভাবে do I বল a হুকুম থেকে এক্সিকিউট on প্রতি নির্মাণ?

সবচেয়ে সহজ উপায় হল রুল মেকানিজম ব্যবহার না করা, কিন্তু সহজভাবে এটি চালানো, যেমন
এই:

ডামি := $(শেল তারিখ > লাস্ট_বিল্ড_টাইমস্ট্যাম্প)

অথবা এটি একটি পার্ল ব্লকে রাখুন, যেমন:

perl_begin
সিস্টেম ("চালানোর আদেশ");
perl_end

এই পদ্ধতির অসুবিধা রয়েছে যে এটি কার্যকর করা হবে এমনকি যদি একটি সম্পর্কহীন লক্ষ্য হয়
চালানো হচ্ছে

একটি দ্বিতীয় পদ্ধতি হল ফাইলটিকে একটি নকল লক্ষ্য হিসাবে ঘোষণা করা, এমনকি এটি একটি বাস্তব ফাইল হলেও।
এটি মেকপকে প্রতিবার এটি তৈরি করার জন্য কমান্ডটি পুনরায় কার্যকর করতে বাধ্য করবে, তবে শুধুমাত্র তা হলে
কিছু নিয়মের নির্ভরতা তালিকায় প্রদর্শিত হয়।

কিভাবে do I কমান দ্য প্রদর্শিত নির্মাণ করা আদেশ?

প্রায়শই কম্পাইলেশন কমান্ডের জন্য অনেকগুলি বিকল্প থাকে যা তে প্রদর্শিত হয়
পর্দা অপঠনযোগ্য। এর প্রদর্শন দমন করে আপনি যা প্রদর্শিত হয় তা পরিবর্তন করতে পারেন
সম্পূর্ণ কমান্ড, এবং তারপর স্পষ্টভাবে কমান্ডের আকর্ষণীয় অংশ মুদ্রণ করুন। এটা
"$(filter_out )" ব্যবহার করে কমান্ডের শুধুমাত্র প্রাসঙ্গিক অংশ প্রিন্ট করা সহজ, যেমন
এই:

ALL_CFLAGS = $(CFLAGS) $(ইনক্লুডস) $(ADDL_CXX_FLAGS) $(DEBUG_FLAGS)

%.o : %.c
@&echo $(notdir $(CC)) ...
$(filter_out -I* $(ADDL_CXX_FLAGS), $(ALL_CFLAGS))
-c $(ইনপুট)
@$(CC) $(ALL_CFLAGS)-c $(ইনপুট) -o $(আউটপুট)

(কমান্ডের সামনের "@" কমান্ডটি প্রিন্ট করাকে দমন করে।)

এটি আপনাকে বেশিরভাগ আকর্ষণীয় বিকল্পগুলি দেখতে অনুমতি দেবে তবে সবগুলি প্রদর্শন করবে না
ডিরেক্টরি অন্তর্ভুক্ত করুন (যার মধ্যে প্রায়শই অনেকগুলি থাকে!) অংশ আপনি আগ্রহী হলে
in আপনার কমান্ডে সংলগ্ন, আপনি "প্রিন্ট" ফাংশনটিও ব্যবহার করতে পারেন (যা যোগ করে a
নিউলাইন, তাই আপনি তাদের কয়েকটি চান না):

লক্ষ্য:
@... $(মুদ্রণ আকর্ষণীয় অংশ) ...

কিভাবে do I রূপান্তর a ফাইল মধ্যে নির্ভরতা?

কিছু অস্পষ্ট ফাইল ফরম্যাটের জন্য এটি একটি স্ক্যানার প্রয়োগ করা উপযুক্ত নয়। একটি প্রকল্পে
আমাদের xml ফাইল আছে, বলুন foobar.xml যার জন্য নির্ভরতা রয়েছে foobar.out:







আমরা এই সহজ লেআউটটি মেনে চলার সিদ্ধান্ত নিয়েছি, তাই আমাদের xml পার্স করার দরকার নেই। সঙ্গে
বিল্টইন &sed, এখানে আমরা তিনটি ধরণের জন্য তিনটি সহজ প্রতিস্থাপনের সাথে কি করি
লাইন:

%.d: %.xml
&sed's! !$(স্টেম).আউট: \\! || s! (.+) !$$1 \\! || s! !# খালি!'
$(ইনপুট)-ও $(আউটপুট)

foobar.d অন্তর্ভুক্ত

এটি অন্তর্ভুক্ত করার চেষ্টা করে, প্রথমে "foobar.d" তৈরি করে:

foobar.out:
a
b
c
#খালি

খালি (শুধু একটি মন্তব্য বা সত্যিই খালি) লাইন ট্রেলিং সম্পর্কে উদ্বিগ্ন হওয়া এড়িয়ে যায়
ব্যাকস্ল্যাশ একটি মাল্টিলাইন তালিকা তৈরির একটি বিকল্প হল:

%.d: %.xml
&sed's! !$(স্টেম).আউট: \$$((! || s! !))! || s!<.+?>!!g'
$(ইনপুট)-ও $(আউটপুট)

foobar.d অন্তর্ভুক্ত

এটি একটি সমতুল্য উত্পাদন করে:

foobar.out: $((
a
b
c
))

আপনার যদি আরও জটিল পুনর্লিখন করতে হয়, তাহলে মেকফাইলের মধ্যে বা a-তে একটি ফাংশন সংজ্ঞায়িত করুন
মডিউল যা আপনি অন্তর্ভুক্ত করেন। যেমন অনির্ধারিত $_ ইনপুট লাইন এড়িয়ে যাবে:

সাব মাইফিল্টার {
undef $_ ফেরত দিন যদি /
আমার $stem = f_stem;
s! !$stem.out: \$((! || s! !))! || s!<.+?>!!g;
}

%.d: %.xml
&sed's! !$(স্টেম).আউট: \$$((! || s! !))! || s!<.+?>!!g'
$(ইনপুট)-ও $(আউটপুট)

foobar.d অন্তর্ভুক্ত

onworks.net পরিষেবা ব্যবহার করে makepp_cookbook অনলাইন ব্যবহার করুন



সর্বশেষ লিনাক্স এবং উইন্ডোজ অনলাইন প্রোগ্রাম