5

makeサブメイクへの変数の通信を防ぐことはできません。私はマニュアルを読み、彼らのアドバイスに従いました (リセットMAKEOVERRIDESMAKEFLAGS) が、まだ機能していません。

次のプロトタイプの Makefile を検討してください。

${warning $(MAKEOVERRIDES)}
${warning $(MAKEFLAGS)}
${warning $(VAR)}

none:
    $(MAKE) -f Makefile MAKEOVERRIDES= MAKEFLAGS= all

all:
    echo done!

Imake VAR=10 noneの場合、次の結果が得られます。

Makefile:2: VAR=10
Makefile:3: 
Makefile:4: 10
make -f Makefile MAKEOVERRIDES= MAKEFLAGS= all
make[1]: Entering directory `/home/adriano/sandbox/makes'
Makefile:2: 
Makefile:3: 
Makefile:4: 10
echo done!
done!
make[1]: Leaving directory `/home/adriano/sandbox/makes'

つまり、サブメイクへのmake通信です。VARこれは正しい動作ですか?

私は試してみましたが、運がunexport VARありbash -c make ...ませんでした。

編集:noneのレシピを次のように変更しました:bash -c "echo $$MAKEOVERRIDES $$MAKEFLAGS $$VAR" ; make ...

このようにして、VAR が実際には、コマンドを実行するために make が作成する環境を通過し、他の変数を通過しないことがわかりました (他の変数もこの方法で make に渡されます)。

私の質問は次のとおりだと思います: サブ make を実行するための新しいシェル/環境を作成するにはどうすればよいですか?

編集: 誰かがなぜ私がこれをしようとしているのかと尋ねました。ここでそれに答えようと思います。

CONFIG という名前の変数を使用する「モジュール」があります。このモジュールをビルドするには、別の部分的に無関係な「モジュール」をビルドする必要があります。これも CONFIG を使用しますが、値は異なります。問題は、「サブモジュール」をビルドしようとすると、CONFIG に「スーパーモジュール」の値が含まれていることです。「サブモジュール」を作成するときにCONFIGを指定できますが、両方のモジュールが同じ名前の多くの変数を使用し、それらをすべて指定しようとすると、モジュールが密結合されてしまい、余裕がありません。

どうしてこんなに難しいんだろう…

4

1 に答える 1

4

これは間違っています:

none:
        $(MAKE) -f Makefile MAKEOVERRIDES= MAKEFLAGS= all

これらの変数 (MAKEOVERRIDESおよびMAKEFLAGS) は、親 make によって環境に設定され、サブ make に渡されます。レシピ内でこれらの値にオーバーライドを設定しても役に立ちません。なぜなら、make はレシピ内のコマンドを実際に開始する前に、レシピの環境を設定する必要があるからです (もちろん)。

親 makefileでこれらの値をオーバーライド/削除する必要があります。これにより、サブ make の環境を構築する前に、これらの変更が親 make に表示されます。

MAKEOVERRIDES =
none:
        $(MAKE) -f Makefile all

これを行う完璧な方法はありません。ただし、ほとんどの場合に機能するトリックをプレイできます。

unexport $(shell echo '$(MAKEOVERRIDES)' | sed 's/=[^ ]*//g')
MAKEOVERRIDES =

最初の行はすべての変数をアンエクスポートしようとしMAKEOVERRIDES、2 行目は MAKEOVERRIDES をリセットします。これにはいくつかの問題があります。1 つは、MAKEOVERRIDES が空の場合、すべてをアンエクスポートする "unexport" を単独で使用することです。これは、シェル関数の前にいくつかの偽の変数を貼り付けることで簡単に回避できます。もう 1 つは、変数の値に空白が含まれている場合、展開ではその変数がエクスポートされていないと見なされることです。それはおそらく大丈夫ですが、奇妙です。

私はそれを行うためのより良い方法を考えることはできません.

なぜこれをやりたいのか、あなたは本当に言いません。を使用して「バニラ」環境にしたいコマンドを実行するなど、何か違うことを考えましたかenv?たとえば、限定された特定の環境変数セットを使用してコマンドを実行する場合は、次のように実行できます。

test:
        env -i PATH='$(PATH)' LANG='$(LANG)' runMyCommand --with --my arguments

残念ながら、一部のバージョンでは;の代わりにenv使用されます。あなたのマニュアルページをチェックしてください。--i

または、ユーザーのシェル設定環境を最初から再読み込みするログイン シェルを開始することもできます。

test:
        /bin/sh -lc 'runMyCommand --with --my arguments'

編集:あなたが求めていること(サブメイクの環境を制限すること)が難しいため、難しいです。

幸いなことに、あなたの説明に基づいて、それは必要ではないようです。Make には、変数値を見つけるための重要な階層があります。コマンド ラインは最高レベルです (まあ、ありoverrideますが無視します)。その後、makefile 自体に設定された変数が続きます。最後に、環境からインポートされた変数が最も低くなります (デフォルトの変数はさらに低いですが、それも無視します)。

したがって、サブ make の変数が、上位レベルの make に与えられたコマンドライン変数の影響を受けないようにすることが目標である場合、環境から変数を取得するというこのすべての困難は必要ありません。サブメイクファイルで設定された変数は、環境内の値よりも優先されます。したがって、コマンド ラインで設定された変数を削除するだけで済みます。これについては、上記でその方法を示しましたが、MAKEOVERRIDES を設定します。

于 2013-06-11T20:35:53.290 に答える