Đôi khi bạn cần một Makefile để có thể chạy trên các hệ điều hành mục tiêu khác nhau và bạn muốn quá trình xây dựng bị lỗi sớm nếu không có tệp thực thi được yêu cầu PATH
thay vì chạy trong một thời gian dài trước khi thất bại.
Giải pháp tuyệt vời do kỹ sưchuan cung cấp đòi hỏi phải tạo ra một mục tiêu . Tuy nhiên, nếu bạn có nhiều tệp thực thi để kiểm tra và Makefile của bạn có nhiều mục tiêu độc lập, mỗi mục tiêu yêu cầu kiểm tra, thì mỗi mục tiêu yêu cầu mục tiêu kiểm tra như một phụ thuộc. Điều đó làm tăng thêm nhiều thời gian nhập cũng như xử lý khi bạn thực hiện nhiều mục tiêu cùng một lúc.
Giải pháp do 0xf cung cấp có thể kiểm tra tệp thực thi mà không cần tạo mục tiêu. Điều đó giúp tiết kiệm rất nhiều thời gian nhập và thực thi khi có nhiều mục tiêu có thể được xây dựng riêng biệt hoặc cùng nhau.
Cải tiến của tôi đối với giải pháp thứ hai là sử dụng which
tệp thực thi ( where
trong Windows), thay vì dựa vào việc có một --version
tùy chọn trong mỗi tệp thực thi, trực tiếp trong ifeq
chỉ thị GNU Make , thay vì xác định một biến mới và sử dụng GNU Make error
chức năng để dừng quá trình xây dựng nếu không có tệp thực thi bắt buộc ${PATH}
. Ví dụ: để kiểm tra lzop
tệp thực thi:
ifeq (, $(shell which lzop))
$(error "No lzop in $(PATH), consider doing apt-get install lzop")
endif
Nếu bạn có một số tệp thực thi cần kiểm tra, thì bạn có thể muốn sử dụng một foreach
hàm với which
tệp thực thi:
EXECUTABLES = ls dd dudu lxop
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
Lưu ý việc sử dụng :=
toán tử gán được yêu cầu để buộc đánh giá biểu thức RHS ngay lập tức. Nếu Makefile của bạn thay đổi PATH
, thì thay vì dòng cuối cùng ở trên, bạn sẽ cần:
$(if $(shell PATH=$(PATH) which $(exec)),some string,$(error "No $(exec) in PATH")))
Điều này sẽ cung cấp cho bạn đầu ra tương tự như:
ads$ make
Makefile:5: *** "No dudu in PATH. Stop.