বিধি কার্যকর করার সময় পরিবর্তনশীল তৈরির সংজ্ঞা দিন


208

আমার GNUmakefile এ, আমি একটি নিয়ম চাই যা অস্থায়ী ডিরেক্টরি ব্যবহার করে। উদাহরণ স্বরূপ:

out.tar: TMP := $(shell mktemp -d)
        echo hi $(TMP)/hi.txt
        tar -C $(TMP) cf $@ .
        rm -rf $(TMP)

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

নিয়ম বহিস্কারের সময় কেবল যখন সংজ্ঞায়িত করা হয় তার বিপরীতে কেবল পরিবর্তনকে সংজ্ঞায়িত করার কোনও উপায় আছে কি?

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

উত্তর:


321

আপনার উদাহরণে, TMPপরিবর্তনশীল সেট করা হয় (এবং অস্থায়ী ডাইরেক্টরি তৈরি করা) যখনই নিয়ম জন্য out.tarমূল্যায়ন করা হয়। ডিরেক্টরিটি তৈরি করতে কেবল যখন out.tarপ্রকৃতভাবে বরখাস্ত করা হয়, আপনাকে ডিরেক্টরি তৈরি করতে হবে পদক্ষেপে:

out.tar : 
    $(eval TMP := $(shell mktemp -d))
    @echo hi $(TMP)/hi.txt
    tar -C $(TMP) cf $@ .
    rm -rf $(TMP)

Eval ফাংশন একটি স্ট্রিং মূল্যায়ণ যেমন যদি এটা Makefile মধ্যে নিজে টাইপ করা হয়েছে। এই ক্ষেত্রে, এটি ফাংশন কলের TMPফলাফলের ক্ষেত্রে ভেরিয়েবল সেট করে shell

সম্পাদনা (মন্তব্যের জবাবে):

একটি অনন্য পরিবর্তনশীল তৈরি করতে, আপনি নিম্নলিখিতগুলি করতে পারেন:

out.tar : 
    $(eval $@_TMP := $(shell mktemp -d))
    @echo hi $($@_TMP)/hi.txt
    tar -C $($@_TMP) cf $@ .
    rm -rf $($@_TMP)

এটি লক্ষ্য সহ (আউটআটার, এই ক্ষেত্রে) এর নামটি ভেরিয়েবলের সাথে সংশোধন করবে, নামের সাথে একটি ভেরিয়েবল তৈরি করবে out.tar_TMP। আশা করি, দ্বন্দ্ব রোধে এটি যথেষ্ট।


2
কয়েকটি স্পষ্টতা শীতল করুন ... এটি এই লক্ষ্যে টিএমপি সুযোগ পাবে না, তাই না? সুতরাং যদি তাদের নিজস্ব rules (টিএমপি) ব্যবহার (সম্ভবত -j সমান্তরালভাবে) থাকে তবে এমন কোনও বিধি রয়েছে, তাহলে বিরোধ হতে পারে? এছাড়াও, @ ইকোও কি প্রয়োজনীয়? মনে হচ্ছে আপনি এটিকে ছেড়ে যেতে পারেন।
এমিল 19

3
কৌশলটি মনে হচ্ছে (যদিও গড় নন-মেক গুরুর তুলনায় কিছুটা অস্বচ্ছ :-) ধন্যবাদ!
এমিল সিট

29
এই সমাধান সঙ্গে সাবধান! $(eval $@_TMP := $(shell mktemp -d))যখন মেকফাইলটি প্রথম মূল্যায়ন করা হয় তখন নিয়ম পদ্ধতি অনুসারে নয় happen অন্য কথায়, $(eval ...)আপনি যত তাড়াতাড়ি চিন্তা করেন তার চেয়ে দ্রুত ঘটে। যদিও এই উদাহরণটির জন্য এটি ঠিক আছে, এই পদ্ধতিটি কিছু অনুক্রমিক ক্রিয়াকলাপগুলির জন্য সমস্যা সৃষ্টি করবে।
জেমস থমাসমুন 1979

1
@ জেমস থমাস মুন ১৯৯৯ আপনি কীভাবে জানেন যে কীভাবে এই সীমাবদ্ধতাগুলি কাটিয়ে উঠতে হবে, উদাহরণস্বরূপ এমন কিছু ভেরিয়েবলগুলি আবিষ্কার করুন যা নিয়মের আগে সম্পাদিত পদক্ষেপের ফলাফল হওয়া উচিত?
ভাদিম কোতোভ

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

63

এটি করার একটি অপেক্ষাকৃত সহজ উপায় হ'ল পুরো ক্রমটি শেল স্ক্রিপ্ট হিসাবে লেখা।

out.tar:
   set -e ;\
   TMP=$$(mktemp -d) ;\
   echo hi $$TMP/hi.txt ;\
   tar -C $$TMP cf $@ . ;\
   rm -rf $$TMP ;\

আমি এখানে সম্পর্কিত কিছু টিপস একীভূত করেছি: https://stackoverflow.com/a/29085684/86967


3
এটি অবশ্যই সহজ এবং সর্বোত্তম উত্তর (এড়ানো @এবং evalএকই কাজ করা) doing মনে রাখবেন যে আপনার আউটপুটে আপনি দেখতে পাবেন $TMP(উদাঃ tar -C $TMP ...) যদিও মানটি সঠিকভাবে কমান্ডকে দেওয়া হয়েছে।
কার্ল রিখটার

এটি সাধারণত এটি করা হয়; আমি আশা করি লোকেরা এই উত্তরটি দেখবে কারণ বাস্তবে কেউ গ্রহণযোগ্যটির সমস্ত চেষ্টা করে না।
pmos

আপনি যদি শেল নির্দিষ্ট কমান্ড ব্যবহার করছেন? সেক্ষেত্রে শেল কমান্ডগুলি কলিং মেকের চেয়ে একই শেল ভাষায় থাকতে হবে, তাই না? আমি শেবাং দিয়ে কিছু মেকফিল দেখেছি।
ptitpion

@ptitpion: আপনি বেস SHELL := /bin/bash-নির্দিষ্ট বৈশিষ্ট্যগুলি সক্ষম করতে আপনার মেকফিলের মধ্যেও থাকতে পারেন ।
নোবার

31

আর একটি সম্ভাবনা হ'ল নিয়ম যখন জ্বলতে থাকে তখন ভেরিয়েবলগুলি সেট আপ করতে আলাদা লাইন ব্যবহার করা।

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

PHONY = ruleA ruleB display

all: ruleA

ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
ruleA: display

ruleB: TMP = $(shell mktemp -d testruleB_XXXX)
ruleB: display

display:
    echo ${TMP}

কোড চালানো প্রত্যাশিত ফলাফল তৈরি করে:

$ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile  testruleB_Y4Ow

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

11
এই সমাধান সঙ্গে সাবধান! ruleA: TMP = $(shell mktemp -d testruleA_XXXX)এবং ruleB: TMP = $(shell mktemp -d testruleB_XXXX)যখন মেকফিলটি প্রথম মূল্যায়ন করা হবে তখনই ঘটবে। অন্য কথায়, ruleA: TMP = $(shell ...আপনি যত তাড়াতাড়ি চিন্তা করেন তার চেয়ে দ্রুত ঘটে। যদিও এটি এই বিশেষ ক্ষেত্রে কাজ করতে পারে, এই পদ্ধতিটি কিছু অনুক্রমিক ক্রিয়াকলাপগুলির জন্য সমস্যা সৃষ্টি করবে।
জেমস থমাসমুন 1979

1

আমি "না" উত্তরগুলি অপছন্দ করি, কিন্তু ... না।

makeএর ভেরিয়েবলগুলি বিশ্বব্যাপী এবং মেকফিলের "পার্সিং" পর্যায়ে নির্ধারণের পর্যায়ে নয়, মূল্যায়ন করার কথা রয়েছে।

এক্ষেত্রে, যতক্ষণ না একক লক্ষ্য হিসাবে চলক স্থানীয় হয়, ততক্ষণ @ নোবারের উত্তর অনুসরণ করুন এবং এটিকে শেল পরিবর্তনশীল করে তুলুন

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

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