]> git.ipfire.org Git - thirdparty/make.git/commitdiff
make.texi: Add an appendix with troubleshooting tips
authorPaul Smith <psmith@gnu.org>
Fri, 25 Aug 2023 15:10:34 +0000 (11:10 -0400)
committerPaul Smith <psmith@gnu.org>
Tue, 29 Aug 2023 19:39:16 +0000 (15:39 -0400)
doc/make.texi

index d3003a8f84f14244614e2366ef9356145891831a..dc10fecf20941585f1257f0097636ef64b7fec0f 100644 (file)
@@ -108,6 +108,7 @@ Cover art by Etienne Suvasa.
                                   GNU programs.
 * Quick Reference::             A quick reference for experienced users.
 * Error Messages::              A list of common errors generated by @code{make}.
+* Troubleshooting::             Advice on finding problems.
 * Complex Makefile::            A real example of a straightforward,
                                   but nontrivial, makefile.
 
@@ -381,6 +382,16 @@ Sharing Job Slots with GNU @code{make}
 * POSIX Jobserver::             Using the jobserver on POSIX systems.
 * Windows Jobserver::           Using the jobserver on Windows systems.
 
+Troubleshooting Make and Makefiles
+
+* Parse Error::                 Syntax errors when parsing makefiles.
+* Command Failure::             Recipe commands exit with error codes.
+* Wrong Rule::                  @code{make} chooses the wrong rule.
+* No Rule Found::               No rule was found to build a target.
+* Extra Rebuilds::              Targets are rebuilt unnecessarily.
+* Missing Rebuilds::            Out-of-date targets are not rebuilt.
+* Troubleshooting Strategies::  Strategies used for troubleshooting issues.
+
 @end detailmenu
 @end menu
 
@@ -465,6 +476,9 @@ others have.
 For a quick summary, see @ref{Options Summary}, @ref{Quick Reference},
 and @ref{Special Targets}.
 
+If you have a makefile already and it is not working as you expect,
+@pxref{Troubleshooting, ,Troubleshooting Make and Makefiles}.
+
 @node Bugs
 @section Problems and Bugs
 @cindex reporting bugs
@@ -13612,6 +13626,381 @@ prerequisite can be suffix rule and this warning will be removed.
 
 @end table
 
+@node Troubleshooting
+@appendix Troubleshooting Make and Makefiles
+
+Troubleshooting @code{make} and makefiles can be tricky.  There are two
+reasons: first, makefiles are not procedural programs and many users are used
+to procedural languages and scripts.  Second, makefiles consist of two
+different syntaxes in one file: makefile syntax, that @code{make} reads, and
+shell syntax, which is sent to a shell program for parsing and execution.
+
+If you have problems with GNU Make, first consider the type of problem you are
+having.  Problems will generally be in one of these categories:
+
+@itemize @bullet
+@item
+A syntax or other error was reported when @code{make} attempted to parse your
+makefiles.
+
+@item
+A command that @code{make} invoked failed (exited with a non-0 exit code).
+
+@item
+The command that @code{make} invoked was not the one you expected.
+
+@item
+@code{make} was not able to find a rule to build a target.
+
+@item
+@code{make} rebuilds a target that you didn't think was out of date.
+
+@item
+Or, @code{make} did not rebuild a target that you expected it to build.
+@end itemize
+
+The strategies for troubleshooting differ for different types of problems.
+For issues related to how makefiles are parsed, strategies include:
+
+@itemize @bullet
+@item
+Using the @samp{-p} option to show the makefile database, after evaluation
+(@pxref{Options Summary, ,Summary of Options}).
+
+@item
+Using the @code{info} or @code{warning} functions to understand how elements
+of the makefile are expanded (@pxref{Make Control Functions, ,Functions That
+Control Make}).
+@end itemize
+
+For issues related to how rules are applied, strategies include:
+
+@itemize @bullet
+@item
+Using the @samp{-n} or @samp{--trace} options to show the commands that
+@code{make} ran, and to explain which rules @code{make} invokes and why
+(@pxref{Options Summary, ,Summary of Options}).
+
+@item
+Using the @samp{--debug=v,i} or full @samp{-d} options to show how @code{make}
+is determining which recipes should be used, or why targets do not need to be
+rebuilt (@pxref{Options Summary, ,Summary of Options}).
+@end itemize
+
+@menu
+* Parse Error::                 Syntax errors when parsing makefiles.
+* Command Failure::             Recipe commands exit with error codes.
+* Wrong Rule::                  @code{make} chooses the wrong rule.
+* No Rule Found::               No rule was found to build a target.
+* Extra Rebuilds::              Targets are rebuilt unnecessarily.
+* Missing Rebuilds::            Out-of-date targets are not rebuilt.
+* Troubleshooting Strategies::  Strategies used for troubleshooting issues.
+@end menu
+
+@node Parse Error
+@appendixsec Errors When Parsing Makefiles
+
+This type of error is the simplest to resolve.  The error output you will see
+will have a format like this:
+
+@example
+Makefile:10: *** missing separator.  Stop.
+@end example
+
+This message gives you all the information you need to address the error: it
+gives the name of the makefile (here @samp{Makefile}) and the line number
+(here @samp{10}) in that makefile where GNU Make's parser failed.  Following
+that is a description of the error.  Further explanations of these error
+messages can be found in @ref{Error Messages, ,Errors Generated by Make}.
+
+@node Command Failure
+@appendixsec Errors Reported by Commands
+
+If GNU Make parses the makefiles correctly and runs a command to rebuild a
+target, it expects that command to exit with an error code of @samp{0} (for
+success).  Any other exit code will be reported by @code{make} as a failure
+and will generate an error message with this form:
+
+@example
+make: *** [Makefile:10: target] Error 2
+@end example
+
+All the information you need to find that command are given: the name of the
+makefile (here @samp{Makefile}) and line number (here @samp{10}) of the
+command make invoked, the target (here @samp{target}) that make was trying to
+build, and finally the exit code of the command (here @samp{2}).
+
+The precise meaning of the error code is different for different commands: you
+must consult the documentation of the command that failed to interpret it.
+However there are some reasons for error codes:
+
+@table @samp
+@item 2
+If the shell fails to parse your command (invalid shell syntax) it will exit
+with a code of @samp{2}.  On Windows this can also mean that the command was
+not found.
+
+@item 127
+If the command you wanted to run was not found, the shell will exit with a
+code of @samp{127}.
+@end table
+
+To troubleshoot these errors (@pxref{Troubleshooting Strategies, ,Strategies
+for Troubleshooting}), use the @samp{-n} or @samp{--trace} options so you can
+see the complete command line being invoked.
+
+Than, examine the output of the command that @code{make} invoked to determine
+what went wrong and why: this output will appear @emph{before} the above error
+message.  The error may be due to an incorrect command line in which case the
+error is in the way your command was written in the makefile, but it's far
+more likely to be a problem with something outside of the makefile (for
+example, a syntax error in the code you are trying to compile).
+
+@node Wrong Rule
+@appendixsec Choosing the Wrong Rule
+
+If @code{make} seems to be invoking a different command than the one you
+intended, it could be that the wrong rule is being chosen.
+
+To troubleshoot these errors (@pxref{Troubleshooting Strategies, ,Strategies
+for Troubleshooting}), add the @samp{--trace} option to the @code{make}
+command line.  This shows the rule that was chosen.
+
+You can also use the @samp{--debug=v,i} or the full @samp{-d} option to
+determine how @code{make} decided to use that rule.
+
+@node No Rule Found
+@appendixsec No Rule to Build A Target
+
+If @code{make} cannot locate a rule to build a target that you requested,
+either via the command line or as a prerequisite of another target, it shows
+an error such as:
+
+@example
+make: *** No rule to make target 'aprogram'.  Stop.
+@end example
+
+If the makefile doesn't provide a rule for this target, you can add one.  If
+there is a rule which you intended @code{make} to use to build this target and
+it wasn't used, the most common reasons for this are:
+
+@itemize @bullet
+@item
+The target was misspelled.  You should consider following the @dfn{DRY}
+principle (Don't Repeat Yourself) by assigning file names (targets and
+prerequisites) to makefile variables and using those variables rather than
+retyping the file names.
+
+@item
+The target is in a different directory.  @code{make} considers @samp{target}
+and @samp{dir/target} (for example) to be different targets.  If you are using
+rules that create files outside of the current working directory, be sure you
+correctly prefix them with their directories everywhere that they appear in
+the makefile.
+
+@item
+A pattern rule didn't match because one of its prerequisites cannot be built.
+Pattern rules will only be used when @strong{all} prerequisites can be
+satisfied: either they exist already or @code{make} can find a way to build
+them.  If any prerequisite cannot be created, then the pattern does not match
+and @code{make} will continue looking for another matching pattern.  If no
+matching pattern can be found, then @code{make} will fail.
+@end itemize
+
+To troubleshoot these issues (@pxref{Troubleshooting Strategies, ,Strategies
+for Troubleshooting}), run @code{make} with the @samp{--debug=v,i} option, or
+the full @samp{-d} option, and examine the detailed output.
+
+If the definition of the rule in your makefile is complicated, you can use the
+@samp{-p} option to ask make to print its internal database of rules to ensure
+they are correct, or as a last resort add invocations of the @code{info} or
+@code{warning} functions to show what steps @code{make} is taking during
+evaluation.
+
+@node Extra Rebuilds
+@appendixsec Unwanted Rebuilding of Targets
+
+If @code{make} is rebuilding a target which you feel is already up to date and
+doesn't need to be rebuilt, there can be a number of reasons:
+
+@itemize @bullet
+@item
+The recipe does not update the target.  A makefile rule is a promise to
+@code{make} that if it invokes the recipe, the target will be updated.  The
+file which @code{make} expects to be updated is placed in the @samp{$@@}
+variable.  If the recipe doesn't update this file, and @emph{exactly} this
+file, then the next time @code{make} is invoked it will try to re-build that
+target again.
+
+@item
+A prerequisite is marked as phony (@pxref{Special Targets, ,Special Built-in
+Target Names}).  All phony targets are always considered out of date, and so
+any targets depending on them are also out of date.
+
+@item
+A directory is used as a prerequisite.  Directories are not treated specially
+by @code{make}: if their modification time is newer than the target then the
+target is considered out of date and rebuilt.  Since directory modification
+times are changed whenever a file is created, deleted, or renamed in that
+directory, it means targets depending on the directory will be considered out
+of date whenever a file is created, deleted, or renamed in that directory.
+
+@item
+Something is deleting the target file.  Of course if a file does not exist it
+is always considered out of date (see the first item above).  If something in
+your environment, either inside the @samp{makefile} or outside if it, is
+deleting the target file then @code{make} will always rebuild it.
+
+@item
+The target is created with a ``too-old'' modification time.  If the recipe
+creates the target with a modification time in the past, then it may still be
+out of date with respect to its prerequisites.  This could happen if, for
+example, you are extracting files from an archive or copying them from another
+location and the tool used to do the extraction or copying preserves the
+original file's modification time.
+@end itemize
+
+To troubleshoot these issues (@pxref{Troubleshooting Strategies, ,Strategies
+for Troubleshooting}), use the @samp{--trace} option to understand why
+@code{make} decides to build a target and see the full command used.
+
+@node Missing Rebuilds
+@appendixsec Out-of-Date Targets Not Rebuilt
+
+The opposite of the previous problem is @code{make} not rebuilding targets
+that you think should be rebuilt.  Some reasons for this might be:
+
+@itemize @bullet
+@item
+The target is not being considered.  Unless the command line specifies
+otherwise, @code{make} will only consider the first target in the makefile and
+its prerequisites.  If the target you expected to be built is not one of
+these, then @code{make} won't build it.
+
+@item
+A different file is being built instead.  Be sure that your target is the file
+you want to be built (including any directory prefix!) and that the recipe
+will create the file listed as @samp{$@@}.  Also consider the directory that
+@code{make} is running in and whether relative pathnames are the ones you
+expect.
+@end itemize
+
+To troubleshoot these issues (@pxref{Troubleshooting Strategies, ,Strategies
+for Troubleshooting}), use the @samp{-n} or @samp{--trace} option to see what
+command is being invoked.
+
+You can also use the @samp{--debug=v,i} option or the full @samp{-d} option to
+obtain a complete description of everything @code{make} considered and why it
+decided to build or not build every target.
+
+@node Troubleshooting Strategies
+@appendixsec Strategies for Troubleshooting
+
+The strategies for troubleshooting differ for different types of problems.
+
+@subheading Show the makefile database
+
+Use the @samp{-p} option to show the makefile database, after evaluation
+(@pxref{Options Summary, ,Summary of Options}).  This allows you to see how
+@code{make} has evaluated the variables and recipes in your makefile.
+
+The @samp{-p} option asks GNU Make to print its internal database of rules,
+after all makefiles have been parsed.  You might see output such as:
+
+@example
+program: prereq.o
+#  Implicit rule search has not been done.
+#  Modification time never checked.
+#  File has not been updated.
+#  recipe to execute (from 'Makefile', line 10):
+        $(CC) -o $@@ $^ $(LDFLAGS) $(LDLIBS)
+@end example
+
+Here we can see the target (here @samp{program}) and prerequisites (here
+@samp{prereq.o}) after variable expansion, as well as the location of the
+definition of the recipe for this rule (here, in @samp{Makefile} at line
+@samp{10}).
+
+@subheading Add @code{info} or @code{warning} calls
+
+The @code{info} or @code{warning} function can help to understand how elements
+of the makefile are expanded (@pxref{Make Control Functions, ,Functions That
+Control Make}).
+
+Although their use requires modifying the makefile, these functions are a
+powerful tool for troubleshooting complex makefiles such as those using
+@code{eval} and @code{call} functions to dynamically generate rules.  For
+example if your makefile contains:
+
+@example
+$(foreach T,$(TARGET),$(eval $(call makerule,$T,$($T_PREREQ))))
+@end example
+
+@noindent
+then duplicating this line and replacing @code{eval} with @code{info} will
+show exactly what content @code{make} will be evaluating:
+
+@example
+$(foreach T,$(TARGET),$(info $(call makerule,$T,$($T_PREREQ))))
+@end example
+
+The @code{warning} function provides the same output as @code{info}, except
+that each output line is prefixed with the filename and line number where the
+@code{warning} function is expanded, and that the output goes to the standard
+error file descriptor and not to standard output.
+
+@subheading Use the @samp{--trace} or @samp{-n} option
+
+The @samp{-n} option will show you which commands would be invoked to bring
+targets up to date, without actually invoking them.  Commands are displayed
+even if the @samp{@@} prefix or the @code{.SILENT} target was specified
+(@pxref{Options Summary, ,Summary of Options}).
+
+Use the @samp{--trace} option on the @code{make} command line to explain which
+rules @code{make} invokes and why (@pxref{Options Summary, ,Summary of
+Options}).  This option also overrides @samp{@@} recipe prefixes and the
+@code{.SILENT} special target and shows the expanded command line.
+
+Adding this will result in output like this for each target which is rebuilt:
+
+@example
+Makefile:10: update target 'program' due to: target does not exist
+@end example
+
+@noindent
+or:
+
+@example
+Makefile:10: update target 'program' due to: prereq.o
+@end example
+
+This shows the filename of the makefile (here @samp{Makefile}) and line number
+(here @samp{10}), along with the name of the target (here @samp{program}) and
+the reason why it was rebuilt: in the first example because the target does
+not exist, and in the second example because there were prerequisites (here,
+@samp{prereq.o}) that were newer than the target.  All newer prerequisites
+would be listed here.
+
+After this information, the expanded command line make invoked will be shown,
+just as it is passed to the shell.  You should examine it carefully to
+determine whether it's correct, and compare it to the pre-expansion recipe in
+the makefile to see what aspect of the recipe might be incorrect.
+
+@subheading Use the @samp{--debug=v,i} or @samp{-d} option
+
+Use the @samp{--debug=v,i}, or the full @samp{-d}, options to show how
+@code{make} is determining which recipes should be used, or why targets do not
+need to be rebuilt (@pxref{Options Summary, ,Summary of Options}).
+
+The amount of output generated by these options can be daunting, but
+redirecting the output to a file then searching it for the target you are
+concerned with will show you exactly what steps GNU Make took when considering
+this target, and why it decided to build, or not build, that target.
+
+If the issue is that @code{make} decides @emph{not} to rebuild the target when
+you think it should, this may be your only recourse since @samp{--trace} only
+shows why targets are considered out of date.
+
 @node Complex Makefile
 @appendix Complex Makefile Example