0

I have a command where I want the return code stored inside of a variable inside a makefile. I found out how to do this stackoverflow page here.

I am failing to make the eval command into multi line inside my makefile since it is very long. trying to change this

.PHONY: target2
target2:  
    $(eval CREATE__ACCOUNT := $(shell curl -o /dev/null -s -w "%{http_code}\n" -X POST "$(dev_url)/api/" -H "accept: application/json" -H "token: $(dev_token)" -H "Content-Type: application/json" -d "{ \"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"value3\", \"key4\": value4, \"key5\": \"value5\", \"key6\": \"value6\", \"key7\": \"value7\", \"key8\": \"value8"}"))
    @if [ ${CREATE_ACCOUNT} -eq 201 ]; then \
        echo "all good, account crated"; \
    else \
        echo "not good, got code ${CREATE_ACCOUNT} , account not created"; \
        exit 1; \
    fi

into someting resembling this

.PHONY: target2
target2: 
    $(eval CREATE__ACCOUNT := $(shell curl -o /dev/null -s -w "%{http_code}\n" \
    -X POST "$(dev_url)/api/" \
    -H "accept: application/json" \
    -H "token: $(dev_token)" \
    -H "Content-Type: application/json" \
    -d "{ \"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"value3\", \"key4\": value4, \"key5\": \"value5\", \"key6\": \"value6\", \"key7\": \"value7\", \"key8\": \"value8"}"))
    @if [ ${CREATE_ACCOUNT} -eq 201 ]; then \
        echo "all good, account crated"; \
    else \
        echo "not good, got code ${CREATE_ACCOUNT} , account not created"; \
        exit 1; \
    fi

It seems int his case using the \ as line continuation is not working. when trying this i get the following error makefile:8: *** missing separator. Stop.

saiyen2002
  • 23
  • 2
  • 4
    You should not use the chosen answer from that question. Even though it has a ton of upvotes, it's the wrong way to do things.. Instead, look down to the answer by Brent Bradburn. That's the right way to do it. If you follow that model and just use normal shell scripting (your recipe is running in a shell after all!) then it will work fine. – MadScientist Aug 08 '20 at 04:46
  • you need to escape meta characters for eval – alecxs Aug 08 '20 at 21:11
  • @alecxs could you give a quick edit of the code to show how it should be done? Must be messing up somewhere since I have tried what you asked but is not working. – saiyen2002 Aug 09 '20 at 08:07
  • https://stackoverflow.com/a/29085684 can you please try for your own i don't know how to do it – alecxs Aug 09 '20 at 08:14

2 Answers2

1

As an alternative to using eval, consider the following solution, which will use compound multi-line rule.

It use a shell variable CREATE_ACCOUNT, and avoid the $(shell ...) function call. Deferring the curl callinto the actual execution of target2.

dev_url = http://google.com/
.PHONY: target2
target2: 
        CREATE_ACCOUNT=$$(curl -o /dev/null -s -w "%{http_code}\n" \
        -X POST "$(dev_url)/api/" \
        -H "accept: application/json" \
        -H "token: $(dev_token)" \
        -H "Content-Type: application/json" \
        -d '{ "key1": "value1", "key2": "value2", "key3": "value3", "key4": value4, "key5": "value5", "key6": "value6", "key7": "value7", "key8": "value8" }') ; \
        if [ "$${CREATE_ACCOUNT}" -eq 201 ]; then \
            echo "all good, account crated"; \
        else \
            echo "not good, got code $${CREATE_ACCOUNT} , account not created"; \
            exit 1; \
        fi

dash-o
  • 13,723
  • 1
  • 10
  • 37
  • i have tried this and it is working nicely. However I missed out something from initial post. inside of target2 i am doing a `PROJECT_ID=$$(cat /tmp/project_id);` . When i proceed to use this in the key value pair in the json, it doesn't expand since it is all in single quotes. `"key1": "$${PROJECT_ID}"` . This just expands to `${PROJECT_ID}`. When I was using double quotes and escaping, it worked. Any advice on this? thanks – saiyen2002 Aug 11 '20 at 11:33
  • If you need variables, you will have to use double quotes and \ escapes on the -d line – dash-o Aug 13 '20 at 05:11
0

Few minor issues:

  • The variable is spelled once as CREATE__ACCOUNT (2 '_'), and once as CREATE_ACOUNT
  • The quoting for the '-d' line s off ('value8' terminating quote should be escaped
  • Missing quote on the '@if' statement to protect against empty response
dev_url = http://google.com/
.PHONY: target2
target2: 
        $(eval CREATE_ACCOUNT := $(shell curl -o /dev/null -s -w "%{http_code}\n" \
        -X POST "$(dev_url)/api/" \
        -H "accept: application/json" \
        -H "token: $(dev_token)" \
        -H "Content-Type: application/json" \
        -d "{ \"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"value3\", \"key4\": value4, \"key5\": \"value5\", \"key6\": \"value6\", \"key7\": \"value7\", \"key8\": \"value8\" }"))
        @if [ "${CREATE_ACCOUNT}" -eq 201 ]; then \
            echo "all good, account crated"; \
        else \
            echo "not good, got code ${CREATE_ACCOUNT} , account not created"; \
            exit 1; \
        fi

Also, consider using single quote on the '-d' line, and replacing the repeated \" sequences with ". I will make the code easier to read/maintain.

dash-o
  • 13,723
  • 1
  • 10
  • 37