2011-08-16 25 views
24

thể trùng lặp:
GNU Makefile rule generating a few targets from a single source fileGNU thực hiện: Nhiều mục tiêu trong một quy tắc đơn

Nếu tôi có một quy tắc Makefile như thế này:

a b c: 
    echo "Creating a b c" 
    touch a b c 

output: a b c 
    cat a b c > output 

và tôi chạy make -j9 output

làm cho thấy 3 phụ thuộc (a, b, c), tìm cách tạo ra chúng: (quy tắc "a b c" ở trên), nhưng điều gì xảy ra tiếp theo? Nếu nó không nhận ra rằng quy tắc "a b c" chỉ cần chạy một lần để tạo ra tất cả 3 mục tiêu?

Đây là những gì làm cho thực sự thực hiện:

[[email protected] test]$ make -j9 output -n 
echo "Creating a b c" 
touch a b c 
echo "Creating a b c" 
touch a b c 
echo "Creating a b c" 
touch a b c                                                                  
cat a b c > output                                                                
[[email protected] test]$ 

Các công thức tương tự được chạy 3 lần, một lần cho mỗi phụ thuộc vào quy tắc "đầu ra"!

Có ai biết tại sao ứng dụng này hoạt động theo cách này không?

+0

Related: http: // stackoverflow.com/questions/3016258/tạo-nhiều mục tiêu-sử dụng-đơn-hành động-quy tắc và http://stackoverflow.com/questions/2973445/gnu-makefile-rule-generating-a-few-targets-from-a- single-source-file – krlmlr

Trả lời

27

quy tắc a b c: bạn nói Làm cho rằng đây là cách để xây dựng bất kỳ của các mục tiêu này, không làm thế nào để xây dựng tất cả trong số họ. Thực hiện không đủ thông minh để phân tích các lệnh và suy ra rằng chạy quy tắc một lần sẽ xây dựng cả ba. Hãy biết (từ quy tắc output) rằng nó phải xây dựng lại a, bc, do đó, đó là những gì nó làm. Quy tắc chạy quy tắc đầu tiên một lần cho a, một lần cho b và một lần cho c.

Nếu bạn muốn xây dựng lại chúng riêng rẽ, làm điều này:

a b c: 
    echo "Creating [email protected]" 
    touch [email protected] 

Nếu bạn muốn xây dựng lại tất cả chúng cùng một lúc, làm một cái gì đó như thế này:

.PHONY: things 
things: 
    echo "Creating a b c" 
    touch a b c 

output: things 
    cat a b c > output 

hay vẫn tốt hơn:

THINGS = a b c 
.PHONY: things 
things: 
    echo "Creating $(THINGS)" 
    touch $(THINGS) 

output: things 
    cat $(THINGS) > output 
+2

Câu trả lời hay! Cảm ơn bạn. Tạo ra một mục tiêu giả tạo theo cách duy nhất, hoặc là có một cách sạch hơn để diễn tả "a ** và ** b ** và ** c được xây dựng theo quy tắc này"? – Pavel

+0

@Pavel, tôi không biết cách nào rõ ràng hơn (và có lẽ tôi sẽ chọn tùy chọn đầu tiên). Nhưng rồi tôi vẫn cố gắng tìm ra câu trả lời của AUZKamath. – Beta

+12

Xem http://www.cmcrossroads.com/ask-mr-make/12908-rules-with-multiple-outputs-in-gnu-make để khảo sát các phương pháp xử lý tình huống này, bao gồm chỉ "đúng" cách để xác định một quy tắc với nhiều đầu ra trong gmake (các quy tắc mẫu, tất nhiên!). –

6

abc là ba mục tiêu/mục tiêu khác nhau không có điều kiện tiên quyết. i, e để nói rằng nó sẽ xây dựng mục tiêu bất cứ khi nào nó được yêu cầu.

a b c: 
    echo "Creating a b c" 
    touch a b c 

Bạn đang yêu cầu tạo mục tiêu có tên đầu ra có b là điều kiện tiên quyết. Vì vậy, mục tiêu một b c được xây dựng tuần tự và cuối cùng đầu ra được xây dựng.

Bây giờ trong trường hợp của bạn, tất cả các mục tiêu được xây dựng không thay đổi khi một trong hai mục tiêu được gọi. Vì vậy, để tránh xây dựng dư thừa, bạn sẽ phải thêm điều kiện tiên quyết vào các mục tiêu a, b, c. Chỉ tạo mục tiêu 'a' nếu 'a' không tồn tại. Tương tự đối với 'b' và 'c'

a b c: [email protected] 
    echo "Creating a b c" 
    touch a b c 

Tuy nhiên điều này không được khuyến khích. Mục tiêu Makefile lý tưởng phải rất cụ thể.

+2

Tác phẩm này hoạt động nhưng tôi không thể thấy được. Jack Kelly đã gửi cho bạn? – Beta

+1

Tuy nhiên, khi chạy lệnh này với 'make -j3 a b c', ba công việc được tạo ra. – krlmlr

+2

Ai có thể giải thích cách thức hoạt động của nó? Tôi không thể giải thích bằng cách đọc https://www.gnu.org/software/make/manual/make.html#index-_0024_0040 – Xiphias

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