Làm cách nào để tôi có thể tạo một biến ngay lập tức từ makefile, giá trị của biến này sẽ là toàn bộ nội dung của một tệp dữ liệu khác.
Câu trả lời:
Tôi đoán rằng bạn muốn đặt một biến trong Makefile của mình thành nội dung của một tệp khác:
FILE=test.txt
VARIABLE=`cat $(FILE)`
target:
echo $(VARIABLE)
VARIABLE
là một chuỗi cat $(FILE)
(trong dấu ngoặc kép) chỉ được mở rộng trong một công thức bởi shell. Hãy thử in giá trị của nó như thế nào $(info ${VARIABLE})
.
VARIABLE
như một lời hứa. Đây là phiên bản duy nhất hoạt động với các phiên bản cũ hơn của make
. Cả hai :=
và $(shell ...)
đều là phần mở rộng GNU.
cat
mỗi khi quy tắc được thực thi. Điều này thường không được dự kiến và cần được cảnh báo, vì nó chậm. Ngoài ra, nếu tập tin là một đường ống, nó có tác dụng phụ không mong muốn. Việc gán phải được thực hiện với :=
để quy tắc sẽ không được đánh giá khi biến được thay thế nhưng khi biến được xác định. Giá trị thay thế phải là $(shell cat $(FILE))
để cat
lệnh được thực thi tại chỗ bởi make, không phải sau đó bởi các quy tắc công thức.
cat
các quy tắc thay thế phức tạp thay vì phức tạp sẽ làm cho các tệp trang điểm của bạn dễ hiểu hơn nhiều và gần như có thể di động hoặc đôi khi di động hơn.
Giả sử GNU thực hiện:
file := whatever.txt
variable := $(shell cat ${file})
GNU make phiên bản 4.2 hỗ trợ thao tác đọc tệp, vì vậy đối với câu trả lời tuyệt vời của Maxim Egorushkin , hiện có một cách tùy chọn để giải quyết vấn đề này:
FILE := test.txt
variable :=$(file < $(FILE))
cat
không tồn tại trên Windows. Giải pháp hoạt động cho Linux và Windows:
cat := $(if $(filter $(OS),Windows_NT),type,cat)
variable := $(shell $(cat) filename)
Giải thích: Có vẻ như trên Windows luôn có OS
biến môi trường được định nghĩa bằng 'Windows_NT'. Theo cách này, type
lệnh cho Windows được sử dụng, cho không phải Windows cat
được sử dụng.
Đơn giản hơn nhiều kể từ khi $(file op filename)
được thêm vào:
VARIABLE = $(file < my_file.txt)
Trang hướng dẫn sử dụng tại đây: https://www.gnu.org/software/make/manual/html_node/File-Function.html#index-file_002c-reading-from
Nếu bạn đang sử dụng GNU make, một cách khác để có được hiệu ứng này là sử dụng make "include" của một makefile khác:
Từ Makefile:
include "./MyFile.mak"
Tạo tệp "MyFile.mak" với nội dung:
FILE := "my file content"
FILE += "more content 1"
FILE += "more content 2"
Makefile:1: "./MyFile.mak": No such file or directory
make -v
choGNU Make 3.81
include ./MyFile
Đây là một giải pháp di động hơn, hoạt động với MAKE
phiên bản 3, khi file
không có chỉ thị. Nhược điểm là nó yêu cầu tạo một tệp tạm thời trong quá trình này.
$(shell echo define my_variable > file.tmp)
$(shell cat my_file.txt >> file.tmp)
$(shell echo endef >> file.tmp)
include file.tmp
Ý tưởng chính là sử dụng define
chỉ thị, được thiết kế đặc biệt để khai báo các biến đa dòng. Tất nhiên, bạn có thể tránh sử dụng shell
và một tệp tạm thời nếu bạn có thể ghi rõ ràng nội dung tệp để sử dụng Makefile.
Hãy nhớ rằng, nếu tệp của bạn chứa $
các dấu hiệu, MAKE
sẽ cố gắng mở rộng chúng dưới dạng các biến / chỉ thị khi my_variable
được mở rộng (hoặc khi được gán, bạn định nghĩa nó bằng :=
). Nếu bạn muốn tránh nó, bạn cần phải thoát khỏi chúng trước khi đưa vào nội dung tệp. Ví dụ, thay vì cat
bạn có thể làm điều này:
$(shell sed 's/\$$/$$$$/g' my_file.txt >> file.tmp)