0

My Makefile:

FULL_VERSION ?= 1.2.3
MINOR_VERSION := $(shell echo "${FULL_VERSION%.*}")

test:
    echo $(MINOR_VERSION)

Running make test gives nothing, I want to get 1.2.

I know I can get it via sed/grep but I'm looking for a more elegant solution, seems there's nothing simpler than bash parameter expansion

1

You'd need to first store the value in a shell variable:

MINOR_VERSION := $(shell v='$(FULL_VERSION)'; echo "$${v%.*}")

(assuming $(FULL_VERSION) doesn't contain single quotes)

Now that calls sh, not bash. ${var%pattern} is a standard sh operator (comes from ksh).

If you wanted to use bash-specific operators, you'd need to tell make to call bash instead of sh with

SHELL = bash

Beware however that many systems don't have bash installed by default which would make your Makefile non-portable (but then, some systems don't have GNU make either and you're already using some GNUisms there)).

  • Although @uzsolt answer is also great because native, I prefer this one because sometimes it can be a non-semantic versioning, e.g. 1.2 instead of 1.2.3. Anyway, I didn't know that you can use single quotes to pass through Makefile vars – csandanov Aug 27 '18 at 11:46
2

You can do it with builtin functions (assume you're using GNU make):

VER=1.2.3
MINORVERTMP=$(subst ., ,${VER})
MINORVER=$(word 1,${MINORVERTMP}).$(word 2,${MINORVERTMP})


all:
    @echo ${MINORVER}

If you can use bmake (BSD make) can have more (and maybe simplier) possibilities:

VER=1.2.3

all: test1 test2

test1:
    # simple regular expression-based replace like sed
    @echo $@: ${VER:C,([^\.]*)\.([^\.]*).*,\1.\2,}

test2:
    # replace all dot to spaces (S),
    # print first and second element (:[1..2])
    # with dot separator (ts.)
    @echo $@: ${VER:S,., ,g:[1..2]:ts.}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.