MakeターゲットでPythonコードスニペットを実行しようとしていますが、このトピックがMakeでどのように機能するかを判断するのに問題があります。
これまでに試したことは次のとおりです。
define BROWSER_PYSCRIPT
import os, webbrowser, sys
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
endef
BROWSER := $(shell python -c '$(BROWSER_PYSCRIPT)')
次のターゲットで$(BROWSER)を使用したいと思います。
docs:
#.. compile docs
$(BROWSER) docs/index.html
これは本当に悪い考えですか?
答え1
関連:https://stackoverflow.com/q/649246/4937930
単一のレシピのように複数行変数を呼び出すことはできませんが、これにより複数のレシピに拡張され、構文エラーが発生します。
考えられる解決策は次のとおりです。
export BROWSER_PYSCRIPT
BROWSER := python -c "$$BROWSER_PYSCRIPT"
docs:
#.. compile docs
$(BROWSER) docs/index.html
答え2
Yaegashiのアプローチはうまくいきますが、それに動的な価値を提供するのは簡単ではありません。 Makefileが解析されると、「export」コマンドが評価され、シェル環境変数がレシピに設定されます。その後、「docs」レシピの実行中に環境変数が評価されます。
コードスニペットがターゲット関連変数を埋める必要がある場合は、次のアプローチをお勧めします。
クイックメソッド
このモードは、数回のクイズを実行する必要がある場合に便利です。
run_script = python -c \
"import time ;\
print 'Hello world!' ;\
print '%d + %d = %d' %($1,$2,$1+$2) ;\
print 'Running target \'%s\' at time %s' %('$3', time.ctime())"
test:
$(call run_script,4,3,$@)
奇妙な方法
奇妙な文字や関数、forループ、または他の複数行構造を使用したい場合は、完璧に機能する素晴らしいパターンがあります。
#--------------------------- Python Script Runner ----------------------------#
define \n
endef
escape_shellstring = \
$(subst `,\`,\
$(subst ",\",\
$(subst $$,\$$,\
$(subst \,\\,\
$1))))
escape_printf = \
$(subst \,\\,\
$(subst %,%%,\
$1))
create_string = \
$(subst $(\n),\n,\
$(call escape_shellstring,\
$(call escape_printf,\
$1)))
python_script = printf "$(call create_string,$($(1)))" | python
#------------------------------- User Scripts --------------------------------#
define my_script
def good_times():
print "good times!"
import time
print 'Hello world!'
print '%d + %d = %d' %($2,$3,$2+$3)
print 'Runni`ng $$BEEF \ttarget \t\n\n"%s" at time %s' %('$4', time.ctime())
good_times()
endef
#--------------------------------- Recipes -----------------------------------#
test:
$(call python_script,my_script,1,2,$@)