somevar := Apple
export somevar
update := $(Shell echo "v=$$somevar")
all:
@echo $(update)
コマンドの出力としてAppleを望んでいましたが、それは空です。エクスポートと:=
さまざまなフェーズで行われる変数の展開。これを克服する方法は?
問題は、export
が変数をコマンドで使用されるサブシェルにエクスポートすることです。他の割り当ての拡張には使用できません。ルール外の環境から取得しようとしないでください。
somevar := Apple
export somevar
update1 := $(Shell Perl -e 'print "method 1 $$ENV{somevar}\n"')
# Make runs the Shell command, the Shell does not know somevar, so update1 is "method 1 ".
update2 := Perl -e 'print "method 2 $$ENV{somevar}\n"'
# Now update2 is Perl -e 'print "method 2 $$ENV{somevar}\n"'
# Lest we forget:
update3 := method 3 $(somevar)
all:
echo $(update1)
$(update2)
echo $(update3)
Perl -e 'print method 4 "$$ENV{somevar}\n"'
メイクファイルを実行する
foo:=Apple
export foo
all:
@echo ">"$(Shell echo "$$foo")
@echo ">""$$foo"
私に与えます(環境で未定義のfooを使用)
$ make
>
>Apple
$ make foo=bar
>
>Apple
$ export foo=bar; make
>bar
>Apple
$ export foo=bar; make foo=bar
>bar
>bar
引用形式(update := "v=$$somevar"
)コマンドの実行時にシェルが展開を処理できるようにします(エクスポートが必要です)
export
は$(Shell ...)
とうまく動作しませんが、簡単な回避策があります。コマンドライン経由でシェルスクリプトにデータを渡すことができます。
もちろん、環境の通過はエスケープとクォートの問題に対して堅牢です。ただし、シェル言語には、すべてを処理する一重引用符のクォートメソッド'...'
があります。唯一の問題は、そこに単一引用符を取得する方法がないことです。もちろん、引用符を終了し、必要な単一引用符をバックスラッシュでエスケープし、新しい引用符を開始することで解決します。つまり、
ab'cd -> 'ab'\''cd'
$(Shell ...)
によって実行されるシェルスクリプトでは、var='$(...)'
という形式の変数割り当てを生成します。$(...)
は、適切にエスケープされたマテリアルを補間するmake式です。したがって、Makefile
:
somevar := Apple with 'quoted' "stuff" and dollar $$signs
Shell_escape = $(subst ','\'',$(1))
update := $(Shell v='$(call Shell_escape,$(somevar))'; echo $$v > file.txt)
.phony: all
all:
cat file.txt
サンプル実行:
$ make
cat file.txt
Apple with 'quoted' "stuff" and dollar $signs
環境変数をコマンドに伝えたい場合は、シェル構文VAR0=val0 VAR1=val1 ... VARn=valn command arg ...
を使用してそれを行うことができます。これは、上記のMakefile
にいくつかの小さな変更を加えることで説明できます。
somevar := Apple with 'quoted' "stuff" and dollar $$signs
Shell_escape = $(subst ','\'',$(1))
update := $(Shell somevar='$(call Shell_escape,$(somevar))' env > file.txt)
.phony: all
all:
grep somevar file.txt
実行:
$ make
grep somevar file.txt
somevar=Apple with 'quoted' "stuff" and dollar $signs
file.txt
には、somevar
を確認できる環境変数のダンプが含まれています。 export
in GNU Makeが正しいことをすれば、次のことができるようになります。
export somevar
update := $(Shell env > file.txt)
しかし、最終結果は同じです。
最終結果はecho $(update)
であるため、GNU渡されたエクスポート変数を$(Shell ...)
に渡す場合でも] Shell_escape
になります。言うには、もう1つMakefile
を見てください。
somevar := Apple with 'quoted' "stuff" and dollar $$signs
Shell_escape = $(subst ','\'',$(1))
update := $(Shell v='$(call Shell_escape,$(somevar))'; echo $$v)
.phony: all
all:
@echo '$(call Shell_escape,$(update))'
@echo $(update)
出力:
Apple with 'quoted' "stuff" and dollar $signs
Apple with quoted stuff and dollar