targets/toolchain_makefile.py
changeset 1387 435965ca8b63
child 1402 49441045b192
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/toolchain_makefile.py	Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,105 @@
+import os, re, operator
+from util.ProcessLogger import ProcessLogger
+import hashlib
+
+import time
+
+includes_re =  re.compile('\s*#include\s*["<]([^">]*)[">].*')
+
+class toolchain_makefile():
+    def __init__(self, CTRInstance):
+        self.CTRInstance = CTRInstance
+        self.md5key = None 
+        self.buildpath = None
+        self.SetBuildPath(self.CTRInstance._getBuildPath())
+
+    def SetBuildPath(self, buildpath):
+        if self.buildpath != buildpath:
+            self.buildpath = buildpath
+            self.md5key = None
+
+    def GetBinaryCode(self):
+        return None
+
+    def _GetMD5FileName(self):
+        return os.path.join(self.buildpath, "lastbuildPLC.md5")
+
+    def ResetBinaryCodeMD5(self):
+        self.md5key = None
+        try:
+            os.remove(self._GetMD5FileName())
+        except Exception, e:
+            pass
+
+    def GetBinaryCodeMD5(self):
+        if self.md5key is not None:
+            return self.md5key
+        else:
+            try:
+                return open(self._GetMD5FileName(), "r").read()
+            except IOError, e:
+                return None
+
+    def concat_deps(self, bn):
+        # read source
+        src = open(os.path.join(self.buildpath, bn),"r").read()
+        # 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)
+        # recurse through deps
+        # TODO detect cicular deps.
+        return reduce(operator.concat, map(self.concat_deps, deps), src)
+
+    def build(self):
+        srcfiles= []
+        cflags = []
+        wholesrcdata = "" 
+        for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
+            # Get CFiles list to give it to makefile
+            for CFile, CFLAGS in CFilesAndCFLAGS:
+                CFileName = os.path.basename(CFile)
+                wholesrcdata += self.concat_deps(CFileName)
+                srcfiles.append(CFileName)
+                if CFLAGS not in cflags:
+                    cflags.append(CFLAGS)
+                        
+        oldmd5 = self.md5key
+        self.md5key = hashlib.md5(wholesrcdata).hexdigest()
+        props = self.CTRInstance.GetProjectProperties()
+        self.md5key += '#'.join([props[key] for key in ['companyName',
+                                                        'projectName',
+                                                        'productName']])
+        self.md5key += '#' #+','.join(map(str,time.localtime()))
+        # Store new PLC filename based on md5 key
+        f = open(self._GetMD5FileName(), "w")
+        f.write(self.md5key)
+        f.close()
+
+        if oldmd5 != self.md5key :
+            target = self.CTRInstance.GetTarget().getcontent()
+            beremizcommand = {"src": ' '.join(srcfiles),
+                              "cflags": ' '.join(cflags),
+                              "md5": self.md5key,
+                              "buildpath": self.buildpath
+                             }
+            
+            command = [ token % beremizcommand for token in target.getCommand().split(' ')]
+
+            # Call Makefile to build PLC code and link it with target specific code
+            status, result, err_result = ProcessLogger(self.CTRInstance.logger,
+                                                       command).spin()
+            if status :
+                self.md5key = None
+                self.CTRInstance.logger.write_error(_("C compilation failed.\n"))
+                return False
+            return True
+        else :
+            self.CTRInstance.logger.write(_("Source didn't change, no build.\n"))
+            return True
+