# HG changeset patch # User etisserant # Date 1231086322 -3600 # Node ID e5782a52dceae350c299f21d92c58fb6fb635588 # Parent 3fecc96090c8dffe82fdf15bd11ba53248683dae Added local C dependency dicovery and changes checking, to speed up build. diff -r 3fecc96090c8 -r e5782a52dcea targets/toolchain_gcc.py --- a/targets/toolchain_gcc.py Tue Dec 30 22:47:15 2008 +0100 +++ b/targets/toolchain_gcc.py Sun Jan 04 17:25:22 2009 +0100 @@ -1,7 +1,9 @@ -import os +import os, re, operator from wxPopen import ProcessLogger import hashlib +includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*') + class toolchain_gcc(): """ This abstract class contains GCC specific code. @@ -15,6 +17,7 @@ self.buildpath = PuginsRootInstance._getBuildPath() self.exe_path = os.path.join(self.buildpath, self.exe) self.md5key = None + self.srcmd5 = {} def GetBinaryCode(self): try: @@ -33,8 +36,33 @@ return open(self._GetMD5FileName(), "r").read() except Exception, e: return None + + def check_and_update_hash_and_deps(self, bn): + # Get latest computed hash and deps + oldhash, deps = self.srcmd5.get(bn,(None,[])) + # read source + src = open(os.path.join(self.buildpath, bn)).read() + # compute new hash + newhash = hashlib.md5(src).hexdigest() + # compare + match = (oldhash == newhash) + if not match: + # file have changed + # update direct dependencies + deps = [] + for l in src.splitlines(): + res = includes_re.match(l) + if res is not None: + depfn = res.groups()[0] + if os.path.exists(os.path.join(self.buildpath, depfn)): + #print bn + " depends on "+depfn + deps.append(depfn) + # store that hashand deps + self.srcmd5[bn] = (newhash, deps) + # recurse through deps + # TODO detect cicular deps. + return reduce(operator.and_, map(self.check_and_update_hash_and_deps, deps), match) - def build(self): # Retrieve toolchain user parameters toolchain_params = self.PuginsRootInstance.BeremizRoot.getTargetType().getcontent()["value"] @@ -52,56 +80,70 @@ else: self.logger.write("PLC :\n") + relink = False for CFile, CFLAGS in CFilesAndCFLAGS: bn = os.path.basename(CFile) obn = os.path.splitext(bn)[0]+".o" + objectfilename = os.path.splitext(CFile)[0]+".o" + + match = self.check_and_update_hash_and_deps(bn) + + if match: + self.logger.write(" [pass] "+bn+" -> "+obn+"\n") + else: + relink = True + + self.logger.write(" [CC] "+bn+" -> "+obn+"\n") + + status, result, err_result = ProcessLogger( + self.logger, + "\"%s\" -c \"%s\" -o \"%s\" %s %s"% + (self.compiler, CFile, objectfilename, self._CFLAGS, CFLAGS) + ).spin() + + if status : + self.logger.write_error("C compilation of "+ bn +" failed.\n") + return False + obns.append(obn) - self.logger.write(" [CC] "+bn+" -> "+obn+"\n") - objectfilename = os.path.splitext(CFile)[0]+".o" - - status, result, err_result = ProcessLogger( - self.logger, - "\"%s\" -c \"%s\" -o \"%s\" %s %s"% - (self.compiler, CFile, objectfilename, self._CFLAGS, CFLAGS) - ).spin() - - if status : - self.logger.write_error("C compilation of "+ bn +" failed.\n") - return False objs.append(objectfilename) ######### GENERATE library FILE ######################################## # Link all the object files into one binary file self.logger.write("Linking :\n") - objstring = [] - - # Generate list .o files - listobjstring = '"' + '" "'.join(objs) + '"' - - ALLldflags = ' '.join(self.CustomLDFLAGS+self.PuginsRootInstance.LDFLAGS+[self._LDFLAGS]) - - self.logger.write(" [CC] " + ' '.join(obns)+" -> " + self.exe + "\n") - - status, result, err_result = ProcessLogger( - self.logger, - "\"%s\" %s -o \"%s\" %s"% - (self.linker, - listobjstring, - self.exe_path, - ALLldflags) - ).spin() - - if status : - return False - else : - # Calculate md5 key and get data for the new created PLC - data=self.GetBinaryCode() - self.md5key = hashlib.md5(data).hexdigest() - - # Store new PLC filename based on md5 key - file = open(self._GetMD5FileName(), "w") - file.write(self.md5key) - file.close() + if relink: + objstring = [] + + # Generate list .o files + listobjstring = '"' + '" "'.join(objs) + '"' + + ALLldflags = ' '.join(self.CustomLDFLAGS+self.PuginsRootInstance.LDFLAGS+[self._LDFLAGS]) + + self.logger.write(" [CC] " + ' '.join(obns)+" -> " + self.exe + "\n") + + status, result, err_result = ProcessLogger( + self.logger, + "\"%s\" %s -o \"%s\" %s"% + (self.linker, + listobjstring, + self.exe_path, + ALLldflags) + ).spin() + + if status : + return False + else : + # Calculate md5 key and get data for the new created PLC + data=self.GetBinaryCode() + self.md5key = hashlib.md5(data).hexdigest() + + # Store new PLC filename based on md5 key + f = open(self._GetMD5FileName(), "w") + f.write(self.md5key) + f.close() + else: + self.logger.write(" [pass] " + ' '.join(obns)+" -> " + self.exe + "\n") + return True