Steve Reed
Steve Reed

Reputation: 373

How to assign value to variable in Makefile?

In trying to test for the failure of a command in a Makefile (in this case jekyll build relative), the variable $$? should contain the exit code of the last command. In testing, this code is shown to be 127. However, I would like to assign it to the variable LAST_EXIT so that an the next if statement can check whether the executed command succeeded or failed.

The problem is that LAST_EXIT never receives the value it is being assigned, as shown in the code below. Any suggestions on how to fix this problem?

Code:

LAST_EXIT = 0

all:
    @echo "Building the website... Running command:"
    - jekyll build relative || LAST_EXIT=$$?
    - jekyll build relative || echo $$? and $(LAST_EXIT)
ifeq ($(LAST_EXIT), 0)
    #echo a message indicating success 

Output:

jekyll build relative || LAST_EXIT=$?
/bin/sh: jekyll: command not found
jekyll build relative || echo $? and 0
/bin/sh: jekyll: command not found
127 and 0

Upvotes: 1

Views: 5604

Answers (2)

Steve Reed
Steve Reed

Reputation: 373

My solution to this problem was calling the following script in the Makefile to check for Jekyll: (called as ./{scriptName}

#!/bin/bash

LINEBREAK="*****************************************************************"
VERSION=0

echo "Checking Jekyll..."
VERSION=$(jekyll --version)

if test "$?" == "0"
then
     echo "$VERSION is installed on this system..."
else
     echo "$LINEBREAK"
     echo "Oops! It looks like you don't have Jekyll yet, lets install it!"
     echo "Running command: \"sudo gem install jekyll\""
     echo "$LINEBREAK"
     sudo gem install jekyll
     if test "$?" != "0"
     then
          echo "$LINEBREAK"
          echo "Jekyll install failed... It needs to be installed as a super-user on your system, which"
          echo "requires your password. You can run \"sudo gem install jekyll\" yourself to install Jekyll."
          echo "You can also see their website at: \"https://jekyllrb.com/docs/installation/\" for more information"
          echo "$LINEBREAK"
          exit 113
     else
          echo "$LINEBREAK"
          echo "Jekyll has been installed on this system..."
          echo "Proceeding to build..."
          echo "$LINEBREAK"
     fi
fi

exit 0

Upvotes: 0

Beta
Beta

Reputation: 99134

There are two problems with your approach.

1) Make resolves conditional parts of the makefile before it executes any rule. This:

all:
    LAST_EXIT=0
ifeq ($(LAST_EXIT), 0)
    #echo a message indicating success 
endif

will not report success (unless you set the value of LAST_EXIT somewhere above the rule).

2) Each command in a recipe executes in its own subshell; shell variable values are not preserved from one line to the next:

all:
    LAST_EXIT=5; echo the value is $$LAST_EXIT
    @echo now the value is $$LAST_EXIT

This should work:

all:
    - jekyll build relative || LAST_EXIT=$$?; \
  if [ $$LAST_EXIT == 0 ]; then  echo success!; fi

Upvotes: 2

Related Questions