2014-04-27 14 views
15

Làm cách nào và khi nào tôi trích dẫn một chuỗi trong tệp tạo? Thực hành tốt nhất là gì?GNU makefile cách thức và thời điểm trích dẫn các chuỗi

Dưới đây là cách báo giá?

$(warning $(shell ls -ld "$(CURDIR)")) 

Tôi quen thuộc với Bash nơi bạn thường trích dẫn các biến để cho phép các không gian được nhúng. Bạn làm như vậy trong một makefile?

Tôi nên làm như thế nào với một chuỗi?

vara := "$(CURDIR)" 

varb := $(CURDIR) 

varc := /home/me/source 

vard := "/home/me/source" 

Còn khoảng trống sau khi bằng nhau thì sao?

Trả lời

14

Bạn không bao giờ nên trích dẫn bất cứ điều gì vì thực hiện. Làm cho không hiểu hoặc phân tích cú pháp các ký tự đơn hoặc kép trong bất kỳ cách nào. Mỗi ký tự trích dẫn bạn viết trong một tệp makefile sẽ được giữ như là một trích dẫn theo nghĩa đen và được truyền đi theo các lệnh thực hiện lời gọi.

Vì vậy, nếu trình bao mong đợi và có thể diễn giải chuỗi được trích dẫn, thì bạn nên sử dụng dấu ngoặc kép. Trong trường hợp shell không mong đợi hoặc sẽ không diễn giải chính xác chuỗi được trích dẫn, bạn không nên sử dụng dấu ngoặc kép.

Trong ví dụ của bạn, cho dù có dấu ngoặc kép là có thể chấp nhận hay không phụ thuộc vào cách các biến là sử dụng. Như trên, làm cho sẽ không làm bất cứ điều gì đặc biệt với dấu ngoặc kép, có nghĩa là vard (ví dụ) chứa chuỗi chữ "/home/me/source" (bao gồm cả dấu ngoặc kép).

Nếu bạn sử dụng giá trị đó một cách hợp vỏ sẽ xử lý các dấu ngoặc kép cho bạn, sau đó nó là tốt:

all: ; echo $(vard) 

sẽ in /home/me/source (không có dấu ngoặc kép) vì vỏ diễn giải chúng. Nhưng nếu bạn sử dụng các biến trong một làm bối cảnh, ví dụ như một mục tiêu hoặc một điều kiện tiên quyết:

all: $(vard) 
$(vard): ; echo [email protected] 

thì đây là không đúng, bởi vì mục tiêu và điều kiện tiên quyết là những chuỗi chữ "/home/me/source" (bao gồm dấu ngoặc kép) .

Nói chung tốt nhất là không sử dụng dấu ngoặc kép xung quanh tên tệp trong các biến và thay vào đó, hãy thêm dấu ngoặc kép trong công thức quanh biến số thực hiện. Tất nhiên nếu biến chứa toàn bộ tập lệnh shell, không chỉ là tên tệp, thì bạn nên thêm trích dẫn thích hợp vào tập lệnh.

+0

ifequ "$ (varx)" "a" là nguồn gây nhầm lẫn một phần cho tôi. – historystamp

+0

Một lần xuất hiện của điều này là _make_ không thể tuân thủ các khoảng trống trong tên tệp. Không gian là dấu tách danh sách và — như MadScientist chỉ ra — không được trích dẫn. _make_ thường chia nhỏ một tên tập tin thành những mảnh vô dụng. – bobbogo

+1

có thể không liên quan đến ý định của OP, nhưng những người dùng khác có thể hạ cánh tại đây và không hiểu sự khác biệt giữa _make variables_ như '$ (VARX)' và _shell variables_ như '$$ {VARZ}' - lưu ý ký hiệu đô la đôi '$ $ 'sử dụng để phân biệt giữa chúng _ và so_ trong tình huống khi bạn muốn chuyển một biến shell vào một lệnh dưới dạng biến ** mà không mở rộng ** thì bạn có thể muốn sử dụng dấu nháy đơn, EG: truyền' $ ORIGIN' với trình liên kết, sau đó sử dụng 'cc -Wl, -rpath = '$$ {ORIGIN}' -shared -fPIC -Wall $ (SRC) -o $ (DIR)/$ (LIB)' với dấu nháy đơn để giữ nó khỏi mở rộng trong vỏ. –

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