2015-11-10 24 views
5

Tôi đã sử dụng các quy tắc lạ như thế này trong một thời gian dài, nhưng đột nhiên họ đang phá vỡ môi trường mới.% và * cùng nhau trên dòng phụ thuộc

Có cách nào hiệu quả để thực hiện việc này không?

all: test.1.out 

test.%.out: %/test*.out 
    /bin/cp -f $< [email protected] 

Trên hộp của tôi (ubuntu):

alishan:~/Dropbox/make_insanity> make --version 
GNU Make 3.81 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. 
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. 

This program built for x86_64-pc-linux-gnu 
alishan:~/Dropbox/make_insanity> make 
/bin/cp -f 1/test.out test.1.out 

Không có vấn đề với loại mã này trên máy Mac của người khác, máy ubuntu, ubuntu máy ảo. Không biết tất cả các phiên bản của họ, nhưng nó có vẻ giống như mã OK.

Trên máy chủ mageia của tôi trong cùng một thư mục sau khi xóa.

[[email protected] make_insanity]$ make --version 
GNU Make 3.82 
Built for x86_64-mageia-linux-gnu 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. 
[[email protected] make_insanity]$ make 
make: *** No rule to make target `test.1.out', needed by `all'. Stop. 
[[email protected] make_insanity]$ 

Thay đổi hoặc các % hoặc * cho văn bản "sửa chữa" thích hợp vấn đề, nhưng dĩ nhiên không tạo ra tính tổng quát mong muốn.

+0

Đã được đề xuất với tôi rằng thay đổi từ thực hiện 3,81 đến 3,82 là thủ phạm có khả năng xảy ra. Tôi nhìn vào các ghi chú phát hành nhưng không tìm thấy bất cứ điều gì dường như áp dụng. https://lists.gnu.org/archive/html/make-alpha/2010-07/msg00025.html –

Trả lời

1

Tôi không hoàn toàn chắc chắn nhưng tôi nghĩ rằng bạn muốn

test.<name>.out 

phải được thực hiện từ

<name>/test.out 

(nếu nó tồn tại). Nếu đúng, bạn có thể làm điều đó một cách mạnh mẽ bằng kỹ thuật đảo ngược tên của điều kiện tiên quyết cho từng mục tiêu từ tên của mục tiêu, ví dụ:

targs := test.1.out test.a.out 

define src_of = 
$(patsubst .%,%,$(suffix $(basename $(1))))/$(basename $(basename $(1)))$(suffix $(1)) 
endef 

all: $(targs) 

test.%.out: $(call src_of,test.%.out) 
    cp -f $< [email protected] 

clean: 
    rm -f *.*.out 

Đó là một chút của một miệng, thừa nhận.

Vì vậy, nếu chúng ta trước sắp xếp một bản demo mà điều kiện tiên quyết tồn tại:

$ ls -LR 
.: 
1 a Makefile 

./1: 
test.out 

./a: 
test.out 
$ make 
cp -f 1/test.out test.1.out 
cp -f a/test.out test.a.out 
+0

Cảm ơn. Đó là hữu ích trong việc học các công cụ thú vị về thực hiện, nhưng tôi có thể thực hiện điều đó bằng cách sử dụng quy tắc ban đầu mà không có *. Ngoài ra, trong ứng dụng cụ thể này, điều quan trọng là các quy tắc có thể đọc được. Quy tắc đơn giản này đã hoạt động trong một thời gian trên nhiều nền tảng khác nhau. Sẽ tốt hơn nếu tôi có thể cứu nó bằng một cái gì đó đơn giản. –

0

Bạn có thể làm điều này bằng secondary expansion và chức năng đại diện. Lưu ý rằng nó không bao giờ hợp lệ mà không có điều này, vì vậy bất kỳ mã nào bạn thấy điều này là nên được coi là bị hỏng.

.SECONDEXPANSION: 

all: test.1.out 

test.%.out: $$(wildcard $$*/test*.out) 
    @echo Prerequisites found: $^ 

Lưu ý việc sử dụng $* hơn % cho phù hợp với mô hình (xem automatic variables) đang bỏ trốn bằng cách thêm một $, và toàn bộ điều được thiết lập để mở rộng gấp đôi vì vậy cả hai bộ giá trị được mở rộng.

Điều đó đang được nói toàn bộ bố cục này có vẻ sai. Bạn đang sử dụng $< chỉ khớp với từ đầu tiên của các điều kiện tiên quyết ngay cả khi có ký tự đại diện, bạn có thể có rất nhiều thẻ. Mike's answer có lẽ là một đặt cược tốt hơn khi tổ chức lại Makefile của bạn để thực sự mạnh mẽ.

+0

Cảm ơn.Đó là những gì tôi đã mong muốn. Tôi hiểu cả hai bạn đang nói gì về cấu trúc. Trường hợp sử dụng cụ thể này liên quan đến việc cung cấp các tệp có tên không phù hợp trong thời gian thực, vì vậy tôi đã bị mắc kẹt với cấu trúc không tốt (tất nhiên là tôi có thể cố gắng khắc phục điều đó, nhưng tôi thường nghĩ đầu tiên cho mọi thứ). Tôi nên nói rằng ngay từ đầu. –

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