সিম্পল সি ++ মেকফিল কীভাবে করবেন


302

আমাদের প্রকল্পের জন্য সমস্ত কিছু একসাথে টেনে তুলতে আমাদের একটি মেকফিল ব্যবহার করা প্রয়োজন, তবে আমাদের অধ্যাপক কীভাবে তা আমাদের দেখান নি।

আমার কাছে কেবল একটি ফাইল আছে a3driver.cpp,। ড্রাইভার একটি অবস্থান থেকে একটি ক্লাস আমদানি করে "/user/cse232/Examples/example32.sequence.cpp",।

এটাই. অন্য সব কিছুতে রয়েছে .cpp

আমি কীভাবে একটি সাধারণ মেকফিল তৈরি করতে যাব যা একটি এক্সিকিউটেবল নামে পরিচিত a3a.exe?


9
.EXE তাই এর অবশ্যই উইন্ডোজ। দ্বিতীয় চিন্তায় ... পথটি ইউনিক্স-স্টাইল। সম্ভবত Mingw-32 ব্যবহার করছেন।
নাথান ওসমান

2
দীর্ঘশ্বাস. আমি মনে করি আপনাকে প্রতিটি ব্যবসায়ের বুনিয়াদি শিখতে হবে, এমনকি যদি আপনি সেগুলি কখনই ব্যবহার না করেন। স্টাফ কীভাবে কাজ করে তা কেবল বুঝতে হবে। সম্ভাবনাগুলি ভাল, তবে আপনি অবশ্যই সবসময় একটি আইডিইতে বিকাশ করবেন, যেমন গ্রহনের মতো। আপনার সাধারণ এক-লাইন মামলার জন্য আপনি এখানে একটি উত্তর পাবেন এবং প্রচুর ওয়েব টিউটোরিয়াল রয়েছে তবে আপনি যদি dpth জ্ঞান চান তবে আপনি ওরিলিলি বইটি হারাতে পারবেন না (বেশিরভাগ s / w বিষয়ের ক্ষেত্রে একই)। amazon.com/Managing-Projects-Make-Nutshell-Handbooks/dp/... অ্যামাজন, half.com থেকে একটি 2nd হাত কপি চয়ন করুন, betterworldbooks ইবে
Mawg পুনর্বহাল মনিকা বলেছেন

2
লিংক @Dennis পোস্ট করেছে এখন মৃত, কিন্তু একই উপাদান এই খুঁজে পাওয়া যেতে পারে archive.org পৃষ্ঠা
গিলহার্ম সালোমো

আমি এই ব্যক্তির ধারণা পছন্দ করি। ( hiltmon.com/blog/2013/07/03/… ) প্রকল্প কাঠামো অনুসারে সহজেই পরিবর্তন করা যেতে পারে। এবং আমি এটিও সম্মত করি যে বিকাশকারীদের সময় অটোমেক / অটোকনফ ব্যতীত অন্য কিছুতে ব্যয় করা উচিত। এই সরঞ্জামগুলির নিজস্ব স্থান রয়েছে তবে সম্ভবত অভ্যন্তরীণ প্রকল্পগুলির জন্য নয়। আমি এমন একটি স্ক্রিপ্ট তৈরি করছি যা এই জাতীয় প্রকল্প কাঠামো তৈরি করবে।
ডাইসুক আরমাকি

@ গিলহেরেমসালোম é ধন্যবাদ, আমি বিশ্বাস করি এটি সর্বোত্তম সহজ এবং সম্পূর্ণ টিউটোরিয়াল।
হরেন লাক্স

উত্তর:


559

যেহেতু এটি ইউনিক্সের জন্য, এক্সিকিউটেবলের কোনও এক্সটেনশন নেই।

একটি বিষয় লক্ষণীয় root-config একটি ইউটিলিটি যা সঠিক সংকলন এবং পতাকা লিঙ্ক সরবরাহ করে; এবং মূলের বিরুদ্ধে অ্যাপ্লিকেশন তৈরির জন্য সঠিক লাইব্রেরি। এই দস্তাবেজের মূল শ্রোতার সাথে সম্পর্কিত কেবল এটিই বিশদ।

আমাকে বাচ্চা বানান

অথবা আপনি যে প্রথমবার তৈরি করেছিলেন তা কখনই ভুলে যান না

মেকের একটি প্রাথমিক ভূমিকা এবং কীভাবে একটি সাধারণ মেকফিল লিখতে হয়

মেক কি? এবং কেন আমার যত্ন নেওয়া উচিত?

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

আসলে, আপনি অন্য জিনিসগুলির জন্যও মেক ব্যবহার করতে পারেন, তবে আমি সে সম্পর্কে কথা বলব না।

একটি তুচ্ছ Makefile

মনে করুন যে আপনার একটি ডিরেক্টরি রয়েছে: tool tool.cc tool.o support.cc support.hhএবং support.oযা নির্ভর করে rootএবং একটি কল করা প্রোগ্রামে সংকলিত হওয়ার কথা tool, এবং ধরুন যে আপনি উত্স ফাইলগুলিতে হ্যাক করছেন (যার অর্থ বর্তমানে বিদ্যমানটি toolপুরানো হয়ে গেছে) এবং চান প্রোগ্রামটি সংকলন করুন

আপনি নিজেই এটি করতে পারেন

  1. হয় কিনা তার চেয়ে নতুন support.ccবা support.hhনতুন কিনা তা পরীক্ষা করে দেখুন support.ocommand

    g++ -g -c -pthread -I/sw/include/root support.cc
  2. এর চেয়ে কম support.hhবা tool.ccনতুন কিনা তা যাচাই করুন tool.oএবং যদি এরকম একটি কমান্ড চালান

    g++ -g  -c -pthread -I/sw/include/root tool.cc
  3. এর tool.oচেয়ে আরও নতুন কিনা তা পরীক্ষা করুন toolএবং যদি এর মতো একটি কমান্ড চালান

    g++ -g tool.o support.o -L/sw/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint \
    -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lz -L/sw/lib -lfreetype -lz -Wl,-framework,CoreServices \
    -Wl,-framework,ApplicationServices -pthread -Wl,-rpath,/sw/lib/root -lm -ldl

রাম রাম! কী ঝামেলা! অনেক কিছু মনে রাখার এবং ভুল করার বিভিন্ন সম্ভাবনা রয়েছে। (বিটিডব্লিউ-- - এখানে প্রদর্শিত কমান্ড লাইনের বিবরণগুলি আমাদের সফ্টওয়্যার পরিবেশের উপর নির্ভর করে ones এগুলি আমার কম্পিউটারে কাজ করে))

অবশ্যই, আপনি প্রতিবার কেবল তিনটি কমান্ড চালাতে পারেন। এটি কাজ করবে, তবে এটি সফটওয়্যারটির যথেষ্ট পরিমাণে ভাল স্কেল করে না (যেমন ডগস যেমন আমার ম্যাকবুকের উপর থেকে গ্রাউন্ড আপ সংকলন করতে 15 মিনিটেরও বেশি সময় নেয়)।

পরিবর্তে আপনি makefileএই নামে পরিচিত একটি ফাইল লিখতে পারেন:

tool: tool.o support.o
    g++ -g -o tool tool.o support.o -L/sw/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint \
        -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lz -L/sw/lib -lfreetype -lz -Wl,-framework,CoreServices \
        -Wl,-framework,ApplicationServices -pthread -Wl,-rpath,/sw/lib/root -lm -ldl

tool.o: tool.cc support.hh
    g++ -g  -c -pthread -I/sw/include/root tool.cc

support.o: support.hh support.cc
    g++ -g -c -pthread -I/sw/include/root support.cc

এবং শুধু টাইপ করুন make কমান্ড লাইনে । যা উপরে প্রদর্শিত তিনটি পদক্ষেপ স্বয়ংক্রিয়ভাবে সম্পাদন করবে।

এখানে আনইনডেন্টেড রেখাগুলিতে "টার্গেট: নির্ভরতা" ফর্ম রয়েছে এবং বলুন যে লক্ষ্যগুলি তুলনায় নির্ভরতাগুলির কোনও নতুন হলে সংশ্লিষ্ট কমান্ডগুলি (ইনডেন্টড লাইনগুলি) চালানো উচিত। এটি হ'ল নির্ভরতা লাইনগুলি বিভিন্ন ফাইলে পরিবর্তনের জন্য পুনর্নির্মাণের প্রয়োজনীয়তার যুক্তি বর্ণনা করে। যদি support.ccপরিবর্তনগুলি এর অর্থ হয় তবে এটি support.oঅবশ্যই পুনর্নির্মাণ tool.oকরতে হবে তবে একা থাকতে পারে। যখন support.oপরিবর্তন toolপুনর্নির্মিত করা আবশ্যক।

প্রতিটি নির্ভরতা রেখার সাথে যুক্ত কমান্ডগুলি একটি ট্যাব দিয়ে সেট করা হয় (নীচে দেখুন) লক্ষ্যটি পরিবর্তন করতে হবে (বা কমপক্ষে পরিবর্তনের সময়টি আপডেট করতে এটি স্পর্শ করুন)।

ভেরিয়েবলস, বিল্ট ইন বিলেস এবং অন্যান্য সামগ্রী

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

ভেরিয়েবলগুলি তৈরি করুন

কোনও মেক ভেরিয়েবল অ্যাক্সেস করার সিনট্যাক্সটি হ'ল $(VAR)

মেক ভেরিয়েবলকে নির্ধারণের জন্য বাক্য গঠনটি হ'ল: VAR = A text value of some kind (বা VAR := A different text value but ignore this for the moment)।

আপনি আমাদের মেকফিলের এই উন্নত সংস্করণের মতো নিয়মে ভেরিয়েবলগুলি ব্যবহার করতে পারেন:

CPPFLAGS=-g -pthread -I/sw/include/root
LDFLAGS=-g
LDLIBS=-L/sw/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint \
       -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lz -L/sw/lib -lfreetype -lz \
       -Wl,-framework,CoreServices -Wl,-framework,ApplicationServices -pthread -Wl,-rpath,/sw/lib/root \
       -lm -ldl

tool: tool.o support.o
    g++ $(LDFLAGS) -o tool tool.o support.o $(LDLIBS)

tool.o: tool.cc support.hh
    g++ $(CPPFLAGS) -c tool.cc

support.o: support.hh support.cc
    g++ $(CPPFLAGS) -c support.cc

যা কিছুটা বেশি পঠনযোগ্য তবে এখনও অনেক টাইপিংয়ের প্রয়োজন

ফাংশন করুন

জিএনইউ মেক সিস্টেমের ফাইল সিস্টেম বা অন্যান্য কমান্ডের তথ্য অ্যাক্সেসের জন্য বিভিন্ন ফাংশন সমর্থন করে। এই ক্ষেত্রে আমরা আগ্রহী যেটি $(shell ...)আর্গুমেন্ট (গুলি) এর আউটপুট প্রসারিত করে এবং $(subst opat,npat,text)যা পাঠ্যের opatসাথে সমস্ত দৃষ্টান্তের পরিবর্তে npat

এর সুবিধা গ্রহণ আমাদের দেয়:

CPPFLAGS=-g $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)

SRCS=tool.cc support.cc
OBJS=$(subst .cc,.o,$(SRCS))

tool: $(OBJS)
    g++ $(LDFLAGS) -o tool $(OBJS) $(LDLIBS)

tool.o: tool.cc support.hh
    g++ $(CPPFLAGS) -c tool.cc

support.o: support.hh support.cc
    g++ $(CPPFLAGS) -c support.cc

যা টাইপ করা সহজ এবং আরও অনেক বেশি পাঠযোগ্য।

লক্ষ্য করুন

  1. আমরা এখনও প্রতিটি বস্তুর ফাইল এবং চূড়ান্ত সম্পাদনযোগ্য এর জন্য স্পষ্টভাবে নির্ভরতা উল্লেখ করছি
  2. উভয় উত্স ফাইলের জন্য আমাদের স্পষ্টভাবে সংকলন নিয়ম টাইপ করতে হয়েছিল

অন্তর্নিহিত এবং প্যাটার্ন বিধি

আমরা সাধারণত প্রত্যাশা করব যে সমস্ত সি ++ উত্স ফাইলগুলি একইরকম আচরণ করা উচিত এবং মেকটি এটিকে বর্ণনা করার জন্য তিনটি উপায় সরবরাহ করে:

  1. প্রত্যয় বিধি (জিএনইউ তৈরিতে অপ্রচলিত হিসাবে বিবেচিত, তবে পিছনের সামঞ্জস্যের জন্য রাখা হয়েছে)
  2. অন্তর্নিহিত বিধি
  3. প্যাটার্ন বিধি

অন্তর্নিহিত নিয়মগুলি অন্তর্নির্মিত, এবং কয়েকটি নীচে আলোচনা করা হবে। প্যাটার্ন বিধি যেমন একটি ফর্ম নির্দিষ্ট করা হয়

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

যার অর্থ হ'ল কমান্ডটি চালিয়ে সি উত্স ফাইলগুলি থেকে অবজেক্ট ফাইলগুলি উত্পন্ন হয়, যেখানে "স্বয়ংক্রিয়" ভেরিয়েবলটি $<প্রথম নির্ভরতার নামে প্রসারিত হয়।

অন্তর্নির্মিত বিধি

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

সি উত্স ফাইলগুলির জন্য নিয়মে অন্তর্নির্মিত GNU হ'ল উপরের প্রদর্শিত। একইভাবে আমরা সি ++ উত্স ফাইলগুলি থেকে একটি নিয়মের মতো অবজেক্ট ফাইল তৈরি করি $(CXX) -c $(CPPFLAGS) $(CFLAGS)

একক অবজেক্ট ফাইলগুলি ব্যবহার করে লিঙ্কযুক্ত $(LD) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS), তবে এটি আমাদের ক্ষেত্রে কার্যকর হবে না, কারণ আমরা একাধিক অবজেক্ট ফাইলগুলি লিঙ্ক করতে চাই।

বিল্ট-ইন বিধি দ্বারা ব্যবহৃত ভেরিয়েবলগুলি

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

  • CC - সি সংকলকটি ব্যবহার করতে হবে
  • CXX - সি ++ ব্যবহারের জন্য সংকলক
  • LD - লিঙ্কার ব্যবহার করতে
  • CFLAGS - সি উত্স ফাইলগুলির জন্য সংকলন পতাকা
  • CXXFLAGS - সি ++ উত্স ফাইলগুলির জন্য সংকলন পতাকাগুলি
  • CPPFLAGS - সি এবং সি ++ দ্বারা ব্যবহৃত সি-প্রিপ্রেসেসরের জন্য পতাকাগুলি (সাধারণত কমান্ড লাইনে সংযুক্ত ফাইলের পাথ এবং চিহ্নগুলি অন্তর্ভুক্ত)
  • LDFLAGS - লিঙ্কার পতাকা
  • LDLIBS - লাইব্রেরি লিঙ্ক

একটি বেসিক Makefile

অন্তর্নির্মিত নিয়মের সুযোগ নিয়ে আমরা আমাদের মেকফিলকে এখানে সহজতর করতে পারি:

CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)

SRCS=tool.cc support.cc
OBJS=$(subst .cc,.o,$(SRCS))

all: tool

tool: $(OBJS)
    $(CXX) $(LDFLAGS) -o tool $(OBJS) $(LDLIBS)

tool.o: tool.cc support.hh

support.o: support.hh support.cc

clean:
    $(RM) $(OBJS)

distclean: clean
    $(RM) tool

আমরা বেশ কয়েকটি মানক লক্ষ্যও যুক্ত করেছি যা বিশেষ ক্রিয়াগুলি সম্পাদন করে (যেমন উত্স ডিরেক্টরিটি পরিষ্কার করা)।

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

আমাদের এখনও সমস্ত নির্ভরতা হার্ড-কোডড।

কিছু রহস্যময় উন্নতি

CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)

SRCS=tool.cc support.cc
OBJS=$(subst .cc,.o,$(SRCS))

all: tool

tool: $(OBJS)
    $(CXX) $(LDFLAGS) -o tool $(OBJS) $(LDLIBS)

depend: .depend

.depend: $(SRCS)
    $(RM) ./.depend
    $(CXX) $(CPPFLAGS) -MM $^>>./.depend;

clean:
    $(RM) $(OBJS)

distclean: clean
    $(RM) *~ .depend

include .depend

লক্ষ্য করুন

  1. সোর্স ফাইলগুলির জন্য আর কোনও নির্ভরতা লাইন নেই!!!
  2. । নির্ভর ও নির্ভর সম্পর্কিত কিছু অদ্ভুত যাদু আছে
  3. যদি আপনি তা করেন makeতবে ls -Aআপনি .dependএমন একটি ফাইল দেখবেন যার মধ্যে এমন জিনিস রয়েছে যা দেখতে নির্ভরতা রেখাগুলি তৈরি করে

অন্যান্য পঠন

বাগ এবং orতিহাসিক নোটগুলি জানুন

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

(আমি পদার্থ বিজ্ঞানের স্নাতক শিক্ষার্থীদের জন্য লিখেছি এমন একটি উইকি পোস্ট থেকে এটি অনুলিপি করা হয়েছিল))


9
নির্ভরতা উত্পন্ন করার এই পদ্ধতিটি অচল এবং আসলে ক্ষতিকারক। দেখুন অ্যাডভান্সড অটো- নির্ভরতা জেনারেশন
ম্যাক্সিম এগারুশকিন

5
-pthreadপতাকা gccপ্রয়োজনীয় ম্যাক্রো সংজ্ঞায়িত করার কারণ , -D_REENTRANTঅপ্রয়োজনীয়।
ম্যাক্সিম এগারুশকিন

8
@ jcoe নির্ভরতা তৈরি করতে এটি একটি অপ্রয়োজনীয় অতিরিক্ত প্রিপ্রোসেসর পাস করে। অপ্রয়োজনীয় কাজ করা কেবল বরফের খুঁটি গলে যাওয়া তাপকে বিলুপ্ত করে এবং আরও বড় আকারে আমাদের মহাবিশ্বের তাপের মৃত্যুর কাছাকাছি চলে আসে।
ম্যাক্সিম এগারুশকিন

2
সম্ভবত "ক্ষতিকারক" খুব বেশি বাচ্চা, তবে সুস্পষ্ট নির্ভরতা-প্রজন্মের পর্যায়গুলি বা লক্ষ্যগুলি পুরানো হয়ে গেছে যেহেতু খুব কমপক্ষে জিসিসি 3 এ, আমি সত্যই মনে করি যে আমাদের সকলকে তাদের অতীত হওয়া উচিত। bruno.defrain.net/techtips/makefile-auto-d
depend

2
সত্যই, গৃহীত উত্তরটি খুব নির্দিষ্ট কোনও সফ্টওয়্যার ( root-config) এর উপর নির্ভর করে না । একই সামর্থ্য সহ আরও সাধারণ বিকল্প প্রস্তাব করা উচিত যদি কোনও বা এটি কেবল বাদ দেওয়া উচিত। সর্বাধিক ঘন ব্যবহৃত মেক্র ম্যাক্রোগুলির তালিকা এবং ব্যাখ্যার কারণে আমি ডাউনটা করি নি।
সবুজ ডায়োড

56

আমি সবসময় ভেবেছিলাম বিস্তারিত উদাহরণ সহকারে শেখা এটি আরও সহজ, সুতরাং আমি কীভাবে মেকফিলগুলি সম্পর্কে চিন্তা করি। প্রতিটি বিভাগের জন্য আপনার কাছে একটি লাইন রয়েছে যা ইন্টেন্টেড নয় এবং এটি নির্ভরতা অনুসারে বিভাগটির নাম দেখায়। নির্ভরতা হয় অন্য বিভাগগুলি (যা বর্তমান বিভাগের আগে চালানো হবে) বা ফাইলগুলি (যা আপডেট হলে বর্তমান বিভাগটি আপনি চালানোর সময় আবার চালাবেন make) run

এখানে একটি দ্রুত উদাহরণ রয়েছে (মনে রাখবেন যে আমি 4 টি স্পেস ব্যবহার করছি যেখানে আমার একটি ট্যাব ব্যবহার করা উচিত, স্ট্যাক ওভারফ্লো আমাকে ট্যাব ব্যবহার করতে দেয় না):

a3driver: a3driver.o
    g++ -o a3driver a3driver.o

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

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

যেহেতু কেবলমাত্র একটি ফাইল আছে, এটি এমনকি এখানে হ্রাস করা যেতে পারে:

a3driver: a3driver.cpp
    g++ -o a3driver a3driver.cpp

আমি প্রথম উদাহরণটি দেখানোর কারণটি হ'ল এটি মেকফাইলগুলির শক্তি দেখায়। আপনার যদি অন্য ফাইলটি সংকলন করতে হয় তবে আপনি কেবলমাত্র অন্য একটি বিভাগ যুক্ত করতে পারেন। এখানে একটি সেকেন্ডফিল.সি.পি. সহ একটি উদাহরণ রয়েছে (যা সেকেন্ডফিল। Hd নামে একটি শিরোনামে লোড হয়):

a3driver: a3driver.o secondFile.o
    g++ -o a3driver a3driver.o secondFile.o

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

secondFile.o: secondFile.cpp secondFile.h
    g++ -c secondFile.cpp

আপনি যদি সেকেন্ডফিল.পি.পি. বা সেকেন্ডফিল। H এ কিছু পরিবর্তন করেন এবং পুনরায় সংকলন করেন তবে এটি কেবল দ্বিতীয় ফাইল ফাইল। পিপি (a3driver.cpp নয়) রিকম্পাইল করবে। অথবা পর্যায়ক্রমে, আপনি যদি a3driver.cpp এ কিছু পরিবর্তন করেন তবে এটি দ্বিতীয় ফাইল ফাইল.cpp পুনরায় সংকলন করবে না।

আপনার এ সম্পর্কে কোনও প্রশ্ন থাকলে আমাকে জানান Let

"সমস্ত" নামের একটি বিভাগ এবং "ক্লিন" নামে একটি বিভাগ অন্তর্ভুক্ত করাও প্রচলিত। "সমস্ত" সাধারণত সমস্ত নির্বাহযোগ্যগুলি তৈরি করে এবং "ক্লিন" "।

all: a3driver ;

clean:
    # -f so this will succeed even if the files don't exist
    rm -f a3driver a3driver.o

সম্পাদনা: আপনি উইন্ডোতে রয়েছেন তা আমি খেয়াল করিনি। আমি মনে করি একমাত্র পার্থক্যটি পরিবর্তন -o a3driverকরা -o a3driver.exe


আমি যে নিখুঁত কোডটি ব্যবহার করার চেষ্টা করছি তা হ'ল: p4a.exe: p4driver.cpp g ++ -o p4a p4driver.cpp তবে এটি আমাকে "অনুপস্থিত বিচ্ছিন্ন" বলে। আমি ট্যাব ব্যবহার করছি, তবে এটি এখনও আমাকে তা বলে। কোন ধারণা?
20:25

2
আমি যতদূর বলতে পারি যে ত্রুটি বার্তাটি কেবলমাত্র যদি আপনার ফাঁকা স্থান থাকে তবেই আসে। নিশ্চিত করুন যে স্পেস দিয়ে শুরু করে আপনার কোনও লাইন নেই (স্পেস + ট্যাব সেই ত্রুটিটি দেবে)। আমি কেবল এটিই ভাবতে পারি ..
ব্রেন্ডন লং

ভবিষ্যতের সম্পাদকদের জন্য নোট: স্ট্যাকওভারফ্লো আপনি উত্তরে সম্পাদনা করলেও ট্যাবগুলি রেন্ডার করতে পারবেন না, সুতরাং দয়া করে সে সম্পর্কে আমার নোটটি "ঠিক" করার চেষ্টা করবেন না।
ব্রেন্ডন লং

35

সবাই কেন উত্স ফাইলগুলি তালিকাভুক্ত করতে পছন্দ করে? একটি সাধারণ ফাইন্ড কমান্ড সহজেই এটি যত্ন নিতে পারে।

এখানে ময়লার সাধারণ সি ++ মেকফিলের উদাহরণ রয়েছে। এটি কেবল .Cফাইল ধারণকারী ডিরেক্টরিতে ফেলে দিন এবং তারপরে টাইপ করুন make...

appname := myapp

CXX := clang++
CXXFLAGS := -std=c++11

srcfiles := $(shell find . -name "*.C")
objects  := $(patsubst %.C, %.o, $(srcfiles))

all: $(appname)

$(appname): $(objects)
    $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(appname) $(objects) $(LDLIBS)

depend: .depend

.depend: $(srcfiles)
    rm -f ./.depend
    $(CXX) $(CXXFLAGS) -MM $^>>./.depend;

clean:
    rm -f $(objects)

dist-clean: clean
    rm -f *~ .depend

include .depend

2
উত্স ফাইলগুলি স্বয়ংক্রিয়ভাবে সন্ধান না করার একটি কারণ হ'ল কারও কাছে বিভিন্ন ফাইলের প্রয়োজন বিভিন্ন বিল্ড লক্ষ্যমাত্রা থাকতে পারে।
হামিজাইল ২ig

@Hmijail এর সাথে সম্মত হয়েছে, এমন সাবমোডিয়ুলগুলি রয়েছে যেগুলিতে এমন এক টন উত্স / শিরোনাম রয়েছে যা আপনি সংকলিত / সংযুক্ত করতে চান না ... এবং নিঃসন্দেহে এমন অনেকগুলি পরিস্থিতি যেখানে নিখরচায় অনুসন্ধান / ব্যবহার অনুপযুক্ত।
ইঞ্জিনিয়ার

পরিবর্তে "শেল ফাইন্ড" এবং "ওয়াইল্ডকার্ড" ব্যবহার করবেন না কেন?
নোলান

1
@ নোলন উত্স ডিরেক্টরি গাছটিতে উত্স ফাইলগুলি সন্ধান করতে
আলেজান্দ্রোভিডি

13

আপনার কাছে দুটি বিকল্প ছিল।

বিকল্প 1: সরল মেকফিল = কোনও মেকিফল নেই।

"A3driver.cpp" এর নাম "a3a.cpp" করুন এবং কমান্ড লাইনে লিখুন:

nmake a3a.exe

এবং এটাই. আপনি যদি জিএনইউ মেক ব্যবহার করছেন তবে "মেক" বা "গেমাক" বা যা কিছু ব্যবহার করুন।

বিকল্প 2: একটি 2-লাইনের মেকফাইল।

a3a.exe: a3driver.obj
    link /out:a3a.exe a3driver.obj

3
এটি যদি ওপির পরিবেশের বিবরণ সম্পর্কে এতগুলি বিষয় অনুমান না করে তবে এটি একটি দুর্দান্ত উত্তর হবে। হ্যাঁ, তারা উইন্ডোজে রয়েছে তবে এর অর্থ এই নয় যে তারা ব্যবহার করছেন nmakelinkকমান্ড লাইন খুব অন্তত নথি যা এক একটি নির্দিষ্ট কম্পাইলার খুব নির্দিষ্ট দেখায়, এবং করা উচিত।
ট্রিপলি

6

আপনার মেক ফাইলে একটি বা দুটি নির্ভরশীলতার বিধি থাকবে যা আপনি একক কমান্ডের সাথে সংকলন করেন এবং লিঙ্কের জন্য একটি কমান্ড সহ এবং একটি লিঙ্কের সাথে লিংক করেন কিনা তার উপর নির্ভর করে।

নির্ভরতা হ'ল নিয়মের একটি গাছ যা দেখতে এই জাতীয় দেখতে লাগে (নোটটি অবশ্যই একটি ট্যাব হতে হবে ):

main_target : source1 source2 etc
    command to build main_target from sources

source1 : dependents for source1
    command to build source1

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

সুতরাং আপনার মেকফিলটি দেখতে এমন কিছু দেখাচ্ছে।

a3a.exe : a3driver.obj 
    link /out:a3a.exe a3driver.obj

a3driver.obj : a3driver.cpp
    cc a3driver.cpp

6

আমি প্রস্তাব দিই (নোটটি একটি ট্যাব বলে মনে করুন):

tool: tool.o file1.o file2.o
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

অথবা

LINK.o = $(CXX) $(LDFLAGS) $(TARGET_ARCH)
tool: tool.o file1.o file2.o

পরবর্তী পরামর্শটি কিছুটা ভাল কারণ এটি জিএনইউকে পুনরায় ব্যবহার করে নিহিত নিয়ম তৈরি করে। তবে, কাজ করার জন্য, একটি উত্স ফাইলের অবশ্যই চূড়ান্ত নির্বাহযোগ্য (যেমন: tool.cএবং tool) হিসাবে একই নাম থাকতে হবে ।

লক্ষ্য করুন, উত্স ঘোষণার প্রয়োজন নেই। অন্তর্বর্তী অবজেক্ট ফাইলগুলি অন্তর্ভুক্ত নিয়ম ব্যবহার করে তৈরি করা হয়। ফলস্বরূপ, Makefileসি এবং সি ++ (এবং ফোর্টরান ইত্যাদির জন্যও ...) এর জন্য এই কাজ।

এছাড়াও লক্ষ্য করুন, ডিফল্ট $(CC)হিসাবে মেকফিল লিঙ্কার হিসাবে ব্যবহার করুন। $(CC)সি ++ অবজেক্ট ফাইল লিঙ্ক করার জন্য কাজ করে না। আমরা LINK.oকেবল সেই কারণে সংশোধন করি। আপনি যদি সি কোডটি সংকলন করতে চান তবে আপনাকে LINK.oমানটি জোর করতে হবে না ।

অবশ্যই, আপনি ভেরিয়েবলের সাথে আপনার সংকলন পতাকাগুলি যুক্ত করতে এবং এতে CFLAGSআপনার লাইব্রেরিগুলি যুক্ত করতে পারেন LDLIBS। উদাহরণ স্বরূপ:

CFLAGS = -Wall
LDLIBS = -lm

এক দিকে নোট: আপনার যদি বাহ্যিক গ্রন্থাগারগুলি ব্যবহার করতে হয় তবে আমি সঠিকভাবে সেট করতে pkg-config ব্যবহার করার পরামর্শ দিচ্ছি CFLAGSএবং LDLIBS:

CFLAGS += $(shell pkg-config --cflags libssl)
LDLIBS += $(shell pkg-config --libs libssl)

মনোযোগী পাঠক লক্ষ্য করবেন যে Makefileযদি একটি শিরোলেখ পরিবর্তন করা হয় তবে এটি সঠিকভাবে পুনর্নির্মাণ করবে না। সমস্যাটি সমাধান করতে এই লাইনগুলি যুক্ত করুন:

override CPPFLAGS += -MMD
include $(wildcard *.d)

-MMDশিরোনাম নির্ভরতা সম্পর্কে Makefile টুকরা রয়েছে .d ফাইল তৈরি করতে দেয়। দ্বিতীয় লাইনটি কেবল তাদের ব্যবহার করে।

অবশ্যই, একটি ভাল লিখিত Makefile এছাড়াও অন্তর্ভুক্ত cleanএবং distcleanনিয়ম করা উচিত :

clean:
    $(RM) *.o *.d

distclean: clean
    $(RM) tool

লক্ষ্য করুন, $(RM)এর সমতুল্য rm -f, তবে rmসরাসরি কল না করা ভাল অভ্যাস ।

allনিয়ম এছাড়াও প্রশংসা করা হয়। কাজ করার জন্য, এটি আপনার ফাইলের প্রথম নিয়ম হওয়া উচিত:

all: tool

আপনি একটি installবিধি যুক্ত করতে পারেন :

PREFIX = /usr/local
install:
    install -m 755 tool $(DESTDIR)$(PREFIX)/bin

DESTDIRডিফল্টভাবে খালি। ব্যবহারকারী এটি বিকল্প প্রোগ্রামে আপনার ক্রসটি ইনস্টল করতে সেট করতে পারেন (ক্রস সংকলন প্রক্রিয়া জন্য বাধ্যতামূলক)। একাধিক বিতরণের জন্য প্যাকেজ রক্ষণাবেক্ষণকারীরা PREFIXআপনার প্যাকেজটি ইন ইনস্টল করার জন্যও পরিবর্তন করতে পারে /usr

একটি চূড়ান্ত শব্দ: উপ-ডিরেক্টরিগুলিতে উত্স ফাইলগুলি রাখবেন না। আপনি যদি সত্যিই এটি করতে চান তবে Makefileএটি রুট ডিরেক্টরিতে রেখে দিন এবং আপনার ফাইলগুলি সনাক্ত করতে পুরো পাথ ব্যবহার করুন (যেমন subdir/file.o)।

সুতরাং সংক্ষেপে বলতে গেলে, আপনার সম্পূর্ণ মেকফিলটি দেখতে হবে:

LINK.o = $(CXX) $(LDFLAGS) $(TARGET_ARCH)
PREFIX = /usr/local
override CPPFLAGS += -MMD
include $(wildcard *.d)

all: tool
tool: tool.o file1.o file2.o
clean:
    $(RM) *.o *.d
distclean: clean
    $(RM) tool
install:
    install -m 755 tool $(DESTDIR)$(PREFIX)/bin

শেষের কাছাকাছি: নিয়মের মধ্যে খালি লাইন থাকা উচিত নয়? জন নোয়েলারের উত্তর দাবি করেছে।
পিটার মর্টেনসেন

makeআমি জানি যে বাস্তবায়নের কোনোটাই (জিএনইউ মেক এবং বিএসডি মেক) নিয়মের মধ্যে ফাঁকা লাইন প্রয়োজন না। তবে এটির makeনিজস্ব বাগ ^ স্পেসিফিকেশন সহ প্রচুর বাস্তবায়ন বিদ্যমান ।
32-তে জেরুমে পাইউলার

5

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

appname := myapp

CXX := g++
CXXFLAGS := -Wall -g

srcfiles := $(shell find . -maxdepth 1 -name "*.cpp")
objects  := $(patsubst %.cpp, %.o, $(srcfiles))

all: $(appname)

$(appname): $(objects)
    $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(appname) $(objects) $(LDLIBS)

depend: .depend

.depend: $(srcfiles)
    rm -f ./.depend
    $(CXX) $(CXXFLAGS) -MM $^>>./.depend;

clean:
    rm -f $(objects)

dist-clean: clean
    rm -f *~ .depend

include .depend

Makefiles খুব জটিল বলে মনে হচ্ছে। আমি একটি ব্যবহার করছিলাম, তবে এটি জি ++ লাইব্রেরিতে লিঙ্ক না করার সম্পর্কিত একটি ত্রুটি তৈরি করছিল। এই কনফিগারেশনটি এই সমস্যার সমাধান করেছে।

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