মেকফাইল প্রতীকগুলি $ @ এবং? <কে কী বোঝায়?


416
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

কি $@এবং $<ঠিক কি?


5
উপরের লিঙ্কটি নষ্ট হয়েছে, এখানে অন্যটি রয়েছে: gnu.org/software/make/manual/html_node/A Automat
Variables.html

1
হাই এটি ".cpp.o:" টার্গেট হিসাবে কী বোঝায়? (প্রাক শেষ লাইন?)
ছদ্মনাম_127

3
".Cpp.o:" এর অর্থ ".cpp" (উত্স ফাইল) থেকে ".o" (অবজেক্ট ফাইল)
জাগুজু

1
আমি মনে করি এটি নীচের লিঙ্কে একটি মেক টিউটোরিয়াল আছে উল্লেখ করা উচিত যা থেকে আমি বিশ্বাস করি যে মোহিত তার পোস্টে মেকফাইলটি পেয়েছিল। mrbook.org/blog/tutorials/make
ডিপডিডপুল

মাইক্রোসফট এটা আহ্বান ফাইলের নাম ম্যাক্রো (NMAKE জন্য) যা চেয়ে পরিষ্কার হয় স্বয়ংক্রিয় ভেরিয়েবল (করতে জন্য)। উভয় পক্ষই শিক্ষাগত উদ্দেশ্যে দেখার জন্য এটি দরকারী।
ইভানজিনহো

উত্তর:


502

$@ফাইলটি উত্পন্ন হওয়ার নাম এবং $<প্রথম পূর্বশর্ত (সাধারণত উত্স ফাইল)। আপনি GNU Make ম্যানুয়ালটিতে এই সমস্ত বিশেষ ভেরিয়েবলের একটি তালিকা পেতে পারেন ।

উদাহরণস্বরূপ, নিম্নলিখিত ঘোষণাটি বিবেচনা করুন:

all: library.cpp main.cpp

এক্ষেত্রে:

  • $@ মূল্যায়ন all
  • $< মূল্যায়ন library.cpp
  • $^ মূল্যায়ন library.cpp main.cpp

16
এটি লক্ষণীয় যে $@অগত্যা ফাইল হওয়া উচিত নয়, এটি একটি .PHONYটার্গেটের নামও হতে পারে ।
এফেমেরা

আমি কি $@sকমান্ডলাইন বিকল্পগুলিতে এটি যুক্ত করতে পারি: নাম.os এর মতো সমাবেশ-আউটপুট তৈরি করতে?
Huseyin tugrul buyukisik

4
প্রথম নির্ভরতা যখন কোনও তালিকা প্রতিনিধিত্ব করে এমন একটি পরিবর্তনশীল তখন সাবধান থাকুন, $ <এটি প্রসারিত হওয়ার পরে মূল্যায়ন করা হয়। সুতরাং যখন তালিকা = lib1.cpp lib2.cpp, এবং সমস্ত: $ IST তালিকা IST main.cpp, $ <কেবল lib1.cpp এ মূল্যায়ন করা হয়। কয়েক বছর আগে, আমি এই আচরণের ফলে কী ঘটবে তা আবিষ্কার করতে কিছু সময় ব্যয় করেছি।
চ্যান কিম

সাধারণভাবে $ @ টার্গেটের নামটি বোঝায় যা এর বাম দিকে রয়েছে:
দীপক কিরণ

78

$@এবং $<বলা হয় স্বয়ংক্রিয় ভেরিয়েবল । ভেরিয়েবলটি $@তৈরি করা ফাইলটির নাম (অর্থাত্ লক্ষ্য) $<উপস্থাপন করে এবং আউটপুট ফাইল তৈরি করার জন্য প্রয়োজনীয় পূর্ব শর্তটি উপস্থাপন করে।
উদাহরণ স্বরূপ:

hello.o: hello.c hello.h
         gcc -c $< -o $@

এখানে, hello.oআউটপুট ফাইল। এটিই $@প্রসারিত হয়। প্রথম নির্ভরতা হয় hello.c। এটিই $<প্রসারিত হয়।

-cপতাকা উত্পন্ন .oফাইল; দেখতে man gccআরো বিস্তারিত ব্যাখ্যার জন্য। -oআউটপুট ফাইল তৈরি করতে নির্দিষ্ট করে।

আরও তথ্যের জন্য, আপনি লিনাক্স মেকফিলগুলি সম্পর্কে এই নিবন্ধটি পড়তে পারেন ।

এছাড়াও, আপনি জিএনইউ makeম্যানুয়ালগুলি পরীক্ষা করতে পারেন । এটি মেকফাইলগুলি তৈরি করা এবং সেগুলি ডিবাগ করা সহজ করে তুলবে।

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

make -p 

1
আপনার উত্তরগুলি মনে হচ্ছে (উভয়) $<তে প্রসারিত হবে hello.c hello.h। পরিষ্কার করে বলো.
ডাঃ বেকো

হ্যাঁ, এটা উভয় hello.c এবং hello.h অন্তর্ভুক্ত করা হবে
পারক

19
$<ঠিক প্রথম আইটেম। সমস্ত অন্তর্ভুক্ত করতে, ব্যবহার করুন $^
ডাঃ বেকো

1
ডঃ বেকো ঠিক বলেছেন। লেখকের তার উত্তরটি পরিবর্তন করা উচিত।
পিটি হুইন

67

জিএনইউ মেকের সাহায্যে প্রকল্পগুলির পরিচালনা থেকে , তৃতীয় সংস্করণ, পৃষ্ঠা। 16 (এটি জিএনইউ ফ্রি ডকুমেন্টেশন লাইসেন্সের আওতায় ):

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

এখানে সাতটি "কোর" স্বয়ংক্রিয় ভেরিয়েবল রয়েছে:

  • $@: লক্ষ্যটি উপস্থাপন করা ফাইলের নাম।

  • $%: একটি সংরক্ষণাগার সদস্যের নির্দিষ্টকরণের ফাইল নাম উপাদান।

  • $<: প্রথম পূর্বশর্তটির ফাইল নাম।

  • $?: লক্ষ্যগুলির চেয়ে নতুন নতুন সমস্ত পূর্ব শর্তগুলির নাম স্পেস দ্বারা পৃথক করা।

  • $^: সমস্ত পূর্বশর্তগুলির ফাইলের নামগুলি স্পেস দিয়ে পৃথক করা। এই তালিকার সদৃশ ফাইলনামগুলি মুছে ফেলা হয়েছে যেহেতু বেশিরভাগ ব্যবহারের জন্য যেমন সংকলন, অনুলিপি, ইত্যাদির জন্য ডুপ্লিকেটগুলি চাওয়া হয় না।

  • $+: এর অনুরূপ $^, এটি হ'ল $+ডুপ্লিকেটগুলি বাদ দিয়ে স্পেস দ্বারা বিচ্ছিন্ন সমস্ত পূর্বশর্তগুলির নাম । এই পরিবর্তনশীলটি নির্দিষ্ট পরিস্থিতির জন্য তৈরি করা হয়েছিল যেমন লেনকারদের পক্ষে যুক্তি যেখানে সদৃশ মানগুলির অর্থ রয়েছে।

  • $*: লক্ষ্য ফাইলের স্টেম। একটি স্টেম সাধারণত তার প্রত্যয় ছাড়াই একটি ফাইলের নাম। প্যাটার্ন বিধিগুলির বাইরে এর ব্যবহার নিরুত্সাহিত করা হয়।

এছাড়াও, উপরের প্রতিটি ভেরিয়েবলের অন্যান্য মেকের সাথে সামঞ্জস্যের জন্য দুটি ভেরিয়েন্ট থাকে। একটি বৈকল্পিক মানটির ডিরেক্টরি অংশটি কেবল ফেরত দেয়। এই প্রতীক একটি "ডি" সংযোজন করে নির্দেশিত হয় $(@D), $(<D)ইত্যাদি অন্যান্য বৈকল্পিক আয় মূল্যের শুধুমাত্র ফাইল অংশ। এটি একটি "এফ" প্রতীক হয়, সংযোজন করে নির্দেশিত হয় $(@F), $(<F)ইত্যাদি নোট যে এই বৈকল্পিক নাম চেয়ে বেশি একটি অক্ষর দীর্ঘ এবং তাই হয় বন্ধনীর মধ্যে ঘিরা ইন করতে হবে। জিএনইউ মেক দির এবং নোটডির ফাংশনগুলির সাথে আরও বেশি পঠনযোগ্য বিকল্প সরবরাহ করে।


37

$@এবং $<বিশেষ ম্যাক্রো হয়।

কোথায়:

$@ লক্ষ্য ফাইলের নাম।

$< প্রথম নির্ভরতার নাম।


19

Makefile নামক তৈরী করে helloযদি যে কোনো একটি এক্সিকিউটেবল main.cpp, hello.cpp, factorial.cppপরিবর্তন করেছেন। এই স্পেসিফিকেশন অর্জনের সবচেয়ে ছোট মেকফিলটি হতে পারে:

hello: main.cpp hello.cpp factorial.cpp
    g++ -o hello main.cpp hello.cpp factorial.cpp
  • প্রো: পড়া খুব সহজ
  • কন: রক্ষণাবেক্ষণ দুঃস্বপ্ন, সি ++ নির্ভরতার নকল
  • কন: দক্ষতার সমস্যা, কেবলমাত্র একটি পরিবর্তন করা হলেও আমরা সমস্ত সি ++ পুনরায় সংকলন করি

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

OBJECTS=main.o hello.o factorial.o

hello: $(OBJECTS)
    g++ -o hello $(OBJECTS)

main.o: main.cpp
    g++ -c main.cpp

hello.o: hello.cpp
    g++ -c hello.cpp

factorial.o: factorial.cpp
    g++ -c factorial.cpp
  • প্রো: দক্ষতা সমস্যা সংশোধন করে
  • কন: নতুন রক্ষণাবেক্ষণ দুঃস্বপ্ন, অবজেক্ট ফাইলের বিধিগুলিতে সম্ভাব্য টাইপ

এটির উন্নতি করার জন্য, আমরা একক নিয়মে সমস্ত অবজেক্ট ফাইলের বিধিগুলি প্রতিস্থাপন করতে পারি .cpp.o:

OBJECTS=main.o hello.o factorial.o

hello: $(OBJECTS)
    g++ -o hello $(OBJECTS)

.cpp.o:
    g++ -c $< -o $@
  • প্রো: শর্ট মেকফাইল করে ফিরে কিছুটা সহজ পড়া

এখানে .cpp.oবিধিটি নির্ধারণ করে যে কীভাবে তৈরি করা anyfile.oযায় anyfile.cpp

  • $< প্রথম নির্ভরতার সাথে মেলে, এক্ষেত্রে, anyfile.cpp
  • $@লক্ষ্য মিলে যায়, এই ক্ষেত্রে, anyfile.o

মেকফাইলে উপস্থিত অন্যান্য পরিবর্তনগুলি হ'ল:

  • G ++ থেকে যেকোন সি ++ কম্পাইলারে সংকলক পরিবর্তন করা সহজ করে তোলা।
  • সংকলক বিকল্পগুলি পরিবর্তন করা সহজ করা।
  • লিঙ্কার বিকল্পগুলি পরিবর্তন করা সহজ করে তোলা।
  • সি ++ উত্স ফাইল এবং আউটপুট পরিবর্তন করা সহজ করা।
  • আপনার অ্যাপ্লিকেশন তৈরির চেষ্টা করার আগে আপনার সমস্ত উত্স ফাইল উপস্থিত রয়েছে তা নিশ্চিত করতে একটি তাত্ক্ষণিক পরীক্ষা হিসাবে কাজ করে এমন একটি ডিফল্ট নিয়ম 'সমস্ত' যুক্ত হয়েছে।

1

উদাহরণে যদি আপনি উত্সগুলি সংকলন করতে চান তবে কোনও ভিন্ন ডিরেক্টরিতে অবজেক্ট থাকে:

আপনার করা দরকার:

gcc -c -o <obj/1.o> <srcs/1.c> <obj/2.o> <srcs/2.c> ...

তবে বেশিরভাগ ম্যাক্রোগুলির সাথে ফলাফলটি সমস্ত উত্স অনুসরণ করবে সমস্ত উত্স অনুসারে, যেমন:

gcc -c -o <all OBJ path> <all SRC path>

সুতরাং এটি কোনও কিছুই সংকলন করবে না ^^ এবং আপনি আপনার বস্তুর ফাইলগুলিকে অন্য একটি ডিয়ারে রাখতে পারবেন না :(

সমাধানটি হ'ল এই বিশেষ ম্যাক্রোগুলি ব্যবহার করা

$@ $<

এটি এসআরসি (src / file.c) এর প্রতিটি .c ফাইলের জন্য একটি .o ফাইল (اعتراض / ফাইল.o) উত্পন্ন করবে

$(OBJ):$(SRC)
   gcc -c -o $@ $< $(HEADERS) $(FLAGS)

এর অর্থ:

    $@ = $(OBJ)
    $< = $(SRC)

তবে লাইনগুলি লাইনগুলি OBJ এর সমস্ত লাইনের INSTEAD এর পরে এসআরসি এর সমস্ত লাইন


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