Search code examples
pythondockerunixmakefilesubprocess

How should I embed a python script in a Makefile?


I want to embed a python script in a Makefile

I built a python -c script (below), and it works well in my MacBook Hyper terminal:

% python -c $'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n    print("Docker desktop failed to launch: exit-code:{}".format(output[0]))'

For reasons I can't yet figure out, this seems to fail if I build a Makefile with it (note: a tab is four spaces... I used tab indentation in the Makefile).

all:
    $(shell python -c $'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n    print("Docker desktop failed to launch: exit-code:{}".format(output[0]))')

Running the make all target...

% make all
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `python -c from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n    print("Docker desktop failed to launch: exit-code:{}".format(output[0]))''
make: `all' is up to date.
%

I have been struggling with this for a while...

Can someone help explain why make all fails and the best way to fix this python -c command? My shell CLI python -c ... command successfully launches Docker desktop on my MacBook.

I understand there are non-python ways to solve this specific problem... I need a general python Makefile solution.


Solution

  • I found a fairly simple way to embed a multiline python script in a Makefile...

    1. Save this as Makefile...
    define MULTILINE_PYTHON_SCRIPT
    ###########################################
    # Start multiline python string here...
    ###########################################
    from subprocess import getstatusoutput as gso
    
    print("Here we go:")
    for hello_int in [1, 2, 3,]:
        print('    Hello World %i' % hello_int)
    
    retval, _ = gso("ls -la")
    assert retval==0, "ls command execution failed"
    
    ###########################################
    # End of multiline python string...
    ###########################################
    endef
    
    export MULTILINE_PYTHON_SCRIPT
    EMBEDDED_PY := python -c "$$MULTILINE_PYTHON_SCRIPT"
    
    .PHONY: nothing
    nothing:
        echo "raw makefile command"
    
    .PHONY: test
    test:
        $(EMBEDDED_PY)
    
    .PHONY: all
    all:
        open --background -a Docker
    
    1. Testing the output:
    % make nothing
    echo "raw makefile command"
    raw makefile command
    %
    % make test
    python -c "$MULTILINE_PYTHON_SCRIPT"
    Here we go:
        Hello World 1
        Hello World 2
        Hello World 3
    %
    %