Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Have Make target depend on binary, which may or may not exist on $PATH

I want to add a Make target that runs a program with envdir.

ENVDIR := $(shell command -v envdir)

serve: | $(ENVDIR)
    $(ENVDIR) /usr/local/myservice/env python -m SimpleHTTPServer 8000

The idea is that if the user doesn't have envdir installed, it will install it for them. I need the pipe character because I don't always want it to run; I just want any version of it to be present. Unfortunately, I can't predict very well where envdir will be installed to.

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...

The other problem I run into is that if the user doesn't have envdir installed, the variable evaluates to the empty string. So a) My "install envdir" target doesn't actually run, and b) after it runs, $(ENVDIR) is still set to the empty string, so loading it in the serve target doesn't work.

Is there a way to a) get the install target to run, even if ENVDIR is undefined, and b) to redefine the value of the variable at the end of the "install envdir" target run?

Please don't respond with "why are you using envdir" - I run into this problem with a variety of different binaries I depend upon, this just happened to be an easily shareable example.

like image 393
Kevin Burke Avatar asked Oct 29 '22 02:10

Kevin Burke


1 Answers

For the "empty" issue you can do this:

ENVDIR := $(or $(shell command -v envdir),envdir)

so that if the shell function expands to the empty string, envdir will be substituted (the or function was added in GNU make 3.81). That will probably be enough to solve all your problems since after the installation the envdir command will now appear on the PATH, so you don't need the full path.

like image 72
MadScientist Avatar answered Dec 29 '22 01:12

MadScientist