2011-06-29 34 views
14

Sự cố với hàm dep2 trong mã mẫu dưới đây là gì?Xác định các chức năng tùy chỉnh của GNU

dep1 = $(eval makefile_list_$1 := $(MAKEFILE_LIST))$(eval -include $1.mk)$(eval MAKEFILE_LIST := $(makefile_list_$1)) 

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)) 
$(eval -include $1.mk) 
$(eval MAKEFILE_LIST := $(makefile_list_$1)) 
endef 

$(call dep1,test) 
$(call dep2,test) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

GNU tạo 3.81 và 3.82 sản xuất Makefile:10: *** missing separator. Stop. trỏ đến lệnh dep2, dep1 chạy không có lỗi. Sự khác biệt duy nhất giữa hai biến thể là các dòng mới trong dep2 (và toàn bộ lý do tại sao tôi muốn sử dụng định nghĩa).

Trả lời

6

Bạn quên =:
xác định dep2 =

EDIT:
Đặt một dấu chấm phẩy ở cuối mỗi dòng. Tôi đã thử nghiệm này và nó hoạt động (trong GNUMake 3,81).

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)); 
$(eval -include $1.mk); 
$(eval MAKEFILE_LIST := $(makefile_list_$1)); 
endef 

Tại sao những dấu chấm phẩy là cần thiết Tôi không biết, nhưng trong tài liệu define dường như được sử dụng cho nhiều dòng "biến" chỉ khi xác định trình tự của vỏ lệnh được sử dụng trong công thức nấu ăn, không Thực hiện các lệnh, vì vậy có thể các quy tắc hơi khác một chút.

+0

Không, '=' là tùy chọn (và chỉ được giới thiệu với GNU tạo thành 3,82). Thêm nó không tạo sự khác biệt. –

+0

@ g.b .: Bạn có thực sự thử không? Tôi đã làm (với GNU làm cho 3,81), và nó đã làm cho một sự khác biệt. Nó hoạt động như mong đợi đối với tôi, nếu tôi thêm '='. – eriktous

+4

@eriktous: Có, tôi đã thử với 3.82. Các phiên bản cũ hơn sẽ hoàn toàn bỏ qua câu lệnh define nếu nó được theo sau bởi '=', đó là lý do tại sao bạn không nhận được thông báo lỗi. –

-1

Có nhiều thứ có thể được cải thiện trong những gì bạn đang làm. Đối với một điều bạn thực sự muốn yếu tố eval cuộc gọi đến một cuộc gọi duy nhất ở đầu trang.

Vấn đề cụ thể của bạn, tuy nhiên, bắt nguồn từ việc không hiểu rằng chuỗi đệ quy nhiều dòng lệnh xác định của lệnh make không bao gồm dòng mới của phụ nữ. Quy ước tự nhiên nhất để viết các chức năng evalable là

xác định Foo Line1 Line2

endef

Bạn có thể nhìn vào eval chuỗi được nhìn thấy và nhìn thấy điều này không thông qua lệnh thông tin, ví dụ $ (thông tin $ (gọi Foo, x) $ (gọi Foo, y)).

1

Tôi sẽ di chuyển các cuộc gọi $(eval ...) bên ngoài dep2. Bằng cách làm theo cách này, không cần dấu chấm phẩy trong dep2. Điều này có nghĩa là tăng gấp đôi các dấu hiệu mở rộng của $ để mở rộng quá sớm. Vì vậy:

define dep2 
makefile_list_$1 := $$(MAKEFILE_LIST) 
-include $1.mk 
MAKEFILE_LIST := $$(makefile_list_$1) 
endef 

$(eval $(call dep2,test)) 

# Quick checks for testing, to be removed from the final code... 
$(info $(makefile_list_test)) 
$(info $(MAKEFILE_LIST)) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

Tôi đã thử nghiệm mã ở trên và nó hoạt động với Gnu Make 4.0. Tôi hy vọng nó sẽ hoạt động trở lại Gnu Hãy 3.8x. Mẫu $(eval $(call ...)) là những gì tôi luôn làm để thực hiện các chức năng tùy chỉnh của mình và tôi đã sử dụng nó trong một thời gian dài.

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