![[LWN Logo]](/images/lcorner.png) |
|
![[LWN.net]](/images/Included.png) |
From: Rob Landley <landley@trommello.org>
To: linux-kernel@vger.kernel.org
Subject: [RFC] [PATCH] Intelligible build progress
Date: Thu, 10 Jan 2002 06:11:20 -0500
I got bored. I wrote a toy. It's an output filter you pipe a build into
that actually explains what's going on. It cuts the output down enough that
you can actually see warnings (wow!), but not so much you don't know what
it's doing or have some kind of progress indicator.
It's evil, it's nasty, it's ugly, it's vicious. It currently requires python
2.x (because I intend to put a curses front end on it, that's why). But it
also seems to be working, so I'm releasing what I've got so far under the GPL
so people can flame me now and avoid the rush. :)
At the moment, you just copy "blueberry.py" onto your system (the "scripts"
directory makes sense) and then use it like this (cut and paste and you've
got a shell script):
### Start of script
# "Entering directory" messages are just clutter in make dep
make dep | scripts/blueberry.py e
# This is short enough we don't need to see progress
echo "Cleaning out old temporary files."
echo " "
make clean > /dev/null
# Okay, build.
make bzImage | scripts/blueberry.py
make modules | scripts/blueberry.py
# make install/modules install require root access, not handling this yet.
### End of script
As I said, later I want to make it part of a curses front-end showing you
what directory you're currently in, what action is being taken, and with
stderr (warnings, etc) scrolling by in its own little box. Oh, and not
having to run make dep and make clean all the time would be nice too, but
that waits on Kieth Owens' new makefiles.
Yeah it's a big evil mess of heuristics. I know. And the above script will
still try to build modules if bzImage bombs with an error. And you've got to
ctrl-c twice to kill it...
I've tested it (if you can use that word) against 2.4.17, I don't know if
there's new stuff in 2.5 it can't deal with yet. (Shouldn't be, but...)
Here's the file.
You may cringe now.
#!/usr/bin/python2
# Kernel build cleaner version 0.00000000001, or less.
# Copyright 2002 Rob Landley
# Released under the GNU General Public License version 2 or higher,
# (the GPL is available from www.gnu.org/copyleft/gpl.html)
import sys, string
noenter=0
def mangle(input, output):
dir="."
shutup=0
leftovers=None
# Repeat until spanked:
while 1 {
result=None
line=input.readline()
if not line: break
if shutup {
output.write(".\n")
continue
# Reassemble split lines
if leftovers {
line="%s %s" % (leftovers,line)
words=line.split()
if words[-1]=='\\' {
leftovers=line
continue
else: leftovers=None
# Stuff to just completely skip:
# make: When one make file calls another, it announces the fact.
# rm: Build explicitly deletes old .o file before calling linker (ld)
if words[0] in ("make", "rm"): continue
if words[0]=="gcc" {
if words[-1].endswith(".c") {
result="Compiling %s/%s" % (dir,words[-1])
} else {
for i in range(len(words)):
if words[i].endswith(".S") {
result="Preprocessing %s/%s" % (dir,words[i])
break
elif words[0]=="ld":
for i in range(len(words)):
if words[i]=="-o" {
result="Linking %s/%s" % (dir,words[i+1])
break
elif words[0]=="as":
result="Assembling %s/%s" % (dir,words[-1])
elif words[0].startswith("make["):
if words[2]=="directory" {
if words[1]=="Entering" {
dir=words[3][1:-1]
if noenter: continue
result="Entering %s" % dir
else: continue # Leaving directory is not interesting.
if words[1]=="Nothing": continue # Pointless error message
elif words[0].endswith("/mkdep"):
result="Finding dependencies in %s" % dir
elif words[0]=="nm":
result="Extracting symbols to %s" % words[-1]
elif words[0].startswith("tmppiggy="):
result="Creating compressed kernel image"
shutup=1
elif words[0]=="ar": # So linker dependencies don't have to change
result="Creating empty object %s" % words[2]
elif words[0]=="sh" or words[0]=='.' or words[0].find("/")!=-1:
if words[0]=="sh" {
while words[1].startswith("-"): words[1:2]=[]
words[0:1]=[]
if words[0].find("/")!=-1 {
while words[0].startswith("./"): words[0]=words[0][2:]
temp=["Running %s/%s" % (dir,words[0])]
else: temp=["Running %s" % words[0]]
temp.extend(words[1:])
result=" ".join(temp)
# That's all we understand. Now do something with it.
if not result {
output.write("Unknown line: %s\n" % line)
} else {
output.write(result)
if not shutup: output.write("\n")
endofline="\r"
if len(sys.argv)>1 {
if sys.argv[1].find("n")!=-1: endofline="\n"
if sys.argv[1].find("c")!=-1: showcount=1
else: showcount=0
if sys.argv[1].find("e")!=-1: noenter=1
mangle(sys.stdin, sys.stdout)
print