জিএনইউ মেকফিল ভেরিয়েবল অ্যাসাইনমেন্ট =,? =,: = এবং + = এর মধ্যে পার্থক্য কী?


763

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

পার্থক্য কি :

 VARIABLE = value
 VARIABLE ?= value
 VARIABLE := value
 VARIABLE += value

আমি জিএনইউ মেকের ম্যানুয়ালটিতে বিভাগটি পড়েছি , তবে এটি এখনও আমার কাছে বোঝায় না।

উত্তর:


1027

অলস সেট

VARIABLE = value

একটি ভেরিয়েবলের সাধারণ সেটিং, তবে valueক্ষেত্রের সাথে উল্লিখিত অন্য যে কোনও ভেরিয়েবলগুলি ভেরিয়েবলটি ব্যবহৃত হয় তার বিন্দুতে পুনরাবৃত্তভাবে প্রসারিত হয়, যখন ঘোষিত হওয়ার আগে এটি ছিল না

তাত্ক্ষণিক সেট

VARIABLE := value

ভিতরে মানগুলির সহজ প্রসারণ সহ একটি ভেরিয়েবলের সেট করা - এর মধ্যে মানগুলি ঘোষণার সময় প্রসারিত হয়।

অনুপস্থিত থাকলে অলস সেট

VARIABLE ?= value

কোনও ভেরিয়েবলের সেটিংয়ের মান যদি না থাকে তবেই। অ্যাক্সেস করা valueহলে সর্বদা মূল্যায়ন VARIABLEকরা হয়। এটি সমান

ifeq ($(origin FOO), undefined)
  FOO = bar
endif

আরও বিশদ জন্য ডকুমেন্টেশন দেখুন ।

পরিশেষে

VARIABLE += value

বিদ্যমান মানটিতে সরবরাহ করা মান যুক্ত করা (বা ভেরিয়েবলটি উপস্থিত না থাকলে সেই মানটিতে সেট করা)


25
A + = B বি বি প্রসারণ করে? এটি যদি আমি A + = B এবং তারপরে বি + = সি করি, তবে কি A $ {B} এবং $ {C aten এর সংক্ষিপ্তকরণের মূল্যায়ন করবে?
আন্তন ডানিয়েকো

15
যেমন ম্যানুয়ালটির লিঙ্কযুক্ত বিভাগটি বলেছে। + = মূল অ্যাসাইনমেন্টটি যা সাধারণ বা পুনরাবৃত্ত শব্দার্থবিজ্ঞান অনুসারে কাজ করে। সুতরাং হ্যাঁ, এটি আরএইচএসকে প্রসারিত করবে তবে এটি তাত্ক্ষণিকভাবে বা মুলতুবি পদ্ধতিতে কিনা তা এলএইচএসে চলকটির ধরণের উপর নির্ভর করে।
এটান রিজনার

6
যখন আপনি বলবেন ভেরিয়েবলের মান প্রসারিত হয় তখন আপনার অর্থ কী?
সাশকো লাইখেনকো

2
@ Expansion সম্প্রসারণের অর্থ পেতে এখানে দেখুন gnu.org/software/make/manual/make.html#Flavors
Umair R

7
"অনুপস্থিত থাকলে সেট" অলস বা তাত্ক্ষণিক? আমি কি "অনুপস্থিত থাকলে অলস সেট" এবং "অবসেট হলে তাত্ক্ষণিক সেট" করতে পারি?
উড্রো বার্লো 14

268

ব্যবহারের =ফলে ভেরিয়েবলকে একটি মান নির্ধারিত হয়। যদি ভেরিয়েবলের ইতিমধ্যে একটি মান থাকে তবে এটি প্রতিস্থাপন করা হয়। এটি ব্যবহার করা হলে এই মানটি প্রসারিত হবে। উদাহরণ স্বরূপ:

HELLO = world
HELLO_WORLD = $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# This echoes "hello world!"
echo $(HELLO_WORLD)

ব্যবহার :=করা ব্যবহারের অনুরূপ =। যাইহোক, মানটি ব্যবহার করার সময় প্রসারিত হওয়ার পরিবর্তে এটি অ্যাসাইনমেন্টের সময় প্রসারিত হয়। উদাহরণ স্বরূপ:

HELLO = world
HELLO_WORLD := $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# Still echoes "world world!"
echo $(HELLO_WORLD)

HELLO_WORLD := $(HELLO) world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

ব্যবহার ?=নির্ধারণ পরিবর্তনশীল একটি মান iff পরিবর্তনশীল পূর্বে নির্ধারিত করা হয় নি। যদি ভেরিয়েবলটি আগে একটি ফাঁকা মান ( VAR=) নির্ধারিত হয় তবে এটি এখনও আমার মনে হয় সেট হিসাবে বিবেচিত হয় । অন্যথায়, ফাংশন ঠিক মত =

ব্যবহার +=করা ব্যবহারের মতো =, তবে মানটি প্রতিস্থাপনের পরিবর্তে, মানটি বর্তমানের সাথে সংযুক্ত করা হয়, এর মধ্যে একটি স্থান দিয়ে। যদি ভেরিয়েবলটি আগে সেট করা থাকে :=তবে এটি প্রসারিত হবে বলে আমার মনে হয় । ফলস্বরূপ মানটি প্রসারিত হয় যখন এটি ব্যবহৃত হয় বলে আমি মনে করি । উদাহরণ স্বরূপ:

HELLO_WORLD = hello
HELLO_WORLD += world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

যদি এর মতো কিছু HELLO_WORLD = $(HELLO_WORLD) world!ব্যবহার করা হয়, তবে পুনরাবৃত্তি ঘটতে পারে, যা সম্ভবত আপনার মেকফিলের সম্পাদন শেষ করে। যদি A := $(A) $(B)ব্যবহার করা হয়, ফলে সঠিক ব্যবহার হিসাবে একই হবে না +=কারণ Bসঙ্গে প্রসারিত হয় :=যেহেতু +=ঘটাবেন না Bপ্রসারিত করতে হবে।


3
এর ফলস্বরূপ তাই VARIABLE = literalএবং VARIABLE := literalসর্বদা সমান। আমি কি অধিকার পেয়েছি?
আইওও

1
আইআওও, হ্যাঁ আক্ষরিক হিসাবে তাদের ব্যবহারগুলি অবিস্মরণীয়
সেবাস্তিয়ান

একটি সূক্ষ্ম পার্থক্য হ'ল: -?: Recursive নামক মেকফাইলগুলিতে কর্মক্ষমতা উন্নত করতে পারে। যেমন যদি if? = $ (শেল কিছু_কমন্ড_ত_ রুনস_লং_টাইম)। পুনরাবৃত্ত কলগুলিতে এটি একবারে মূল্যায়ন করা হবে। বিল্ড পারফরম্যান্সে লাভের কারণ। : = কমান্ডটি অকারণে একাধিকবার চলমান হওয়ায় ধীর হয়ে যাবে
কেশভ

61

আমি আপনাকে "মেক" ব্যবহার করে কিছু পরীক্ষা-নিরীক্ষা করার পরামর্শ দিচ্ছি। এখানে একটি সাধারণ ডেমো রয়েছে =এবং এর মধ্যে পার্থক্য দেখায় :=

/* Filename: Makefile*/
x := foo
y := $(x) bar
x := later

a = foo
b = $(a) bar
a = later

test:
    @echo x - $(x)
    @echo y - $(y)
    @echo a - $(a)
    @echo b - $(b)

make test কপি করে প্রিন্ট:

x - later
y - foo bar
a - later
b - later bar

এখানে আরও বিস্তৃত ব্যাখ্যা পরীক্ষা করুন


5
@ফলাফলের এই বিভ্রান্তিকর পুনরাবৃত্তি এড়াতে প্রতিটি রেসিপি সামনে রেখে ব্যবহার করা ভাল ।
আলেকজান্দ্রো ডি অলিভিরা

2
মেক /* ... */ব্লক মন্তব্য সমর্থন করে না
ইওংহম

31

আপনি যখন ব্যবহার করেন VARIABLE = value, যদি valueবাস্তবে অন্য কোনও চলকের রেফারেন্স হয়, তবে মানটি VARIABLEব্যবহৃত হয় যখন তখন নির্ধারিত হয়। এটি সর্বোত্তম উদাহরণ সহ উদাহরণস্বরূপ:

VAL = foo
VARIABLE = $(VAL)
VAL = bar

# VARIABLE and VAL will both evaluate to "bar"

আপনি যখন ব্যবহার করবেন VARIABLE := value, আপনি value এখন হিসাবে এটির মান পাবেন । উদাহরণ স্বরূপ:

VAL = foo
VARIABLE := $(VAL)
VAL = bar

# VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"

ব্যবহারের VARIABLE ?= valঅর্থ হ'ল আপনি VARIABLE যদি VARIABLE ইতিমধ্যে সেট না করে থাকে তবে এর মান সেট করেন । যদি এটি ইতিমধ্যে সেট না করা থাকে তবে মানটির সেটিংটি VARIABLEব্যবহার না করা অবধি স্থগিত করা হয় (উদাহরণস্বরূপ 1)।

VARIABLE += valueশুধু appends valueকরতে VARIABLE। এর আসল মান valueএটি হিসাবে নির্ধারিত হয় যখন এটি শুরুতে সেট করা হয়, হয় উভয় =বা ব্যবহার করে :=


প্রকৃতপক্ষে, আপনার প্রথম উদাহরণে, ভেরিয়েবলটি হ'ল V (VAL) এবং VAL বার। এটি ব্যবহার করা হলে বৈচিত্র্য প্রসারিত হয়।
স্ট্রাগার

1
হ্যাঁ, মন্তব্যগুলি যখন তাদের ব্যবহার করা হবে তখন কী হবে তা ব্যাখ্যা করছে।
মিপাডি

আহ; আমি অনুমান করি আপনি এটি সংশোধন করেছেন, বা আমি "মূল্যায়ন" হিসাবে "হতে" হিসাবে ভুল লিখেছি।
স্ট্রাগার

7

উপরের উত্তরে, "ঘোষণার / ব্যবহারের সময় মানগুলি প্রসারিত হয়" এর অর্থ কী তা বোঝা গুরুত্বপূর্ণ । এর মতো মান দেওয়া কোনও *.cপ্রকারের প্রসার ঘটাতে পারে না। এই স্ট্রিংটি কোনও কমান্ড দ্বারা ব্যবহৃত হলেই এটি সম্ভবত কিছু গ্লোববিং ট্রিগার করবে। একইভাবে, মত একটি মান $(wildcard *.c)বা $(shell ls *.c)কোন সম্প্রসারণ ফলস্বরূপ ঘটা করে না এবং সম্পূর্ণরূপে সংজ্ঞা সময় এমনকি যদি আমরা ব্যবহৃত এ মূল্যায়ন করা হয় :=পরিবর্তনশীল সংজ্ঞা।

আপনার কিছু সি ফাইল রয়েছে এমন ডিরেক্টরিতে নিম্নলিখিত মেকফিল চেষ্টা করুন:

VAR1 = *.c
VAR2 := *.c
VAR3 = $(wildcard *.c)
VAR4 := $(wildcard *.c)
VAR5 = $(shell ls *.c)
VAR6 := $(shell ls *.c)

all :
    touch foo.c
    @echo "now VAR1 = \"$(VAR1)\"" ; ls $(VAR1)
    @echo "now VAR2 = \"$(VAR2)\"" ; ls $(VAR2)
    @echo "now VAR3 = \"$(VAR3)\"" ; ls $(VAR3)
    @echo "now VAR4 = \"$(VAR4)\"" ; ls $(VAR4)
    @echo "now VAR5 = \"$(VAR5)\"" ; ls $(VAR5)
    @echo "now VAR6 = \"$(VAR6)\"" ; ls $(VAR6)
    rm -v foo.c

রানিং makeএমন একটি নিয়মকে ট্রিগার করবে যা একটি অতিরিক্ত (খালি) সি ফাইল তৈরি করে, যাকে বলা হয় foo.cতবে 6 ভেরিয়েবলের কোনওটিরই foo.cমান নেই।


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