targets/toolchain_gcc.py
changeset 1681 21f40ed5238f
parent 1511 91538d0c242c
child 1731 6ebd9c40b2be
equal deleted inserted replaced
1680:6db967480b7d 1681:21f40ed5238f
     3 
     3 
     4 # This file is part of Beremiz, a Integrated Development Environment for
     4 # This file is part of Beremiz, a Integrated Development Environment for
     5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
     5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
     6 #
     6 #
     7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     8 # Copyright (C) 2017: Paul Beltyukov
     8 #
     9 #
     9 # See COPYING file for copyrights details.
    10 # See COPYING file for copyrights details.
    10 #
    11 #
    11 # This program is free software; you can redistribute it and/or
    12 # This program is free software; you can redistribute it and/or
    12 # modify it under the terms of the GNU General Public License
    13 # modify it under the terms of the GNU General Public License
    50         Returns list of builder specific LDFLAGS
    51         Returns list of builder specific LDFLAGS
    51         """
    52         """
    52         return self.CTRInstance.LDFLAGS + \
    53         return self.CTRInstance.LDFLAGS + \
    53                [self.CTRInstance.GetTarget().getcontent().getLDFLAGS()]
    54                [self.CTRInstance.GetTarget().getcontent().getLDFLAGS()]
    54 
    55 
       
    56     def getCompiler(self):
       
    57         """
       
    58         Returns compiler
       
    59         """
       
    60         return self.CTRInstance.GetTarget().getcontent().getCompiler()
       
    61       
       
    62     def getLinker(self):
       
    63         """
       
    64         Returns linker
       
    65         """
       
    66         return self.CTRInstance.GetTarget().getcontent().getLinker()
       
    67                
    55     def GetBinaryCode(self):
    68     def GetBinaryCode(self):
    56         try:
    69         try:
    57             return open(self.exe_path, "rb").read()
    70             return open(self.exe_path, "rb").read()
    58         except Exception, e:
    71         except Exception, e:
    59             return None
    72             return None
    82             self.buildpath = buildpath
    95             self.buildpath = buildpath
    83             self.exe = self.CTRInstance.GetProjectName() + self.extension
    96             self.exe = self.CTRInstance.GetProjectName() + self.extension
    84             self.exe_path = os.path.join(self.buildpath, self.exe)
    97             self.exe_path = os.path.join(self.buildpath, self.exe)
    85             self.md5key = None
    98             self.md5key = None
    86             self.srcmd5 = {}
    99             self.srcmd5 = {}
    87     
   100             
       
   101     def append_cfile_deps(self, src, deps):
       
   102         for l in src.splitlines():
       
   103             res = includes_re.match(l)
       
   104             if res is not None:
       
   105                 depfn = res.groups()[0]
       
   106                 if os.path.exists(os.path.join(self.buildpath, depfn)):
       
   107                     deps.append(depfn)
       
   108                     
       
   109     def concat_deps(self, bn):
       
   110         # read source
       
   111         src = open(os.path.join(self.buildpath, bn),"r").read()
       
   112         # update direct dependencies
       
   113         deps = []
       
   114         self.append_cfile_deps(src, deps)
       
   115         # recurse through deps
       
   116         # TODO detect cicular deps.
       
   117         return reduce(operator.concat, map(self.concat_deps, deps), src)
       
   118         
    88     def check_and_update_hash_and_deps(self, bn):
   119     def check_and_update_hash_and_deps(self, bn):
    89         # Get latest computed hash and deps
   120         # Get latest computed hash and deps
    90         oldhash, deps = self.srcmd5.get(bn,(None,[]))
   121         oldhash, deps = self.srcmd5.get(bn,(None,[]))
    91         # read source
   122         # read source
    92         src = open(os.path.join(self.buildpath, bn)).read()
   123         src = open(os.path.join(self.buildpath, bn)).read()
    96         match = (oldhash == newhash)
   127         match = (oldhash == newhash)
    97         if not match:
   128         if not match:
    98             # file have changed
   129             # file have changed
    99             # update direct dependencies
   130             # update direct dependencies
   100             deps = []
   131             deps = []
   101             for l in src.splitlines():
   132             self.append_cfile_deps(src, deps)
   102                 res = includes_re.match(l)
       
   103                 if res is not None:
       
   104                     depfn = res.groups()[0]
       
   105                     if os.path.exists(os.path.join(self.buildpath, depfn)):
       
   106                         #print bn + " depends on "+depfn
       
   107                         deps.append(depfn)
       
   108             # store that hashand deps
   133             # store that hashand deps
   109             self.srcmd5[bn] = (newhash, deps)
   134             self.srcmd5[bn] = (newhash, deps)
   110         # recurse through deps
   135         # recurse through deps
   111         # TODO detect cicular deps.
   136         # TODO detect cicular deps.
   112         return reduce(operator.and_, map(self.check_and_update_hash_and_deps, deps), match)
   137         return reduce(operator.and_, map(self.check_and_update_hash_and_deps, deps), match)
   113                 
   138         
       
   139     def calc_source_md5(self):
       
   140         wholesrcdata = ""
       
   141         for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
       
   142             # Get CFiles list to give it to makefile
       
   143             for CFile, CFLAGS in CFilesAndCFLAGS:
       
   144                 CFileName = os.path.basename(CFile)
       
   145                 wholesrcdata += self.concat_deps(CFileName)
       
   146         return hashlib.md5(wholesrcdata).hexdigest()
       
   147     
       
   148     def calc_md5(self):
       
   149         return hashlib.md5(self.GetBinaryCode()).hexdigest()
       
   150     
   114     def build(self):
   151     def build(self):
   115         # Retrieve toolchain user parameters
   152         # Retrieve compiler and linker
   116         toolchain_params = self.CTRInstance.GetTarget().getcontent()
   153         self.compiler = self.getCompiler()
   117         self.compiler = toolchain_params.getCompiler()
   154         self.linker = self.getLinker()
   118         self.linker = toolchain_params.getLinker()
       
   119 
   155 
   120         Builder_CFLAGS = ' '.join(self.getBuilderCFLAGS())
   156         Builder_CFLAGS = ' '.join(self.getBuilderCFLAGS())
   121 
   157 
   122         ######### GENERATE OBJECT FILES ########################################
   158         ######### GENERATE OBJECT FILES ########################################
   123         obns = []
   159         obns = []
   159                     objs.append(objectfilename)
   195                     objs.append(objectfilename)
   160                 elif CFile.endswith(".o"):
   196                 elif CFile.endswith(".o"):
   161                     obns.append(os.path.basename(CFile))
   197                     obns.append(os.path.basename(CFile))
   162                     objs.append(CFile)
   198                     objs.append(CFile)
   163 
   199 
   164         ######### GENERATE library FILE ########################################
   200         ######### GENERATE OUTPUT FILE ########################################
   165         # Link all the object files into one binary file
   201         # Link all the object files into one binary file
   166         self.CTRInstance.logger.write(_("Linking :\n"))
   202         self.CTRInstance.logger.write(_("Linking :\n"))
   167         if relink:
   203         if relink:
   168             objstring = []
   204             objstring = []
   169     
   205     
   188                 
   224                 
   189         else:
   225         else:
   190             self.CTRInstance.logger.write("   [pass]  " + ' '.join(obns)+" -> " + self.exe + "\n")
   226             self.CTRInstance.logger.write("   [pass]  " + ' '.join(obns)+" -> " + self.exe + "\n")
   191         
   227         
   192         # Calculate md5 key and get data for the new created PLC
   228         # Calculate md5 key and get data for the new created PLC
   193         data=self.GetBinaryCode()
   229         self.md5key = self.calc_md5()
   194         self.md5key = hashlib.md5(data).hexdigest()
       
   195 
   230 
   196         # Store new PLC filename based on md5 key
   231         # Store new PLC filename based on md5 key
   197         f = open(self._GetMD5FileName(), "w")
   232         f = open(self._GetMD5FileName(), "w")
   198         f.write(self.md5key)
   233         f.write(self.md5key)
   199         f.close()
   234         f.close()