2013-02-01 40 views
14
GNU Make 3.82 
gcc 4.7.2 
c89 

Tôi đã sau làm cho file:Bắt làm để tạo ra các file đối tượng trong một thư mục cụ thể

INC_PATH=-I/home/dev_tools/apr/include/apr-1 
LIB_PATH=-L/home/dev_tools/apr/lib 
LIBS=-lapr-1 -laprutil-1 
RUNTIME_PATH=-Wl,-rpath,/home/dev_tools/apr/lib 
CC=gcc 
CFLAGS=-Wall -Wextra -g -m32 -O2 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE $(INC_PATH) 
SOURCES=$(wildcard src/*.c) 
OBJECTS=$(patsubst %.c, %.o, $(SOURCES)) 

EXECUTABLE=bin/to 

all: build $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(CFLAGS) -o [email protected] $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS) 

$(OBJECTS): $(SOURCES) 
    $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) 

build: 
    @mkdir -p bin 

clean: 
    rm -rf $(EXECUTABLE) $(OBJECTS) bin 
    find . -name "*~" -exec rm {} \; 
    find . -name "*.o" -exec rm {} \; 

cấu trúc thư mục của tôi là như project/src project/bin này. Makefile của tôi nằm trong thư mục project (root) và tất cả các tệp * .h và * .c của tôi nằm trong thư mục src. Hiện nay tôi chỉ có một tập tin nguồn được gọi là timeout.c

tôi nhận được lỗi này:

gcc: error: src/timeout.o: No such file or directory 

Tôi đã sử dụng này để có được tất cả các file nguồn:

SOURCES=$(wildcard src/*.c) 

Và các tập tin đối tượng:

OBJECTS=$(patsubst %.c, %.o, $(SOURCES)) 

Tuy nhiên, việc tạo dường như tạo tệp đối tượng trong thư mục gốc của dự án nơi Mak efile là. Nó không nên đặt nó trong thư mục src?

Trả lời

12

Bạn có hai vấn đề trong quy tắc này (tốt, ba):

$(OBJECTS): $(SOURCES) 
    $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) 

Bạn chưa nhận thấy bài viết nào, nhưng nguyên tắc làm mỗi đối tượng phụ thuộc vào tất cả nguồn khác nhau, và cố gắng xây dựng theo cách đó. Không phải là một vấn đề miễn là bạn chỉ có một nguồn. Dễ dàng sửa chữa với một static pattern rulean automatic variable:

$(OBJECTS): src/%.o : src/%.c 
    $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) 

Ngoài ra, các lệnh ("$ (CC) ...") không xác định một tên tập tin đầu ra, vì vậy gcc sẽ suy ra nó từ tên tập tin nguồn ; nếu bạn cung cấp cho nó src/timeout.c, nó sẽ sản xuất timeout.o (trong thư mục làm việc, project/). Vì vậy, bạn nên chỉ định đường dẫn mong muốn vào tập tin đầu ra. Dễ dàng thực hiện với một biến tự động khác:

$(OBJECTS): src/%.o : src/%.c 
    $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) -o [email protected] 
+0

Còn việc tạo thư viện dùng chung thì sao? Tôi chạy trên một trang web tuyên bố tôi cần chuyển đổi '-c' để tạo một thư viện được chia sẻ, nhưng việc sử dụng điều này ngăn cản tôi sử dụng' -o'. Và hiện tại, tạo ra các tệp đối tượng ngay trong thư mục gốc của dự án. Cấu trúc thư mục của tôi là: 'src/lib/*', và tôi muốn các tập tin obj được tạo ra trong 'obj/lib/*' Lệnh gcc là: 'g ++ -std = C++ 11 -g -I./include -fPIC -Wall -c ./src/lib/Source1.cpp./src/lib/Source2.cpp' – krb686

+0

Ok, tôi hiểu rồi. Đã cố gắng biên dịch nhiều đối tượng phụ thuộc vào nhiều nguồn. Tôi đã thay thế bằng quy tắc mẫu tĩnh của bạn và các biến tự động '$ <' và '$ @' và nó hoạt động như một nét duyên dáng. Cũng không biết tại sao gcc phàn nàn và nói rằng bạn không thể sử dụng '-c' với' -o' nhưng bạn chắc chắn có thể. – krb686

4

Sử dụng gcc '-o tùy chọn ghi tệp đầu ra vào một vị trí cụ thể. Ví dụ, bạn có thể nói:

$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) -o $(OBJECTS) 

Thật không may, có một vấn đề với dòng này: nếu có tập tin nhiều hơn một nguồn tin trong $(SOURCES), nó sẽ không làm việc, kể từ $(OBJECTS) cũng sẽ chứa nhiều tên tập tin, và tùy chọn -o chỉ liên kết với đối số đầu tiên.

Cách để biên dịch từng tệp trong danh sách tệp mã nguồn là sử dụng quy tắc ngầm. Trong gmake, bạn sẽ viết:

$(EXECUTABLE): $(OBJECTS) 
     $(CC) $(CFLAGS) -o [email protected] $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS) 

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

nơi $ < được thay thế bằng tên của tập tin đầu vào và $ @ được thay thế bằng tên ra các tập tin đầu ra.

+2

Điều này hoạt động miễn là chỉ có một nguồn. – Beta

+0

@Beta Xin lỗi, "Điều này" bạn đang đề cập đến là gì? – radical7

+0

Giải pháp của bạn, "cách thích hợp".Hãy thử nó với nhiều hơn một tập tin nguồn và bạn sẽ thấy những gì tôi có ý nghĩa. – Beta

Các vấn đề liên quan