2012-02-20 37 views
5

trong kernel MakefileMakefile lỗi quy tắc: *** hỗn hợp tiềm ẩn và bình thường quy tắc

# Modules                                            
/%/: prepare scripts FORCE 
    $(cmd_crmodverdir) 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ 
    $(build)=$(build-dir) 
%.ko: prepare scripts FORCE 
    $(cmd_crmodverdir) 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ 
    $(build)=$(build-dir) $(@:.ko=.o) 
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost 

gây ra lỗi quy tắc ngầm và bình thường hỗn hợp Makefile. (đến chuỗi đầu tiên trên mã được cung cấp)

Tôi nghĩ có điều gì đó sai với cú pháp /%/, làm cách nào để sửa chữa?

cho đến nay tôi đang suy nghĩ về tách quy tắc theo cách này:

# Modules                                            
/: prepare scripts FORCE 
    $(cmd_crmodverdir) 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ 
    $(build)=$(build-dir) 
%/: prepare scripts FORCE 
    $(cmd_crmodverdir) 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ 
    $(build)=$(build-dir) 
%.ko: prepare scripts FORCE 
    $(cmd_crmodverdir) 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ 
    $(build)=$(build-dir) $(@:.ko=.o) 
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost 

Nhưng nó khó hiểu đối với tôi.

Trả lời

4

Bạn nghĩ quy tắc / %/ đang làm gì (ngoài việc gây nhầm lẫn cho bạn và make - và tôi)? Bạn đang cố gắng đạt được điều gì với bit %/?

Bạn có thể có hai (hoặc nhiều) mục tiêu ở bên trái dấu hai chấm, nhưng cả hai đều cần phần trăm ít hơn.

prog1 prog2: something 
    $(CC) -o [email protected] [email protected] ${LIBRARIES} 

Các metacharater % không thể được sử dụng với một quy tắc mà không cần bất kỳ % trong nó, nhưng make được giải thích:

/ %/: 

như giống như ví dụ prog1 prog2, nhưng một trong những mục tiêu có một % và cái kia thì không, và bạn không được phép trộn chúng lại. Quy tắc / là quy tắc rõ ràng; nó xuất hiện để được hướng dẫn về cách cập nhật thư mục gốc của hệ thống của bạn. %/ là quy tắc ngầm; nó có thể làm một cái gì đó liên quan đến việc làm cho các thư mục được cập nhật.


Sao chép một số tài liệu lên từ nhận xét:

DIRECTORY_BUILD_RULES = \ 
    $(cmd_crmodverdir); \ 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(build-dir) 

/: prepare scripts FORCE; $(DIRECTORY_BUILD_RULES) 

%/: prepare scripts FORCE; $(DIRECTORY_BUILD_RULES) 

Ký hiệu này nên làm việc (đó là lý do tôi đã sử dụng nó trong các bình luận), nhưng những gì tôi muốn viết trong một makefile là:

DIRECTORY_DEPENDENCIES = prepare scripts FORCE 
DIRECTORY_BUILD_RULES = \ 
    $(cmd_crmodverdir); \ 
    $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(build-dir) 

/: $(DIRECTORY_DEPENDENCIES) 
    $(DIRECTORY_BUILD_RULES) 

%/: $(DIRECTORY_DEPENDENCIES) 
    $(DIRECTORY_BUILD_RULES) 

Nếu điều này vẫn gây ra sự cố, hãy xem lại quy tắc đầu tiên (/:) là gì. Bạn có chắc chắn nó là cần thiết?

+0

Tốt nhưng giải pháp của tôi có chính xác không? Theo như tôi hiểu tôi cần phải tách nó theo cách này nhưng chạy cùng làm cho 2 lần là trông kỳ lạ đối với tôi. – Cynede

+2

Có; sự tách biệt sẽ là cần thiết. Có, viết ra các quy tắc tương tự hai lần không phải là tuyệt vời. Có thể tạo macro cho các hành động và sau đó sử dụng macro đó trong các quy tắc. 'DIRECTORY_BUILD_RULES = $ (cmd_crmodverdir); $ (Q) $ (MAKE) KBUILD_MODULES = $ (nếu $ (CONFIG_MODULES), 1) $ (build) = $ (build-dir) ', sau đó:' /: chuẩn bị tập lệnh FORCE; $ (DIRECTORY_BUILD_RULES) 'và'% s: chuẩn bị tập lệnh FORCE; $ (DIRECTORY_BUILD_RULES) '. Bạn thậm chí có thể làm cho danh sách phụ thuộc vào macro khác ... –

+0

bây giờ nó nói: Biến đệ quy 'DIRECTORY_BUILD_RULES 'tham chiếu chính nó (cuối cùng). Dừng lại. – Cynede