[coreboot-gerrit] New patch to review for coreboot: a9f1580 util/about/abuild.py: Rewrite abuild script to avoid races

Edward O'Callaghan (eocallaghan@alterapraxis.com) gerrit at coreboot.org
Sat Nov 15 20:20:28 CET 2014


Edward O'Callaghan (eocallaghan at alterapraxis.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7475

-gerrit

commit a9f1580e0c875c00a1dd128f5f91145487330fe6
Author: Edward O'Callaghan <eocallaghan at alterapraxis.com>
Date:   Sun Nov 16 06:17:38 2014 +1100

    util/about/abuild.py: Rewrite abuild script to avoid races
    
    This is a complete rewrite of the abuild shell script into
    python as to avoid nasty shell inconsistences and races. This
    also allows for better integration into buildbot for deeper
    diagnostics on patches under review.
    
    NOTFORMERGE - yet -
    
    Change-Id: Iec1be1bac37860d0b5c87ad02fd557ef7e74e4cd
    Signed-off-by: Edward O'Callaghan <eocallaghan at alterapraxis.com>
---
 util/abuild/abuild.py | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/util/abuild/abuild.py b/util/abuild/abuild.py
new file mode 100755
index 0000000..a99e00c
--- /dev/null
+++ b/util/abuild/abuild.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python2
+# -*- coding: UTF-8 -*-
+# vim: ai ts=4 sts=4 et sw=4
+
+# Copyright (C) 2014 Edward O'Callaghan <eocallaghan at alterapraxis.com>
+# Subject to the GNU GPL v2, or (at your option) any later version.
+
+import xml.dom.minidom
+import os
+import glob
+import re
+
+
+#
+# Class extracts various information from coreboots source tree
+#
+class CorebootSourceInfo:
+    def __init__(self): pass
+
+    def vendor(self, root='./'):
+        vendors = []
+        vendor_kconfigs = glob.glob(root+'src/mainboard/*/Kconfig')
+        for idx in vendor_kconfigs:
+            m = re.match(r'^'+root+'src/mainboard/(.*)/Kconfig$', idx)
+            if m: vendor = m.group(1)
+            vendors.append(vendor)
+        return vendors
+
+    def mainboard(self, vendor, root='./'):
+        mainboards = []
+        mainboard_kconfigs = glob.glob(root+'src/mainboard/'+vendor+'/*/Kconfig')
+        for idx in mainboard_kconfigs:
+            m = re.match(r'^'+root+'src/mainboard/'+vendor+'/(.*)/Kconfig$', idx)
+            if m: mainboard = m.group(1)
+            mainboards.append(mainboard)
+        return mainboards
+
+
+#
+# All things XML here
+#
+class JUnit:
+    def __init__(self): pass
+
+    def buildlog_element(self, doc, buildoutput, ret):
+        if not ret:
+            cnode = doc.createElement('system-out')
+        else:
+            cnode = doc.createElement('failure')
+            cnode.setAttribute('type', 'BuildFailed')
+        cdata = doc.createCDATASection('\n'+buildoutput+'\n')
+        cnode.appendChild(cdata)
+        return cnode
+
+    def create_testcase(self, doc, vendor, board, ret, sysout, time):
+        root = doc.createElement('testcase')
+        root.setAttribute('classname', 'board')
+        root.setAttribute('name', vendor+'/'+board)
+        root.setAttribute('time', time)
+        cnode = buildlog_element(doc, sysout, ret)
+        root.appendChild(cnode)
+        return root
+
+    def create_abuildfile(self):
+        doc = xml.dom.minidom.Document()
+        root = doc.createElement('testsuite')
+        for x in range(0, 3):
+            case = create_testcase(doc, 'jetway', 'nf86-t56n-lf', 0, 'wow', '123')
+            root.appendChild(case)
+        doc.appendChild(root)
+        return doc
+
+    def write_to_file(self, doc, name='abuild.xml'):
+        fd = open(name, 'w')
+        doc.writexml(fd, encoding='utf-8', indent='   ', addindent='   ', newl='\n')
+        fd.close()
+
+#..
+#write_to_file(create_abuildfile())
+
+#
+# Main testsuite class
+#
+class TestSuite:
+    # Where shall we place all the build trees?
+    target = []
+    top = os.getcwd()
+
+    def __init__(self):
+        self.target = os.environ.get('COREBOOT_BUILD_DIR','')+'coreboot-builds'
+
+    def elaborate_testsuite(self):
+        treeInfo = CorebootSourceInfo()
+        vendors = treeInfo.vendor()
+        for vendor in vendors:
+            boards = treeInfo.mainboard(vendor)
+            for board in boards:
+                self.__create_env(vendor, board, '')
+
+    def __create_env(self, vendor, mainboard, config):
+        self.__create_config(vendor, mainboard, config)
+        # Allow simple "make" in the target directory
+        makefile      = []
+        makefile_path = self.target+'/'+vendor+'_'+mainboard+'/Makefile'
+        makefile.append('# autogenerated')
+        makefile.append('TOP=$ROOT')
+        makefile.append('BUILD='+self.target)
+        makefile.append('OBJ=\$(BUILD)/'+vendor+'_'+mainboard)
+        makefile.append('OBJUTIL=\$(BUILD)/sharedutils')
+        makefile.append('all:')
+        makefile.append('	@cp -a config.h config.h.bak')
+        makefile.append('	@cd \$(TOP); \$(MAKE) oldconfig DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)')
+        makefile.append('	@tail -n+6 config.h > config.new; tail -n+6 config.h.bak > config.old')
+        makefile.append('	@cmp -s config.new config.old && cp -a config.h.bak config.h || echo \"Config file changed\"')
+        makefile.append('	@rm config.h.bak config.new config.old')
+        makefile.append('	@cd \$(TOP); \$(MAKE) DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)')
+        # write out resulting Makefile
+        fd = open(makefile_path, 'w')
+        for make_rule in makefile:
+            fd.write('%s\n' % make_rule)
+        fd.close()
+
+    def __create_config(self, vendor, mainboard, config):
+        config_build = []
+        build_dir = self.target+'/'+vendor+'_'+mainboard
+        if not os.path.exists(build_dir):
+            os.makedirs(build_dir)
+        if not os.path.exists(self.target+'/'+'sharedutils'):
+            os.makedirs(self.target+'/'+'sharedutils')
+
+        if not config == '':
+            print ('  Using existing configuration %s ... ' % config)
+            # cp src/mainboard/$VENDOR/$MAINBOARD/$CONFIG ${build_dir}/config.build
+        else:
+            print ('  Creating config file for (%s)... ' % (vendor+'/'+mainboard))
+            config_build.append(self.__vendor_select(vendor))
+            #FIXME crash
+            #config_build.append(self.__board_romsize(vendor, mainboard))
+            config_build.append(self.__board_directory(vendor, mainboard))
+            # XXX: fix payload to none
+            config_build.append('CONFIG_PAYLOAD_NONE=y')
+            # write out resulting config.build file
+            fd = open(build_dir+'/config.build', 'w')
+            for config_parm in config_build:
+                fd.write('%s\n' % config_parm)
+            fd.close()
+
+    # Helper methods - nasty regexp stuff
+    def __vendor_select(self, vendor):
+        with open('src/mainboard/'+vendor+'/Kconfig', 'r') as fd:
+            kconfig = fd.readlines()
+            for line in kconfig:
+                m = re.match('if[\t ]*VENDOR.+', line)
+                if m: exp = re.sub(r'^.*(VENDOR_.*)[^A-Z0-9_]*', r'CONFIG_\1', m.group())
+            fd.close()
+        return exp
+
+    def __board_romsize(self, vendor, board):
+        # print (board)
+        with open('src/mainboard/'+vendor+'/'+board+'/Kconfig', 'r') as fd:
+            kconfig = fd.readlines()
+            for line in kconfig:
+                m = re.match('\tselect[\t ]*BOARD.+', line)
+                if m: exp = re.sub(r'^.*(BOARD_.*)[^A-Z0-9_]*', r'CONFIG_\1', m.group())
+            fd.close()
+        return exp
+
+    def __board_directory(self, vendor, mainboard):
+        return 'CONFIG_MAINBOARD_DIR=\"'+vendor+'/'+mainboard+'\"'
+
+
+
+# Go off now, construct and run the test suite else all this was a wast of time..
+testSuite = TestSuite()
+testSuite.elaborate_testsuite()



More information about the coreboot-gerrit mailing list