2009-08-27 31 views
13

Tôi đang cố gắng viết một GNU tạo Makefile có tải trọng các mục tiêu tương tự, trong đó các lệnh xây dựng hơi khác nhau giữa chúng. Tôi đang cố gắng sử dụng target-specific variables để trình bày các biến thể này. Một số giá trị biến này đề cập đến các tệp mà tôi muốn sử dụng làm điều kiện tiên quyết. Ví dụ:Biến mục tiêu cụ thể là Điều kiện tiên quyết trong Makefile

target_1:special_filename=target1_prereq 
target_2:special_filename=target2_prereq 

target_1 target_2: common_filename $(special_filename) 
    do_something common_filename --a-weird-option=$(special_filename) 

Khi tôi gọi 'make target_1', tôi muốn làm cho target1_prereq nếu nó không tồn tại. Tại thời điểm này, nó dường như không sử dụng target1_prereq như một điều kiện tiên quyết, mặc dù lệnh build (do_something) được gọi với tham số đúng.

Tôi đang sử dụng GNU Tạo 3,80.


Chỉnh sửa: Một vài biến chứng khác từ hệ thống thực. Một số biến là bản thân dựa trên giá trị của các biến khác. Chỉ định thủ công các điều kiện tiên quyết sẽ không mở rộng quy mô. Một ví dụ hơi phức tạp hơn:

target_1:special_filename_base=target1_prereq 
target_2:special_filename_base=target2_prereq 

some_filename_a = $(special_filename_base).exta 
some_filename_b = $(special_filename_base).extb 

target_1 target_2: common_filename $(special_filename_b) $(special_filename_a) 
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b) 

Trả lời

3

Biến mục tiêu cụ thể chỉ được xác định trong các lệnh của mục tiêu (hoặc trong các nhiệm vụ đích cụ thể khác); nó không thể được sử dụng như một trong những điều kiện tiên quyết của mục tiêu. Tôi không nghĩ rằng có một cách sạch sẽ để làm những gì bạn muốn trong Make, nhưng có một số cách tiếp cận kludgey, chẳng hạn như sau:

 
EXTENSIONS = .exta .extb 
target_1: $(addprefix target1_prereq,$(EXTENSIONS)) 
target_2: $(addprefix target2_prereq,$(EXTENSIONS)) 

target_1 target_2: common_filename 
    do_something common_filename --a-weird-option=$(filter %.exta,$^) --second=$(filter %.extb,$^) 
+4

Phục hồi chủ đề này vì lợi ích của bất kỳ ai khác tình cờ gặp nó. Một [giải pháp thanh lịch hơn] (http://stackoverflow.com/questions/9311743/make-using-target-specific-variables-in-prerequisites) sử dụng mở rộng thứ cấp. – Seth

+0

@Seth, tôi đồng ý: 'target_1 target_2: common_filename $$ (special_filename_base) .exta $$ (special_filename_base) .extb ...' – Beta

2

Là một workaround đơn giản:

 
target_1:special_filename=target1_prereq 
target_1:target1_prereq 
target_2:special_filename=target2_prereq 
target_2:target2_prereq 

target_1 target_2: common_filename $(special_filename) 
    do_something common_filename --a-weird-option=$(special_filename) 

Có một số dư thừa, nhưng nó là cục bộ, do đó, nó không phải là quá xấu.

+0

Tôi đoán rằng giải quyết trường hợp cụ thể mà tôi đã đăng, nhưng tôi đã hy vọng cho một giải pháp tổng quát hơn. Tôi sẽ chỉnh sửa bằng một ví dụ phức tạp hơn. –

2

Tôi đã tìm thấy một cách khá sạch của phụ bước hạn chế này . Nó muốn đi một cái gì đó như thế này:

target_1:export special_filename_base=target1_prereq 
target_2:export special_filename_base=target2_prereq 

some_filename_a = $(special_filename_base).exta 
some_filename_b = $(special_filename_base).extb 

target_1 target_2: 
    $(MAKE) -f $(firstword $(MAKEFILE_LIST)) target-proxy 

target-proxy: common_filename $(special_filename_b) $(special_filename_a) 
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b) 

Hai điểm quan trọng:

  1. export các biến mục tiêu, do đó họ sẽ có thể truy cập khi chúng ta chạy lại Makefile.
  2. Tạo mục tiêu proxy có tất cả các điều kiện tiên quyết ban đầu của target_1 target_2 và trong target_1 target_2 hãy gọi lại hàm Makefile bằng mục tiêu proxy này. Kể từ khi mục tiêu biến cụ thể sẽ có giá trị bởi sau đó (chúng tôi trong công thức vào thời điểm đó) họ đã export ed, họ sẽ có sẵn trong target-proxy - thì đấy :)

Nhược điểm của cách tiếp cận này là chúng tôi đang tạo một quy trình make khác - nếu đó chỉ là một quy trình khác thì có thể là ok, nhưng YMMV rất cẩn thận.

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