targets/toolchain_makefile.py
changeset 734 5c42cafaee15
parent 733 915be999f3f0
child 735 d9f4ecee761d
equal deleted inserted replaced
733:915be999f3f0 734:5c42cafaee15
     1 import os, re, operator
       
     2 from util.ProcessLogger import ProcessLogger
       
     3 import hashlib
       
     4 
       
     5 import time
       
     6 
       
     7 includes_re =  re.compile('\s*#include\s*["<]([^">]*)[">].*')
       
     8 
       
     9 class toolchain_makefile():
       
    10     def __init__(self, CTRInstance):
       
    11         self.CTRInstance = CTRInstance
       
    12         self.md5key = None 
       
    13         self.buildpath = None
       
    14         self.SetBuildPath(self.CTRInstance._getBuildPath())
       
    15 
       
    16     def SetBuildPath(self, buildpath):
       
    17         if self.buildpath != buildpath:
       
    18             self.buildpath = buildpath
       
    19             self.md5key = None
       
    20 
       
    21     def GetBinaryCode(self):
       
    22         return None
       
    23 
       
    24     def _GetMD5FileName(self):
       
    25         return os.path.join(self.buildpath, "lastbuildPLC.md5")
       
    26 
       
    27     def ResetBinaryCodeMD5(self):
       
    28         self.md5key = None
       
    29         try:
       
    30             os.remove(self._GetMD5FileName())
       
    31         except Exception, e:
       
    32             pass
       
    33 
       
    34     def GetBinaryCodeMD5(self):
       
    35         if self.md5key is not None:
       
    36             return self.md5key
       
    37         else:
       
    38             try:
       
    39                 return open(self._GetMD5FileName(), "r").read()
       
    40             except IOError, e:
       
    41                 return None
       
    42 
       
    43     def concat_deps(self, bn):
       
    44         # read source
       
    45         src = open(os.path.join(self.buildpath, bn),"r").read()
       
    46         # update direct dependencies
       
    47         deps = []
       
    48         for l in src.splitlines():
       
    49             res = includes_re.match(l)
       
    50             if res is not None:
       
    51                 depfn = res.groups()[0]
       
    52                 if os.path.exists(os.path.join(self.buildpath, depfn)):
       
    53                     #print bn + " depends on "+depfn
       
    54                     deps.append(depfn)
       
    55         # recurse through deps
       
    56         # TODO detect cicular deps.
       
    57         return reduce(operator.concat, map(self.concat_deps, deps), src)
       
    58 
       
    59     def build(self):
       
    60         srcfiles= []
       
    61         cflags = []
       
    62         wholesrcdata = "" 
       
    63         for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
       
    64             # Get CFiles list to give it to makefile
       
    65             for CFile, CFLAGS in CFilesAndCFLAGS:
       
    66                 CFileName = os.path.basename(CFile)
       
    67                 wholesrcdata += self.concat_deps(CFileName)
       
    68                 #wholesrcdata += open(CFile, "r").read()
       
    69                 srcfiles.append(CFileName)
       
    70                 if CFLAGS not in cflags:
       
    71                     cflags.append(CFLAGS)
       
    72                         
       
    73         oldmd5 = self.md5key
       
    74         self.md5key = hashlib.md5(wholesrcdata).hexdigest()
       
    75         props = self.CTRInstance.GetProjectProperties()
       
    76         self.md5key += '#'.join([props[key] for key in ['companyName',
       
    77                                                         'projectName',
       
    78                                                         'productName']])
       
    79         self.md5key += '#' #+','.join(map(str,time.localtime()))
       
    80         # Store new PLC filename based on md5 key
       
    81         f = open(self._GetMD5FileName(), "w")
       
    82         f.write(self.md5key)
       
    83         f.close()
       
    84 
       
    85         if oldmd5 != self.md5key :
       
    86             beremizcommand = {"src": ' '.join(srcfiles),
       
    87                               "cflags": ' '.join(cflags),
       
    88                               "md5": '"'+self.md5key+'"'
       
    89                              }
       
    90             
       
    91             target = self.CTRInstance.GetTarget().getcontent()["value"]
       
    92             command = target.getCommand().split(' ') +\
       
    93                       [target.getBuildPath()] +\
       
    94                       [arg % beremizcommand for arg in target.getArguments().split(' ')] +\
       
    95                       target.getRule().split(' ')
       
    96             
       
    97             # Call Makefile to build PLC code and link it with target specific code
       
    98             status, result, err_result = ProcessLogger(self.CTRInstance.logger,
       
    99                                                        command).spin()
       
   100             if status :
       
   101                 self.md5key = None
       
   102                 self.CTRInstance.logger.write_error(_("C compilation failed.\n"))
       
   103                 return False
       
   104             return True
       
   105         else :
       
   106             self.CTRInstance.logger.write(_("Source didn't change, no build.\n"))
       
   107             return True
       
   108