targets/toolchain_gcc.py
changeset 1735 c02818d7e29f
parent 1734 750eeb7230a1
child 1736 7e61baa047f0
equal deleted inserted replaced
1734:750eeb7230a1 1735:c02818d7e29f
    39     """
    39     """
    40     def __init__(self, CTRInstance):
    40     def __init__(self, CTRInstance):
    41         self.CTRInstance = CTRInstance
    41         self.CTRInstance = CTRInstance
    42         self.buildpath = None
    42         self.buildpath = None
    43         self.SetBuildPath(self.CTRInstance._getBuildPath())
    43         self.SetBuildPath(self.CTRInstance._getBuildPath())
    44     
    44 
    45     def getBuilderCFLAGS(self):
    45     def getBuilderCFLAGS(self):
    46         """
    46         """
    47         Returns list of builder specific CFLAGS
    47         Returns list of builder specific CFLAGS
    48         """
    48         """
    49         return [self.CTRInstance.GetTarget().getcontent().getCFLAGS()]
    49         return [self.CTRInstance.GetTarget().getcontent().getCFLAGS()]
    58     def getCompiler(self):
    58     def getCompiler(self):
    59         """
    59         """
    60         Returns compiler
    60         Returns compiler
    61         """
    61         """
    62         return self.CTRInstance.GetTarget().getcontent().getCompiler()
    62         return self.CTRInstance.GetTarget().getcontent().getCompiler()
    63       
    63 
    64     def getLinker(self):
    64     def getLinker(self):
    65         """
    65         """
    66         Returns linker
    66         Returns linker
    67         """
    67         """
    68         return self.CTRInstance.GetTarget().getcontent().getLinker()
    68         return self.CTRInstance.GetTarget().getcontent().getLinker()
    69                
    69 
    70     def GetBinaryCode(self):
    70     def GetBinaryCode(self):
    71         try:
    71         try:
    72             return open(self.exe_path, "rb").read()
    72             return open(self.exe_path, "rb").read()
    73         except Exception, e:
    73         except Exception, e:
    74             return None
    74             return None
    75         
    75 
    76     def _GetMD5FileName(self):
    76     def _GetMD5FileName(self):
    77         return os.path.join(self.buildpath, "lastbuildPLC.md5")
    77         return os.path.join(self.buildpath, "lastbuildPLC.md5")
    78 
    78 
    79     def ResetBinaryCodeMD5(self):
    79     def ResetBinaryCodeMD5(self):
    80         self.md5key = None
    80         self.md5key = None
    81         try:
    81         try:
    82             os.remove(self._GetMD5FileName())
    82             os.remove(self._GetMD5FileName())
    83         except Exception, e:
    83         except Exception, e:
    84             pass
    84             pass
    85     
    85 
    86     def GetBinaryCodeMD5(self):
    86     def GetBinaryCodeMD5(self):
    87         if self.md5key is not None:
    87         if self.md5key is not None:
    88             return self.md5key
    88             return self.md5key
    89         else:
    89         else:
    90             try:
    90             try:
    91                 return open(self._GetMD5FileName(), "r").read()
    91                 return open(self._GetMD5FileName(), "r").read()
    92             except Exception, e:
    92             except Exception, e:
    93                 return None
    93                 return None
    94     
    94 
    95     def SetBuildPath(self, buildpath):
    95     def SetBuildPath(self, buildpath):
    96         if self.buildpath != buildpath:
    96         if self.buildpath != buildpath:
    97             self.buildpath = buildpath
    97             self.buildpath = buildpath
    98             self.exe = self.CTRInstance.GetProjectName() + self.extension
    98             self.exe = self.CTRInstance.GetProjectName() + self.extension
    99             self.exe_path = os.path.join(self.buildpath, self.exe)
    99             self.exe_path = os.path.join(self.buildpath, self.exe)
   100             self.md5key = None
   100             self.md5key = None
   101             self.srcmd5 = {}
   101             self.srcmd5 = {}
   102             
   102 
   103     def append_cfile_deps(self, src, deps):
   103     def append_cfile_deps(self, src, deps):
   104         for l in src.splitlines():
   104         for l in src.splitlines():
   105             res = includes_re.match(l)
   105             res = includes_re.match(l)
   106             if res is not None:
   106             if res is not None:
   107                 depfn = res.groups()[0]
   107                 depfn = res.groups()[0]
   108                 if os.path.exists(os.path.join(self.buildpath, depfn)):
   108                 if os.path.exists(os.path.join(self.buildpath, depfn)):
   109                     deps.append(depfn)
   109                     deps.append(depfn)
   110                     
   110 
   111     def concat_deps(self, bn):
   111     def concat_deps(self, bn):
   112         # read source
   112         # read source
   113         src = open(os.path.join(self.buildpath, bn),"r").read()
   113         src = open(os.path.join(self.buildpath, bn),"r").read()
   114         # update direct dependencies
   114         # update direct dependencies
   115         deps = []
   115         deps = []
   116         self.append_cfile_deps(src, deps)
   116         self.append_cfile_deps(src, deps)
   117         # recurse through deps
   117         # recurse through deps
   118         # TODO detect cicular deps.
   118         # TODO detect cicular deps.
   119         return reduce(operator.concat, map(self.concat_deps, deps), src)
   119         return reduce(operator.concat, map(self.concat_deps, deps), src)
   120         
   120 
   121     def check_and_update_hash_and_deps(self, bn):
   121     def check_and_update_hash_and_deps(self, bn):
   122         # Get latest computed hash and deps
   122         # Get latest computed hash and deps
   123         oldhash, deps = self.srcmd5.get(bn,(None,[]))
   123         oldhash, deps = self.srcmd5.get(bn,(None,[]))
   124         # read source
   124         # read source
   125         src = open(os.path.join(self.buildpath, bn)).read()
   125         src = open(os.path.join(self.buildpath, bn)).read()
   135             # store that hashand deps
   135             # store that hashand deps
   136             self.srcmd5[bn] = (newhash, deps)
   136             self.srcmd5[bn] = (newhash, deps)
   137         # recurse through deps
   137         # recurse through deps
   138         # TODO detect cicular deps.
   138         # TODO detect cicular deps.
   139         return reduce(operator.and_, map(self.check_and_update_hash_and_deps, deps), match)
   139         return reduce(operator.and_, map(self.check_and_update_hash_and_deps, deps), match)
   140         
   140 
   141     def calc_source_md5(self):
   141     def calc_source_md5(self):
   142         wholesrcdata = ""
   142         wholesrcdata = ""
   143         for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
   143         for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
   144             # Get CFiles list to give it to makefile
   144             # Get CFiles list to give it to makefile
   145             for CFile, CFLAGS in CFilesAndCFLAGS:
   145             for CFile, CFLAGS in CFilesAndCFLAGS:
   146                 CFileName = os.path.basename(CFile)
   146                 CFileName = os.path.basename(CFile)
   147                 wholesrcdata += self.concat_deps(CFileName)
   147                 wholesrcdata += self.concat_deps(CFileName)
   148         return hashlib.md5(wholesrcdata).hexdigest()
   148         return hashlib.md5(wholesrcdata).hexdigest()
   149     
   149 
   150     def calc_md5(self):
   150     def calc_md5(self):
   151         return hashlib.md5(self.GetBinaryCode()).hexdigest()
   151         return hashlib.md5(self.GetBinaryCode()).hexdigest()
   152     
   152 
   153     def build(self):
   153     def build(self):
   154         # Retrieve compiler and linker
   154         # Retrieve compiler and linker
   155         self.compiler = self.getCompiler()
   155         self.compiler = self.getCompiler()
   156         self.linker = self.getLinker()
   156         self.linker = self.getLinker()
   157 
   157 
   165             if CFilesAndCFLAGS:
   165             if CFilesAndCFLAGS:
   166                 if Location :
   166                 if Location :
   167                     self.CTRInstance.logger.write(".".join(map(str,Location))+" :\n")
   167                     self.CTRInstance.logger.write(".".join(map(str,Location))+" :\n")
   168                 else:
   168                 else:
   169                     self.CTRInstance.logger.write(_("PLC :\n"))
   169                     self.CTRInstance.logger.write(_("PLC :\n"))
   170                 
   170 
   171             for CFile, CFLAGS in CFilesAndCFLAGS:
   171             for CFile, CFLAGS in CFilesAndCFLAGS:
   172                 if CFile.endswith(".c"):
   172                 if CFile.endswith(".c"):
   173                     bn = os.path.basename(CFile)
   173                     bn = os.path.basename(CFile)
   174                     obn = os.path.splitext(bn)[0]+".o"
   174                     obn = os.path.splitext(bn)[0]+".o"
   175                     objectfilename = os.path.splitext(CFile)[0]+".o"
   175                     objectfilename = os.path.splitext(CFile)[0]+".o"
   176 
   176 
   177                     match = self.check_and_update_hash_and_deps(bn)
   177                     match = self.check_and_update_hash_and_deps(bn)
   178                     
   178 
   179                     if match:
   179                     if match:
   180                         self.CTRInstance.logger.write("   [pass]  "+bn+" -> "+obn+"\n")
   180                         self.CTRInstance.logger.write("   [pass]  "+bn+" -> "+obn+"\n")
   181                     else:
   181                     else:
   182                         relink = True
   182                         relink = True
   183 
   183 
   184                         self.CTRInstance.logger.write("   [CC]  "+bn+" -> "+obn+"\n")
   184                         self.CTRInstance.logger.write("   [CC]  "+bn+" -> "+obn+"\n")
   185                         
   185 
   186                         status, result, err_result = ProcessLogger(
   186                         status, result, err_result = ProcessLogger(
   187                                self.CTRInstance.logger,
   187                                self.CTRInstance.logger,
   188                                "\"%s\" -c \"%s\" -o \"%s\" %s %s"%
   188                                "\"%s\" -c \"%s\" -o \"%s\" %s %s"%
   189                                    (self.compiler, CFile, objectfilename, Builder_CFLAGS, CFLAGS)
   189                                    (self.compiler, CFile, objectfilename, Builder_CFLAGS, CFLAGS)
   190                                ).spin()
   190                                ).spin()
   202         ######### GENERATE OUTPUT FILE ########################################
   202         ######### GENERATE OUTPUT FILE ########################################
   203         # Link all the object files into one binary file
   203         # Link all the object files into one binary file
   204         self.CTRInstance.logger.write(_("Linking :\n"))
   204         self.CTRInstance.logger.write(_("Linking :\n"))
   205         if relink:
   205         if relink:
   206             objstring = []
   206             objstring = []
   207     
   207 
   208             # Generate list .o files
   208             # Generate list .o files
   209             listobjstring = '"' + '"  "'.join(objs) + '"'
   209             listobjstring = '"' + '"  "'.join(objs) + '"'
   210     
   210 
   211             ALLldflags = ' '.join(self.getBuilderLDFLAGS())
   211             ALLldflags = ' '.join(self.getBuilderLDFLAGS())
   212     
   212 
   213             self.CTRInstance.logger.write("   [CC]  " + ' '.join(obns)+" -> " + self.exe + "\n")
   213             self.CTRInstance.logger.write("   [CC]  " + ' '.join(obns)+" -> " + self.exe + "\n")
   214     
   214 
   215             status, result, err_result = ProcessLogger(
   215             status, result, err_result = ProcessLogger(
   216                    self.CTRInstance.logger,
   216                    self.CTRInstance.logger,
   217                    "\"%s\" %s -o \"%s\" %s"%
   217                    "\"%s\" %s -o \"%s\" %s"%
   218                        (self.linker,
   218                        (self.linker,
   219                         listobjstring,
   219                         listobjstring,
   220                         self.exe_path,
   220                         self.exe_path,
   221                         ALLldflags)
   221                         ALLldflags)
   222                    ).spin()
   222                    ).spin()
   223             
   223 
   224             if status :
   224             if status :
   225                 return False
   225                 return False
   226                 
   226 
   227         else:
   227         else:
   228             self.CTRInstance.logger.write("   [pass]  " + ' '.join(obns)+" -> " + self.exe + "\n")
   228             self.CTRInstance.logger.write("   [pass]  " + ' '.join(obns)+" -> " + self.exe + "\n")
   229         
   229 
   230         # Calculate md5 key and get data for the new created PLC
   230         # Calculate md5 key and get data for the new created PLC
   231         self.md5key = self.calc_md5()
   231         self.md5key = self.calc_md5()
   232 
   232 
   233         # Store new PLC filename based on md5 key
   233         # Store new PLC filename based on md5 key
   234         f = open(self._GetMD5FileName(), "w")
   234         f = open(self._GetMD5FileName(), "w")
   235         f.write(self.md5key)
   235         f.write(self.md5key)
   236         f.close()
   236         f.close()
   237         
   237 
   238         return True
   238         return True
   239