Kể từ khi câu hỏi là về cách viết lại có thể sử dụng mã trong Makefiles, tôi sẽ đưa ra một ví dụ về cách sử dụng quy tắc mẫu trong GNU Make (nó trông như đó là những gì bạn đang sử dụng kể từ khi bạn đề cập đến mục tiêu .PHONY
). Tuy nhiên, nếu bạn không sử dụng bất kỳ kiểm tra phụ thuộc Make, nó có thể được đơn giản để làm điều này với một kịch bản shell - một cái gì đó như:
#!/bin/sh
TASKS="task01 task02 task03"
for i in $TASKS; do
rm $i $i.ext $i.o -f;
compiler $i.ext -O2 --make;
./$i;
done
Tuy nhiên, để mở rộng nguyên tắc để thực hiện, chúng tôi có một vấn đề khác để giải quyết. Dòng có dạng:
task01-all: task01-clean task01 task01-run
đừng nói Hãy theo thứ tự nào để xây dựng các điều kiện tiên quyết - chỉ rằng tất cả họ đều cần phải được thực hiện trước task01-all
được xây dựng. Thay vào đó, mỗi bước chạy sẽ phụ thuộc vào bước trước đó. Một cái gì đó như thế này:
TASKS=task01-run task02-run task03-run
.PHONY: all $(TASKS) $(TASKS:run=clean)
all: $(TASKS)
$(TASKS:run=clean): %-clean:
rm $* $*.ext $*.o -f
%: %.ext | %-clean
compiler $< -O2 --make
$(TASKS): %-run: %
./$<
Các quy tắc với %
được gọi là "quy tắc mẫu", và họ là một công cụ tuyệt vời để tránh tái bằng văn bản cùng một quy tắc nhiều lần cho các mục tiêu khác nhau. Một lưu ý là Make thường không kiểm tra các quy tắc mẫu cho mục tiêu .PHONY
; chúng tôi yêu cầu Thực hiện điều này một cách rõ ràng bằng cách đặt trước các quy tắc đó với danh sách các mục tiêu và dấu hai chấm thứ hai (ví dụ: $(TASKS):
).
Vì task01-run
cần task01
để hoạt động, chúng tôi thực hiện mục tiêu %-run
phụ thuộc vào %
. Ngoài ra, Makefile của bạn cho thấy rằng bạn muốn chạy sạch mọi lúc, vì vậy chúng tôi thực hiện %
phụ thuộc vào %-clean
. Vì %-clean
không thực sự tạo ra bất kỳ đầu ra nào, chúng tôi thực hiện điều này là phụ thuộc "chỉ đặt hàng" - Không tìm kiếm dấu thời gian hoặc bất kỳ thứ gì, nó sẽ chỉ chạy quy tắc %-clean
trước bất kỳ lúc nào cần chạy %
qui định. "Order chỉ" phụ thuộc được đặt sau một |
:
%: %.ext | %-clean
Đó là đáng nói đến là một trong những thế mạnh lớn nhất Make là nó có thể tiết kiệm thời gian bằng cách không lặp đi lặp lại công việc mà không cần phải được lặp đi lặp lại - tức là, nó chỉ chạy một quy tắc nếu các phụ thuộc mới hơn mục tiêu.Vì vậy, bạn có thể rời khỏi sự phụ thuộc vào %-clean
, mà có thể gây ra làm để chỉ chạy compiler $< -O2 --make
nếu %.ext
mới hơn %
:
%: %.ext
compiler $< -O2 --make
Sau đó, bạn có thể thêm một quy tắc chỉ để chạy tất cả các %-clean
mục tiêu:
.PHONY: all $(TASKS) $(TASKS:run=clean) clean
clean: $(TASKS:run=clean)
Điều cuối cùng: Tôi sử dụng một số biến đặc biệt trong công thức nấu ăn. [email protected]
là viết tắt của mục tiêu đang được xây dựng. $<
là viết tắt của sự phụ thuộc đầu tiên. $*
là viết tắt của "gốc" của quy tắc mẫu (tức là phần khớp với %
).
Giải thích hay. Cảm ơn! –
Cung cấp ví dụ về "|" thật tuyệt, cảm ơn. –