2012-03-08 40 views
7

Tôi muốn viết một cái gì đó dọc theo những dòng:GNU Make cho vòng lặp với hai biến

$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);) 

Làm thế nào để đi về việc này trong một makefile GNU?

+0

Bên trong một quy tắc, hoặc bên ngoài? – Beta

+0

Bên trong một quy tắc - –

+0

Cũng như tôi đang viết điều này ra một chặng đường dài tôi nhận ra tôi sẽ cần nó bên ngoài một quy tắc. –

Trả lời

8

Beta để sử dụng tham gia là đi đúng hướng, nhưng vấn đề là nó không phải dễ dàng như vậy để sử dụng nó trong một cách mà xây dựng một dòng lệnh có chứa khoảng trắng, ví dụ như một trong những bạn ban đầu muốn:

$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);) 

vì tham gia kết hợp các từ với nhau: ban đầu nó được dùng để xây dựng tên tệp. Tuy nhiên bạn có thể chơi một thủ thuật; đây là một ví dụ về cách sử dụng tham gia cung cấp cho bạn kết quả bạn đang tìm kiếm:

$(subst ^, ,$(join $(addprefix cp^,$(LIST1)),$(patsubst %,^%;,$(LIST2)))) 

Nếu bạn nghĩ rằng danh sách của bạn có thể chứa ^ ký tự sau đó chọn cái gì khác. Hãy cho tôi biết nếu bạn cần giải nén/giải nén này.

+0

Điều này làm việc cho tôi dựa trên câu hỏi trên. –

2
LIST1 := a b c 
LIST2 := 1 2 3 

# outside a rule: 
$(foreach var1, a b c, $(foreach var2, 1 2 3, $(info $(var1)_$(var2)))) 

# inside a rule: first line starts with a TAB, all the rest are spaces 
all: 
    @for x in $(LIST1);\ 
    do \ 
     for y in $(LIST2);\ 
     do\ 
     echo $$x $$y; \ 
     done \ 
    done 

(Xin lưu ý rằng một vòng lặp lồng nhau mà không cp không có ý nghĩa nhiều.)

EDIT:
Vâng tại sao anh không nói như vậy? đề nghị

LIST3 := $(join $(LIST1),$(LIST2)) 
+1

Yup vì tôi không muốn sản phẩm chéo tôi cần một ánh xạ một. Đó là những gì bộ não của tôi đi vào vòng lặp. –

+0

Sooooo ... bạn đã đánh dấu câu trả lời này là chính xác. Nó dường như không trả lời câu hỏi mà bạn có. Đây có phải là điều bạn muốn hay không? – MadScientist

+0

Đó không phải là câu trả lời tôi muốn, nhưng không ai trả lời sau một vài ngày, vì vậy tôi đánh dấu nó là câu trả lời chính xác nhất. Nếu bạn có câu trả lời hay hơn, hãy đăng bài. –

0

Đây là một ứng cử viên tốt cho gsml (GNU Make Standard Library). Bạn có thể bao gồm nó bằng cách đặt các tệp __gmslgml trong thư mục hiện tại (hoặc trong /usr/gnu/include, /usr/local/include/ v.v.) và thêm dòng include gsml vào Makefile của bạn. Nó bao gồm chức năng pairmap, thực hiện chính xác những gì bạn muốn (ví dụ: zipWith).

include gmsl 
cp2 = cp $1 $2; 
zip = $1 : $2 
$(LIST2): 
    @echo $(call pairmap, zip, $(LIST1), $(LIST2)) 
    $(call pairmap, cp2, $(LIST1), $(LIST2)) 

Đầu ra

$ make 
A : 1 B : 2 C : 3 D : 4 
cp A 1; cp B 2; cp C 3; cp D 4; 
Các vấn đề liên quan