বিভিন্ন ডিরেক্টরিতে উত্স ফাইল সহ Makefiles iles


135

আমার একটি প্রকল্প রয়েছে যেখানে ডিরেক্টরি কাঠামোটি এরকম:

                         $projectroot
                              |
              +---------------+----------------+
              |               |                |
            part1/          part2/           part3/
              |               |                |
       +------+-----+     +---+----+       +---+-----+
       |      |     |     |        |       |         |
     data/   src/  inc/  src/     inc/   src/       inc/

আমি কীভাবে এমন একটি মেকফিল লিখব যা অংশ / এসআরসি-তে থাকবে (বা সত্যিই যেখানেই হোক) যে অংশে সি / সি ++ উত্স ফাইলগুলিতে সম্পূর্ণ / লিঙ্ক করতে পারে? / Src?

আমি কি -I $ প্রজেক্ট্রুট / পার্ট 1 / সিআরসি-আই $ প্রজেক্ট্রুট / পার্ট 1 / ইনক-আই $ প্রজেক্টরুট / পার্ট 2 / এসসিআর এর মতো কিছু করতে পারি ...

যদি এটি কাজ করে তবে এটি করার সহজ উপায় কি আছে? আমি এমন প্রকল্পগুলি দেখেছি যেখানে প্রতিটি অংশে একটি মেকফাইল রয়েছে? ফোল্ডার নেই। [এই পোস্টে আমি প্রশ্ন চিহ্নটি ব্যাশ সিনট্যাক্সের মতো ব্যবহার করেছি]



1
ফোনি টার্গেটের অধীনে মূল gnu ম্যানুয়ালটিতে ( gnu.org/software/make/manual/html_node/Phony-Targets.html ) তে একটি নমুনা রয়েছে recursive invocation, সেই কাপলটি বেশ মার্জিত হতে পারে।
ফ্রাঙ্ক নোক

এই পাঠ্য গ্রাফিকটি তৈরি করতে আপনি কোন সরঞ্জামটি ব্যবহার করেছেন?
খালিদ হুসেন

উত্তর:


114

ঐতিহ্যগত ভাবে থাকতে হয় Makefileসাবডিরেক্টরি (প্রতিটি part1, part2ইত্যাদি) আপনি তাদের স্বাধীনভাবে গড়ে তুলতে সক্ষম হবেন। আরও, Makefileপ্রকল্পের মূল ডিরেক্টরিতে একটি রয়েছে যা সবকিছু তৈরি করে। "রুট" Makefileনীচের মত কিছু হবে:

all:
    +$(MAKE) -C part1
    +$(MAKE) -C part2
    +$(MAKE) -C part3

যেহেতু একটি মেক টার্গেটের প্রতিটি লাইন তার নিজস্ব শেলটিতে চালিত হয়, তাই ডিরেক্টরি ট্রি বা অন্য ডিরেক্টরিগুলিতে ব্যাকআপ নেওয়ার বিষয়ে চিন্তা করার দরকার নেই।

আমি জিএনইউতে ম্যানুয়াল বিভাগ 5.7 তৈরির দিকে একবার নজর দেওয়ার পরামর্শ দিই ; এটা খুব সহায়ক।


26
এটি +$(MAKE) -C part1ইত্যাদি হওয়া উচিত This এটি মেকের কাজের নিয়ন্ত্রণকে উপ-ডিরেক্টরিতে কাজ করতে দেয়।
প্রাক্তন

26
এটি একটি ধ্রুপদী পদ্ধতির এবং ব্যাপকভাবে ব্যবহৃত হয়, তবে প্রকল্পটি বাড়ার সাথে সাথে এটি বেশ কয়েকটি উপ-অনুকূল। ডেভ হিন্টন অনুসরণ করতে পয়েন্টার আছে।
ডিএমকেই --- প্রাক্তন-মডারেটর বিড়ালছানা

89

যদি আপনার অন্য সাব-ডিরেক্টরিতে কোডের উপর নির্ভর করে একটি উপ-ডিরেক্টরিতে কোড থাকে তবে আপনি সম্ভবত শীর্ষ স্তরের একক মেকফাইল দিয়ে ভাল।

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

উপরের লিঙ্কটি পৌঁছনীয় নয় বলে মনে হচ্ছে। একই নথিটি এখানে পৌঁছনোযোগ্য:


3
আপনাকে ধন্যবাদ, এই সম্পর্কে সচেতন ছিল না। "স্রেফ কাজ" বা মান হিসাবে গ্রহণযোগ্য উপায়গুলির পরিবর্তে জিনিসগুলি করার "সঠিক উপায়" জানতে এটি খুব দরকারী।
tjklemz

3
রিকার্সিভ মেকটি ক্ষতিকারক হিসাবে বিবেচিত হয়েছিল, ফিরে যখন এটি সত্যিই ভাল কাজ করে না। আজকাল এটি ক্ষতিকারক হিসাবে বিবেচিত হয় না, বাস্তবে, অটোটুলগুলি / অটোমেক বড় প্রকল্পগুলি কীভাবে পরিচালনা করে।
এডউইন বাক

36

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

CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src

OutputExecutable: part1api.o part2api.o part3api.o

এটি স্বয়ংক্রিয়ভাবে VPATH নির্দিষ্ট ডিরেক্টরিগুলির যে কোনও মিলিয়ে থাকা partXapi.cpp ফাইলগুলি সন্ধান করবে এবং সেগুলি সংকলন করবে। তবে আপনার এসসিআর ডিরেক্টরিটি উপ-ডিরেক্টরিতে বিভক্ত হয়ে গেলে এটি আরও কার্যকর more আপনি যা বর্ণনা করেছেন তার জন্য, যেমন অন্যেরা বলেছেন, আপনি প্রতিটি অংশের জন্য একটি মেকফিল দিয়ে সম্ভবত আরও ভাল, বিশেষত যদি প্রতিটি অংশ একা দাঁড়িয়ে থাকতে পারে।


2
আমি বিশ্বাস করতে পারি না এই সাধারণ নিখুঁত উত্তরটি আরও বেশি ভোট পেল না। এটি আমার কাছ থেকে একটি +1।
নিকোলাস হ্যামিল্টন

2
সাবফোল্ডারগুলিতে বেশ কয়েকটি পৃথক প্রকল্পের জন্য একটি উচ্চতর ডিরেক্টরিতে আমার কয়েকটি সাধারণ উত্স ফাইল ছিল, VPATH=..আমার জন্য কাজ করেছিল!
এক্রির্কে

23

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

সিসি = ছ ++,
Target = cppTest
OTHERDIR = .. / .. / someotherpath / এ / প্রকল্প / src

উত্স = cppTest.cpp
উত্স = $ (OTHERDIR) / ফাইল ফাইল। পিপি

## শেষ উত্স সংজ্ঞা
INCLUDE = -I./ $ (আন.ন.প.  
অন্তর্ভুক্ত = -I। $ (OTHERDIR) /../ ইনক
## শেষ আরও অন্তর্ভুক্ত

VPATH = $ (OTHERDIR)
ওবিজে = $ (যোগ দিন $ (অ্যাডসফিক্স ../obj/, $ (দির $ (উত্সাহ))), $ (নটডির $ (উত্স: .সিপি = .ও))) 

## src ডিয়ারের সাথে আপেক্ষিকতার গন্তব্য স্থির করুন ../.dep
ডিপেন্ডস = $ (যোগ দিন $ (অ্যাডসফিক্স ../.dep/, $ (দির $ (উত্সাহ)))), $ (নোটডির S (উত্স: .সিপিপি =। ডি)))

## ডিফল্ট বিধি কার্যকর করা হয়েছে
সমস্ত: $ (টার্গেট)
        @true

## পরিষ্কার বিধি
পরিষ্কার:
        @ -rm -f $ (টার্গেট) $ (ওবিজে) $ (নির্ধারিত)


## আসল টার্গেট করার নিয়ম
$ (টারগেট): $ (ওবিজে)
        @ কেচো "==============" "
        @ কেচো "লক্ষ্য সংযুক্ত করে $ @"
        @ কেচো "==============" "
        @ $ (সিসি) $ (সিএফএলএজিএস) -ও $ @ $ ^ $ (এলআইবিএস)
        @ কেচো - লিঙ্কটি সমাপ্ত -

## জেনেরিক সংকলন নিয়ম
% .o:% .cpp
        @mkdir -p $ (দির $ @)
        @ কেচো "==============" "
        @echo "সংকলন $ <"
        @ $ (সিসি) $ (সিএফএলজিএস) -সি $ <-o $ @


## সিপিপি ফাইলগুলি থেকে অবজেক্ট ফাইলগুলির নিয়ম
## প্রতিটি ফাইলের জন্য অবজেক্ট ফাইলটি اعتراض ডিরেক্টরিতে রাখা হয়
## আসল উত্স ডিরেক্টরি থেকে এক স্তর উপরে।
../obj/%.o:% .cpp
        @mkdir -p $ (দির $ @)
        @ কেচো "==============" "
        @echo "সংকলন $ <"
        @ $ (সিসি) $ (সিএফএলজিএস) -সি $ <-o $ @

"অন্যান্য ডিরেক্টরি" র জন্য নিয়ম আপনার প্রতি "অন্যান্য" ডিয়ারের জন্য প্রয়োজন
OTHER (OTHERDIR) /../ আপত্তি /%। ও:% .সিপি
        @mkdir -p $ (দির $ @)
        @ কেচো "==============" "
        @echo "সংকলন $ <"
        @ $ (সিসি) $ (সিএফএলজিএস) -সি $ <-o $ @

## নির্ভরতা বিধি তৈরি করুন
../.dep/%.d:% .cpp
        @mkdir -p $ (দির $ @)
        @ কেচো "==============" "
        ech * o এর জন্য @ বেচো বিল্ডিং নির্ভরতা ফাইল
        @ $ (বিক্রয়) -সি '$ (সিসি) -এম $ (সিএফএলএজিএস) $ <| সেড "এস ^ $ *। ও ^ .. / আপত্তি / $ *। ও ^"> $ @ '

## "অন্যান্য" ডিরেক্টরিতে নির্ভরতা নিয়ম
OTHER (OTHERDIR) /../। Dep /%। D:% .cpp
        @mkdir -p $ (দির $ @)
        @ কেচো "==============" "
        ech * o এর জন্য @ বেচো বিল্ডিং নির্ভরতা ফাইল
        @ $ (বিক্রয়) -সি '$ (সিসি) -এম $ (সিএফএলএজিএস) $ <| সেড "এস ^ $ *। ও ^ $ (OTHERDIR) /../ আপত্তি / $ *। ও ^"> $ @ '

## নির্ভরতা ফাইল অন্তর্ভুক্ত করুন
অন্তর্ভুক্ত $ (নির্ধারিত)


7
আমি জানি এখনই এটি বেশ পুরাতন তবে, SOURCE এবং অন্তর্ভুক্ত নয় উভয়ই এক অ্যাসাইনমেন্টের দ্বারা এক লাইন পরে ওভাররাইট করা?
স্কেলিয়াম

@ স্কেলিয়াম হ্যাঁ, এটি করে।
ন্যাব্রায়ান

1
এই পদ্ধতির DRY নীতি লঙ্ঘন। প্রতিটি "অন্যান্য ডিরেক্টরি" এর কোড নকল করা খারাপ ধারণা
যীশু এইচ

20

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

# common sources
COMMON_SRC := ./main.cpp \
              ../src1/somefile.cpp \
              ../src1/somefile2.cpp \
              ../src2/somefile3.cpp \

আমি তখন VPATHএই পদ্ধতিতে সেট করতে পারি :

VPATH := ../src1:../src2

তারপরে আমি বস্তুগুলি তৈরি করি:

COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(ARCH)$(DEBUG).o, $(notdir $(COMMON_SRC)))

এখন নিয়মটি সহজ:

# the "common" object files
$(ObjDir)/%$(ARCH)$(DEBUG).o : %.cpp Makefile
    @echo creating $@ ...
    $(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<

এবং আউটপুট তৈরি করা আরও সহজ:

# This will make the cbsdk shared library
$(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS)
    @echo building output ...
    $(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)

একটি এমনকি VPATHপ্রজন্মটি স্বয়ংক্রিয়ভাবে তৈরি করতে পারে :

VPATH := $(dir $(COMMON_SRC))

অথবা সত্য যা sortডুপ্লিকেটগুলি সরায় (যদিও এটি বিবেচনা করা উচিত নয়) ব্যবহার করে:

VPATH := $(sort  $(dir $(COMMON_SRC)))

এটি ছোট প্রকল্পগুলির জন্য দুর্দান্ত কাজ করে যেখানে আপনি কেবল কয়েকটি কাস্টম লাইব্রেরি যুক্ত করতে এবং একটি পৃথক ফোল্ডারে রাখতে চান। আপনাকে অনেক ধন্যবাদ
zitroneneis

6

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

এটি একটি দুর্দান্ত সরঞ্জাম তবে এটির সরাসরি ব্যবহারটি 2010+ এ অপ্রচলিত হিসাবে বিবেচনা করা উচিত।

অবশ্যই, যদি না আপনি কোনও বিশেষ পরিবেশে কাজ করছেন, যেমন কোনও উত্তরাধিকার প্রকল্প ইত্যাদি working

একটি IDE ব্যবহার করুন CMake বা, যদি আপনি হার্ড অন্তর কুরিয়া ফেলা করছি, Autotools

(ডাউনভোটের কারণে সম্পাদিত, নির্দেশ করার জন্য টায় হোনজা)


1
ডাউনভোটগুলি ব্যাখ্যা করে দেওয়া ভাল লাগবে। আমি আমার মেকফিলগুলি নিজেই তৈরি করতাম।
ইলডান

2
আমি "সেই কাজটি করব না" পরামর্শটির জন্য অগ্রগতি করছি - কেডেফের কাছে মেক এবং অন্যান্য বিল্ড সিস্টেমগুলি কনফিগার করার জন্য খুব গ্রাফিকাল ইন্টারফেস রয়েছে এবং আমি নিজে মেকফিলস লেখার সময় কেডেভলফ আমার সহকর্মীদের কাছে যা দিয়ে থাকি - তবে আমি অটোটুলস লিঙ্কটি সহায়তা করে বলে মনে করবেন না। অটোটুলগুলি বুঝতে, আপনাকে এম 4, লিবটোল, অটোমেক, অটোকনফ, শেল, মেক এবং মূলত পুরো স্ট্যাকটি বুঝতে হবে।
মোহাম্মদী

7
ডাউনভোটগুলি সম্ভবত আপনার নিজের প্রশ্নের উত্তর দিচ্ছেন বলেই। প্রশ্নটি মেকফাইল ব্যবহার করা উচিত কিনা তা নিয়ে ছিল না। এগুলি কীভাবে লিখবেন সে সম্পর্কে ছিল।
হনজা

8
এটি চমৎকার হবে যদি আপনি এটি কয়েকটি বাক্যে ব্যাখ্যা করতে পারেন যে আধুনিক সরঞ্জামগুলি কীভাবে মেকফিল লেখার পক্ষে জীবনকে আরও সহজ করে তোলে। তারা কি উচ্চ স্তরের বিমূর্ততা সরবরাহ করে? অথবা কি?
অভিষেক আনন্দ

1
xterm, vi, bash, makefile == বিশ্ব শাসন করুন, cmake এমন লোকদের জন্য যারা কোড হ্যাক করতে পারে না।
λαβέ.λαβέ

2

আরসির পোস্টটি সুপারের উপকারী ছিল। আমি কখনই $ (দির $ @) ফাংশনটি ব্যবহার করার কথা ভাবি নি, তবে এটি করার জন্য আমার যা প্রয়োজন ঠিক তা করেছে।

প্যারেন্টডিয়ারে, তাদের মধ্যে উত্স ফাইল সহ ডিরেক্টরিগুলির একটি গোছা রয়েছে: dirA, dirB, dirC। বিভিন্ন ফাইল অন্যান্য ডিরেক্টরিতে অবজেক্ট ফাইলগুলির উপর নির্ভর করে, তাই আমি একটি ডিরেক্টরি থেকে একটি ফাইল তৈরি করতে সক্ষম হতে চেয়েছিলাম এবং সেই নির্ভরতার সাথে যুক্ত মেকফিলকে কল করে সেই নির্ভরতা তৈরি করতে চাই।

মূলত, আমি প্যারেন্টডায়ারে একটি মেকফাইল তৈরি করেছি যা আরসির মতো একটি জেনেরিক নিয়ম ছিল (অন্যান্য অনেক জিনিসের মধ্যে):

%.o : %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo "Compiling $<"
        @$(CC) $(CFLAGS) -c $< -o $@

এই জেনেরিক নিয়ম উত্তরাধিকারী করার জন্য প্রতিটি উপ-ডিরেক্টরিতে এই উচ্চ-স্তরের মেকফিল অন্তর্ভুক্ত থাকে। প্রতিটি উপ-ডিরেক্টরির মেকফাইলে আমি প্রতিটি ফাইলের জন্য একটি কাস্টম নিয়ম লিখেছিলাম যাতে প্রতিটি পৃথক ফাইল নির্ভর করে এমন সমস্ত কিছুর উপর নজর রাখতে পারি।

যখনই আমার কোনও ফাইল তৈরি করার দরকার হয়েছিল, আমি নিয়মটি (প্রয়োজনীয়ভাবে) পুনরাবৃত্তভাবে যে কোনও / সমস্ত নির্ভরতা তৈরি করতে ব্যবহার করেছিলাম। পারফেক্ট!

দ্রষ্টব্য: "মেকপ" নামক একটি ইউটিলিটি রয়েছে যা মনে হয় এই কাজটি আরও স্বজ্ঞাতভাবে করতে পারে তবে বহনযোগ্যতার জন্য এবং অন্য কোনও সরঞ্জামের উপর নির্ভর করে নয়, আমি এটি এইভাবেই বেছে নিয়েছি।

আশাকরি এটা সাহায্য করবে!


2

মেক এর পুনরাবৃত্তি ব্যবহার

all:
    +$(MAKE) -C part1
    +$(MAKE) -C part2
    +$(MAKE) -C part3

এটি makeচাকরিতে বিভক্ত হয়ে একাধিক কোর ব্যবহার করতে দেয়


2
এরকম কিছু করার চেয়ে এটি কীভাবে ভাল make -j4?
Devin

1
@ দেবিন যেমনটি দেখছি, তেমনটি নয় ভাল , এটি কেবলমাত্র কাজের নিয়ন্ত্রণ ব্যবহার করতে সক্ষম make করে। মেকের পৃথক প্রক্রিয়া চলাকালীন, এটি কাজ নিয়ন্ত্রণের সাপেক্ষে নয়।
মাইকেল পানকভ 5

1

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

PROJ_NAME=mono

CPP_FILES=$(shell find . -name "*.cpp")

S_OBJ=$(patsubst %.cpp, %.o, $(CPP_FILES))

CXXFLAGS=-c \
         -g \
        -Wall

all: $(PROJ_NAME)
    @echo Running application
    @echo
    @./$(PROJ_NAME)

$(PROJ_NAME): $(S_OBJ)
    @echo Linking objects...
    @g++ -o $@ $^

%.o: %.cpp %.h
    @echo Compiling and generating object $@ ...
    @g++ $< $(CXXFLAGS) -o $@

main.o: main.cpp
    @echo Compiling and generating object $@ ...
    @g++ $< $(CXXFLAGS)

clean:
    @echo Removing secondary things
    @rm -r -f objects $(S_OBJ) $(PROJ_NAME)
    @echo Done!

আমি জানি যে এটি সহজ এবং কিছু লোকের জন্য আমার পতাকাগুলি ভুল, কিন্তু আমি যেমন বলেছিলাম যে এটি আমার প্রকল্পটি একাধিক ডায়ারে সংকলন করে এবং তারপর আমার বাক্সটি তৈরি করার জন্য সমস্তগুলি সংযুক্ত করে।

আমি মামলা গ্রহণ করছি: ডি


-1

আমি ব্যবহার করার পরামর্শ দিচ্ছি autotools:

//## উত্পাদিত অবজেক্ট ফাইলগুলি (.o) তাদের উত্স ফাইল হিসাবে একই ডিরেক্টরিতে রাখুন, যখন পুনরাবৃত্তিযোগ্য মেক ব্যবহার করা হয় তখন সংঘর্ষ এড়ানোর জন্য।

AUTOMAKE_OPTIONS = subdir-objects

শুধু এটি অন্তর্ভুক্ত Makefile.am অন্যান্য বেশ সাধারণ স্টাফ ।

টিউটোরিয়াল এখানে ।

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