4

I have a bunch of targets, each for a different shell as follow:

BASH_VERSION := 4.4
FISH_VERSION := 3.0.0
…
ZSH_VERSION := 5.4.2-r1

.PHONY: dev-pure-on-bash
dev-pure-on-bash:
    $(MAKE) dev-pure-on TARGET=bash VERSION="${BASH_VERSION}" ARGS="VERSION=${BASH_VERSION}"

.PHONY: dev-pure-on-elvish
dev-pure-on-elvish:
    $(MAKE) dev-pure-on TARGET=elvish VERSION="${ELVISH_VERSION}" ARGS="VERSION=${ELVISH_VERSION}"

.PHONY: dev-pure-on-fish
dev-pure-on-fish:
    $(MAKE) dev-pure-on TARGET=fish VERSION="${FISH_VERSION}" ARGS="VERSION=${FISH_VERSION}"

…

.PHONY: dev-pure-on-xonsh
dev-pure-on-xonsh:
    $(MAKE) dev-pure-on TARGET=xonsh VERSION="${XONSH_VERSION}" ARGS="VERSION=${XONSH_VERSION}"

.PHONY: dev-pure-on-zsh
dev-pure-on-zsh:
    $(MAKE) dev-pure-on TARGET=zsh VERSION="${ZSH_VERSION}" ARGS="VERSION=${ZSH_VERSION}"

.PHONY: dev-pure-on
dev-pure-on:
    docker run \
        --name run-pure-on-${TARGET} \
        --rm \
        --interactive \
        --tty \
        --volume=$$PWD:/home/pure/.pure/ \
        pure-on-${TARGET}-${VERSION}

Attempt

I tried to use a pattern rule without success:

dev-pure-on-%:
    $(MAKE) dev-pure-on TARGET=$* VERSION="${$*_VERSION}" ARGS="VERSION=${$*_VERSION}"

However I need the $* in ${$*_VERSION} to be uppercase

Question

How do I uppercase the value of $* inside and use it in another variable?

Édouard Lopez
  • 40,270
  • 28
  • 126
  • 178
  • Use shell/tr, it's much easier. To uppercase purely in make look for gmsl (GNU Make Standard Library). – Matt Mar 28 '19 at 17:46
  • 1
    Does this answer your question? [In GNU Make, how do I convert a variable to lower case?](https://stackoverflow.com/questions/664601/in-gnu-make-how-do-i-convert-a-variable-to-lower-case) – Victor Sergienko Apr 01 '20 at 23:46

2 Answers2

11

As Matt suggested, why don't you use something like:

UC = $(shell echo '$*' | tr '[:lower:]' '[:upper:]')

then use $(UC) in place of $*. Or if you want to do it more generically:

UC = $(shell echo '$1' | tr '[:lower:]' '[:upper:]')

then use $(call UC,$*) (or anything else instead of $*).

Using recursion trying to use special shell facilities seems like a lot of overhead just to uppercase a string.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • thanks, it's indeed better, I was wrongly placing it in the target body instead of before the target. I will update my answer accordingly – Édouard Lopez Mar 28 '19 at 19:04
1

Please, upvote @MadScientist's answer which lead me to my full implementation.


In my first attempt to use tr I was wrongly placing the code in the target body instead of before the target (as make code).

Solution

BASH_VERSION := 4.4
ZSH_VERSION := 5.4.2-r1

shell = $*
shell_name = $(shell echo '$*' | tr '[:lower:]' '[:upper:]')
shell_version = ${${shell_name}_VERSION}

.PHONY: dev-pure-on-%
dev-pure-on-%:
    @echo ${shell} ${shell_version}
    docker run \
        --name run-pure-on-${shell} \
        --rm \
        --interactive \
        --tty \
        --volume=$$PWD:/home/pure/.pure/ \
        pure-on-${shell}-${shell_version}
  • shell is not necessary but provide more meaning than $*
  • shell_name is the uppercase shell name
  • shell_version expand shell_name then expand the resulting variable (e.g. ZSH_VERSION, BASH_VERSION, etc.)

Usage

make dev-pure-on-bash
make dev-pure-on-zsh
Édouard Lopez
  • 40,270
  • 28
  • 126
  • 178