Backtrace for GNU make

2019-04-07 16:44发布

问题:

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?

回答1:

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.



回答2:

make -p and make -d provide interesting information, but not precisely what you are asking for. See make's man page.



回答3:

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.