embed python script inside Makefile

Sometimes it’s necessary to embed some lines of python script inside Makefile, here is some examples:

1. original python snippet:

x = "2018-12-25"
match = re.search(r'^(\d{4})-(\d{2})-(\d{2})', x)
if match:
    y = int(match.group(1)) - 2000
    m = int(match.group(2))
    # 7 bits allocated for the year, 4 bits for the month
    assert y >= 0 and y < 128
    assert m > 0 and m <= 12
    print (y << 4) | m
else:
    print ('Something is wrong')

Output is:

300

2. single line makefile command:

We can use http://jagt.github.io/python-single-line-convert/ to generate the 1-line command for makefiles.

theCmd := """import re\nx = '2018-12-25'\nmatch = re.search(r'^(\\d{4})-(\\d{2})-(\\d{2})', x)\nif match:\n    y = int(match.group(1)) - 2000\n    m = int(match.group(2))\n    assert y >= -1 and y < 128\n    assert m > 0 and m <= 12\n    print (y << 4) | m\nelse:\n    print ('Something is wrong')\n"""
osPatchLvl := $(shell echo -e $(theCmd) | python)
single:
    echo $(osPatchLvl)

3. multiple line Makefile commands:

Conversion tips:

s/^/\\n/g
s/$/"/g

and make sure no misleading ‘ or “ inside each line.
Converted multi-line commands are:

theCmdStr := "import re"
theCmdStr += "\nx = '2018-12-25'"
theCmdStr += "\nmatch = re.search(r'^(\d{4})-(\d{2})-(\d{2})', x)"
theCmdStr += "\nif match:"
theCmdStr += "\n    y = int(match.group(1)) - 2000"
theCmdStr += "\n    m = int(match.group(2))"
theCmdStr += "\n    assert y >= 0 and y < 128"
theCmdStr += "\n    assert m > 0 and m <= 12"
theCmdStr += "\n    print (y << 4) | m"
theCmdStr += "\nelse:"
theCmdStr += "\n    print ('Something is wrong')"
osPatchLvl2 := $(shell echo -e $(theCmdStr) | python)
multi:
    echo $(osPatchLvl2)