Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNU make yields "commands commence before first target" error

Tags:

makefile

gnu

In my makefile, I would like to check for the existence of a library and give an informative error message. I created a conditional that should exit the make process when the file is not found:

 9: ifeq ($(${JSONLIBPATH}),)
10:    JSONLIBPATH = ${ALTJSONLIBDIR}/${LIBJSON}
11: endif
12: ifeq ($(${JSONLIBPATH}),)
13:    $(error JSON library is not found. Please install libjson before building)
14: endif 

My makefile gets stuck on line 13:

Makefile:13: *** commands commence before first target.  Stop.

After line 13, my makefile has its targets.

I tried putting this conditional block into a target (e.g. a target called isJSONLibraryInstalled) but this does not execute correctly.

How would I check for a file's existence and handle the error case, before processing targets? Apologies if this is a dumb question.

like image 545
Alex Reynolds Avatar asked Jan 17 '11 13:01

Alex Reynolds


4 Answers

First of all, you are looking at the contents of a variable that is named after the current path, which is probably not what you want. A simple environment variable reference is $(name) or ${name}, not $(${name}). Due to this, line 13 is always evaluated.

Second, I think it is choking on the indentation of the $(error ...) expression. While the expression resolves to an empty string, there is still a tab character at the start of the line, which indicates a command, which in turn cannot exist outside a rule.

I think using spaces rather than tabs to indent would work.

like image 141
Simon Richter Avatar answered Oct 05 '22 07:10

Simon Richter


When you get Make error messages, always check the Error message documentation

On GNU Make 3.81 (error appears to have been removed from newer versions), it says:

This means the first thing in the makefile seems to be part of a command script: it begins with a TAB character and doesn't appear to be a legal make command (such as a variable assignment). Command scripts must always be associated with a target.

What makes matters more confusing is that "doesn't appear to be a legal make command" part. That explains why in:

    a := b
    $(error a)

the error happens at line 2 and not 1: make simply accepts statements that it can parse, like the assignment, so the following works:

    a := b
a:
    echo $a

Note: SO currently converts tabs to spaces in code, so you can't just copy the above code into your editor.


For me it was an unnecessary white space before the connector that was causing this. On slickEdit I selected the option to view all special character and noticed the black sheep.

like image 38
RobGajula Avatar answered Oct 05 '22 08:10

RobGajula


You can check whitespaces, spaces and tabs by using VSCode [View > Render Whitespace]

As you can see;

  • command-1 has a tab (->) and whitespace at the end
  • command-2 has space at first
  • command-3/4 has tab+spaces

enter image description here

So, you should remove the whitespaces at the end and apply the same spaces with the same action. e.g: tab like the following;

enter image description here

like image 37
hbceylan Avatar answered Oct 05 '22 06:10

hbceylan