这是我到目前为止所拥有的。我不是在寻找特定于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
能够像往常一样运行 - 我不想隐藏用户的安装过程。
答案 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