Is there any way to get GNU make to print a "backtrace" of the targets that led to the command being executed when it fails? I regularly deal with heavily obfuscated makefiles while resolving portability issues building software on a new system, and it seems like this should be an extremely simple thing for make to do that would greatly aid in debugging, but I can't find any way to request it. What I'd like to see is something like:
gcc: error: ...
make[2]: error: gcc ...
make[2]: error building target bar
make[2]: error building dependency bar for target foo
make[1]: error: make -C subdir
make[1]: error building target subdir
make[1]: error building dependency subdir for target all
...
showing the entire dependency path for how the failed command ended up getting executed.
Is there any way to do this?
Use remake. It is a patched version of GNU Make that adds improved error reporting, the ability to trace execution in a comprehensible way, and a debugger.
make -p
and make -d
provide interesting information, but not precisely what you are asking for. See make's man page.
Yes, remake can give you a backtrace. Here is a run to using the remake's Makefile show this:
remake --debugger Makefile
GNU Make 4.1+dbg0.91
Built for x86_64-unknown-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 2015 Rocky Bernstein.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating makefiles....
-> (/src/github/remake/Makefile:608)
Makefile: Makefile.in config.status
remake<0> bt
=>#0 Makefile at /src/github/remake/Makefile:608
remake<1> s
-> (/src/github/remake/Makefile:594)
Makefile.in:
remake<2> bt
=>#0 Makefile.in at /src/github/remake/Makefile:594
#1 Makefile at /src/github/remake/Makefile:608
remake<3> s
-> (/src/github/remake/Makefile:618)
config.status: configure
remake<4> bt
=>#0 config.status at /src/github/remake/Makefile:618
#1 Makefile at /src/github/remake/Makefile:608
remake<5> s
-> (/src/github/remake/Makefile:621)
configure:
remake<6> bt
=<#0 configure at /src/github/remake/Makefile:621
#1 config.status at /src/github/remake/Makefile:618
#2 Makefile at /src/github/remake/Makefile:608
remake<7>
You could also set a breakpoint at a particular target (break
), go there (continue
) and backtrace
that. And on error, you will get a backtrace of where you were at when you crashed.