2012-10-03 17 views
5

बनाने के लिए मैं कोई समस्या नहीं के साथ एक सरल Makefile चला रहा हूँ:Makefile सी उपनिर्देशिका नियम obj

CC=gcc 
CFLAGS= -std=c99 -ggdb -Wall -I. 
DEPS = hellomake.h 
OBJ = hellomake.o hellofunc.o 

%.o: %.c $(DEPS) 
    $(CC) -c -o [email protected] $< $(CFLAGS) 

hellomake: $(OBJ) 
    gcc -o [email protected] $^ $(CFLAGS) 

फ़ाइलें मुख्य परियोजना की निर्देशिका में हैं:

./project/Makefile 
./project/hellomake.c 
./project/hellomake.h 

तब मैं संगठित फ़ाइलों की कोशिश की

./project/Makefile 
./project/src/hellomake.c 
./project/include/hellomake.h 

और अतिरिक्त उप निर्देशिकाओं निर्देशिका:, और तरह बातें डाल

012,
./project/lib 
./project/obj 

फिर Makefile का नया संस्करण:

IDIR =include 
CC=gcc 
CFLAGS= -std=c99 -ggdb -Wall -I$(IDIR) 

ODIR=obj 
LDIR =lib 

LIBS=-lm 

_DEPS = hellomake.h 
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) 

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) 


$(ODIR)/%.o: %.c $(DEPS) 
    $(CC) -c -o [email protected] $< $(CFLAGS) 

hellomake: $(OBJ) 
    gcc -o [email protected] $^ $(CFLAGS) $(LIBS) 

.PHONY: clean 

clean: 
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

मैं जीसीसी संकलक के साथ Emacs का उपयोग कर लिनक्स पर संकलन कर रहा हूँ:

$ gcc --version 
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 

फिर, मैं पर Emacs चलाएँ:

<Esc> 
x 
compile 
make 

और यह संदेश देता है:

"./project/src/" -*- 
make: *** No rule to make target `obj/hellomake.o', needed by `hellomake'. Stop. 
Compilation exited abnormally with code 2 at Wed Oct 3 17:10:01 

मेकफ़ाइल फ़ाइल में शामिल करने के लिए कौन सा नियम गुम होना चाहिए?

सभी टिप्पणियां और सुझाव अत्यधिक सराहना की जाती हैं।


आपके सुझाव के लिए धन्यवाद, यह कोड में जोड़ा गया है। फिर संकलक शिकायत करता है:

make -k 
make: *** No rule to make target `src/hellomake.c', needed by `obj/hellomake.o'. 
make: *** No rule to make target `../include/hellomake.h', needed by `obj/hellomake.o'. 
make: Target `obj/hellomake.o' not remade because of errors 

कुछ अन्य सुझाव?

अग्रिम धन्यवाद!

$(ODIR)/%.o: %.c $(DEPS) 

करने के लिए::

$(OBJ): $(ODIR)/%.o: src/%.c $(DEPS) 

यह $(OBJ) चर में सभी वस्तुओं के लिए एक नियम बनाता है

+0

'प्रोजेक्ट/ओबीजे' 'प्रोजेक्ट/src/obj' –

+0

हैलो स्टीव-ओ से अधिक समझदार होगा। धन्यवाद! मैंने आपके द्वारा सुझाए गए परिवर्तन को बनाया है। – ThreaderSlash

उत्तर

5

त्रुटि make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

बदलें इस लाइन ठीक करने के लिए। दूसरा पैरामीटर ('$(ODIR)/%.o') फ़ाइल नाम को तीसरे पैरामीटर ('src/%.c') पर पास करने के लिए पूर्ण पथ से फ़ाइल नाम निकालता है।

+0

हैलो रयान। आप सही हैं .. फाइलें "src /" में गायब थीं। जैसा कि आपने सुझाव दिया है, मैं भी ".." हटा देता हूं। लेकिन एक त्रुटि बाकी है: बनाएं: *** 'obj/hellomake.o' द्वारा आवश्यक लक्ष्य '/include/hellomake.h 'बनाने का कोई नियम नहीं है। – ThreaderSlash

+0

शुरुआत/शामिल से निकालें। वह मेकफ़ाइल को आपके प्रोजेक्ट फ़ोल्डर की बजाय फाइल सिस्टम की मूल निर्देशिका में देखने के लिए कहता है। – Ryan

+0

रयान फिर से धन्यवाद! मैंने "/" बंद कर दिया। एक शेष त्रुटि चली गई है। फिर में (gdb) रन ... देता है: {{(gdb) रन प्रोग्राम प्रारंभ करना: कोई निष्पादन योग्य फ़ाइल निर्दिष्ट नहीं है। "फ़ाइल" या "exec-file" कमांड का उपयोग करें।}} – ThreaderSlash

-1

ठीक है।अब मैं एक और उदाहरण यहां पाया [How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?] कोशिश कर रहा हूँ और यहाँ यह जाता है:

make -k 
/usr/bin/ld: cannot open output file /bin/hi.sh: Permission denied 
collect2: ld returned 1 exit status 
make: *** [bin/bin/hi.sh] Error 1 
:

./project/bin/ executable 
./project/ojb/*.0 
./project/src/*.c and *.h 
./project/Makefile 

संकलक केवल एक ही शिकायत दे बनी रहती है: के रूप में

TARGET = hi.sh 
CC  = gcc 
# compiling flags here 
CFLAGS = -std=c99 -ggdb -Wall -I./src 
TARGET = bin/hi.sh 

LINKER = gcc -o 
# linking flags here 
LFLAGS = -Wall -I. -lm 

# change these to set the proper directories where each files shoould be 
SRCDIR = src 
OBJDIR = obj 
BINDIR = bin 

SOURCES := $(wildcard $(SRCDIR)/*.c) 
INCLUDES := $(wildcard $(SRCDIR)/*.h) 
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) 
rm  = rm -f 


$(BINDIR)/$(TARGET): $(OBJECTS) 
    @$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS) 
    @echo "Linking complete!" 

OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) 

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 
    @echo "Compiled "$<" successfully!" 

.PHONEY: clean 
clean: 
    @$(rm) $(OBJECTS) 
    @echo "Cleanup complete!" 

.PHONEY: remove 
remove: clean 
    @$(rm) $(BINDIR)/$(TARGET) 
    @echo "Executable removed!" 

फ़ाइलें आयोजन किया जाता है

सभी टिप्पणियों और सुझावों के लिए बहुत बहुत धन्यवाद!

+0

भले ही यह साल पुराना हो, आपकी समस्या यह है कि 'तारगेट' को परिभाषित नहीं किया गया है और इसलिए लिंकर में '$ (TARGETPATH)/$ (TARGET) ''/bin' को हल किया जाएगा। – xtra