2012-01-10 29 views
9

Tôi nắm bắt ý định của Makefile trong mã giả, sau đó chỉ ra các vấn đề tôi có. Tôi đang tìm một Makefile thân thiện với người dùng hơn trong môi trường thử nghiệm. Việc sử dụng chính xác của Makefile là một trong những điều sau.Sử dụng các quy tắc có điều kiện trong một makefile

make CATEGORY=parser TEST=basic. 
    make ALL 

Nếu người dùng cung cấp cho "JUST" các lệnh như được chỉ ra dưới đây, nó sẽ in một thông báo "CATEGORY định nghĩa THỬ không xác định" và ngược lại

make CATEGORY=parser 
    make TEST=basic 

Tôi cố gắng viết Makefile trong sau cách khác nhau, nhưng nó lỗi ra:

help: 
     echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case> 
     echo"  make ALL 

    ifdef CATEGORY 
     ifdef TEST 
      CATEGORY_TEST_DEFINED = 1 
     else 
      echo "TEST not defined" 
    else 
     echo "CATEGORY not defined" 
    endif 



    ifeq ($(CATEGORY_TEST_DEFINED), 1) 
    $(CATEGORY): 
     cd $(PROJ)/$(CATEGORY) 
     make -f test.mk $(TEST) 
    endif 

    ifdef ALL 
    $(ALL): 
     for i in `ls` 
     cd $$(i) 
     make all 
    endif 

Các câu hỏi tôi có bao gồm:

  1. Liệu các quy tắc trong Makefile có thể được chọn lọc hay không (sử dụng ifdef để chọn các quy tắc và mục tiêu).

  2. echo không hoạt động. echo sẽ giúp người dùng sử dụng đúng cách.

+0

Theo dõi điểm @ Beta, bạn nên xem [FAQ] (http://stackoverflow.com/faq) và đặc biệt là phần [Làm cách nào để đặt câu hỏi tại đây?] (Http://stackoverflow.com/faq # howtoask). –

Trả lời

15

Vấn đề là echo thuộc về vỏ; Làm cho nó có thể truyền nó vào shell trong một lệnh, nhưng Make không thể thực thi nó. Sử dụng info thay vì:

ifdef CATEGORY 
$(info CATEGORY defined) 
else 
$(info CATEGORY undefined) 
endif 

Nếu bạn muốn các quy tắc để có điều kiện:

ifdef CATEGORY 
ifdef TEST 
$(CATEGORY): 
    whatever 
else 
$(info TEST not defined) 
else 
$(info CATEGORY not defined) 
endif 
+0

Cảm ơn bạn đã nhập. Nếu Make không thể thực hiện lệnh shell, thì tôi đã thấy Makefiles có (thụt đầu dòng khó ở đây) nói ví dụ: hello: @echo "Hello There". chào kết quả đầu ra -> Xin chào Có – Mike

+0

@Mike: vâng, trong trường hợp đó 'echo' nằm trong lệnh trong quy tắc' hello'. Khi bạn "make hello", Make gửi lệnh đó đến shell. Nếu bạn muốn thực hiện theo cách đó, bạn phải kết hợp các thông báo "không được định nghĩa" với một số mục tiêu, điều này dường như không có gì. – Beta

3

Những dòng này là không rõ ràng:

help: 
    echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case> 
    echo"  make ALL 

Bạn cần một không gian giữa echo và chuỗi, và chuỗi cần phải được chấm dứt:

help: 
    echo "Usage: make CATEGORY=<advanced|basic> TEST=<test-case>" 
    echo "  make ALL" 

Những dòng này là không rõ ràng:

ifdef CATEGORY 
    ifdef TEST 
     CATEGORY_TEST_DEFINED = 1 
    else 
     echo "TEST not defined" 
else 
    echo "CATEGORY not defined" 
endif 

Chắc chắn bạn cần một endif trước thứ hai else? (Thậm chí nếu nó không phải là cú pháp bắt buộc, tôi khuyên bạn nên nó.)

ifdef CATEGORY 
    ifdef TEST 
     CATEGORY_TEST_DEFINED = 1 
    else 
     echo "TEST not defined" 
    endif 
else 
    echo "CATEGORY not defined" 
endif 

Bên cạnh đó, make chỉ thực hiện lệnh như echo được coi là khi xử lý một đối tượng (quy tắc). Nó sẽ không thực hiện echo ở đó; nó sẽ đơn giản phản đối rằng bạn không thể định nghĩa các lệnh mà không có chúng là hành động cho một đích. Mặc dù mọi thứ mà GNU Make thêm vào một makefile, ngôn ngữ trong một makefile là một ngôn ngữ khai báo chứ không phải là một ngôn ngữ thủ tục.


Một cách khác để xử lý này là để xác định giá trị mặc định cho các macro:

CATEGORY = advanced 
TEST  = all 

Xác định các giá trị mặc định mà làm điều gì đó bán hợp lý; cho phép người dùng ghi đè mặc định nếu họ muốn.Bạn có thể có một quy tắc như:

${CATEGORY}/${TEST}: ...dependencies... 
    ...actions... 

Bạn có thể để help làm quy tắc đầu tiên. Tôi có một số thư mục nơi mà các quy tắc đầu tiên là:

null: 
    @echo "You must specify a target with this makefile!" 

này tương đương với những gì bạn có (ngoại trừ việc make không hiển thị các lệnh trước khi chạy nó, vì vậy tôi chỉ thấy thông báo thay vì dòng lệnh echo và tin nhắn; đó là @ tại nơi làm việc). Các makefile này xuất phát từ cũng có một quy tắc all đó là nếu không thường là hợp lý nhất đầu tiên (mặc định) quy tắc.

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