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