क्या मैं सभी .cpp फ़ाइलों को src / .o .o में obj / में संकलित कर सकता हूं, फिर बाइनरी में लिंक करें? /?


116

मेरी परियोजना निर्देशिका इस प्रकार है:

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

मैं सभी को संकलित किया जाएगा करने के लिए मेरी makefile चाहते हैं क्या .cppमें फाइल /srcकरने के लिए फ़ोल्डर .oमें फ़ाइलों को /objफ़ोल्डर, तो सभी लिंक .oमें फ़ाइलों को /objशीर्ष-स्तरीय फ़ोल्डर में उत्पादन बाइनरी में /project

मेरे पास मेकफाइल्स के साथ कोई अनुभव नहीं है, और वास्तव में मुझे यकीन नहीं है कि इसे पूरा करने के लिए क्या खोजना है।

इसके अलावा, यह ऐसा करने के लिए एक "अच्छा" तरीका है, या क्या मैं जो करने की कोशिश कर रहा हूं, उसके लिए एक अधिक मानक दृष्टिकोण है?



6
@aaa: मुझे लगता है कि ओपी एक समाधान चाहता है जिसे प्रत्येक स्रोत फ़ाइल को स्पष्ट रूप से सूचीबद्ध करने की आवश्यकता नहीं है।
कास्कैबेल

7
मैं अपने पास मौजूद प्रत्येक स्रोत फ़ाइल को निर्दिष्ट नहीं करना चाहता, और मैंने उस मैनुअल को पहले पढ़ने की कोशिश की है, लेकिन मुझे यह अव्यवस्थित और समझने में कठिन लगता है। मैं एक वास्तविक उदाहरण से बहुत बेहतर सीखता हूं जो वह करता है जो मैं अपेक्षा करता हूं और इसे अच्छी तरह से समझाया जाता है, बजाय सूखे तकनीकी मैनुअल के।
ऑस्टिन हाइड

ठीक है। लेकिन प्रलेखन अच्छे उदाहरणों के साथ उत्कृष्ट है (यह तकनीकी मैनुअल की कोशिश नहीं है)। आप पैटर्न नियमों की तलाश कर रहे हैं: gnu.org/software/make/manual/make.html#Pattern-Rules
Anycorn

11
जो मैं चाहता हूं, वह थोड़ा और अच्छा लगता है। हालांकि, IMHO, मेक मैनुअल थोड़ा सूखा है, क्योंकि यह उन डेवलपर्स को अधिक लक्षित लगता है जो मेक-अप के साथ एक मध्यवर्ती स्तर पर हैं, और इससे परे बहुत बड़ी और गहराई में हैं। शायद बहुत ज्यादा।
ऑस्टिन हाइड

जवाबों:


180

प्रश्न का मेकफाइल हिस्सा

यह बहुत आसान है, जब तक आपको नीचे दिए गए कोड की तरह कुछ करने की कोशिश करने की ज़रूरत नहीं है (लेकिन जी ++ के पास टैब के साथ अंतरिक्ष इंडेंटेशन बदलें)

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

स्वचालित निर्भरता ग्राफ पीढ़ी

अधिकांश मेक सिस्टम के लिए "मस्ट" फीचर। GCC के साथ एक एकल पास में संकलित करने के साइड इफेक्ट के रूप में किया जा सकता है और -MMDझंडे के शरीर के अंत में ध्वज को जोड़कर :CXXFLAGS -include $(OBJ_FILES:.o=.d)

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

और जैसा कि लोगों ने पहले ही उल्लेख किया है, हमेशा जीएनयू मेक मैनुअल के आसपास है, यह बहुत मददगार है।


11
आह, तुमने मुझे सेकंड से हराया। लेकिन मैं सुझाव देता हूं OBJ_FILES = $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES))
बीटा

1
मुझे इसे काम करने के लिए बदलना पड़ा: main.exe नियम के लिए $<होना चाहिए $^और मुझे लगता है कि इसके साथ एक टाइपो है obj/%.o: src/%cpp

1
@bobah आपको याद कर रहे हैं '।' सीपीपी के लिए अपनी वस्तुओं के शासन में
regomodo

1
विशेष चर शायद समझाने लायक हैं, क्योंकि वे खोज करने के लिए विशिष्ट और कठिन हैं: gnu.org/software/make/manual/html_node/Automatic-Variables.html
Blake

2
मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन मैंने अपनी परियोजना के अनुसार थोड़ा संशोधित किया है, लेकिन यह काम नहीं कर रहा है। यहाँ मेरा मेकफाइल है: pastebin.com/4CksG9Wc मुझे कंसोल में मिलता है:make: *** No rule to make target '/main.o', needed by 'bin/main'. Pare.
Mateus Felipe

5

वाइल्डकार्ड मेरे लिए भी काम करता है, लेकिन मैं निर्देशिका चर का उपयोग करने वालों के लिए एक साइड नोट देना चाहूंगा। हमेशा फ़ोल्डर ट्री के लिए स्लैश का उपयोग करें (बैकस्लैश नहीं), अन्यथा यह विफल हो जाएगा:

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)

क्या आपका मतलब था आगे की स्लैश? आपके उदाहरण से पता चलता है कि पारंपरिक रूप से आगे के स्लैश को क्या माना जाता है। विशेष रूप से, "सही झुकाव" वाले लोगों को "आगे" माना जाता है और जो बाएं हैं उन्हें "पीछे" माना जाता है
इवान टेरन

हां, आप सही हैं, मेरा मतलब केवल "स्लैश" है। मैंने पोस्ट अपडेट की।
xesf
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.