| [Top] | [Contents] | [Index] | [ ? ] |
This file describes the GNU Make debugger
This is the 3.80+dbg-0.62 Edition, February 2007
Copyright (C) 2004, 2005, 2006, 2007 Rocky Bernstein
| 1. Summary of the GNU Make Debugger | Overview of Debugger with a sample session | |
| 2. Getting in and out and new GNU Remake Command Options | Getting in and out and GNU Make command options | |
| 3. GNU Remake Debugger Command Reference | the GNU Make debugger command reference | |
| 4. Using the GNU Make debugger from a front-end user interface | ||
| 5. Reporting Bugs | Reporting bugs | |
| 6. History and Acknowledgments | ||
Indexes (nodes containing large menus) | ||
| Command Index | An item for each command name. | |
| General Index | An item for each concept. | |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The purpose of a debugger such as the GNU Make debugger is to allow you to see what is going on "inside" the GNU Make debugger when it processes a Makefile.
The GNU Remake debugger can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
Although you can use the the GNU Make debugger to debug Makefiles, it can also be used just as a front-end for learning more about Makefiles and writing them with GNU Remake.
A degenerate and less-interactive form of debugging is tracing in which one passively watches some of the steps that go on in processing a Makefile.
| 1.1 Sample GNU Remake Debugger Sessions | Sample GNU Make Debugger sessions | |
| Free software | Freely redistributable software |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can use this manual at your leisure to read all about the GNU Make debugger. However, a handful of commands are enough to get started using the debugger. This chapter illustrates those commands.
| 1.1.1 How NOT to debug GNU Make | How NOT to debug your program | |
| 1.1.2 Sample GNU Remake Trace Sessions | Using -trace or -x on a simple example | |
| 1.1.3 Tracing Makefile Reading | A real-world trace. | |
| 1.1.4 Simple GNU Remake Debug Sessions | Getting into the Debugger (-debugging) | |
| 1.1.5 Debugging Variables | ||
| 1.1.6 Debugging Commands |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Before we get into debugging proper, we'll discuss tracing and a
pitfall the author once made in his first attempt to debug a large and
mysterious Makefile. Chances you may have have happened to you too.
A simplified form of debugging is tracing. Often this may be
good enough to understand what might have gone wrong. In fact, in the
Unix shell world (tcsh, csh, bash, sh)
prior to my debugger for bash (http://bashdb.sourceforge.net)
tracing along with print statements was about all that was available
to debug a program.
GNU Make has had for a long time a "debug" flag (--debug
or -d) which prints "lots of debugging information." For the
unwary one might think you just add this simple option and that's
going to do what you want. Wrong!(1)
Alas, the --debug option gives way too much information to be
helpful. Furthermore, debug-flag information omits information
that would be helpful.
To elaborate upon this, here is a simple small Makefile with an
invalid shell command in it:
!: # Makefile to show off tracing 2: .PHONY: all 3: all: foo 4: 5: foo: 6: @case $(MAKE) in \ 7: */remake|remake) echo "Enlightended!";; \ 8: */make|make) echo "This is what most folks use.";; \ 9: esac 10: @bogus-command |
But now let's see what happens when we run "debug" from an unpatched GNU Make:
$ /usr/bin/make -d -f test1.mk Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Reading makefiles... Reading makefile `test1.mk'... Updating makefiles.... Considering target file `test1.mk'. Looking for an implicit rule for `test1.mk'. Trying pattern rule with stem `test1.mk'. Trying implicit prerequisite `test1.mk.o'. Trying pattern rule with stem `test1.mk'. Trying implicit prerequisite `test1.mk.c'. ... over 350 lines later ... No need to remake target `test1.mk'. Updating goal targets.... Considering target file `all'. File `all' does not exist. Considering target file `foo'. File `foo' does not exist. Finished prerequisites of target file `foo'. Must remake target `foo'. This is what most folks use. Got a SIGCHLD; 1 unreaped children. Putting child 0x095b1310 (foo) PID 13440 on the chain. Live child 0x095b1310 (foo) PID 13440 Reaping winning child 0x095b1310 PID 13440 make: bogus-command: Command not found Got a SIGCHLD; 1 unreaped children. Live child 0x095b1310 (foo) PID 13441 Reaping losing child 0x095b1310 PID 13441 make: *** [foo] Error 127 Removing child 0x095b1310 PID 13441 from chain. |
The output would have been about twice as long were it not for the
fact that we declared all a "phony" target!
Clearly this information referring to rule stems, implicit
prerequisites, SIGCHLD, pids, and unreaped children is intended
for someone who is well versed with the internals of GNU Make.
But even for someone such as myself who has become more knowledgeable (through writing this debugger), it still isn't all that helpful. In the midst of the above jumble, the program reports:
make: bogus-command: command not found |
?? Okay. But where in the source Makefile did that come from?
Since we added the debug output we see "foo" listed
beforehand after skipping hundreds of lines, but in a normal make,
there would have been no mention of "foo." In our simple example
tracking down the location is easy. But when you have a Makefile
which is hundreds of lines long as any Makefile is when it is
generated from automake, it would be nice to list the line in
the Makefile and full filename as well as the target name.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Okay so now that we know what not to do, lets delve into things may be more helpful.
There are variants of the --debug command option that provide
shorter and more-interesting information. One is called "basic"
tracing. Another is the --just-print option.
Again here's the sample Makefile:
!: # Makefile to show off tracing 2: .PHONY: all 3: all: foo 4: 5: foo: 6: @case $(MAKE) in \ 7: */remake|remake) echo "Enlightended!";; \ 8: */make|make) echo "This is what most folks use.";; \ 9: esac 10: @bogus-command |
In an unpatched GNU Make version 3.81 (and earlier) GNU Make,
--just-print gives this:
$ make --just-print -f test1.mk case make in \ */remake|remake) echo "Enlightended!";; \ */make|make) echo "This is what most folks use.";; \ esac This is what most folks use. bogus-command |
Well, not much different from the original Makefile, except that information about where this gets run from is curiously missing. If there had been several targets that had commands, from the output it would not be possible to determine which command was associated with which target.
One of the goals of GNU Remake is to include reference information. Here's what we give instead:
$ make --just-print -f test.mk1 ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/test1.mk:6: foo case /tmp/remake/src/./make in \ */remake|remake) echo "Enlightended!";; \ */make|make) echo "This is what most folks use.";; \ esac ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< This is what most folks use. ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/test1.mk:10: foo bogus-command ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
What's different is that we make more clear where in the file this
command is getting run from and from what target. This may be a little
bit subtle, but from the above output it is more apparent that there
are two separate commands(2) that are getting run
from target foo: one at line 6 and another at line 10.
One last and perhaps also subtle point is the format of the location
information. This format is similar to other debugger output. The
above command is run inside a GNU Emacs compilation buffer the format
of the message is such that compile-goto-error will possition
one at that point in the file in another Emacs window.
Now let's try --debug=basic alluded to at the beginning of this
section. In an unpatched GNU Make version 3.81 (and earlier)
GNU Make --debug=basic gives this:
$ make --debug=basic -f test1.mk GNU Make 3.80 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Reading makefiles... Updating goal targets.... File `all' does not exist. File `foo' does not exist. Must remake target `foo'. This is what most folks use. make: bogus-command: Command not found make: *** [foo] Error 127 ########################################################## |
The --debug=basic command-line switch also works in
GNU Remake as well if that's all you want.(3)
Now let's try the new kind of trace we provide in this patched
GNU Remake. We use the new option --trace which has the
short-form option format -x.
And here's the trace of it:
$ remake --trace -f test1.mk Reading makefiles... Updating goal targets.... /tmp/test1.mk:3 File `all' does not exist. /tmp/test1.mk:5 File `foo' does not exist. /tmp/test1.mk:5 Must remake target `foo'. ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/test1.mk:6: foo case /tmp/remake/src/./make in \ */remake|remake) echo "Enlightended!";; \ */make|make) echo "This is what most folks use.";; \ esac ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + case /tmp/remake/src/./make in + echo 'This is what most folks use.' This is what most folks use. ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/remake/src/test1.mk:10: foo bogus-command ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + bogus-command /bin/sh: bogus-command: command not found test1.mk:10: *** [foo] Error 127 #0 foo at /tmp/test1.mk:10 #1 all at /tmp/test1.mk:3 Command-line arguments: "--trace -f test1.mk" |
So in some ways this is just a combination of the enhanced (with
location information) --just-print option combined with the
enhanced --debug=basic information.
What is completely new and hasn't been seen above is the shell tracing
information and information given when we hit an error. After the
error and we report the return code (127), the stack of targets is
listed. We were working on target foo on line 10 of file
/tmp/test1.mk which was rebuilt because we were making target
all on line 3 of file /tmp/test1.mk.
In other words, when we hit the error, the above trace gives some idea of why we decided to to run line 10 and what got executed before that, what targets were in the process of getting considered at the error, and how the program was run.
One last subtlety that you might not have noticed is that we echoed
the command bogus-command even though the original makefile had
this set to be silent (in particular by preceding that command with an
@). When tracing, we override any silent execution (making execution
more verbose); information is usually helpful in finding what's going
on and what got run.
In sum, I hope I've conveyed the idea that the goal is simple trace output for a simple Makefile. Although I think that the above may be improved, it is far better than what has previously been available in GNU make.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Make and GNU Remake work like many other interpreters. First Makefiles are read in and parsed and then they are "executed" which in GNU Make means that dependency checks are done and actions are performed based on those checks. However there is quite a bit work that may be done just in portion which reads in the Makefiles and performs variable expansion.
To see this, let's use a real example - the Makefile for the GNU Make + Debugger. For comparison, here is a simple trace:
$ remake --trace Reading makefiles... Updating goal targets.... /tmp/remake/src/Makefile:257 File `all' does not exist. /tmp/remake/src/Makefile:470 File `all-am' does not exist. /tmp/remake/src/Makefile:470 Must remake target `all-am'. Is a phony target. /tmp/remake/src/Makefile:470 Successfully remade target file `all-am'. /tmp/remake/src/Makefile:257 Must remake target `all'. Is a phony target. /tmp/remake/src/Makefile:257 Successfully remade target file `all'. remake: Nothing to be done for `all'. |
So far so good - still pretty simple output even though the Makefile
in this case is pretty complex, is hundreds of lines long and has
thousands of dependencies noted. Digging just a little into this
complexity, If we want to trace the files that were read in performing
the above, we can use the sub-option read on the --trace
option:
$ remake --trace=read Makefile Reading makefiles... Reading makefile `Makefile'... /tmp/remake/src/Makefile:329 Reading makefile `.deps/alloca.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:330 Reading makefile `.deps/getloadavg.Po' (search path) (no ~ expansion)... ... about 32 more lines like the above ... Updating goal targets.... remake: `Makefile' is up to date. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Now let's go into the debugger. To do this, use the --debugger
or -X option. Again we'll use the Makefile from the source code
of this distribution.
$ remake --debugger Reading makefiles... (/tmp/src/remake/src/Makefile:263) Makefile.in: Makefile.am ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac ../aclocal.m4 mdb<0> |
Before the prompt mdb<0>, we show the position in the file,
the target Makefile.in, and the dependencies of this target
Makefile.am, ..config/readline.m4 ....
The "0" in the prompt mdb<0> is the command history number
it increments as we enter commands.
Is this really the top-level target? The where command,
(see Backtraces (`where')), shows you the target call stack:
mdb<0> where =>#0 Makefile.in at /tmp/src/remake/src/Makefile:263 #1 Makefile at /tmp/src/remake/src/Makefile:276 mdb<1> |
No, we were triggered by checking dependencies from
Makefile.(4)
Notice that the prompt now lists "1" since we entered a command.
We can use the step command, (Step (`step')), to progress a little
in the interpretation or execution of the makefile:
mdb<1> step (/tmp/src/remake/src/Makefile:290) ../aclocal.m4: ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac mdb<2> where =>#0 ../aclocal.m4 at /tmp/remake/src/Makefile:290 #1 Makefile.in at /tmp/remake/src/Makefile:263 #2 Makefile at /tmp/remake/src/Makefile:276 |
Before the prompt the debugger printed some information about the
target, namely its name and dependencies. However if you want the full
details about a target, one can use the target (Examining Targets (`target')
command:
mdb<3> target ../aclocal.m4: ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac # Implicit rule search has not been done. # Implicit/static pattern stem: `' # Last modified 2005-12-10 21:41:10 # File has not been updated. # automatic # := ../aclocal.m4 # automatic # % := # automatic # * := # automatic # + := ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac # automatic # | := # automatic # < := ../config/readline.m4 # automatic # ^ := ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac # automatic # ? := # commands to execute (from `Makefile', line 291): cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
I could have gotten the same output explicitly giving a target name
such as target ../aclocal.m4, or used the GNU Make
automatic variable name @.
What is going on here is we are checking to see if the Makefile needs
to be remade, and in doing this we need to see if Makefile.in needs
to be remade and that depends on target ../aclocal.m4.
We don't have to be stopped on a target to get information about it:
mdb<4> target all-am target all-am all-am: Makefile make loadavg ar_fns.h arscan.h commands.h dbg_break.h dbg_cmd.h dbg_fns.h dbg_stack.h debug.h default.h dep.h dir_fns.h expand.h file.h function.h gettext.h hash.h implicit.h job.h make.h misc.h print.h read.h remake.h remote-stub.h rule.h trace.h types.h variable.h vpath.h # Phony target (prerequisite of .PHONY). # Implicit rule search has not been done. # Implicit/static pattern stem: `' # File does not exist. # File has not been updated. # automatic # := all-am # automatic # % := # automatic # * := # automatic # + := Makefile make loadavg ar_fns.h arscan.h commands.h dbg_break.h dbg_cmd.h dbg_fns.h dbg_stack.h debug.h default.h dep.h dir_fns.h expand.h file.h function.h gettext.h hash.h implicit.h job.h make.h misc.h print.h read.h remake.h remote-stub.h rule.h trace.h types.h variable.h vpath.h # automatic # | := # automatic # < := all-am # automatic # ^ := Makefile make loadavg ar_fns.h arscan.h commands.h dbg_break.h dbg_cmd.h dbg_fns.h dbg_stack.h debug.h default.h dep.h dir_fns.h expand.h file.h function.h gettext.h hash.h implicit.h job.h make.h misc.h print.h read.h remake.h remote-stub.h rule.h trace.h types.h variable.h vpath.h # automatic # ? := mdb<5> |
However information may change depending on where Make is. In particular note that "Implicit rule search has not been done."
If all of this is proceeding too slowly, could set a
breakpoint on a target of interest, perhaps all-am. Like
this:
mdb<4> restart Changing directory to /tmp/remake/src and restarting... Reading makefiles... /tmp/remake/src/Makefile:255: Makefile.in mdb<0> break all-am Breakpoint on target all-am set. |
The restart command was used to restart execution since we've
already passed considering the "all-am" target. So let's
continue, (Continue (`continue')), execution and see what happens:
mdb<1> continue Updating goal targets.... /tmp/remake/src/Makefile:250 File `all' does not exist. /tmp/remake/src/Makefile:461: all-am mdb<2> where =>#0 all-am at /tmp/src/remake/src/Makefile:472 #1 all at /tmp/src/remake/src/Makefile:259 |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
We've seen we can get information about GNU Remake's targets. We
can also get information about GNU Remake's variables. That is done
with the print command. (See Print variable info (`print').)
mdb<4> print MAKE (origin default) MAKE = $(MAKE_COMMAND) |
The (origin default) means this is a built-in
definition. There is another print which does full expansion
of the variables. So if I run x (examine) instead I get:
mdb<5> examine MAKE (origin default) MAKE := /tmp/remake/src/./make |
Note that in printing expanded values we use ":=" while non-expanded values we use "=". This output matches the semantics of these assignment operators.
In fact, examine doesn't need a variable name, it will work
with a string. So I could type "x This is $(MAKE)" or
"x $(bin_PROGRAMS) $(noinst_PROGRAMS)". For the latter, I
get:
mdb<6> x $(bin_PROGRAMS) $(noinst_PROGRAMS) make loadavg |
No location identification is given here since what I put in isn't a variable.
But I can also change values too using either set or
setq. (See Setting a variable to an expanded string (`set variable') and Setting a variable to an unexpanded string (`setq').) Let's see the difference
between the two.
mdb<7> set MAKE $(MAKE_COMMAND) Variable MAKE now has value '/tmp/remake/src/./make' mdb<8> setq MAKE $(MAKE_COMMAND) Variable MAKE now has value '$(MAKE_COMMAND)' |
So with set, the value in the expression $(MAKE_COMMAND)
is expanded before the variable definition is assigned. With
setq, See section Setting a variable to an unexpanded string (`setq'), the internal variables are kept
unexpanded. Which you use or want is up to you.
Note the irregular syntax of set and "setq. Don't put an
equal sign (=) between the variable and the expression. That
is, set MAKE = $(MAKE_COMMAND)" gives:
Variable MAKE now has value '= /tmp/remake/src/./make' |
which is probably not what you want. One may optionally put in the
the word "variable" when using set, one must not supply
it with "setq." Down the line, someone (maybe you!) will
probably put in a command parser.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Now consider the following sample Makefile:
$ cat -n test2 1 PACKAGE=make 2 3 all: $(PACKAGE).txt 4 5 $(PACKAGE).txt: ../doc/mdb.texi 6 makeinfo --no-headers $< > $ |
$ remake -X -f test2 Reading makefiles... Updating goal targets.... /tmp/remake/src/test2:3 File `all' does not exist. (/tmp/remake/src/test2:3): all |
As before we'll use the target command to show information about
all:
mdb<0> target all: make.txt # Implicit rule search has not been done. # Implicit/static pattern stem: `' # File does not exist. # File has not been updated. # automatic # @ := all # automatic # % := # automatic # * := # automatic # + := make.txt # automatic # | := # automatic # < := all # automatic # ^ := make.txt # automatic # ? := |
When asking about target information on line 3, we now see that a
number of automatic variables have been set. We can also get
information about just these variables using the command target
all variables or info locals:
mdb<1> info locals @ := all % := * := + := make.txt | := < := all ^ := make.txt ? := |
The target "all" doesn't have any commands associated with it. If we
next to a target that does, we can see a full expansion of the
command that is about to be run:
mdb<2> next /tmp/remake/src/test2:5 File `make.txt' does not exist. (/tmp/remake/src/test2:5): make.txt mdb<3> target make.txt commands make.txt: # commands to execute (from `test2', line 6): makeinfo --no-headers $< > $@ mdb<4> examine makeinfo --no-headers $< > $@ makeinfo --no-headers ../doc/mdb.texi > make.txt |
Another way to do the above target and examine commands
in one go is ito use the "expand" option on the target command
rather than the "commands" option:
mdb<5> target @ expand make.txt: # commands to execute (from `test2', line 6): -makeinfo --no-headers $< > $ # commands to execute (from `test2', line 6): -makeinfo --no-headers ../doc/mdb.texi > make.txt |
Notice instead of giving the target name make.txt, @
works as well.
Now if we want to write out those commands as a shell script which
we might want to execute, we can use the write (Write commands of a target (`write'))
command:
(/tmp/remake/src/test2:6): make.txt
mdb<6> write
File "/tmp/make.txt.sh" written.
mdb<7> shell cat -n /tmp/make.txt.sh
1 #!/bin/sh
2 # cd /tmp/remake/src/
3 #/tmp/remake/src/test2:5
4 makeinfo --no-headers ../doc/mdb.texi > make.txt
5
|
And last we see that we can even issue a shell command (cat -n
/tmp/make.txt.sh) via the debugger command shell. (See
Running Shell commands ( `shell').)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
the GNU Make debugger is free software, protected by the GNU General Public License (GPL). The GPL gives you the freedom to copy or adapt a licensed program--but every person getting a copy also gets with it the freedom to modify that copy (which means that they must get access to the source code), and the freedom to distribute further copies. Typical software companies use copyrights to limit your freedoms; the Free Software Foundation uses the GPL to preserve these freedoms.
Fundamentally, the General Public License is a license which says that you have these freedoms and that you cannot take these freedoms away from anyone else.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The biggest deficiency in the free software community today is not in the software--it is the lack of good free documentation that we can include with the free software. Many of our most important programs do not come with free reference manuals and free introductory texts. Documentation is an essential part of any software package; when an important free software package does not come with a free manual and a free tutorial, that is a major gap. We have many such gaps today.
Consider Perl, for instance. The tutorial manuals that people normally use are non-free. How did this come about? Because the authors of those manuals published them with restrictive terms--no copying, no modification, source files not available--which exclude them from the free software world.
That wasn't the first time this sort of thing happened, and it was far from the last. Many times we have heard a GNU user eagerly describe a manual that he is writing, his intended contribution to the community, only to learn that he had ruined everything by signing a publication contract to make it non-free.
Free documentation, like free software, is a matter of freedom, not price. The problem with the non-free manual is not that publishers charge a price for printed copies--that in itself is fine. (The Free Software Foundation sells printed copies of manuals, too.) The problem is the restrictions on the use of the manual. Free manuals are available in source code form, and give you permission to copy and modify. Non-free manuals do not allow this.
The criteria of freedom for a free manual are roughly the same as for free software. Redistribution (including the normal kinds of commercial redistribution) must be permitted, so that the manual can accompany every copy of the program, both on-line and on paper.
Permission for modification of the technical content is crucial too. When people modify the software, adding or changing features, if they are conscientious they will change the manual too--so they can provide accurate and clear documentation for the modified program. A manual that leaves you no choice but to write a new manual to document a changed version of the program is not really available to our community.
Some kinds of limits on the way modification is handled are acceptable. For example, requirements to preserve the original author's copyright notice, the distribution terms, or the list of authors, are ok. It is also no problem to require modified versions to include notice that they were modified. Even entire sections that may not be deleted or changed are acceptable, as long as they deal with nontechnical topics (like this one). These kinds of restrictions are acceptable because they don't obstruct the community's normal use of the manual.
However, it must be possible to modify all the technical content of the manual, and then distribute the result in all the usual media, through all the usual channels. Otherwise, the restrictions obstruct the use of the manual, it is not free, and we need another manual to replace it.
Please spread the word about this issue. Our community continues to lose manuals to proprietary publishing. If we spread the word that free software needs free reference manuals and free tutorials, perhaps the next person who wants to contribute by writing documentation will realize, before it is too late, that only free manuals contribute to the free software community.
If you are writing documentation, please insist on publishing it under the GNU Free Documentation License or another free documentation license. Remember that this decision requires your approval--you don't have to let the publisher decide. Some commercial publishers will use a free license if you insist, but they will not propose the option; it is up to you to raise the issue and say firmly that this is what you want. If the publisher you are dealing with refuses, please try other publishers. If you're not sure whether a proposed license is free, write to licensing@gnu.org.
You can encourage commercial publishers to sell more free, copylefted manuals and tutorials by buying them, and particularly by buying copies from the publishers that paid for their writing or for major improvements. Meanwhile, try to avoid buying non-free documentation at all. Check the distribution terms of a manual before you buy it, and insist that whoever seeks your business must respect your freedom. Check the history of the book, and try to reward the publishers that have paid or pay the authors to work on it.
The Free Software Foundation maintains a list of free documentation published by other publishers, at http://www.fsf.org/doc/other-free-books.html.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter discusses how to start the GNU Make debugger, and how to get out of it. The essentials are:
You don't have to use the command-line interface. At present there is
a front-end available via GNU Emacs which can be entered
via the Emacs command M-x mdb after loading Emacs' Grand
Unified Debugger, gud. See Using the GNU Make debugger from GNU Emacs. In the future there may be support in a DDD
as well.
| 2.1 Starting the GNU Make debugger | How to enter the the GNU Make debugger | |
| 2.2 Quitting the GNU Make debugger | How to leave the the GNU Make debugger |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Note: it is important to use a debugger-enabled GNU Make. You will get usage help output if a patched GNU Make is not used.
As mentioned above, one can enter the GNU Make debugger via Emacs (and perhaps later DDD). However you don't have to use either of these. And these still need a way on their own to get things started.
The enter the GNU Make debugger from a command line, use the `--debugger' or it's short form `-X' option:
make --debugger other-make-arguments... make -X other-make-arguments... |
This runs GNU Remake as it would normally do; that is Makefiles are read and dependencies are checked. However it is in a "stepping" mode and will go into the debugger read loop when before encounter in "interesting" target. An "interesting" target is one that has commands associated with it to rebuild the target.
A suboption to the --debugger (or -X) option specifies
under what conditions to enter the debugger; it is specified by
putting an equals sign (`=') and then the suboption; for example:
make -X=preread other-make-arguments... |
Here is a full list of debugger options and suboptions...
--debugger [preread | preaction | full | error | fatal]-X [preread | preaction | full | error | fatal]The "preread" suboption enters the debugger after command-line options are parsed but before any Makefiles have been read. It also puts GNU Remake in step-tracing mode and sets the debugger to enter if it encounters an error.
The "preaction" suboption enters the debugger after command-line options are parsed and after Makefiles have been read, but before any action is performed. It also puts GNU Remake in step-tracing mode and sets the debugger to enter if it encounters an error.
The "error" suboption enters the debugger when it encounters an
error. Depending on other conditions, GNU Remake can ignore errors
and continue processing. So the overall effect could be like the
--keep-going flag.
The "fatal" suboption enters the debugger when it encounters a fatal error. A fatal error generally cause GNU Remake to abort execution.
The "full" suboption is just a convenience for giving the "enter," "error," and "fatal" options described above. execution.
If no suboption is provided, "full" is assumed.
--no-extended-errorsThis option causes GNU Remake to not print a target stack trace if it encounters an error.
--trace [=suboption]-xCauses target names which have commands associated with them to get printed before they are considered. If a target has multiple commands each one is printed before they are run whether or not the command has the GNU Remake @ specifier which would otherwise cause them not to echo.
This option also allows for suboptions, read, normal,
and full. The default is normal; read adds
tracing as Makefiles are read.
tracing is independent of the --debugger option and can be used
in conjunction with it. Inside the debugger one can have the same
effect by issuing the debugger set trace on command.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An interrupt (often C-c) does not exit from the GNU Make debugger, but
rather terminates the action of any the GNU Make debugger command that is in
progress and returns to the GNU Make debugger command level. Inside a debugger
command interpreter, use quit command (see section Quitting the Make debugger).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can abbreviate the long name of the GNU Make debugger command to the first
few letters of the command name, if that abbreviation is unambiguous;
and you can repeat the next o rstep commands by typing
just RET. Some commands which require a parameter, such as
print remember the argument that was given to them.
| 3.1 Command syntax | How to give commands to the the GNU Make debugger | |
| 3.2 Getting help (`help') | How to ask for help (help) | |
| 3.3 Quitting the GNU Make debugger (`quit') | Leaving the debugger (quit) | |
| 3.4 Stopping and Resuming Execution | Stopping and continuing (break, watch, step, cont...) | |
| 3.5 Status and Debugger Settings (`info', `show', `set') | Status and Debugger settings (info, show) | |
| 3.6 Examining the Stack (`where', `frame', `up', `down') | Examining the stack (where, up, down, frame) | |
| 3.7 Examining Data | Examining data (print, target, examine, info variables) | |
| 3.8 Evaluation and Execution | Arbitrary execution (eval, shell) | |
| 3.9 Interfacing to the OS (`cd', `pwd') | Interfacing to the OS (cd, pwd) | |
| 3.10 Controlling the GNU Make debugger | Controlling make (annotate, file, prompt...) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A GNU Remake debugger command is a single line of input. There is
no limit on how long it can be. It starts with a command name, which
is followed by arguments whose meaning depends on the command name.
For example, the command step accepts an argument which is the
number of times to step, as in `step 5'. You can also use the
step command with no arguments. Some commands do not allow any
arguments. In commands that have attributes, the attribute can be
abbreviated to the minimum string that makes it unique. For example
"commands"in target all commands can be shortened to
"command" or "com" or just "c".
A blank line as input to the GNU Make debugger (typing just RET) means to repeat the previous next or step command.
Any text from a # to the end of the line is a comment; it does nothing. This is useful mainly in command files
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Once inside the debugger, you can always ask it for information on its
commands, using the command help.
helphYou can use help (abbreviated h) with no arguments to
display a short list of named classes of commands:
mdb<0> help
Command Short Name Aliases
---------------------- ---------- ---------
break *target* (b) L
comment *text* (#)
continue (c)
delete breakpoint numbers.. (d)
down [amount] (D)
eval *string* (e)
examine *string* (x)
finish (F)
frame *n* (f)
help [command] (h) ?, ??
info [thing] (i)
next [amount] (n)
print {*variable* [attrs...]} (p)
quit [exit-status] (q) exit, return
run (R) restart
set {*option*|variable} *value* (=)
setq *variable* *value* (")
shell *string* (!) !!
show [thing] (S)
skip (k)
step [amount] (s)
target (t)
up [amount] (u)
where (T) backtrace, bt
write [*target* [*filename*]] (w)
Readline command line editing (emacs/vi mode) is available.
For more detailed help, type h <cmd> or consult online-documentation.
|
help commandWith a command name as help argument, GNU Remake displays
short information on how to use that command.
mdb<3> help where where: Show target stack. |
In addition to help, you can use the debugger command
info to inquire about the state of your script, or the state of
the GNU Make debugger itself. The listings under info in the Index
point to all the sub-commands. See section Command Index.
infoThis command (abbreviated i) is for describing the state of
your program. For example, you can list the arguments given to your
script with info args. You can get a complete list of the
info sub-commands with help info.
mdb<0> help info info [thing]: Show the state of thing. If no 'thing' is specified, show everything there is to show. Available info subcommands are: line locals makefiles target variables warranty |
Subcommands can be abbreviated with the minimum number of letters to
make that subcommand distinct from another. For example info lo
is the same as info locals and info li is the same as
info line.
info lineShows the line number and file of for the place that you are currently stopped.
info localsDisplays a the values of the automatic variables.
info makefilesDisplays the list of Makefiles read in the order that they were read in. The last Makefile listed is the one you started with (e.g. Makefile).
info targetDisplays target information.
info warrantyDisplays GNU Warranty
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
quit [return-code]q [return-code]To exit the GNU Make debugger, use the quit command (abbreviated
q), or type an end-of-file character (usually C-d). If
you do not supply return-code, the GNU Make debugger will terminate
normally or with exit code 0. Otherwise it use the value of the
return-code as the exit code. Usually a 0 exit is a normal exit.
Often when running GNU Remake, a recursive call is made or made in
another directory. The quit only terminates only the last one:
the one that the debugger is in. The GNU Remake debugger arranges for the debug
flags to get passed down in recursive calls. Consequently when you
quit one of the inner make calls, you may find yourself still in the
debugger but up a call level.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
One important use of a debugger is to stop execution before it gets into trouble, so you can investigate and find out what is going on. However should GNU Remake accidentally continue to termination, the GNU Make debugger has arranged for it not to leave the debugger without your explicit instruction. That way, you can restart the program using the same command arguments.
Inside the GNU Make debugger, your script may stop for any of several reasons,
such as a signal, a breakpoint, or reaching a new line after a
debugger command such as step. You may then examine and
change variables, set new breakpoints or remove old ones, and then
continue execution.
| 3.4.1 Breakpoints | Breakpoints, watchpoints (break, clear) | |
| 3.4.2 Resuming Execution | Resuming execution (continue, step, next, skip) | |
| 3.4.3 Signals |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A breakpoint arranges for GNU Remake to stop whenever a certain point in the Makefile is reached.
You can set breakpoints with the break command and its variants
(see section Setting breakpoints), to specify the place where
your script should stop by target name.
| 3.4.1.1 Setting breakpoints (`break') | Setting breakpoints (break) | |
| 3.4.1.2 Deleting breakpoints (`delete') | Deleting breakpoints (delete, clear) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Breakpoints are set with the break command (abbreviated
b).
break targetSet a breakpoint at target in the current Makefile.
Examples:
mdb<0> break all Breakpoint on target all set. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It may be desirable to eliminate a breakpoint once it has done its job and you no longer want stop there. This is called deleting the breakpoint. A breakpoint that has been deleted no longer exists; it is forgotten.
It is not necessary to delete a breakpoint to proceed past it. the GNU Make debugger automatically ignores breakpoints on the first instruction to be executed when you continue execution.
delete breakpoint-number...Delete the breakpoints by breakpoint-number specified as arguments.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Continuing means resuming program execution until your script completes normally. In contrast, stepping means executing just one more "step" of your script, where "step" may mean either one line of source code. Either when continuing or when stepping, your script may stop even sooner, due to a breakpoint or a signal.
| 3.4.2.1 Next (`next') | running the next statement (next) | |
| 3.4.2.2 Step (`step') | running the next statement in small increments (step) | |
| 3.4.2.3 Skip (`skip') | skipping the next statement (skip) | |
| 3.4.2.4 Continue (`continue') | continuing execution (continue) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
nextContinue processing your Makefile until control reaches a different
interesting source line, then stop it and return control to
the GNU Make debugger. This command is abbreviated n.
next [count]Continue running as in next, but do so count times. If a
breakpoint is reached, or a signal not related to stepping occurs before
count steps, stepping stops right away.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
stepStepping is like next but it is more fine-grained. It will stop
at every target that needs to be remade whether or not there are
commands associated with it.
If there are multiple commands associated with a target step
will stop before each one.
step [count]Continue running as in step, but do so count times. If a
breakpoint is reached, or a signal not related to stepping occurs before
count steps, stepping stops right away.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
skip [count]Skip executing the remaining commands of the target you are stopped at. This may be useful if you have an action that "fixes" existing code in a Makefile.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Resume program execution, at the address where your script last stopped; any breakpoints set at that address are bypassed.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A signal is an asynchronous event that can happen in a program. The
operating system defines the possible kinds of signals, and gives each
kind a name and a number. For example, in Unix SIGINT is the
signal a program gets when you type an interrupt character (often
C-c); SIGALRM occurs when the alarm clock timer goes off
(which happens only if your program has requested an alarm).
GNU Remake sets up some signal handlers of children it spawns. When we are running under the debugger when and we get a signal the debugger read loop is entered.
Some signals, including SIGALRM, are a normal part of the
functioning of your program. Others, such as SIGSEGV, indicate
errors; these signals are fatal (they kill your program
immediately) if the program has not specified in advance some other
way to handle the signal. SIGINT does not indicate an error in
your program, but it is normally fatal so it can carry out the purpose
of the interrupt: to kill the program.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In addition to help, you can use the GNU Make debugger commands
info and show to inquire about the state of your
program, or the state of GNU Remake itself. Each command supports
many topics of inquiry; here we introduce each of them in the
appropriate context. The listings under info in the Index
point to all the sub-commands. See section Command Index.
infoThis command (abbreviated i) is for describing the state of
your debugger setting. For example, you can show whether GNU Remake
has set to ignore errors or not.
setIn addition to showing GNU Remake settings you can change them or
change GNU Remake variables with set. For example, you can
change setting GNU Remake has whether to ignore errors.
showIn contrast to info, show is for describing the state of
GNU Remake itself.
You can change most of the things you can show, by using the
related command set;
The distinction between info and show however is a bit
fuzzy and is kept here to try to follow the GDB interface.
To display all the settable parameters and their current
values, you can use show with no arguments; you may also use
info set. Both commands produce the same display.
Here are force miscellaneous show subcommands, all of which are
exceptional in lacking corresponding set commands:
show commandShows the list of commands previously entered
show versionShow what version of GNU Remake is running. You should include this information in the GNU Make debugger bug-reports. If multiple versions of GNU Remake are in use at your site, you may need to determine which version you are running; as the GNU Make debugger evolves, new commands are introduced, and old ones may wither away. The version number is the same as the one announced when you start GNU Remake.
show warrantyDisplay the GNU "NO WARRANTY" statement, or a warranty, if your version of the GNU Make debugger comes with one.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you enter the debugger, one thing you'll probably want to know is where it stopped and some idea of how it got there.
Each time your Makefile performs dependency checking (sometimes as implicit rules or pattern-substitution rules), information about the target that caused the new target to be considered action is saved on a stack. This target call stack then is this a history of the dependency checks that got you to the point that you are currently stopped at.
One of the stack frames is selected by the GNU Make debugger and many the GNU Make debugger commands refer implicitly to the selected frame. In particular, whenever you ask the GNU Make debugger to list lines without giving a line number or location the value is found in the selected frame. There are special the GNU Make debugger commands to select whichever frame you are interested in. See section Selecting a frame.
When your program stops, the GNU Make debugger automatically selects the
currently executing frame and describes it briefly, similar to the
frame command.
| 3.6.1 Stack frames | ||
| 3.6.2 Backtraces (`where') | Backtraces (where) | |
| 3.6.3 Selecting a frame (`up', `down', `frame') | Selecting a frame (up, down, frame) | |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The target stack is divided up into contiguous pieces called stack frames, or frames for short. The frame contains the line number of the target which triggered the next one to be considered, the Makefile file name that the line in that refers to a target name. When some of this information is be missing you may see a filename shown as "null" or have line number 0.
When your script is started, the stack has only one frame, that of the
function main. This is called the initial frame or the
outermost frame. Each time a function is called, a new frame is
made. Each time a function returns, the frame for that function invocation
is eliminated. If a function is recursive, there can be many frames for
the same function. The frame for the function in which execution is
actually occurring is called the innermost frame. This is the most
recently created of all the stack frames that still exist.
the GNU Make debugger assigns numbers to all existing stack frames, starting with zero for the innermost frame, one for the frame that called it, and so on upward. These numbers do not really exist in your script; they are assigned by the GNU Make debugger to give you a way of designating stack frames in the GNU Make debugger commands.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A backtrace is essentially the same as the call stack: a summary of how your script got where it is. It shows one line per frame, for many frames, starting with the place that you are stopped at (frame zero), followed by its caller (frame one), and on up the stack.
If GNU Remake is in the reading phase the backtrace shows the nesting of include files. If GNU Remake is in the interpretation phase the backtrace shows the nesting of targets.
wherebacktracebtTIf we are reading Makefiles, print a backtrace of the included Makefile stack. If we are evaluating the Makefile to bring targets up to date, print a backtrace of the target stack. In either case, we print line per frame.
where nbacktrace nbt nT nSimilar, but print only the innermost n frames. A negative number prints the outermost n frames.
Each line in the backtrace shows the frame number and the function name, the source file name and line number, as well as the function name.
Here is an example of a backtrace taken a program in the regression-tests `parm.sh'.
./make -X /tmp/remake/src/Makefile:228: Makefile.in mdb<0> step /tmp/remake/src/Makefile:263: make mdb<1> where =>#0 make at /tmp/remake/src/Makefile:263 #1 all-am at /tmp/remake/src/Makefile:386 #2 all at /tmp/remake/src/Makefile:224 |
However if we have set debugging to stop before reading makefiles are we are in the reading phase, we show included Makefiles:
$ ./make --debugger=preread Reading makefiles... Reading makefile `Makefile'... (/tmp/remake/src/Makefile:1) mdb<0> step /tmp/remake/src/Makefile:324 Reading makefile `.deps/alloca.Po' (search path) (no ~ expansion)... (/tmp/remake/src/.deps/alloca.Po:1) mdb<1> where =>#0 /tmp/remake/src/.deps/alloca.Po:1 #1 /tmp/remake/src/Makefile:324 mdb<2> next /tmp/remake/src/Makefile:327 Reading makefile `.deps/getloadavg.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:328 Reading makefile `.deps/ar_fns.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:329 ... lots of lines deleted ... Reading makefile `.deps/version.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:360 Reading makefile `.deps/vpath.Po' (search path) (no ~ expansion)... Updating goal targets.... /tmp/remake/src/Makefile:254 File `all' does not exist. (/tmp/remake/src/Makefile:254): all mdb<3> |
Note in the above `step' goes on to the next read of a makefile while the `next' command can be used to skip over all of the remaining reads.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Commands for printing targets script work on whichever stack frame is selected at the moment. Here are the commands for selecting a stack frame; all of them finish by printing a brief description of the stack frame just selected.
up nMove n frames up the stack. For positive numbers n, this advances toward the outermost frame, to higher frame numbers, to frames that have existed longer. n defaults to one.
down nMove n frames down the stack. For positive numbers n, this
advances toward the innermost frame, to lower frame numbers, to frames
that were created more recently. n defaults to one. You may
abbreviate down as do.
All of these commands end by printing two lines of output describing the frame. The first line shows the frame number, the function name, the arguments, and the source file and line number of execution in that frame. The second line shows the text of that source line.
For example:
mdb<8> up /tmp/remake/src/Makefile:386: all-am mdb<8> T #0 make at /tmp/remake/src/Makefile:263 =>#1 all-am at /tmp/remake/src/Makefile:386 #2 all at /tmp/remake/src/Makefile:224 |
frame argsThe frame command allows you to move from one stack frame to
another, and to print the stack frame you select. args is the
the stack frame number. Without an argument, frame prints the
current stack frame.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| 3.7.1 Print variable info (`print') | Print variable info | |
| 3.7.2 Print a string expanded (`examine') | Print a string expanded | |
| 3.7.3 Examining Targets (`target') | Print target Info | |
| 3.7.4 Write commands of a target (`write') | Write commands of a target | |
| 3.7.5 Print all variables (`info variables') | Print all variables |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
One way to examine variables the print
command (abbreviated p). However a more versatile print command
is x; it can print arbitrary string expands which of course
includes variable.
print variable-nameUse print to display GNU Remake's variables. As such,
variable names should not be preceded with a dollar sign.
mdb<0> print SHELL Makefile:168 (origin: makefile) SHELL = /bin/sh /tmp/remake/Makefile:243: Makefile.in mdb<1> print $MAKE # don't use $ Can't find variable $MAKE /tmp/remake/Makefile:243: Makefile.in mdb<1> print shell # note case is significant Can't find variable shell |
printpIf you omit variable, the GNU Make debugger displays the last expression again.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
x stringThe x command expands the string given using GNU Remake's
internal variables. The expansion would be the same as if the string
were given as a command inside the target.
mdb<0> examine MAKE (origin default) MAKE := /tmp/remake/src/./make /tmp/remake/src/Makefile:264: Makefile.in mdb<1> print MAKE # note the difference with the ``print'' (origin default) MAKE = $(MAKE_COMMAND) mdb<2> examine $(MAKE) # Note using $( ) doesn't matter here... /tmp/remake/src/./make # except in output format - no origin info /tmp/remake/src/Makefile:264: Makefile.in mdb<2> p COMPILE Makefile:104 (origin: makefile) COMPILE := $(CC) $(DEFS) $(DEFAULT_INCLUDES) /tmp/remake/src/Makefile:264: Makefile.in mdb<10> x compile starts: $(CC) $(DEFS) $(DEFAULT_INCLUDES) compile starts: gcc -DLOCALEDIR=\"\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I.. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
the GNU Make debugger can print information about targets. When your script stops, the GNU Make debugger spontaneously prints the line and target name where it stopped. Likewise, when you select a stack frame (see section Selecting a frame), the GNU Make debugger the default target name is changed.
targettprint information about the current target.
target targett targetPrint information about target. A list of attributes can be specified after the target name. The list of attributes names are
Show the list of "attributes" associated with the target. Attributes can be:
Show the list of commands that need to get run in order to bring the target up to date.
Show the targets that this one depends on.
Show the list of commands that need to get run in order to bring the target up to date with GNU Remake variables expanded.
Show the dependencies that are not ordered.
Show status of target:
This shows the time that the file was last modified and if the file has been brought up to date. If it is not up to date you will see the message "File is very old." If a target is "phony", i.e. doesn't have file associated with it, the message "File does not exist." will appear instead of the time. In some cases you may see "Modification time never checked."
Show single-character automatic state variables (if defined):
Note that there are other automatic variables defined based on
these. In particular those that have a `D' or `F' suffix, e.g. $(@D),
or $(*F). These however are not listed here but can shown in a
print command or figured out from their corresponding
single-letter variable name.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
write [target [filename|here]]Use this to write the command portion of a target with GNU Remake's internal variables expanded. If a filename is given that is the file where the expanded commands are written. If the filename is "here" then it is not written to a file but output inside the debugger as other debugger command behaves. And if no file name is given a filename based on the target name is created.
| [ < ] | [ > ] | [ |