11

マニュアルでは:

eval関数は非常に特殊です。定数ではない新しいmakefile構造を定義できます。これは、他の変数や関数を評価した結果です。eval関数の引数が展開され、その展開の結果がmakefile構文として解析されます。

eval引数が2回展開されることを理解することが重要です。最初にeval関数によって、次にその展開の結果がmakefile構文として解析されるときに再び展開されます。これは、evalを使用するときに、「$」文字に追加のレベルのエスケープを提供する必要がある場合があることを意味します。

「2回拡張」は私を混乱させます。

たとえば、makefileを作成します。

define func
    tmp = $(OBJPATH)/$(strip $1)
    objs += $$(tmp)
    $$(tmp) : $2
        gcc $$^ -o $$@
endef

all : foo

$(eval $(call func, foo, 1.c))    

eval関数はどのように拡張されますか?

4

2 に答える 2

24

それを理解する最も簡単な方法は、evalをinfoに置き換えることです。

$(info $(call func, foo, 1.c))

これにより、最初の展開の結果が出力として表示されるため、実際に解析されるmakeを確認できます。OBJPATH変数の値を指定しませんでしたがobj、たとえば、指定した場合、(呼び出し関数の)最初の展開は次のようになります。

tmp = obj/foo
objs += $(tmp)
$(tmp) : 1.c
    gcc $^ -o $@

次に、makeパーサーがこれを評価し、その過程で再び展開するので、のようなもの$(tmp)が展開されます。

于 2012-05-03T18:09:45.517 に答える
3

これは私にとって問題でしたが、私は素晴らしい回避策を見つけました。私の場合、それはAWSdockerログインに関連していました。以前にシェルスクリプトに含まれていました:

eval $(aws ecr get-login --region eu-west-1 --no-include-email --profile someprofile)

しかし、それを入れるMakefileとうまくいきませんでした。この回避策は、行を次のように変更することです。

$$(aws ecr get-login --region eu-west-1 --no-include-email --profile someprofile)

于 2021-02-09T09:42:33.433 に答える