targets/toolchain_makefile.py
changeset 1784 64beb9e9c749
parent 1782 5b6ad7a7fd9d
child 1831 56b48961cc68
equal deleted inserted replaced
1729:31e63e25b4cc 1784:64beb9e9c749
    20 #
    20 #
    21 # You should have received a copy of the GNU General Public License
    21 # You should have received a copy of the GNU General Public License
    22 # along with this program; if not, write to the Free Software
    22 # along with this program; if not, write to the Free Software
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 
    24 
    25 import os, re, operator
    25 import os
       
    26 import re
       
    27 import operator
    26 from util.ProcessLogger import ProcessLogger
    28 from util.ProcessLogger import ProcessLogger
    27 import hashlib
    29 import hashlib
    28 
    30 
    29 import time
    31 import time
    30 
    32 
    31 includes_re =  re.compile('\s*#include\s*["<]([^">]*)[">].*')
    33 includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*')
       
    34 
    32 
    35 
    33 class toolchain_makefile():
    36 class toolchain_makefile():
    34     def __init__(self, CTRInstance):
    37     def __init__(self, CTRInstance):
    35         self.CTRInstance = CTRInstance
    38         self.CTRInstance = CTRInstance
    36         self.md5key = None 
    39         self.md5key = None
    37         self.buildpath = None
    40         self.buildpath = None
    38         self.SetBuildPath(self.CTRInstance._getBuildPath())
    41         self.SetBuildPath(self.CTRInstance._getBuildPath())
    39 
    42 
    40     def SetBuildPath(self, buildpath):
    43     def SetBuildPath(self, buildpath):
    41         if self.buildpath != buildpath:
    44         if self.buildpath != buildpath:
    64             except IOError, e:
    67             except IOError, e:
    65                 return None
    68                 return None
    66 
    69 
    67     def concat_deps(self, bn):
    70     def concat_deps(self, bn):
    68         # read source
    71         # read source
    69         src = open(os.path.join(self.buildpath, bn),"r").read()
    72         src = open(os.path.join(self.buildpath, bn), "r").read()
    70         # update direct dependencies
    73         # update direct dependencies
    71         deps = []
    74         deps = []
    72         for l in src.splitlines():
    75         for l in src.splitlines():
    73             res = includes_re.match(l)
    76             res = includes_re.match(l)
    74             if res is not None:
    77             if res is not None:
    75                 depfn = res.groups()[0]
    78                 depfn = res.groups()[0]
    76                 if os.path.exists(os.path.join(self.buildpath, depfn)):
    79                 if os.path.exists(os.path.join(self.buildpath, depfn)):
    77                     #print bn + " depends on "+depfn
    80                     # print bn + " depends on "+depfn
    78                     deps.append(depfn)
    81                     deps.append(depfn)
    79         # recurse through deps
    82         # recurse through deps
    80         # TODO detect cicular deps.
    83         # TODO detect cicular deps.
    81         return reduce(operator.concat, map(self.concat_deps, deps), src)
    84         return reduce(operator.concat, map(self.concat_deps, deps), src)
    82 
    85 
    83     def build(self):
    86     def build(self):
    84         srcfiles= []
    87         srcfiles = []
    85         cflags = []
    88         cflags = []
    86         wholesrcdata = "" 
    89         wholesrcdata = ""
    87         for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
    90         for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
    88             # Get CFiles list to give it to makefile
    91             # Get CFiles list to give it to makefile
    89             for CFile, CFLAGS in CFilesAndCFLAGS:
    92             for CFile, CFLAGS in CFilesAndCFLAGS:
    90                 CFileName = os.path.basename(CFile)
    93                 CFileName = os.path.basename(CFile)
    91                 wholesrcdata += self.concat_deps(CFileName)
    94                 wholesrcdata += self.concat_deps(CFileName)
    92                 srcfiles.append(CFileName)
    95                 srcfiles.append(CFileName)
    93                 if CFLAGS not in cflags:
    96                 if CFLAGS not in cflags:
    94                     cflags.append(CFLAGS)
    97                     cflags.append(CFLAGS)
    95                         
    98 
    96         oldmd5 = self.md5key
    99         oldmd5 = self.md5key
    97         self.md5key = hashlib.md5(wholesrcdata).hexdigest()
   100         self.md5key = hashlib.md5(wholesrcdata).hexdigest()
    98 
   101 
    99         # Store new PLC filename based on md5 key
   102         # Store new PLC filename based on md5 key
   100         f = open(self._GetMD5FileName(), "w")
   103         f = open(self._GetMD5FileName(), "w")
   101         f.write(self.md5key)
   104         f.write(self.md5key)
   102         f.close()
   105         f.close()
   103 
   106 
   104         if oldmd5 != self.md5key :
   107         if oldmd5 != self.md5key:
   105             target = self.CTRInstance.GetTarget().getcontent()
   108             target = self.CTRInstance.GetTarget().getcontent()
   106             beremizcommand = {"src": ' '.join(srcfiles),
   109             beremizcommand = {"src": ' '.join(srcfiles),
   107                               "cflags": ' '.join(cflags),
   110                               "cflags": ' '.join(cflags),
   108                               "md5": self.md5key,
   111                               "md5": self.md5key,
   109                               "buildpath": self.buildpath
   112                               "buildpath": self.buildpath}
   110                              }
   113 
   111             
   114             # clean sequence of multiple whitespaces
   112             # clean sequence of multiple whitespaces 
       
   113             cmd = re.sub(r"[ ]+", " ", target.getCommand().strip())
   115             cmd = re.sub(r"[ ]+", " ", target.getCommand().strip())
   114 
   116 
   115             command = [ token % beremizcommand for token in cmd.split(' ')]
   117             command = [token % beremizcommand for token in cmd.split(' ')]
   116 
   118 
   117             # Call Makefile to build PLC code and link it with target specific code
   119             # Call Makefile to build PLC code and link it with target specific code
   118             status, result, err_result = ProcessLogger(self.CTRInstance.logger,
   120             status, result, err_result = ProcessLogger(self.CTRInstance.logger,
   119                                                        command).spin()
   121                                                        command).spin()
   120             if status :
   122             if status:
   121                 self.md5key = None
   123                 self.md5key = None
   122                 self.CTRInstance.logger.write_error(_("C compilation failed.\n"))
   124                 self.CTRInstance.logger.write_error(_("C compilation failed.\n"))
   123                 return False
   125                 return False
   124             return True
   126             return True
   125         else :
   127         else:
   126             self.CTRInstance.logger.write(_("Source didn't change, no build.\n"))
   128             self.CTRInstance.logger.write(_("Source didn't change, no build.\n"))
   127             return True
   129             return True
   128