在bash中我可以做这样的事情来检查程序是否存在:
if type -P vim > /dev/null; then
echo "vim installed"
else
echo "vim not installed"
fi
我想在Makefile中做同样的事情。 在细节中我想选择" python3"如果安装,否则" python" (2)。我的Makefile看起来像这样:
PYTHON = python
TSCRIPT = test/test_psutil.py
test:
$(PYTHON) $(TSCRIPT)
我可以做些什么来围绕PYTHON = python
行使用条件?我知道Makefile可以被告知以某种方式使用bash语法(SHELL:=/bin/bash
?)但我不是专家。
答案 0 :(得分:3)
最简单的事情可能是使用$(shell)
来确定python3
是否可以调用:
ifeq ($(shell which python3),)
PYTHON = python
else
PYTHON = python3
endif
$(shell which python 3)
在shell中运行which python3
并展开到该命令的输出。如果python3
可用,则为$(shell type -P python3)
的路径,否则为空。这可以在条件中使用。
附录:关于注释中的可移植性问题:/bin/sh
不起作用的原因是GNU尝试优化掉shell调用和fork / exec本身,这不适用于shell内置。我是从here发现的。如果您的type -P
知道# note the semicolon -------v
ifeq ($(shell type -P python3;),)
,那么
/bin/sh
的工作原理。我的dash
是ifeq ($(shell type python3;),)
,因此对我不起作用(它抱怨-P不是有效的命令)。做了什么
dash
因为$(shell)
的类型将有关不可用命令的错误消息发送到stderr,而不是stdout(因此which
扩展为空字符串)。如果你可以依赖ifeq ($(shell bash -c 'type -P python3'),)
,我认为这样做是最干净的。如果你可以依赖bash,那么
SHELL = bash
ifeq ($(shell type -P python3;),)
也有效。可替代地,
PYTHON = $(shell IFS=:; for dir in $$PATH; do if test -f "$$dir/python3" && test -x "$$dir/python3"; then echo python3; exit 0; fi; done; echo python)
具有相同的效果。如果这些都不是一个选项,像@ MadScientist的答案这样的绝望措施会变得有吸引力。
或者,如果所有其他方法都失败了,您可以自己搜索路径:
autoconf
这取决于AC_CHECK_PROG
{{1}}的实施方式。我不确定我是否想要这个。
答案 1 :(得分:2)
如果您想要更具可移植性,可以尝试调用命令本身以查看它是否有效:
PYTHON := $(shell python3 --version >/dev/null 2>&1 && echo python3 || echo python)
答案 2 :(得分:1)
PYTHON := $(shell type -P python3 || echo "python")
答案 3 :(得分:0)
您可以使用 command -v
:
PYTHON := $(shell command -v python3 2> /dev/null || echo python)
在 Bash 中,command
是一个内置命令。
以上示例适用于 GNU Make。其他 Make 程序可能有不同的语法来运行 shell 命令。