2012-10-03 22 views
5

Tôi đang chạy một Makefile đơn giản với không có vấn đề:Makefile quy tắc C thư mục con để làm cho 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) 

Các tập tin nằm trong thư mục chính của dự án của:

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

Sau đó, tôi đã cố gắng để các tập tin tổ chức và đặt các thông tin như:

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

và thư mục con phụ khác:

./project/lib 
./project/obj 

Sau đó, phiên bản mới của 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)/*~ 

Tôi đang biên soạn trên Linux sử dụng Emacs với trình biên dịch gcc:

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

Sau đó, tôi chạy trên Emacs:

<Esc> 
x 
compile 
make 

Và nó cung cấp thông báo:

"./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 

Quy tắc nào cần được đưa vào tệp Makefile?

Tất cả nhận xét và đề xuất đều được đánh giá cao.


Cảm ơn đề xuất của bạn, nó được thêm vào mã. Sau đó trình biên dịch khiếu nại:

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 

Một số đề xuất khác?

Cảm ơn trước!

+0

'dự án/obj' sẽ tad hợp lý hơn' project/src/obj' –

+0

Xin chào Steve-o. Cảm ơn! Tôi đã thực hiện thay đổi bạn đã đề xuất. – ThreaderSlash

Trả lời

5

Để khắc phục lỗi make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

Thay đổi dòng này:

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

Để:

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

Điều này tạo ra một quy tắc cho tất cả các đối tượng trong biến $(OBJ). Tham số thứ hai ('$(ODIR)/%.o') trích xuất tên tệp từ đường dẫn đầy đủ để chỉ chuyển tên tệp đến tham số thứ ba ('src/%.c').

+0

Xin chào Ryan. Bạn đã đúng .. các tệp bị thiếu trong "src /". Tôi cũng xóa ".." như bạn đã đề xuất. Nhưng một lỗi còn lại: make: *** Không có quy tắc để thực hiện mục tiêu '/include/hellomake.h ', cần thiết bởi' obj/hellomake.o'. – ThreaderSlash

+0

Xóa đầu/từ bao gồm. Điều đó/yêu cầu Makefile nhìn vào thư mục gốc của hệ thống tập tin thay vì thư mục dự án của bạn. – Ryan

+0

Ryan cảm ơn một lần nữa! Tôi đã tắt "/". Một lỗi còn lại đã biến mất. Sau đó, trong (gdb) chạy ... cho: {{(gdb) chạy Bắt đầu chương trình: Không có tệp thực thi nào được chỉ định. Sử dụng lệnh "tệp" hoặc "exec-file".}} – ThreaderSlash

-1

Ok.Bây giờ tôi đang cố gắng một ví dụ khác tìm thấy ở đây [How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?] và ở đây nó đi:

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!" 

Các tập tin được tổ chức như:

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

Trình biên dịch vẫn tồn cho chỉ có một đơn khiếu nại:

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 

Cảm ơn rất nhiều ý kiến ​​đóng góp và góp ý!

+0

Ngay cả khi điều này là tuổi, vấn đề của bạn chỉ đơn giản là 'TARGETPATH' không được xác định và do đó' $ (TARGETPATH)/$ (TARGET) 'trong trình liên kết sẽ giải quyết thành'/bin'. – xtra