如何测试Make中是否有可用的程序?

时间:2015-01-04 22:57:09

标签: makefile

这是我到目前为止所拥有的。我不是在寻找特定于RVM的答案 - 我需要能够将rvm替换为evm。只想挑选每个人都熟悉的东西:)

install_rvm:
ifeq ("`which rvm > /dev/null; echo $?`", "0")
    @echo "rvm already installed!"
else
    @echo "installing rvm..."
    install_rvm_cmd
endif

修改

很抱歉没有预先说明这一点,但我希望install_rvm_cmd能够像往常一样运行 - 我不想隐藏用户的安装过程。

3 个答案:

答案 0 :(得分:0)

我会这样做:

.PHONY: install_rvm
install_rvm:
    @if which rvm > /dev/null; then \
      echo "rvm already installed!"; \
    else \
      echo "installing rvm..."; \
      install_rvm_cmd; \
    fi

可以使用ifeq,但即使which rvm不是install_rvm特定游戏中的实际目标,也需要执行make检查。 (我假设install_rvm只是其中一个目标的一般情况。)

虽然字符串install_rmv_cmd本身不会'由make输出,其输出将照常输出。如果你真的希望在stdout上输出install_rmv_cmd,你可以在命令本身之前添加echo install_rmv_cmd。为避免重复,您可以将else分支设为:

  echo "installing rvm..."; \
  cmd=install_rmv_cmd; \
  echo $$cmd; \
  $$cmd; \

答案 1 :(得分:0)

除路易斯的答案外,您还可以使用ifdef。例如:

EVM_LOCATION := $(shell which evm)
CASK_LOCATION := $(shell which cask)

install_cask:
ifdef CASK_LOCATION
    $(info cask is already installed!)
else
    curl -fsSkL https://raw.github.com/cask/cask/master/go | python
endif

install_evm:
ifdef EVM_LOCATION
    $(info evm is already installed!)
else
    curl -fsSkL https://raw.github.com/rejeep/evm/master/go | bash
endif

答案 2 :(得分:0)

你可以使用这样的东西(未经测试),它使用一个标记文件,以避免在完成后做任何工作。

install_rvm_stamp:
        __rvm=$$(command -v rvm);\
        if [ -z "$$__rvm" ] || ! "$$__rvm" --version >/dev/null 2>&1; then \
            echo "installing rvm..."; \
            install_rvm_cmd; \
        else \
            echo 'rvm already installed!'
        fi
        touch '$@'

.PHONY: install_rvm
install_rvm: install_rvm_stamp

或者,如果你不介意“功能测试”二进制文件,你可以做这样的事情。

rvm_bin := $(or $(realpath /usr/local/bin/rvm),$(realpath /bin/rvm),$(realpath /usr/bin/rvm),do_install_rvm)
install_rvm: $(rvm_bin)

do_install_rvm:
        @echo "installing rvm..."
        install_rvm_cmd

最后一条评论,作为对答案中提出的制作级别ifdef选项的补充;如果有问题的目标仅用于手动运行(并且不用作任何其他目标的先决条件),则可以通过一些额外的生成级别检查来避免无关的which调用。

ifneq (,$(findstring install_evm,$(MAKECMDGOALS)))
    EVM_LOCATION := $(shell which evm)
endif

如果使用MAKECMDGOALS,请将以下内容包装起来,以避免有关--warn-undefined-variables的未定义变量警告。

ifneq (undefined,$(origin MAKECMDGOALS))
....
endif