Makefileに組み込まれたPythonスクリプトを使用する

Makefileに組み込まれたPythonスクリプトを使用する

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,$@)

関連情報