让Make目标依赖于二进制,这可能存在于$ PATH上,也可能不存在

Kev*_*rke 5 dependencies makefile target

我想添加一个使用envdir运行程序的Make目标.

ENVDIR := $(shell command -v envdir)

serve: | $(ENVDIR)
    $(ENVDIR) /usr/local/myservice/env python -m SimpleHTTPServer 8000
Run Code Online (Sandbox Code Playgroud)

这个想法是,如果用户没有安装envdir,它将为他们安装它.我需要管道角色,因为我并不总是希望它能够运行; 我只是希望它的任何版本都存在.不幸的是,我无法很好地预测将安装envdir的位置.

UNAME := $(shell uname)
$(ENVDIR):
ifeq ($(UNAME), Darwin)
    brew install daemontools
endif
ifeq ($(UNAME), Linux)
    sudo apt-get install daemontools
endif
# Add other operating systems here as appropriate...
Run Code Online (Sandbox Code Playgroud)

我遇到的另一个问题是,如果用户没有安装envdir,则变量将计算为空字符串.所以a)我的"安装envdir"目标实际上没有运行,并且b)运行后,$(ENVDIR)仍然设置为空字符串,因此将其加载到服务目标中不起作用.

是否有办法a)使安装目标运行,即使ENVDIR未定义,以及b)在"安装envdir"目标运行结束时重新定义变量的值?

请不要回答"你为什么使用envdir" - 我遇到了我依赖的各种不同二进制文件这个问题,这恰好是一个容易分享的例子.

Mad*_*ist 1

对于“空”问题,您可以这样做:

ENVDIR := $(or $(shell command -v envdir),envdir)
Run Code Online (Sandbox Code Playgroud)

这样,如果shell函数扩展为空字符串,envdir将被替换(该or函数是在 GNU make 3.81 中添加的)。这可能足以解决您的所有问题,因为安装后该envdir命令现在将出现在 PATH 上,因此您不需要完整路径。