2013-02-21 34 views
6

Có cách nào để lấy khoảng trắng bên trong tên mục tiêu hoạt động khi sử dụng make.exe không? Nó có vẻ là bất khả thi nếu báo cáo lỗi thực sự cổ này là đúng: http://savannah.gnu.org/bugs/?712Cho phép không gian trong mục tiêu của GCC makefile

Để tham khảo, vấn đề lớn là mảnh makefile lệnh như:

"foo bar baz": $(OBJ) 
    $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) 

... dường như được coi là ba lệnh riêng biệt: một để xây dựng "foo (lưu ý bao gồm"), một để xây dựng thanh, và cuối cùng, một để xây dựng baz "(một lần nữa, bao gồm cả"). Điều này là do make.exe dường như đang sử dụng không gian làm dấu phân tách.

Tuy nhiên, bạn nên giả định rằng người ta có thể muốn tạo "Hello World.exe" chẳng hạn. Điều này dường như không thể. Dấu ngoặc kép không hoạt động và không thoát khỏi các từ riêng biệt (tôi đã đọc ở đâu đó, không nhớ liên kết):

"foo\\ bar\\ baz": $(OBJ) 
    $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) 

Còn cách nào khác để sửa lỗi này không? Hướng dẫn chính thức duy nhất khẳng định những thứ tokenize-by-không gian, nhưng không cung cấp một cách để sử dụng không gian cho bất kỳ mục đích nào khác: http://www.gnu.org/software/make/manual/make.html#Rule-Syntax

Edit: như đề nghị, tôi đã cố gắng dấu gạch chéo đơn quá, nhưng chúng có cùng hiệu ứng giống như hai dấu gạch chéo. Khiếu nại không thể tìm thấy các quy tắc cho từ đầu tiên:

mingw32-make.exe: *** No rule to make target `foo', needed by `all'. Stop. 

Thực thi chính xác "foo bar baz.exe" được tạo đúng cách nhưng liên kết được thực hiện mỗi lần cho mỗi từ.

Trả lời

1

Thay vì sử dụng dấu gạch chéo ngược kép. Các Makefile sau làm việc (ít nhất là cho làm gnu):

goal: foo\ bar 

foo\ bar: 
    gcc -o "foo bar" "foo bar.c" 
+0

Điều đó dường như không hoạt động, hãy xem bản chỉnh sửa. – Orwell

+0

@Orwell: Sau đó, nó có vẻ là một vấn đề của hệ điều hành. Làm thế nào để bạn chỉ định một tập tin với không gian trong tên tại vỏ của bạn? – Matthias

1

như Matthias nói, đó là một vấn đề "\", nhưng các dấu nháy kép quá. Dưới đây là cách tôi succeded vào đây:

EXECUTABLE=foo\ bar\ baz 
all: $(SOURCES) $(EXECUTABLE) 
$(EXECUTABLE): $(OBJECTS) 
       $(CC) $(OBJECTS) -o "[email protected]" $(LDFLAGS) 

Lưu ý các dấu ngoặc kép quanh $ @ Dường như với tôi rằng khi làm đạt được mục tiêu "$ (thực thi)" nó mở rộng "\", do đó lệnh dòng trở thành

gcc file.o -o foo bar baz -LFlags 

không phải là thứ bạn muốn, bạn muốn báo giá kép xung quanh tên tệp.

Bây giờ bạn đang ở trên cửa sổ và tôi không nhớ cách nó đề với không gian trong tên, như Matthias nói, trước tiên hãy kiểm tra cách "cmd.exe" giao dịch với không gian (ngoại trừ tên xung quanh với dấu ngoặc kép ...)

0

Có thể dễ dàng xem xét một Makefile đơn giản hơn, bỏ qua các phụ thuộc trong lời gọi targetRule: dependencies tiêu chuẩn. OP là dành cho Windows và bên dưới được thực hiện trên Linux trong vỏ bash; nhưng có lẽ nó nên được áp dụng cho Windows bằng cách sử dụng vỏ bash qua cygwin, tôi đoán vậy.Tôi đã điều sau đây trong Makefile của tôi (lưu ý, cần có một TAB trước echo lệnh, mà SO chuyển thành khoảng trống):

testA: 
    echo "testA" 

unrelated: 
    echo "unrelated" 

testA\ clean: 
    echo "testA clean" 

clean: 
    echo "clean" 

Nếu tôi gọi make với mục tiêu clean hoặc testA tại nhà ga bash vỏ , tôi nhận được kết quả mong đợi:

$ make testA 
echo "testA" 
testA 
$ make clean 
echo "clean" 
clean 

Bây giờ, nếu tôi gọi make testA clean chỉ viết như là, vỏ bash sẽ chia các đối số tại chỗ, vì vậy make sẽ nhận hai đối số, và sẽ chạy chúng một cách riêng biệt:

$ make testA clean 
echo "testA" 
testA 
echo "clean" 
clean 

... nhưng nếu tôi quấn mục tiêu cung cấp cho make trong dấu ngoặc kép - hoặc nếu tôi thoát khỏi không gian - vỏ sẽ hiểu rằng nó là vụ phải là một đối số duy nhất với một không gian bên trong, và sẽ tuyên truyền nó như vậy để make, mà sẽ tiến hành thực hiện những gì được viết dưới dạng các quy tắc testA\ clean mục tiêu:

$ make "testA clean" 
echo "testA clean" 
testA clean 
$ make testA\ clean 
echo "testA clean" 
testA clean 

một hệ quả của việc này, đó là không may bạn không thể " TAB "tại dòng lệnh để tự động hoàn thành testA\ clean; nếu bạn nhập make teTAB tại dòng lệnh, chỉ testA sẽ tự động được hoàn thành (và testA\ clean sẽ không được hiển thị dưới dạng tùy chọn tự động điền).

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