Reputation: 667
I have the following simple statement that works without problems in the shell:
if [ -z "$(command -v brew)" ]; then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
in short: if the program is not found, then install it.
The problem is that I can't convert this construction into a Makefile. So far I understand that the construction itself should look like this:
if [ -z "$(shell command -v brew)" ]; then \
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \
fi
But how to correctly convert /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
string I do not quite understand. Could you give some tips in this matter?
Upvotes: 1
Views: 3074
Reputation: 361556
The dollar signs need to be doubled so make doesn't interpret them. Also there needs to be a semicolon at the end of the bash
command to separate it from fi
since the backslash will eat the usual newline command separator.
some_target:
if [ -z "$$(command -v brew)" ]; then \
/bin/bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; \
fi
Upvotes: 3
Reputation: 94584
You need to break it into a couple of items.
Firstly, check for brew:
BREW := $(shell command -v brew)
Then check if the variable is set. If it's not set, then run the installer:
ifeq ($(BREW),)
$(shell bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
BREW := $(shell command -v brew)
endif
It's doable in an entire single shell command, but this breaks it into a couple of shell pieces.
the use of :=
means that the evaluation happens at the time the line is parsed, which is how you get to check and override the value.
In a small, self-contained makefile:
BREW := $(shell command -v brew)
ifeq ($(BREW),)
$(shell bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
BREW := $(shell command -v brew)
endif
all:
echo $(BREW)
Upvotes: 1