在 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”命令,并将 shell 环境变量设置为配方。然后在执行“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,$@)

相关内容