2014-05-06 22 views
5

Tôi đang cố gắng cải thiện giải pháp ngây thơ (các quy tắc đơn để biên dịch các mục tiêu và bổ sung để liên kết tất cả các mục tiêu trước đó với nhau) mà tôi đã sử dụng im makefile của mình. tôi đã đưa ra Makefile sau (cắt):Quy tắc mục tiêu chung của Makefile

.PHONY: clean 

BASE_DIR = ../ 

CC = gcc 
CROSS_COMPILE = arm-none-eabi- 
CFLAGS =-g -I${BASE_DIR}/include 
LDFLAGS =-L${BASE_DIR}/lib -Ttarget.ld -nostdlib 

SOURCES = first.c second.c third.c fourth.c 
OBJECTS = $(SOURCES:.c=.o) 
EXECUTABLE = $(OBJECTS:.o=) 

all: $(EXECUTABLE) 

%: 
    ${CROSS_COMPILE}$(CC) $(CFLAGS) $(LDFLAGS) $*.c -o $* 

clean: 
    rm ${EXECUTABLE} 

này hoạt động tốt nhưng tôi muốn để tách biên soạn và các quá trình liên kết. Do đó, tôi đã cố gắng sửa đổi nó như sau:

.PHONY: clean 

BASE_DIR = ../ 

CC = gcc 
CROSS_COMPILE = arm-none-eabi- 

CFLAGS =-c -g -I${BASE_DIR}/include 
LDFLAGS =-L${BASE_DIR}/lib -Ttarget.ld -nostdlib 

SOURCES = first.c second.c third.c fourth.c 
OBJECTS = $(SOURCES:.c=.o) 
EXECUTABLE = $(OBJECTS:.o=) 

all : $(EXECUTABLE) 

%.o : %.c 
    @echo "Compiling c file into o file" 
    ${CROSS_COMPILE}$(CC) $(CFLAGS) $< -o [email protected] 

% : %.o 
    @echo "Linking o file into executable" 
    ${CROSS_COMPILE}$(CC) $(LDFLAGS) $< -o [email protected] 

clean: 
    rm ${EXECUTABLE} 

Điều này làm việc ok sau đó tôi gọi Makefile là ví dụ: make first.o; make first hoặc nếu tôi sửa đổi EXECUTABLE = $(OBJECTS:.o=) thành EXECUTABLE = $(OBJECTS:.o=.out)% : %.o thành %.out : %.o. Tuy nhiên, nếu tôi cố gắng gọi trình biên dịch là make hoặc make first các quy tắc ngầm được sử dụng.

Tôi đã thử xem qua hướng dẫn sử dụng Makefile nhưng thực sự có rất nhiều thông tin trong đó, tôi thấy hơi bối rối.

Làm thế nào tôi có thể sửa đổi các Makefile để được phép gọi xây dựng các mục tiêu riêng biệt như make <target> hoặc tất cả các chỉ tiêu như make như cùng một lúc?

Trả lời

6

Đoạn mà bạn mô tả vấn đề của mình rất khó hiểu và khó hiểu. Khi đặt câu hỏi, hãy đảm bảo rằng phần mô tả vấn đề là rõ ràng nhất: rất hữu ích nếu bạn cung cấp kết quả đầu ra mẫu cho biết chính xác các lệnh bạn đã nhập và kết quả bạn nhận được và giải thích những gì bạn mong muốn. Tuy nhiên, cách giải thích của tôi là nếu bạn chạy make first, nó sử dụng quy tắc dựng sẵn để biên dịch first trực tiếp từ first.c, chứ không phải là quy tắc mẫu của bạn (lưu ý rằng cả quy tắc và quy tắc mẫu của bạn được xem là "ẩn" quy tắc").

Đó là do thực hiện sẽ chọn chuỗi quy tắc ngầm "ngắn hơn" để quy tắc xây dựng tệp thực thi trực tiếp từ nguồn, trong một bước, thay vì xây dựng đối tượng, sau đó thực thi theo hai bước sẽ được ưu tiên. Nếu bạn không muốn sử dụng được xây dựng trong quy tắc ngầm thì bạn cần phải hoặc là gọi thực hiện với các -r cờ, nếu không delete it bằng cách thêm:

% : %.c 

(chỉ là) để makefile của bạn.

+0

Tôi xin lỗi nếu mô tả của tôi gây nhầm lẫn, cố gắng hết sức để làm rõ. Ý của bạn là gì bởi "cả quy tắc dựng sẵn và quy tắc mẫu của bạn được coi là" quy tắc ngầm "? Các quy tắc tôi cung cấp không được coi là rõ ràng? –

+0

Không. Quy tắc rõ ràng là các quy tắc như 'foo: foo.o': chúng có các tên mục tiêu _explicit_. Các quy tắc hậu tố ('.c.o') và các quy tắc mẫu ('% .o:% .c') không có mục tiêu rõ ràng; chúng là những quy tắc ngầm. Có một số quy tắc ngầm định được cung cấp theo mặc định bằng cách thực hiện, đó là các quy tắc _built-in_. – MadScientist

+0

Hãy trả lời câu hỏi của bạn: đọc lại mô tả này, cố gắng tưởng tượng bạn không biết gì khác về vấn đề: _Điều này hoạt động ok sau đó tôi gọi Makefile là ví dụ: 'make first.o; thực hiện đầu tiên' hoặc nếu tôi sửa đổi 'EXECUTABLE = $ (OBJECTS: .o =)' thành 'EXECUTABLE = $ (OBJECTS: .o = .out)' và '%:% .o' thành'% .out:% .o'. Tuy nhiên, nếu tôi cố gắng gọi trình biên dịch là 'make' hoặc 'make first' thì các quy tắc ngầm được sử dụng._ Điều đó có thực sự rõ ràng với bạn không? – MadScientist

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