Makefile:如果存在,则使用$ exe1,否则为$ exe2

时间:2015-02-12 14:37:56

标签: python bash makefile

在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?)但我不是专家。

4 个答案:

答案 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

的工作原理。我的dashifeq ($(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 命令。