转载请注明出处:http://blog.csdn.net/zb1234890/article/details/35298083
1. Over view
This short and ugly essay aims to introduce "GNU Remake",
the patched GNU Make enhanced with debugging and tracing functionality.
You maybe surprise at this, debugging Makefile?
Yes,debug Makefile,like gdb's debugging to program.
Debugger always plays very important role in the development.
Most of the time, we talk about debugger as program debugger,like GNU Debugger,
programs usually are the final product we expect, it is paid so much attention.
Beside debugger, also so many powerful tracing and profiling tools exists for program.
But think twice, before you could use your power to play with your source code,
what's the first difficulty you maybe meet, when facing a huge software system you are not familiar with?
I am guessing, maybe the make system.
Metal analyzing the complex make system is admirable, but here, we reach to the tool, GNU Remake, for help.
2. Where to get GNU Remake.
Believe you also get other surprise when accessing the link, :-).
3. Building and installing GNU Remake.
Once you unpack it, you will found it is equipped with autoconf/automake,so very easy to build and install.
Assume you do the following.
$ ./configure --prefix=<SomeDir>/remake-3.82+dbg0.9-install
$ make && make install
Once succeed, you got the executable "remake" at <SomeDir>/remake-3.82+dbg0.9-install/bin.
Adding it to your PATH, if you like.
4. Using GNU Remake.
Usually, more or less some company's software system's make system tends to be complex,
and programmer maybe need to modify it. But I have no right to use them as a example here.
So let's use u-boot as example, although you may never modify its make system,
but the debugging method are common, let's assume we need to modify them as we need to modifycompany's private make system.
For people want to know how the final u-boot.bin constructed step by step, may want to track the whole building process.
To do this, let's the make process stop after dependence analysing but before action being taken.
Assume, we have u-boot source code configured correctly for some arm box.
$ remake --debugger=preaction
The following will be got:
See, it stops at the first target "include/autoconf.mk",like program stops in GDB debuggingsession.
The current target is "include/autoconf.mk"
"step" could be used to step through the Makefile, just like the gdb's step doing to program.
"where/bt" could be used to show the target back trace, just like the gdb's "bt".
"info <arg>" could be used show a lot of useful information, such as info variable to show all the variables, etc.
"break" to set breakpoint, "continue" to go on, and a lot of other command.
...
...
let's try these commands.
Back trace.
List makefile.
Show alll targets in the current Makefile.
so many targets
...
...
Get information of current target "include/autoconf.mk".
Get information of the target "all".
Since "all" depends on "u-boot.bin", let'sset breakpoint at target "u-boot.bin", then"continue"...
...
...
After "continue" so many times, still not hit at u-boot.bin. So frustrating!
What a hell, so much information, how could I debug ....?
You may have the feeling :). So do I.
Yes, that's my feel when trying GNU Remake first time.
A quick explanation is that,this is reasonable, since GNU Remake's debuggingcontext belongs to current process only.
Before hitting the break point at current Makefile's "u-boot.bin" target, U-Boot's make system works recursively, it start anotherGNU Remake session when "make -c xxxx".
Sure, in my opinion, recursive make system limits GNU Remake's debuggingefficiency. But, still, we have way to use it more convenient for recursive make system.
Usually, stepping through a big make system is not reasonable, since remake shows too much detail information.
More often, we need only stop on the point, which we have question on, then retrieve useful information by using GNU Remake.
Let's see the following more practicalmethod on debugging.
Assume we are confusing aboutthe exact value of "$GEN_UBOOT", when "$(obj)u-boot" target is building.
Maybe, you would say why not, just using "error/warning" to print out its value.
Yes, it works. But you could get any variable's value, modify it, execute shell commands, and do a lot of related things, in a debugging session.
We just "expand" and show the value of "$GEN_UBOOT", as a quick example.
See the "xyz: ...", it is the part I added, the "$(debugger )" function is supplied by GNU Remake, it is a break point set directly in the Makefile.
And, I let "$(obj)u-boot: xyz ...", as a temp solution to stop "$(obj)u-boot", once it is hit, we could do a lot of things.
Use GNU Remake to make U-Boot, the "debugger=preaction" is not needed any more. Since the break point is set in the Makefile already.
As expected, the break point stop the building process, we could stepthrough the dummy target "xyz",if we like.
Use "bt", to show where we are now.
Use "expand $(GEN_UBOOT)" to show its value. That's the exact correct value, you could depend to analyze the make system further.
See, we get our question on the value of "$(GEN_UBOOT)".
This is an efficient way to use GNU Remake, comparing to step throughthe whole building process.
Almost forget a very important usage of GNU Remake:-), let's talk it here.
As talked above, remake --debugger=preaction, could stop building process before any real action taken,
another useful way is, remake --debugger=error, which is very helpful on debuggingmakesystem/building error.
5. Things you would/should know on GNU Remake.
Like U-Boot, Linux, their make system are so recursive, sorry to use U-Boot as example here, since I have no big
"FAT" make system, like Android's, in hand. So if you hack make system like Android's, Remake will show you its supper power:).
b. When face recursive make system, use $(debugger ) to set break point should be much reasonable than set break point
in the debugging session.
c. So far, the most useful features I found are, "expand" and "$(debugger )".
d. Its debugging feature's implement is very interesting ...
f. Before digging into valuable and "too much and detail" information exposed by GNU Remake,
make sure yourself be somewhat familiar with the make system you are debugging.We'd batter to have question in mind when using Gnu Remake, let it supply us the "fact" about current make system,
which would be the stable logic foundation when analyzing the make system.
Without this, we may lose our way because of an incorrect assumption on the hacked make system.
How? Think about "#ifeq" and "$(debugger )". You will find your way, better way :-), to use GNU Remake.
h. The more you understand how GNU Make work, the more you will use GNU Remakeefficiently.
6. The end.
Also, the document of GNU Remake is very good, even make you hope you read it before this poor introduction of mine :-).
GNU Remake support so rich set of debugging and tracing features, much more than this very limited features introduced here.
You would find them by yourself, very easily.I never write a blog before this, I believe there must be a lot of issue in this small introduction, feel free to let me know,
if your found some, thank you in advance.
Have fun!
Bruce Zhang
2014/06/29 20:57