Re-introduced toolchain_makefile.py. This time, it comes with a 'Generic' target, and a 'genericmake' example
--- a/ProjectController.py Sun Jan 19 22:39:25 2014 +0100
+++ b/ProjectController.py Mon Jan 20 11:04:19 2014 +0100
@@ -665,7 +665,7 @@
# Keep track of generated C files for later use by self.CTNGenerate_C
self.PLCGeneratedCFiles = C_files
# compute CFLAGS for plc
- self.plcCFLAGS = "\"-I"+self.ieclib_path+"\""
+ self.plcCFLAGS = "-I"+self.ieclib_path
return True
def GetBuilder(self):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/Generic/XSD Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,6 @@
+
+ <xsd:element name="Generic">
+ <xsd:complexType>
+ %(toolchain_makefile)s
+ </xsd:complexType>
+ </xsd:element>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/Generic/__init__.py Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,4 @@
+from ..toolchain_makefile import toolchain_makefile
+
+class Generic_target(toolchain_makefile):
+ pass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/Generic/plc_Generic_main.c Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,4 @@
+/**
+ * No platform specific code for "Generic" target
+ **/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/XSD_toolchain_makefile Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,3 @@
+
+ <xsd:attribute name="Command" type="xsd:string" use="optional" default="make -C %(buildpath)s all BEREMIZSRC=%(src)s BEREMIZCFLAGS=%(cflags)s MD5=%(md5)s USE_BEREMIZ=1 FROM_BEREMIZ=1"/>
+
--- a/targets/__init__.py Sun Jan 19 22:39:25 2014 +0100
+++ b/targets/__init__.py Mon Jan 20 11:04:19 2014 +0100
@@ -43,7 +43,8 @@
if path.isdir(path.join(_base_path, name))
and not name.startswith("__")])
-toolchains = {"gcc": path.join(_base_path, "XSD_toolchain_gcc")}
+toolchains = {"gcc": path.join(_base_path, "XSD_toolchain_gcc"),
+ "makefile": path.join(_base_path, "XSD_toolchain_makefile")}
def GetBuilder(targetname):
return targets[targetname]["class"]()
@@ -55,10 +56,8 @@
# Get all xsd toolchains
for toolchainname,xsdfilename in toolchains.iteritems() :
if path.isfile(xsdfilename):
- xsd_toolchain_string = ""
- for line in open(xsdfilename).readlines():
- xsd_toolchain_string += line
- DictXSD_toolchain["toolchain_"+toolchainname] = xsd_toolchain_string
+ DictXSD_toolchain["toolchain_"+toolchainname] = \
+ open(xsdfilename).read()
# Get all xsd targets
for targetname,nfo in targets.iteritems():
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/toolchain_makefile.py Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,105 @@
+import os, re, operator
+from util.ProcessLogger import ProcessLogger
+import hashlib
+
+import time
+
+includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*')
+
+class toolchain_makefile():
+ def __init__(self, CTRInstance):
+ self.CTRInstance = CTRInstance
+ self.md5key = None
+ self.buildpath = None
+ self.SetBuildPath(self.CTRInstance._getBuildPath())
+
+ def SetBuildPath(self, buildpath):
+ if self.buildpath != buildpath:
+ self.buildpath = buildpath
+ self.md5key = None
+
+ def GetBinaryCode(self):
+ return None
+
+ def _GetMD5FileName(self):
+ return os.path.join(self.buildpath, "lastbuildPLC.md5")
+
+ def ResetBinaryCodeMD5(self):
+ self.md5key = None
+ try:
+ os.remove(self._GetMD5FileName())
+ except Exception, e:
+ pass
+
+ def GetBinaryCodeMD5(self):
+ if self.md5key is not None:
+ return self.md5key
+ else:
+ try:
+ return open(self._GetMD5FileName(), "r").read()
+ except IOError, e:
+ return None
+
+ def concat_deps(self, bn):
+ # read source
+ src = open(os.path.join(self.buildpath, bn),"r").read()
+ # update direct dependencies
+ deps = []
+ for l in src.splitlines():
+ res = includes_re.match(l)
+ if res is not None:
+ depfn = res.groups()[0]
+ if os.path.exists(os.path.join(self.buildpath, depfn)):
+ #print bn + " depends on "+depfn
+ deps.append(depfn)
+ # recurse through deps
+ # TODO detect cicular deps.
+ return reduce(operator.concat, map(self.concat_deps, deps), src)
+
+ def build(self):
+ srcfiles= []
+ cflags = []
+ wholesrcdata = ""
+ for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
+ # Get CFiles list to give it to makefile
+ for CFile, CFLAGS in CFilesAndCFLAGS:
+ CFileName = os.path.basename(CFile)
+ wholesrcdata += self.concat_deps(CFileName)
+ srcfiles.append(CFileName)
+ if CFLAGS not in cflags:
+ cflags.append(CFLAGS)
+
+ oldmd5 = self.md5key
+ self.md5key = hashlib.md5(wholesrcdata).hexdigest()
+ props = self.CTRInstance.GetProjectProperties()
+ self.md5key += '#'.join([props[key] for key in ['companyName',
+ 'projectName',
+ 'productName']])
+ self.md5key += '#' #+','.join(map(str,time.localtime()))
+ # Store new PLC filename based on md5 key
+ f = open(self._GetMD5FileName(), "w")
+ f.write(self.md5key)
+ f.close()
+
+ if oldmd5 != self.md5key :
+ target = self.CTRInstance.GetTarget().getcontent()
+ beremizcommand = {"src": ' '.join(srcfiles),
+ "cflags": ' '.join(cflags),
+ "md5": self.md5key,
+ "buildpath": self.buildpath
+ }
+
+ command = [ token % beremizcommand for token in target.getCommand().split(' ')]
+
+ # Call Makefile to build PLC code and link it with target specific code
+ status, result, err_result = ProcessLogger(self.CTRInstance.logger,
+ command).spin()
+ if status :
+ self.md5key = None
+ self.CTRInstance.logger.write_error(_("C compilation failed.\n"))
+ return False
+ return True
+ else :
+ self.CTRInstance.logger.write(_("Source didn't change, no build.\n"))
+ return True
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/genericmake/beremiz.xml Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<BeremizRoot xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <TargetType>
+ <Generic Command="make -C %(buildpath)s -f ../project_files/Makefile all BEREMIZSRC=%(src)s BEREMIZCFLAGS=%(cflags)s MD5=%(md5)s USE_BEREMIZ=1 FROM_BEREMIZ=1"/>
+ </TargetType>
+ <Libraries Enable_Native_Library="false" Enable_Python_Library="false" Enable_SVGUI_Library="false"/>
+</BeremizRoot>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/genericmake/plc.xml Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,73 @@
+<?xml version='1.0' encoding='utf-8'?>
+<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
+ <fileHeader companyName="Unknown" productName="Unnamed" productVersion="1" creationDateTime="2014-01-19T11:14:47"/>
+ <contentHeader name="Unnamed" modificationDateTime="2014-01-20T01:37:01">
+ <coordinateInfo>
+ <fbd>
+ <scaling x="0" y="0"/>
+ </fbd>
+ <ld>
+ <scaling x="0" y="0"/>
+ </ld>
+ <sfc>
+ <scaling x="0" y="0"/>
+ </sfc>
+ </coordinateInfo>
+ </contentHeader>
+ <types>
+ <dataTypes/>
+ <pous>
+ <pou name="program0" pouType="program">
+ <interface>
+ <localVars>
+ <variable name="LocalVara">
+ <type>
+ <INT/>
+ </type>
+ </variable>
+ <variable name="LocalVarb">
+ <type>
+ <INT/>
+ </type>
+ </variable>
+ </localVars>
+ </interface>
+ <body>
+ <FBD>
+ <inVariable localId="1" executionOrderId="0" height="27" width="77" negated="false">
+ <position x="196" y="224"/>
+ <connectionPointOut>
+ <relPosition x="77" y="13"/>
+ </connectionPointOut>
+ <expression>LocalVara</expression>
+ </inVariable>
+ <outVariable localId="2" executionOrderId="0" height="27" width="77" negated="false">
+ <position x="305" y="227"/>
+ <connectionPointIn>
+ <relPosition x="0" y="13"/>
+ <connection refLocalId="1">
+ <position x="305" y="240"/>
+ <position x="288" y="240"/>
+ <position x="288" y="237"/>
+ <position x="273" y="237"/>
+ </connection>
+ </connectionPointIn>
+ <expression>LocalVarb</expression>
+ </outVariable>
+ </FBD>
+ </body>
+ </pou>
+ </pous>
+ </types>
+ <instances>
+ <configurations>
+ <configuration name="config">
+ <resource name="resource1">
+ <task name="Tsk" priority="0" interval="T#100ms">
+ <pouInstance name="Inst" typeName="program0"/>
+ </task>
+ </resource>
+ </configuration>
+ </configurations>
+ </instances>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/genericmake/project_files/Makefile Mon Jan 20 11:04:19 2014 +0100
@@ -0,0 +1,13 @@
+BEREMIZ_OBJS = $(BEREMIZSRC:.c=.o)
+
+all: warn some_binary
+ @echo "*** all done ***"
+
+warn:
+ @echo "*** Sample Makefile, does nothing ***"
+
+some_binary: $(BEREMIZ_OBJS)
+ @echo "* Would link $^ -> $@"
+
+%o : %c
+ @echo "* Would compile $< -> $@"