I've gone through a few iterations of the format of make error messages
and I'm still not happy.
Originally we didn't put the makefile name/linenumber in the error at
all when a recipe failed (we did for syntax errors in makefiles of
course). Then someone asked for make to show a reference to the recipe
that failed when make detected an error, so I changed it to this:
make: *** [Makefile:3: myprog.o] Error 1
The idea was to use the same format that the compiler, etc. used so
that (for example) Emacs compile mode would be able to jump to errors.
That didn't work, however, because particularly in recursive make the
makefile name is likely not qualified with a path, but the current
working directory when the build is invoked is not the same as the one
where make is invoked--thus "Makefile" is at best ambiguous.
So now I've changed the output to use a semicolon between the name and
the line number to try to "hide" this from Emacs compile mode:
make: *** [Makefile;3: myprog.o] Error 1
This fixed the problem at least for Emacs compile mode; it no longer
recognizes this as an error line. But it still seems suboptimal to me.
I've been wondering if we shouldn't make an attempt to show the
"correct" path to the makefile in these error messages. The way I was
imagining it could work is something like this:
(a) when make is invoked it looks for special environment variable,
like MAKE_ROOTDIR or something. If that value is set it is remembered.
If that variable is not set then it is set to the value of
current_directory (already computed in main() using getcwd()) and
exported. The result is that MAKE_ROOTDIR should be the current
working directory of the user when they invoked the top-level make,
even if we're in a recursive make.
(b) when make wants to generate an error message containing the name of
the current makefile, it computes the fully-qualified path of the
makefile then strips off the prefix MAKE_ROOTDIR and prints that as the
name of the makefile. Of course if the path doesn't start with
MAKE_ROOTDIR we print the fully-qualified path.
Obviously there are some weirdnesses here... for example the ever-
present issue of symlinks yielding multiple different paths to the same
directory, but in that situation you'd simply get the fully-qualified
Also, if you had a script that changed directory then invoked the root
make it would not work... but your script could pre-set $MAKE_ROOTDIR
before starting make.
Or we could always print the fully-qualified path but that may look
This would also allow us to go back to the error message with a ":"
since Emacs could jump to the correct place in the correct makefile.
> That didn't work, however, because particularly in recursive make the
> makefile name is likely not qualified with a path, but the current
> working directory when the build is invoked is not the same as the one
> where make is invoked--thus "Makefile" is at best ambiguous.
But isn't that the same situation as with any other error message in a
recursive make, which Emacs already handles correctly (with the help of
Andreas Schwab, SUSE Labs, [hidden email] GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
On Wed, 2019-09-11 at 08:44 +0200, Andreas Schwab wrote:
> On Sep 10 2019, Paul Smith <[hidden email]> wrote:
> > That didn't work, however, because particularly in recursive make
> > the makefile name is likely not qualified with a path, but the
> > current working directory when the build is invoked is not the same
> > as the one where make is invoked--thus "Makefile" is at best
> > ambiguous.
> But isn't that the same situation as with any other error message in
> a recursive make, which Emacs already handles correctly (with the
> help of make --print-directory)?
Thanks for getting me to look into this more deeply.
The problem is not print-directory, etc. The problem is that Emacs
compile mode doesn't have a matcher for error messages generated by GNU
make when a target fails. As such it matches some other regex in
compilation-error-regexp-alist-alist and computes the filename
I've sent a patch to Emacs for compile.el which adds a matching regex
for GNU make error messages, and assigns them the INFO level since they
are usually not needed, but sometimes is is very handy to be able to
jump to the makefile recipe.
In the meantime I've added this to my init.el:
;; Add support for GNU make error matching, if it doesn't yet exist
(or (member 'gmake compilation-error-regexp-alist)
(setf (alist-get 'gmake compilation-error-regexp-alist-alist)
'(": \\*\\*\\* \\[\\(\\(.+?\\):\\([0-9]+\\): .+\\)\\]"
2 3 nil 0 1))
(add-to-list 'compilation-error-regexp-alist 'gmake))))
I'm going to revert the change I made to GNU make to use ";" instead of
":" between the filename and line number (that was never part of any
release of GNU make) and go back to ":".