edouard@573: import os, re, operator edouard@571: from wxPopen import ProcessLogger edouard@571: import hashlib edouard@571: edouard@571: import time edouard@571: edouard@571: includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*') edouard@571: edouard@571: class toolchain_makefile(): Edouard@717: def __init__(self, ConfigTreeRootInstance): Edouard@717: self.ConfigTreeRootInstance = ConfigTreeRootInstance edouard@571: self.md5key = None edouard@571: self.buildpath = None Edouard@717: self.SetBuildPath(self.ConfigTreeRootInstance._getBuildPath()) edouard@571: edouard@571: def SetBuildPath(self, buildpath): edouard@572: if self.buildpath != buildpath: edouard@572: self.buildpath = buildpath edouard@572: self.md5key = None edouard@571: edouard@571: def GetBinaryCode(self): edouard@571: return None edouard@571: edouard@571: def _GetMD5FileName(self): edouard@571: return os.path.join(self.buildpath, "lastbuildPLC.md5") edouard@571: laurent@677: def ResetBinaryCodeMD5(self): laurent@677: self.md5key = None laurent@677: try: laurent@677: os.remove(self._GetMD5FileName()) laurent@677: except Exception, e: laurent@677: pass laurent@677: edouard@571: def GetBinaryCodeMD5(self): edouard@571: if self.md5key is not None: edouard@571: return self.md5key edouard@571: else: edouard@571: try: edouard@571: return open(self._GetMD5FileName(), "r").read() edouard@571: except IOError, e: edouard@571: return None edouard@571: edouard@573: def concat_deps(self, bn): edouard@573: # read source edouard@573: src = open(os.path.join(self.buildpath, bn),"r").read() edouard@573: # update direct dependencies edouard@573: deps = [] edouard@573: for l in src.splitlines(): edouard@573: res = includes_re.match(l) edouard@573: if res is not None: edouard@573: depfn = res.groups()[0] edouard@573: if os.path.exists(os.path.join(self.buildpath, depfn)): edouard@573: #print bn + " depends on "+depfn edouard@573: deps.append(depfn) edouard@573: # recurse through deps edouard@573: # TODO detect cicular deps. edouard@573: return reduce(operator.concat, map(self.concat_deps, deps), src) edouard@573: edouard@571: def build(self): edouard@571: srcfiles= [] edouard@571: cflags = [] edouard@572: wholesrcdata = "" Edouard@717: for Location, CFilesAndCFLAGS, DoCalls in self.ConfigTreeRootInstance.LocationCFilesAndCFLAGS: edouard@571: # Get CFiles list to give it to makefile edouard@571: for CFile, CFLAGS in CFilesAndCFLAGS: edouard@571: CFileName = os.path.basename(CFile) edouard@573: wholesrcdata += self.concat_deps(CFileName) edouard@573: #wholesrcdata += open(CFile, "r").read() edouard@571: srcfiles.append(CFileName) edouard@571: if CFLAGS not in cflags: edouard@571: cflags.append(CFLAGS) edouard@572: edouard@572: oldmd5 = self.md5key edouard@572: self.md5key = hashlib.md5(wholesrcdata).hexdigest() Edouard@717: props = self.ConfigTreeRootInstance.GetProjectProperties() edouard@572: self.md5key += '#'.join([props[key] for key in ['companyName', edouard@572: 'projectName', edouard@572: 'productName']]) edouard@572: self.md5key += '#' #+','.join(map(str,time.localtime())) edouard@572: # Store new PLC filename based on md5 key edouard@572: f = open(self._GetMD5FileName(), "w") edouard@572: f.write(self.md5key) edouard@572: f.close() edouard@572: edouard@572: if oldmd5 != self.md5key : edouard@572: beremizcommand = {"src": ' '.join(srcfiles), edouard@572: "cflags": ' '.join(cflags), edouard@572: "md5": '"'+self.md5key+'"' edouard@572: } edouard@572: Edouard@717: target = self.ConfigTreeRootInstance.GetTarget().getcontent()["value"] edouard@572: command = target.getCommand().split(' ') +\ edouard@572: [target.getBuildPath()] +\ edouard@572: [arg % beremizcommand for arg in target.getArguments().split(' ')] +\ edouard@572: target.getRule().split(' ') edouard@572: edouard@572: # Call Makefile to build PLC code and link it with target specific code Edouard@717: status, result, err_result = ProcessLogger(self.ConfigTreeRootInstance.logger, edouard@572: command).spin() edouard@572: if status : smarteh-dev@691: self.md5key = None Edouard@717: self.ConfigTreeRootInstance.logger.write_error(_("C compilation failed.\n")) edouard@572: return False edouard@572: return True edouard@572: else : Edouard@717: self.ConfigTreeRootInstance.logger.write(_("Source didn't change, no build.\n")) edouard@572: return True edouard@572: