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 |
|