2010-11-08 17 views
42

Tôi muốn vô hiệu hóa các quy tắc và biến được xây dựng theo cách truyền -r and -R options để GNU tạo, từ bên trong tệp tạo. Các giải pháp khác cho phép tôi thực hiện điều này một cách rõ ràng và minh bạch cũng được hoan nghênh.Vô hiệu hóa các quy tắc và biến được xây dựng từ bên trong tạo tệp

Tôi đã tìm thấy several references để sử dụng MAKEFLAGS và gặp sự cố tương tự.

+2

Bạn không thực hiện một hệ thống xây dựng cthulhoid, bạn có Joiner? –

+0

Một trong rất nhiều, lần này nó tạo ra các tập tin cho sự song song tự do. Chuyển đổi sang C++ đã tăng gấp 10 lần thời gian xây dựng của tôi, điều này là không thể chấp nhận được. –

+4

"Chuyển đổi thành C++ ... không thể chấp nhận được". - Matt Joiner. ;-) –

Trả lời

29

Vô hiệu hóa các quy tắc được xây dựng-in được thực hiện bằng writing an empty rule for .SUFFIXES:

.SUFFIXES: 

Sau khi xóa các quy tắc được xây dựng-in, tôi không chắc chắn rằng xóa được xây dựng trong các biến giúp bạn nhiều hơn chỉ là nhớ tới tự đặt chúng hoặc không sử dụng chúng, nhưng bạn có thể sử dụng một cái gì đó như

$(foreach V 
    $(shell make -p -f/dev/null 2>/dev/null | sed -n '/^[^:#= ]* *=/s/ .*//p'), 
    $(if $(findstring default,$(origin $V)),$(eval $V=))) 

... được cho là khá điên rồ. Nếu có một cách để có được một danh sách các biến được định nghĩa từ bên trong make (thay vì bắn phá ra các biến khác), nó sẽ là khả thi. Vì nó là, nó không thực sự tốt hơn nhiều so

CC= 
CXX= 
# etc, for each likely built-in variable 
+0

Điều này là tốt đẹp, nhưng một chút quá hacky. –

+2

Tôi không nghĩ rằng điều này xử lý được xây dựng trong [phù hợp với bất kỳ quy tắc] (http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Rules) –

+1

[Có vẻ như] (https: //savannah.gnu.org/bugs/?20501) rằng trong một số phiên bản của GNU Make, việc xóa '.SUFFIXES' vô hiệu hóa các quy tắc _suffix dựng sẵn_ nhưng không phải là _pattern rules_ (xem câu trả lời của Brandon). Tuy nhiên, trong phiên bản GNU Make (3.81) '.SUFFIXES' của tôi xuất hiện đầy đủ. –

1

Bạn có thể bắt đầu Makefile với một #! và gọi nó là một cái gì đó khác nhau để mọi người không cố gắng sử dụng make trực tiếp:

#!/usr/bin/make -rRf 
# ... 

chí này gây ra các vấn đề khủng khiếp nếu GNU tạo ra không phải là hệ thống make. Có lẽ một kịch bản wrapper?

Bạn cũng có thể đọc $(MAKEFLAGS) và đảm bảo có các cờ bắt buộc.

+3

Tôi nghĩ bạn muốn '#!/Usr/bin/env make -rRf' ?. Ồ, tôi hiểu ý anh là gì. –

+0

'/ usr/bin/env' có lẽ tốt hơn. –

+0

Điều này sẽ không hoạt động và mang lại '/ usr/bin/env: 'make-rRf': Không có tệp hoặc thư mục' trên nhiều hệ thống (ví dụ như Linux) vì chỉ có một đối số tùy chọn duy nhất được hỗ trợ trên dòng shebang và không chia tách lệnh được thực hiện. Xem [tại đây] (https://en.wikipedia.org/wiki/Shebang_ (Unix) #Portability). –

4

này làm việc cho tôi:

# Disable implicit rules to speedup build 
.SUFFIXES: 
SUFFIXES := 
%.out: 
%.a: 
%.ln: 
%.o: 
%: %.o 
%.c: 
%: %.c 
%.ln: %.c 
%.o: %.c 
%.cc: 
%: %.cc 
%.o: %.cc 
%.C: 
%: %.C 
%.o: %.C 
%.cpp: 
%: %.cpp 
%.o: %.cpp 
%.p: 
%: %.p 
%.o: %.p 
%.f: 
%: %.f 
%.o: %.f 
%.F: 
%: %.F 
%.o: %.F 
%.f: %.F 
%.r: 
%: %.r 
%.o: %.r 
%.f: %.r 
%.y: 
%.ln: %.y 
%.c: %.y 
%.l: 
%.ln: %.l 
%.c: %.l 
%.r: %.l 
%.s: 
%: %.s 
%.o: %.s 
%.S: 
%: %.S 
%.o: %.S 
%.s: %.S 
%.mod: 
%: %.mod 
%.o: %.mod 
%.sym: 
%.def: 
%.sym: %.def 
%.h: 
%.info: 
%.dvi: 
%.tex: 
%.dvi: %.tex 
%.texinfo: 
%.info: %.texinfo 
%.dvi: %.texinfo 
%.texi: 
%.info: %.texi 
%.dvi: %.texi 
%.txinfo: 
%.info: %.txinfo 
%.dvi: %.txinfo 
%.w: 
%.c: %.w 
%.tex: %.w 
%.ch: 
%.web: 
%.p: %.web 
%.tex: %.web 
%.sh: 
%: %.sh 
%.elc: 
%.el: 
(%): % 
%.out: % 
%.c: %.w %.ch 
%.tex: %.w %.ch 
%: %,v 
%: RCS/%,v 
%: RCS/% 
%: s.% 
%: SCCS/s.% 
.web.p: 
.l.r: 
.dvi: 
.F.o: 
.l: 
.y.ln: 
.o: 
.y: 
.def.sym: 
.p.o: 
.p: 
.txinfo.dvi: 
.a: 
.l.ln: 
.w.c: 
.texi.dvi: 
.sh: 
.cc: 
.cc.o: 
.def: 
.c.o: 
.r.o: 
.r: 
.info: 
.elc: 
.l.c: 
.out: 
.C: 
.r.f: 
.S: 
.texinfo.info: 
.c: 
.w.tex: 
.c.ln: 
.s.o: 
.s: 
.texinfo.dvi: 
.el: 
.texinfo: 
.y.c: 
.web.tex: 
.texi.info: 
.DEFAULT: 
.h: 
.tex.dvi: 
.cpp.o: 
.cpp: 
.C.o: 
.ln: 
.texi: 
.txinfo: 
.tex: 
.txinfo.info: 
.ch: 
.S.s: 
.mod: 
.mod.o: 
.F.f: 
.w: 
.S.o: 
.F: 
.web: 
.sym: 
.f: 
.f.o: 

Đặt điều này trong một file có tên disable_implicit_rules.mk và include nó trong mỗi makefile.

4
################################################################ 
# DISABLE BUILT-IN RULES 
# 
.SUFFIXES: 
    MAKEFLAGS += -r 
+4

Tôi không chắc chắn tại sao phép gán biến đó lại được lồng nhau .... –

20

@hseldon có ý tưởng đúng vì .SUFFIXES không bao gồm các quy tắc ngầm được tích hợp sẵn. Tuy nhiên, tôi không nghĩ cú pháp của anh ấy là chính xác.

MAKEFLAGS += --no-builtin-rules 

.SUFFIXES: 
.SUFFIXES: .you .own .here 

Xem http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Ruleshttp://www.gnu.org/software/make/manual/make.html#index-g_t_002eSUFFIXES-998

+0

Điều đó không làm điều đó cho tôi. Tôi có một quy tắc. %: foo.o bar.o và trên thực hiện, hãy thực hiện "rm foo.o bar.o". Điều đó không biến mất với cài đặt cờ được đề xuất của bạn. –

+2

@VictorEijkhout: Điều đó không phải do các quy tắc tích hợp, mà là do [chuỗi quy tắc] (https://www.gnu.org/software/make/manual/html_node/Chained-Rules.html). Sử dụng '.SECONDARY' để ngăn xóa tự động. –

5

Vô hiệu hóa các quy tắc được xây dựng-in bằng cách viết một quy tắc trống cho .SUFFIXES không hoạt động nếu một sau đó viết khác .SUFFIXES quy tắc để thêm hậu tố được biết đến trước đó - các quy tắc tích hợp là đã bật lại. Ví dụ: Một người muốn xác định các quy tắc cho .c.i.i.o và để tắt quy tắc được tích hợp sẵn .c.o. Viết

.SUFFIXES: 
.SUFFIXES: .o .i .c 

không hoạt động - không ngăn quy tắc tích hợp .c.o không được áp dụng.

Giải pháp là một trong những nhân viên của Marc Eaddy và tài liệu trong GNU làm thủ công, 10.5.6 Canceling Implicit Rules:

Bạn có thể ghi đè lên một built-in quy tắc ngầm (hoặc một bạn đã xác định mình) bằng cách xác định quy tắc mẫu mới có cùng mục tiêu và các điều kiện tiên quyết, nhưng là một công thức khác. Khi quy tắc mới được xác định, cài đặt sẵn được thay thế. Vị trí của quy tắc mới trong chuỗi của các quy tắc ngầm định được xác định bởi nơi bạn viết quy tắc mới.

Bạn có thể hủy quy tắc ngầm được cài sẵn bằng cách xác định quy tắc mẫu với cùng mục tiêu và điều kiện tiên quyết, nhưng không có công thức. Ví dụ, sau đây sẽ hủy bỏ các quy tắc mà chạy lắp ráp:

%.o : %.s