2012-01-10 17 views
9

メイクファイルの意図を擬似コードで取得し、問題点を示します。私はテスト環境でよりユーザーフレンドリーなMakefileを探しています。 Makefileの正しい使い方は以下の通りです。メイクファイルの条件付きルールの使用

make CATEGORY=parser TEST=basic. 
    make ALL 

ユーザーは「JUST」コマンドを与えた場合は以下に示すように、それは「CATEGORY定義されたTEST未定義」というメッセージをプリントし、その逆

make CATEGORY=parser 
    make TEST=basic 

なければならない私は、次のようにMakefileを書いてみました方法、それエラーアウト:私が持っている

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 

質問は以下のとおりです。

  1. Makefile内のルールが選択可能であるかどうか(ifdefを使用してルールとターゲットを選択するかどうか)。

  2. エコーが機能しません。エコーはユーザーに正しい使用方法を教えてください。

+0

@ Betaのポイントをフォローして、[FAQ](http://stackoverflow.com/faq)と特に[ここで質問するにはどうすればいいですか?](http://stackoverflow.com)をご覧ください。/faq#howtoask)。 –

答えて

15

問題はechoがシェルに属していることです。 Makeはコマンドでシェルに渡すことができますが、Makeはそれを実行できません。あなたはルールが条件になりたい場合は

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

:これらの行は疑わしいです

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

ありがとうございます。 Makeがシェルコマンドを実行できない場合、Makefileは(ここではインデントが難しい)例えばhello:<次の行でタブ> @echo "Hello There"と言っています。 hello出力を作成する - > Hello There – Mike

+0

@Mike:はい、その場合、 'echo'は' hello'ルールのコマンドにあります。 make helloを実行すると、Makeはそのコマンドをシェルに送信します。このようにしたい場合は、「定義されていない」メッセージをいくつかのターゲットに関連付ける必要があります。 – Beta

3

:代わりにinfoを使用し

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

あなたがechoと文字列の間のスペースを必要とし、文字列を終了する必要があります。

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 

きっとあなたは、第二elseendifが必要ですか? (それは文法的に必須ではありません場合でも、私はそれをお勧めします。)

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

また、makeだけなechoなどのコマンドを実行し、ターゲット(ルール)を処理するときにすることになっています。そこにはechoが実行されません。ターゲットに対してアクションではなくコマンドを定義することはできません。 GNU Makeがmakefileに追加するすべてのものにもかかわらず、makefileの言語は手続き型言語ではなく宣言型言語です。


これを処理する別の方法は、マクロのデフォルト値を定義することです:

CATEGORY = advanced 
TEST  = all 

は、半合理的な何かをデフォルト値を定義します。必要に応じてユーザーがデフォルトを上書きできるようにします。あなたが最初のルールとしてhelp残すことができます

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

:あなたは、次のようなルールを持つことができます。私は最初のルールがあるいくつかのディレクトリがあります。

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

をそのmakeがそれを実行する前にコマンドをエコーし​​ません除いてこれは(あなたが持っているものと同等であるので、私は唯一の代わりにechoコマンドラインのメッセージが表示され、そのメッセージは、仕事中の@です)。これに由来するmakefileには、普通は最も合理的な最初の(デフォルト)ルールであるルールallがあります。