[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Adding debugging to GNU make (Mailing lists are a disaster lately!)

From: Paul D. Smith
Subject: Re: Adding debugging to GNU make (Mailing lists are a disaster lately!)
Date: Sun, 14 Mar 2004 16:50:53 -0500

I'm CC'ing this to the GNU make developer's list, address@hidden
If you're serious about working on this it would be a good idea to
subscribe to this list as I try to discuss every major feature on that

%% "R. Bernstein" <address@hidden> writes:

  rb> For a very long time I've wanted wanted a debugger for make. (For
  rb> example, I see I mentioned it last July in

The thing about a debugger for make is that make is not a procedural
language, like bash or C or whatever: it's much closer to functional
language like Lisp, with some database stuff thrown in, vaguely like

Also, make proceeds in two distinct and very different steps: basically
make is a combination of compiler and execution engine.  The first step
is to walk through the makefiles, internalizing all the variable values
and relationships.  This is not just a "read-in" step that can be
ignored for debugging purposes, though, like when GDB reads in the
program before it's run: many expansions of variables, etc. are done at
this step.  This step actually does look a lot like the traditional
procedural language.

Once that's done, make proceeds to the second step, actually walking the
dependency graph and invoking the rules necessary to bring the target up
to date.

Nevertheless of course something could be done, it's just a SMOP! :)

For example, maybe there could be two main "root" functions that
appeared at the top of the "traceback": one would be something like
eval() and cover the first step, and the second would be something like
run() and cover the second step.

Also the "stack" of the two steps would probably be very different: the
second step is pretty easy; the stack would be the dependency graph.
The second step is really just a straight walk.  However, when you
eval() you do recurse quite a bit in make, and even a run() "function"
will almost always invoke eval() numerous times to expand variables and

It might be slightly warped, but I think it could work, actually.

  rb> By "make debugging" I don't mean the "-d" option which gives way
  rb> too much detail, most of really not of interest to most people.

Well.  Put another way all of it is of interest to someone at some
point, but most of it is probably not that interesting for debugging any
given problem.  I tried to address that somewhat by breaking up the
debugging statements into different types and allowing the user to
select only certain types.

Anyway, on the TODO list for a long time has been a way to generate an
"elaborated" makefile, much like you can get preprocessed output from
the C compiler with the -E flag (in fact, I have intended to use the -E
flag in GNU make as well).  This would basically be what make sees after
the initial read-in evaluation steps are performed.  It would be
something like -p except generated as make reads things in, while -p
shows you the database after make is all done reading everything in.
And, -E would put things in proper order instead of hash table order,
and preserve line numbers and filenames and all that... I intend it to
use the same sorts of conventions for that as 'gcc -E' output.  I have
an implementation of this started, but haven't gotten back to it for a
while now.

The ability to show how variables are expanded is something else I've
thought about implementing.  The first problem is that make does so much
evaluation that the output of this would be _enormous_ and it would be
difficult to find what you were looking for.  You'd almost like to have
the ability to trace a given variable or set of variables rather than
just show every variable expansion.

  rb> Without having looked at the code, my guess is that as with bash,
  rb> the changes will necessity be somewhat drastic. Probably some
  rb> internal structure is going to need to store a line number and a
  rb> source file name and that's going to have to get updated which
  rb> probably means getting this from the parser or scanner.

Nope.  GNU make already internally stores the line number/filename of
every variable setting and target definition.  You've got no problems

The bigger problem you're going to have, I expect, is that the
implementation of make is very recursive.  That means that information
like the target/prerequisite build path from the "root" target to the
current target is not available to you programmatically.  It's inherent
in the call stack of the make program itself, so there's no place where
it's kept as data by GNU make itself.  You will have to start keeping
this information, I expect, if you want to create a debugger.

I don't want to discourage you because I think a debugger would be cool.
My one doubt is that it would be overkill.  Do we really need something
this interactive?  Sure, it could be very neat, and there are some very
complex makefiles around but I still have to wonder if overall it's
really needed.  Maybe the -E-type output would be good enough for the
complex cases that might otherwise use a debugger.

  rb> I imagine I should start from CVS sources. It looks like the this is
  rb> pretty stable right now -- mostly OS portability fixes rather than
  rb> "feature" enhancements (such as what I am proposing). Right? 

At the moment I'm stabilizing the code for a 3.81 release, so correct,
there aren't any major enhancements going in right now.

 Paul D. Smith <address@hidden>          Find some GNU make tips at:            
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

reply via email to

[Prev in Thread] Current Thread [Next in Thread]