2012-07-11 33 views
6

Đây chỉ là một phân đoạn của một makefile. Tôi không hiểu chuyện gì đang diễn ra.Nhiều dấu hai chấm và dấu bằng trong makefile (cần giải thích)

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) 
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

Tất cả những gì tôi hiểu là những dòng này biên dịch .cpp tệp thành .o, sau 'print-opts', với 'cc-command'. Nhưng tôi không hiểu ngữ nghĩa.

Nếu tôi mở rộng vĩ mô của 'OBJS', dòng này sẽ là:

$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

Đối với tôi, nó trông giống như trong '$ (Các SRC:. $ (SRC)/cpp% = $ (OBJ) /%. o) ', nó tuyên bố tất cả .cpp trong $ (SRC) sẽ đến .o bằng $ (OBJ), nhưng điều này sẽ phụ thuộc vào $ (OBJ) /%. o, phụ thuộc vào $ (SRC) /%.cpp. Điều này không có ý nghĩa ...

Tôi không hiểu ý nghĩa của dấu bằng ở đây là gì và ý nghĩa của nhiều dấu hai chấm.

Trả lời

14

Giả sử bạn đã xác định ba biến (và nếu bạn chưa có, các quy tắc sẽ không hoạt động rất tốt):

SRC = source_dir 
OBJ = object_dir 
SRCS = source_dir/foo.cpp source_dir/bar.cpp 

Bây giờ xem xét việc giao

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) 

Đây là a substitution reference; nó nói "cho bất kỳ thứ gì trong $(SRCS) có dạng $(SRC)/%.cpp, hãy đổi thành $(OBJ)/%.o". Vì vậy, OBJS sẽ đánh giá là object_dir/foo.o object_dir/bar.o.

Bây giờ quy tắc:

$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

Thuis là một static pattern rule. Nó chỉ định một danh sách các mục tiêu ($(OBJS)), một mẫu đích ($(OBJ)/%.o) và một mẫu điều kiện tiên quyết ($(SRC)/%.cpp). Làm cho phù hợp với một mục tiêu để các mô hình mục tiêu, và sử dụng đó để xây dựng tên điều kiện tiên quyết. Vì vậy, nếu sử dụng quy tắc này để xây dựng object_dir/foo.o, thân cây sẽ là foo và điều kiện tiên quyết sẽ là source_dir/foo.cpp.

(Bạn đã không hỏi về | print-opts, vì vậy tôi cho rằng nó đã rõ ràng.)

+0

Thank you very much. Các tham chiếu đến hướng dẫn sử dụng gnu 'make' cũng rất hữu ích. (Tôi đã xem xét hướng dẫn đó trước đây, nhưng tôi không thể xác định được thông tin mình cần) – qinsoon

+0

Có chút bối rối bởi tham chiếu thay thế. Vì vậy, nếu tôi có 'main.c', nó sẽ dính nó vào thư mục tệp đối tượng và chỉ thay đổi phần mở rộng của tệp thành' .o'. Điều này bảo toàn nội dung của tệp và chỉ thay đổi phần mở rộng. Điều này đặt tên cho tất cả các tệp đối tượng mà chúng tôi sẽ kết thúc. Sau đó chúng tôi sử dụng danh sách các tên như một mục tiêu và biên dịch thành các tệp đối tượng và ghi đè các tệp bằng tệp đối tượng mới mà chúng tôi vừa biên soạn. Chính xác? – Ungeheuer

+0

@Ungeheuer: Không, tham chiếu thay thế không làm gì cả với các tệp, nó chỉ biến đổi các biến. Nó biến "source_dir/main.cpp" thành "object_dir/main.o"; đó là * tên tệp *, chứ không phải * tệp *. Khi chúng ta có chuỗi "object_dir/main.o", chúng ta có thể chuyển nó tới quy tắc mẫu, nó biết cách xây dựng một tệp của tên đó. – Beta

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