web-dev-qa-db-ja.com

makefileでの条件付きルールの使用

Makefileの意図を疑似コードでキャプチャし、問題を示します。テスト環境でよりユーザーフレンドリーなMakefileを探しています。 Makefileの正しい使い方は次のいずれかです。

    make CATEGORY=parser TEST=basic.
    make ALL

ユーザーが以下に示すように「JUST」コマンドを与えると、「CATEGORY defined TEST undefined」というメッセージが表示され、その逆も同様です。

    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. エコーが機能しません。 echoは、正しい使用法でユーザーを助ける必要があります。

14
Mike

問題は、echoがシェルに属していることです。 Makeはそれをコマンドでシェルに渡すことができますが、Makeはそれを実行できません。代わりにinfoを使用してください:

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
20
Beta

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

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

確かに2番目の前にendifが必要ですelse? (構文的に必須ではない場合でも、お勧めします。)

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がメイクファイルに追加するすべてのものにもかかわらず、メイクファイル内の言語は宣言型言語であり、手続き型言語ではありません。


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

CATEGORY = advanced
TEST     = all

ある程度合理的なことを行うデフォルト値を定義します。必要に応じて、ユーザーがデフォルトを上書きできるようにします。次のようなルールを設定できます。

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

最初のルールとしてhelpを残すことができます。最初のルールがいくつかのディレクトリがあります:

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

これはあなたが持っているものと同等です(ただしmakeは実行前にコマンドをエコーし​​ないため、エコーコマンドラインとメッセージの代わりにメッセージのみが表示されます。それが@の作業です)。これが由来するメイクファイルには、ルールallもあります。それ以外の場合は、通常、最も賢明な最初の(デフォルト)ルールです。

3