The 3.81 GNU make manual includes an excellent section listing make error messages and their causes. We review a few of the most common ones here. Some of the issues described are not strictly make errors, such as syntax errors in command scripts, but are nonetheless common problems for developers. For a complete list of make errors, see the make manual.
Error messages printed by make have a standard format:
makefile : n : *** message . Stop.
make: n : *** message . Stop.
The makefile part is the name of the makefile or include file in which the error occurred. The next part is the line number where the error occurred, followed by three asterisks and, finally, the error message.
Note that it is make 's job to run other programs and that, if errors occur, it is very likely that problems in your makefile will manifest themselves as errors in these other programs. For instance, shell errors may result from badly formed command scripts, or compiler errors from incorrect command-line arguments. Figuring out what program produced the error message is your first task in solving the problem. Fortunately, make 's error messages are fairly self-evident.
12.3.1 Syntax Errors
These are usually typographical errors: missing parentheses, using spaces instead of tabs, etc.
One of the most common errors for new make users is omitting parentheses around variable names :
foo: for f in $SOURCES; \ do \ ... \ done
This will likely result in make expanding $S to nothing, and the shell executing the loop only once with f having a value of OURCES . Depending on what you do with f , you may get a nice shell error message like:
OURCES: No such file or directory
but you might just as easily get no message at all. Remember to surround your make variables with parentheses.
184.108.40.206 missing separator
makefile:2:missing separator. Stop.
makefile:2:missing separator (did you mean TAB instead of 8 spaces?). Stop.
usually means you have a command script that is using spaces instead of tabs.
The more literal interpretation is that make was looking for a make separator such as :, = , or a tab, and didn't find one. Instead, it found something it didn't understand.
220.127.116.11 commands commence before first target
The tab character strikes again!
This error message was first covered in Section 5.1 in Chapter 5. This error seems to appear most often in the middle of makefile s when a line outside of a command script begins with a tab character. make does its best to disambiguate this situation, but if the line cannot be identified as a variable assignment, conditional expression, or multiline macro definition, make considers it a misplaced command.
18.104.22.168 unterminated variable reference
This is a simple but common error. It means you failed to close a variable reference or function call with the proper number of parentheses. With deeply nested function calls and variable references, make files can begin to look like Lisp! A good editor that does parenthesis matching, such as Emacs, is the surest way to avoid these types of errors.
12.3.2 Errors in Command Scripts
There are three common types of errors in command scripts: a missing semicolon in multiline commands, an incomplete or incorrect path variable, or a command that simply encounters a problem when run.
We discussed missing semicolons in Section 12.2.1, so we won't elaborate further here.
The classic error message:
bash: foo: command not found
is displayed when the shell cannot find the command foo . That is, the shell has searched each directory in the PATH variable for the executable and found no match. To correct this error, you must update your PATH variable, usually in your .profile (Bourne shell), .bashrc (bash), or . cshrc (C shell). Of course, it is also possible to set the PATH variable in the makefile itself, and export the PATH variable from make .
Finally, when a shell command fails, it terminates with a nonzero exit status. In this case, make reports the failure with the message:
$ make touch /foo/bar touch: creating /foo/bar: No such file or directory make: *** [all] Error 1
Here the failing command is touch , which prints its own error message explaining the failure. The next line is make 's summary of the error. The failing makefile target is shown in square brackets followed by the exit value of the failing program. Sometimes make will print a more verbose message if the program exits due to a signal, rather than simply a nonzero exit status.
Note also that commands executed silently with the @ modifier can also fail. In these cases, the error message presented may appear as if from nowhere.
In either of these cases, the error originates with the program make is running, rather than make itself.
12.3.3 No Rule to Make Target
This message has two forms:
make: *** No rule to make target XXX. Stop.
make: *** No rule to make target XXX, needed by YYY. Stop.
It means that make decided the file XXX needed to be updated, but make could not find any rule to perform the job. make will search all the implicit and explicit rules in its database before giving up and printing the message.
There are three possible reasons for this error:
Your makefile is missing a rule required to update the file. In this case, you will have to add the rule describing how to build the target.
There is a typo in the makefile . Either make is looking for the wrong file or the rule to update the file specifies the wrong file. Typos can be hard to find in makefile s due to the use of make variables. Sometimes the only way to really be sure of the value of a complex filename is to print it out either by printing the variable directly or examining make 's internal database.
The file should exist but make cannot find it either, because it is missing or because make doesn't know where to look. Of course, sometimes make is absolutely correct. The file is missing ”perhaps you forgot to check it out of CVS. More often, make simply can't find the file, because the source is placed somewhere else. Sometimes the source is in a separate source tree, or maybe the file is generated by another program and the generated file is in the binary tree.
12.3.4 Overriding Commands for Target
make allows only one command script for a target (except for double- colon rules, which are rarely used). If a target is given more than one command script, make prints the warning:
makefile:5: warning: overriding commands for target foo
It may also display the warning:
makefile:2: warning: ignoring old commands for target foo
The first warning indicates the line at which the second command script is found, while the second warning indicates the location of the original command script that is being overridden.
In complex makefile s, targets are often specified many times, each adding its own prerequisites. One of these targets usually includes a command script, but during development or debugging it is easy to add another command script without realizing you are actually overriding an existing set of commands.
For example, we might define a generic target in an include file:
# Create a jar file. $(jar_file): $(JAR) $(JARFLAGS) -f $@ $^
and allow several separate makefile s to add their own prerequisites. Then in a makefile we could write:
# Set the target for creating the jar and add prerequisites jar_file = parser.jar $(jar_file): $(class_files)
If we were to inadvertently add a command script to this makefile text, make would produce the overriding warning.