আপনি কীভাবে কোনও মেকফিলকে লক্ষ্য পুনর্নির্মাণ করতে বাধ্য করেন


182

আমার একটি মেকফাইল রয়েছে যা পরে তৈরি করে এবং অন্য মেকফিলকে কল করে। যেহেতু এই মেকফিলটি আরও মেকফাইলগুলিকে কল করে যা এটি কাজ করে যা আসলেই পরিবর্তিত হয় না। সুতরাং এটি প্রকল্পটি নির্মিত এবং তারিখ অবধি ভাবতে থাকে।

dnetdev11 ~ # make
make: `release' is up to date.

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

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

দ্রষ্টব্য: নিরীহদের রক্ষার জন্য নামগুলি সরানো হয়েছে

সম্পাদনা: চূড়ান্ত স্থির সংস্করণ:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib

লডল, যেহেতু এটি প্রায়শই দেখা যাওয়া প্রশ্ন, আপনি কি আরও আধুনিক হতে প্রশ্নটি সম্পাদনা করতে চান? (দেখে মনে হচ্ছে .PHONYএটি আপনার একমাত্র সমস্যা ছিল না, এবং আপনি সমস্যার সমাধানটি আসলেই সম্পাদনা করার কথা বলেছিলেন না বা কমপক্ষে আর নয়।)
কীথ এম

উত্তর:


22

আপনি আপনার এক বা একাধিক লক্ষ্যকে নকল হতে ঘোষণা করতে পারেন ।

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

...

একটি স্বল্প লক্ষ্য একটি আসল লক্ষ্য ফাইলের পূর্বশর্ত হওয়া উচিত নয়; যদি এটি হয় তবে তার রেসিপিটি প্রতিবার তৈরি করা হবে সেই ফাইলটি আপডেট করতে। ফোনি টার্গেট কখনই আসল টার্গেটের পূর্বশর্ত না হওয়া পর্যন্ত ফোনি টার্গেটের রেসিপি তখনই কার্যকর করা হবে যখন ফোনি টার্গেট একটি নির্দিষ্ট লক্ষ্য থাকে


68
এই উত্তরটি, যদিও এটি "স্বীকৃত" এবং অত্যন্ত "আপভোটেড" হলেও সত্যই এই চিহ্নটি অফ-দ্য মার্ক। প্রথমে এটি বলে যে "লক্ষ্যকে কলঙ্কিত হওয়ার ঘোষণা করুন" তবে তারপরে "ফনি টার্গেট আসলে কোনও ফাইলের নাম নয়"। ঠিক আছে, যদি আপনার টার্গেটটি কোনও ফাইল হয় তবে তা উত্তরের বৈপরীত্য। দ্বিতীয়ত, এটি বলে যে "স্বল্প লক্ষ্য একটি বাস্তবের পূর্বশর্ত হওয়া উচিত নয়" - ভাল, যদি তা হয় তবে? আসল প্রশ্ন, এটি কিনা তা নির্দিষ্ট করে না বা তা হয় না। সঠিক উত্তর হল, না ডিক্লেয়ার করার মত আপনার অপ্রকৃত হতে লক্ষ্যমাত্রা, বরং অতিরিক্ত অপ্রকৃত লক্ষ্য ঘোষণা, এবং তারপর,, লক্ষ্যমাত্রা আপনি পুনর্নির্মিত চান নির্ভর যে।
মার্ক গ্যালেক

2
@MarkGaleck। যখন উত্তরে বলা হয় যে "ফোনি টার্গেট এমনটি যা আসলে কোনও ফাইলের নাম নয়" এটি সরাসরি জিসিসি মেকুয়াল থেকে উদ্ধৃত করে is এটা পুরোপুরি সঠিক।
ড্রোলি

"টার্গেট" হ'ল একটি মেক টার্ম যা কোনও কোলনের বাম দিকে পাঠ্যকে বোঝায় :, কেবল আপনি যে ফলাফল তৈরি করতে চান তা শেষ নয় (যেমন আপনার বাইনারি ফাইল)। প্রশ্ন সালে release, debug, clean, এবং installমেক লক্ষ্যমাত্রা নয়, xxx_utilবা xxxcore.soবা অন্য কিছু।
কিথ এম

727

-Bকরতে সুইচ, যার দীর্ঘ ফর্ম --always-make, বলে makeউপেক্ষা টাইমস্ট্যাম্প প্রয়োজন এবং নির্দিষ্ট লক্ষ্যমাত্রা আছে। এটি মেক ব্যবহারের উদ্দেশ্যকে পরাজিত করতে পারে তবে এটি আপনার প্রয়োজনের হতে পারে।


4
@ মারককোয়ান আমি সম্পূর্ণরূপে একমত! এই বিকল্পগুলি হ'ল আমি যা খুঁজছিলাম ঠিক সেটাই, ডেভের পরামর্শ অনুসারে কিছুটা হ্যাক নয়।
মার্টেন বামেলিস 21

8
এই পদ্ধতির সাথে সাবধানতা হ'ল এটি কেবল অনেক কিছু তৈরি করে। বিশেষত অটোটুলের সাহায্যে, আমি এটি কনফিগারটি পুনরায় চালিত করতে দেখেছি .. আমি আশা করি একটি এলডি_প্রেলোড ভিত্তিক সমাধান তৈরি করা যায় !!
vrdhn

হ্যাঁ, এবং এটি আপনি না চান এমন ফাইলগুলি আবারও লিখতে পারে! যেমন গ্লোবাল সিস্টেমের লাইব্রেরিগুলি যা নির্ভরতাগুলিতে উপস্থিত হয় এবং পুনর্নির্মাণ এবং ওভাররাইট করা হয় ...
জুলিও গেরা

18

একটি কৌশল যা সান ম্যানুয়ালটিতে নথিভুক্ত করা হত তা make(অস্তিত্বহীন) লক্ষ্য '.FORCE' ব্যবহার করা। আপনি এটি ফাইল, ফোর্স.এমকে তৈরি করে এটি করতে পারেন যা এতে রয়েছে:

.FORCE:
$(FORCE_DEPS): .FORCE

তারপরে, ধরেই নেওয়া আপনার বিদ্যমান মেকফাইলটি বলা হয় makefile, আপনি চালাতে পারেন:

make FORCE_DEPS=release -f force.mk -f makefile release

থেকে .FORCE অস্তিত্ব নেই, তাই এর উপর নির্ভর করে যে কোনও কিছুই পুরানো এবং পুনর্নির্মাণ করা হবে।

এই সমস্ত কোনও সংস্করণের সাথে কাজ করবে make; লিনাক্সে আপনার জিএনইউ মেক আছে এবং তাই আলোচিত হিসাবে PHONY লক্ষ্য ব্যবহার করতে পারেন।

makeমুক্তির বিষয়টি আপ টু ডেট বলে কেন বিবেচনা করে তা বিবেচ্য। এটি হতে পারে কারণ touch releaseকার্যকর করা আদেশগুলির মধ্যে আপনার একটি কমান্ড রয়েছে; এটি হতে পারে কারণ 'রিলিজ' নামক একটি ফাইল বা ডিরেক্টরি রয়েছে যা বিদ্যমান এবং এর কোনও নির্ভরতা নেই এবং তাই আপ টু ডেট। তারপরে আসল কারণ আছে ...


14

অন্য কেউ পরামর্শ দিলেন .PHONY যা অবশ্যই সঠিক। .ফোনিকে কোনও নিয়মের জন্য ব্যবহার করা উচিত যার জন্য ইনপুট এবং আউটপুটটির মধ্যে তারিখের তুলনাটি অবৈধ। যেহেতু আপনার কাছে ফর্মের কোনও লক্ষ্য নেইoutput: input ব্যবহার করা উচিত them তাদের সকলের জন্য PHONY!

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

সম্পাদনা: যুক্ত উদাহরণ। স্বীকৃত নয়, তবে আপনি এটি করেন P

.PHONY: clean    
clean:
    $(clean)

1
আচ্ছা আপনি যদি আমাকে একটি উদাহরণ দেখাতে পারেন তবে এটি ভাল লাগবে। এটিএম আমি কেবল বাঁধের জিনিসটি কাজ করার চেষ্টা করে এটি হ্যাক করছি: পি
লডল

1
.PHONYটার্গেটের অবস্থানটি কোনও বিষয় নয়। এটি যে কোনও জায়গায় হতে পারে Makefile
অ্যাড্রিয়ান ডাব্লু

5

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


5

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

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make

3

আমি এটি চেষ্টা করেছিলাম এবং এটি আমার পক্ষে কাজ করে

এই লাইনগুলি মেকফাইলে যুক্ত করুন

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

সংরক্ষণ করুন এবং এখন কল করুন

make new 

এবং এটি সবকিছু আবার সংকলিত হবে

কি হলো?

1) 'নতুন' কল পরিষ্কার। 'clean' do 'rm' যা '.o' এর এক্সটেনশন থাকা সমস্ত অবজেক্ট ফাইলগুলি সরিয়ে দেয়।

2) 'নতুন' কল 'মেক'। 'তৈরি' দেখুন যে কোনও '.o' ফাইল নেই, তাই এটি সমস্ত '.o' আবার তৈরি করে। তারপরে লিঙ্কার সমস্ত .o ফাইলের একটিতে এক্সিকিউটেবল আউটপুট যুক্ত করে

শুভকামনা


1
এর চেয়ে newআরও ভাল ব্যবহারের রেসিপিটিতে$(MAKE)make
বেসাইল স্টারিনকিভিচ

1

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

অবশ্যই GNU এর সাথে এড়ানো জটিলতর করুন umbers এবং তারা এই সমস্যা সম্পর্কে সচেতন হলেও এটি তাদের কাজ করার নথিভুক্ত পদ্ধতি।

OTOH, ওটো মেকআপ এই সমস্যার সমাধান হিসাবে তৈরি করা হয়েছিল। আপনি প্রতি মেকফাইলগুলি প্রতিটি ডিরেক্টরি স্তরে লিখতে পারেন, তবুও সেগুলি আপনার প্রকল্পের সম্পূর্ণ দৃশ্যে একত্রিত হয়।

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


প্রশ্নের উত্তর দেয়নি: মূল বিন্দুতে স্পর্শক এবং একটি মন্তব্য হওয়া উচিত উত্তর নয়।
ফ্লুংগো

আমি যথেষ্ট পরিষ্কার ছিল না। সঙ্গে makepp এই পুরো মোড়কের Makefile প্রয়োজন হয় না। সঠিক নির্ভরতা (এগুলি সমস্তই, এরপরে কী তালিকাভুক্ত করা হয় তা নয় :) জেনে এটি প্রয়োজনীয় অবস্থায় সর্বদা পুনর্নির্মাণ করবে।
ড্যানিয়েল

1

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

nmake /A 

পুনর্নির্মাণ সমস্ত


0

এটি আসলে লক্ষ্য কী তার উপর নির্ভর করে। যদি এটি কোনও মূর্খ টার্গেট হয় (যেমন লক্ষ্য কোনও ফাইলের সাথে সম্পর্কিত নয়) আপনার এটিকে .PHONY হিসাবে ঘোষণা করতে হবে।

তবে লক্ষ্যটি যদি কোনও কৌতুকপূর্ণ লক্ষ্য না হয় তবে আপনি কেবল এটি কোনও কারণে পুনর্নির্মাণ করতে চান (উদাহরণস্বরূপ আপনি যখন __Time__ প্রিপ্রসেসিং ম্যাক্রো ব্যবহার করেন), আপনার এখানে উত্তরে বর্ণিত ফোর্স স্কিমটি ব্যবহার করা উচিত।



0

এটি ইতিমধ্যে উল্লেখ করা হয়েছিল, তবে আমি ভেবেছিলাম ব্যবহারে যুক্ত করতে পারি touch

যদি আপনি touchসমস্ত উত্স ফাইলগুলি সংকলন করতে হয় তবে touchকমান্ডটি একটি ফাইলের টাইমস্ট্যাম্পগুলি পরিবর্তনের সময় touchকমান্ডটি কার্যকর করার সময় সিস্টেমের সাথে পরিবর্তন করে ।

উত্স ফাইল টাইমস্ট্যাম্প হ'ল makeকোনও ফাইল "জেনে" ব্যবহার করে যা পরিবর্তিত হয়েছে এবং পুনরায় সংকলন করা দরকার

উদাহরণস্বরূপ: প্রকল্পের একটি C ++ প্রকল্প ছিল, তাহলে কি touch *.cppতারপর রান make, আবার করুন এবং সমগ্র প্রকল্প পুনরায় কম্পাইল করা উচিত নয়।



0

আর্নিয়ার হিসাবে উল্লেখ করা হয়েছে, জিএনইউ মেকুয়ালটিতে একটি প্রস্তাবিত সমাধান রয়েছে যা লক্ষ্য পুনর্নির্মাণে বাধ্য করতে 'জাল' লক্ষ্য ব্যবহার করে:

clean: FORCE
        rm $(objects)
FORCE: ; 

এটি অন্য কোনও নির্ভরতা নির্বিশেষে পরিচ্ছন্নভাবে চলবে।

আমি ম্যানুয়াল থেকে সমাধানটিতে সেমিকোলন যুক্ত করেছি, অন্যথায় একটি খালি লাইন প্রয়োজন।


-1

আমার লিনাক্স সিস্টেমে (সেন্টোস .2.২), লক্ষ্য ঘোষণা করার সময় .FONY এবং ফোর্সের উপর একটি জাল নির্ভরতা তৈরি করার মধ্যে একটি উল্লেখযোগ্য পার্থক্য রয়েছে, যখন নিয়মটি আসলে লক্ষ্যটির সাথে মিলে একটি ফাইল তৈরি করে। যখন ফাইলটি প্রতিবারই পুনঃজেনার করাতে হবে তখন ফাইলের জন্য নকল নির্ভরতা FORCE এবং জাল নির্ভরতার জন্য PHONY উভয়ই দরকার।

ভুল:

date > $@

ডানে:

FORCE
    date > $@
FORCE:
    .PHONY: FORCE
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.