[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH-RFC] reproducable build script



Introduce a build script to build the drivers given a specified version
This does require gitpython module to retrieve parameters from the HEAD commit

usage: repro-build.py [free|checked|sdv] [major] [minor] [micro] [build]

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 repro-build.py | 401 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 401 insertions(+)
 create mode 100644 repro-build.py

diff --git a/repro-build.py b/repro-build.py
new file mode 100644
index 0000000..6019698
--- /dev/null
+++ b/repro-build.py
@@ -0,0 +1,401 @@
+#!python -u
+
+import os, sys
+import datetime
+import argparse
+import git
+import time
+import subprocess
+import re
+import shutil
+import glob
+import tarfile
+
+def make_header():
+    print("Generating include/version.h")
+    file = open('include\\version.h', 'w')
+    file.write('#define VENDOR_NAME_STR\t\t"' + os.environ['VENDOR_NAME'] + 
'"\n')
+    file.write('#define VENDOR_PREFIX_STR\t"' + os.environ['VENDOR_PREFIX'] + 
'"\n')
+    if 'VENDOR_DEVICE_ID' in os.environ.keys():
+        file.write('#define VENDOR_DEVICE_ID_STR\t"' + 
os.environ['VENDOR_DEVICE_ID'] + '"\n')
+    file.write('#define PRODUCT_NAME_STR\t"' + os.environ['PRODUCT_NAME'] + 
'"\n')
+    file.write('\n')
+    file.write('#define MAJOR_VERSION\t\t' + os.environ['MAJOR_VERSION'] + 
'\n')
+    file.write('#define MAJOR_VERSION_STR\t"' + os.environ['MAJOR_VERSION'] + 
'"\n')
+    file.write('\n')
+    file.write('#define MINOR_VERSION\t\t' + os.environ['MINOR_VERSION'] + 
'\n')
+    file.write('#define MINOR_VERSION_STR\t"' + os.environ['MINOR_VERSION'] + 
'"\n')
+    file.write('\n')
+    file.write('#define MICRO_VERSION\t\t' + os.environ['MICRO_VERSION'] + 
'\n')
+    file.write('#define MICRO_VERSION_STR\t"' + os.environ['MICRO_VERSION'] + 
'"\n')
+    file.write('\n')
+    file.write('#define BUILD_NUMBER\t\t' + os.environ['BUILD_NUMBER'] + '\n')
+    file.write('#define BUILD_NUMBER_STR\t"' + os.environ['BUILD_NUMBER'] + 
'"\n')
+    file.write('\n')
+    file.write('#define YEAR\t\t\t' + os.environ['GIT_YEAR'] + '\n')
+    file.write('#define YEAR_STR\t\t"' + os.environ['GIT_YEAR'] + '"\n')
+    file.write('\n')
+    file.write('#define MONTH\t\t\t' + os.environ['GIT_MONTH'] + '\n')
+    file.write('#define MONTH_STR\t\t"' + os.environ['GIT_MONTH'] + '"\n')
+    file.write('\n')
+    file.write('#define DAY\t\t\t' + os.environ['GIT_DAY'] + '\n')
+    file.write('#define DAY_STR\t\t\t"' + os.environ['GIT_DAY'] + '"\n')
+    file.write('\n')
+    file.write('\n')
+    file.write('#define REVISION_STR\t\t\t' + os.environ['GIT_REVISION'] + 
'\n')
+    file.write('\n')
+    file.close()
+
+def make_inf(name, proj):
+    print("Generating xenbus.inf")
+    src = open('src\\%s.inf' % name, 'r')
+    dst = open('%s\\%s.inf' % (proj, name), 'w')
+    for line in src:
+        line = re.sub('@MAJOR_VERSION@', os.environ['MAJOR_VERSION'], line)
+        line = re.sub('@MINOR_VERSION@', os.environ['MINOR_VERSION'], line)
+        line = re.sub('@MICRO_VERSION@', os.environ['MICRO_VERSION'], line)
+        line = re.sub('@BUILD_NUMBER@', os.environ['BUILD_NUMBER'], line)
+        line = re.sub('@VENDOR_NAME@', os.environ['VENDOR_NAME'], line)
+        line = re.sub('@PRODUCT_NAME@', os.environ['PRODUCT_NAME'], line)
+        if re.search('@VENDOR_DEVICE_ID@', line):
+            if 'VENDOR_DEVICE_ID' not in os.environ.keys():
+                continue
+            line = re.sub('@VENDOR_DEVICE_ID@', 
os.environ['VENDOR_DEVICE_ID'], line)
+        dst.write(line)
+    dst.close()
+    src.close()
+
+def get_configuration(release, debug):
+    configuration = release
+    if debug:
+        configuration += ' Debug'
+    else:
+        configuration += ' Release'
+    return configuration
+
+def get_target_path(release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+    name = ''.join(configuration.split(' '))
+    target = { 'x86': os.sep.join([name, 'Win32']), 'x64': os.sep.join([name, 
'x64']) }
+    target_path = os.sep.join([vs, target[arch]])
+    return target_path
+
+def shell(command, dir):
+    print(dir)
+    print(command)
+    sys.stdout.flush()
+    sub = subprocess.Popen(' '.join(command), cwd=dir,
+                           stdout=subprocess.PIPE,
+                           stderr=subprocess.STDOUT)
+    for line in sub.stdout:
+        print(line.decode(sys.getdefaultencoding()).rstrip())
+    sub.wait()
+    return sub.returncode
+
+class msbuild_failure(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+def msbuild(platform, configuration, target, file, args, dir):
+    vcvarsall = find('vcvarsall.bat', os.environ['VS'])
+    os.environ['MSBUILD_PLATFORM'] = platform
+    os.environ['MSBUILD_CONFIGURATION'] = configuration
+    os.environ['MSBUILD_TARGET'] = target
+    os.environ['MSBUILD_FILE'] = file
+    os.environ['MSBUILD_EXTRA'] = args
+    os.environ['MSBUILD_VCVARSALL'] = vcvarsall
+    bin = os.path.join(os.getcwd(), 'msbuild.bat')
+    status = shell([bin], dir)
+    if (status != 0):
+        raise msbuild_failure(configuration)
+
+def build_sln(name, release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+    if arch == 'x86':
+        platform = 'Win32'
+    elif arch == 'x64':
+        platform = 'x64'
+    msbuild(platform, configuration, 'Build', name + '.sln', '', vs)
+
+def manifest():
+    cmd = ['git', 'ls-tree', '-r', '--name-only', 'HEAD']
+    sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+    output = sub.communicate()[0]
+    ret = sub.returncode
+    if ret != 0:
+        raise(Exception("Error %d in : %s" % (ret, cmd)))
+    return output.decode('utf-8')
+
+def archive(filename, files, tgz=False):
+    print(filename)
+    access='w'
+    if tgz:
+        access='w:gz'
+    tar = tarfile.open(filename, access)
+    for name in files :
+        try:
+            tar.add(name)
+        except:
+            pass
+    tar.close()
+
+def copy_package(name, release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+    if arch == 'x86':
+        platform = 'Win32'
+    elif arch == 'x64':
+        platform = 'x64'
+    pattern = '/'.join([vs, ''.join(configuration.split(' ')), platform, 
'package', '*'])
+    print('Copying package from %s' % pattern)
+    files = glob.glob(pattern)
+    dst = os.path.join(name, arch)
+    os.makedirs(dst, exist_ok=True)
+    for file in files:
+        new = shutil.copy(file, dst)
+        print(new)
+    print('')
+
+def remove_timestamps(path):
+    try:
+        os.unlink(path + '.orig')
+    except OSError:
+        pass
+
+    os.rename(path, path + '.orig')
+
+    src = open(path + '.orig', 'r')
+    dst = open(path, 'w')
+
+    for line in src:
+        if line.find('TimeStamp') == -1:
+            dst.write(line)
+
+    dst.close()
+    src.close()
+
+def do_sdv(drivers, dir, vs):
+    print("Running SDV")
+    release = { 'vs2015':'Windows 10',
+                'vs2017':'Windows 10' }
+    configuration = get_configuration(release[vs], False)
+    platform = 'x64'
+
+    for name in drivers:
+        msbuild(platform, configuration, 'Build', name + '.vcxproj',
+                '', os.path.join(vs, name))
+
+        msbuild(platform, configuration, 'sdv', name + '.vcxproj',
+                '/p:Inputs="/clean"', os.path.join(vs, name))
+
+        msbuild(platform, configuration, 'sdv', name + '.vcxproj',
+                '/p:Inputs="/check:default.sdv /debug"', os.path.join(vs, 
name))
+
+        path = [vs, name, 'sdv', 'SDV.DVL.xml']
+        remove_timestamps(os.path.join(*path))
+
+        msbuild(platform, configuration, 'dvl', name + '.vcxproj',
+                '', os.path.join(vs, name))
+
+        path = [vs, name, name + '.DVL.XML']
+        shutil.copy(os.path.join(*path), dir)
+
+        path = [vs, name, 'refine.sdv']
+        if os.path.isfile(os.path.join(*path)):
+            msbuild(platform, configuration, 'sdv', name + '.vcxproj',
+                    '/p:Inputs=/refine', os.path.join(vs, name))
+    archive(driver + '-sdv.tar', driver + '\\*.DVL.XML')
+
+def get_target_path(release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+    name = ''.join(configuration.split(' '))
+    target = { 'x86': os.sep.join([name, 'Win32']), 'x64': os.sep.join([name, 
'x64']) }
+    target_path = os.sep.join([vs, target[arch]])
+
+    return target_path
+
+
+def get_expired_symbols(name, age = 30):
+    path = os.path.join(os.environ['SYMBOL_SERVER'], '000Admin\\history.txt')
+    try:
+        file = open(path, 'r')
+    except IOError:
+        return []
+    threshold = datetime.datetime.utcnow() - datetime.timedelta(days = age)
+    expired = []
+    for line in file:
+        item = line.split(',')
+
+        if (re.match('add', item[1])):
+            id = item[0]
+            date = item[3].split('/')
+            time = item[4].split(':')
+            tag = item[5].strip('"')
+
+            age = datetime.datetime(year = int(date[2]),
+                                    month = int(date[0]),
+                                    day = int(date[1]),
+                                    hour = int(time[0]),
+                                    minute = int(time[1]),
+                                    second = int(time[2]))
+            if (tag == name and age < threshold):
+                expired.append(id)
+        elif (re.match('del', item[1])):
+            id = item[2].rstrip()
+            try:
+                expired.remove(id)
+            except ValueError:
+                pass
+    file.close()
+    return expired
+
+def symstore_del(name, age):
+    symstore_path = [os.environ['KIT'], 'Debuggers']
+    if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86':
+        symstore_path.append('x86')
+    else:
+        symstore_path.append('x64')
+    symstore_path.append('symstore.exe')
+
+    symstore = os.path.join(*symstore_path)
+
+    for id in get_expired_symbols(name, age):
+        command=['"' + symstore + '"']
+        command.append('del')
+        command.append('/i')
+        command.append(str(id))
+        command.append('/s')
+        command.append(os.environ['SYMBOL_SERVER'])
+
+        shell(command, None)
+
+def symstore_add(name, release, arch, debug, vs):
+    target_path = get_target_path(release, arch, debug, vs)
+
+    symstore_path = [os.environ['KIT'], 'Debuggers']
+    if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86':
+        symstore_path.append('x86')
+    else:
+        symstore_path.append('x64')
+    symstore_path.append('symstore.exe')
+
+    symstore = os.path.join(*symstore_path)
+
+    version = '.'.join([os.environ['MAJOR_VERSION'],
+                        os.environ['MINOR_VERSION'],
+                        os.environ['MICRO_VERSION'],
+                        os.environ['BUILD_NUMBER']])
+
+    command=['"' + symstore + '"']
+    command.append('add')
+    command.append('/s')
+    command.append(os.environ['SYMBOL_SERVER'])
+    command.append('/r')
+    command.append('/f')
+    command.append('*.pdb')
+    command.append('/t')
+    command.append(name)
+    command.append('/v')
+    command.append(version)
+
+    shell(command, target_path)
+
+def do_build(driver, vs, debug):
+    print("Building... Debug=%s" %debug)
+    release = { 'vs2015':'Windows 8',
+                'vs2017':'Windows 8' }
+
+    shutil.rmtree(driver, ignore_errors=True)
+
+    build_sln(driver, release[vs], 'x86', debug, vs)
+    copy_package(driver, release[vs], 'x86', debug, vs)
+
+    build_sln(driver, release[vs], 'x64', debug, vs)
+    copy_package(driver, release[vs], 'x64', debug, vs)
+
+    symstore_add(driver, release[vs], 'x86', debug, vs)
+    symstore_add(driver, release[vs], 'x64', debug, vs)
+
+    archive(driver + '\\source.tgz', manifest().splitlines(), tgz=True)
+    archive(driver + '.tar', [driver,'revision'])
+
+def find(name, path):
+    for root, dirs, files in os.walk(path):
+        if name in files:
+            return os.path.join(root, name)
+
+def getVsVersion():
+    vsenv = {}
+    vcvarsall= find('vcvarsall.bat', os.environ['VS'])
+    vars = subprocess.check_output([vcvarsall, 'x86_amd64', '&&', 'set'], 
shell=True)
+    for var in vars.splitlines():
+        k, _, v = map(str.strip, var.strip().decode('utf-8').partition('='))
+        if k.startswith('?'):
+            continue
+        vsenv[k] = v
+    mapping = { '14.0':'vs2015',
+                '15.0':'vs2017'}
+    return mapping[vsenv['VisualStudioVersion']]
+
+def main():
+    driver = 'xenbus'
+    driverlist = ['xen','xenfilt','xenbus']
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("target")
+    parser.add_argument("major", type=int)
+    parser.add_argument("minor", type=int)
+    parser.add_argument("micro", type=int)
+    parser.add_argument("build", type=int)
+    args = parser.parse_args()
+    vs = getVsVersion()
+
+    if 'VENDOR_NAME' not in os.environ.keys():
+        os.environ['VENDOR_NAME'] = 'Xen Project'
+    if 'VENDOR_PREFIX' not in os.environ.keys():
+        os.environ['VENDOR_PREFIX'] = 'XP'
+    if 'PRODUCT_NAME' not in os.environ.keys():
+        os.environ['PRODUCT_NAME'] = 'Xen'
+    os.environ['MAJOR_VERSION'] = str(args.major)
+    os.environ['MINOR_VERSION'] = str(args.minor)
+    os.environ['MICRO_VERSION'] = str(args.micro)
+    os.environ['BUILD_NUMBER'] = str(args.build)
+
+    repo = git.Repo()
+    gittime = time.gmtime(repo.head.object.authored_date)
+    os.environ['GIT_REVISION'] = str(repo.head.object.hexsha)
+    os.environ['GIT_YEAR'] = time.strftime('%Y', gittime)
+    os.environ['GIT_MONTH'] = time.strftime('%m', gittime)
+    os.environ['GIT_DAY'] = time.strftime('%d', gittime)
+
+    print("VENDOR_NAME\t\t'%s'" % os.environ['VENDOR_NAME'])
+    print("VENDOR_PREFIX\t\t'%s'" % os.environ['VENDOR_PREFIX'])
+
+    if 'VENDOR_DEVICE_ID' in os.environ.keys():
+        print("VENDOR_DEVICE_ID\t'%s'" % os.environ['VENDOR_DEVICE_ID'])
+
+    print("PRODUCT_NAME\t\t'%s'" % os.environ['PRODUCT_NAME'])
+    print("MAJOR_VERSION\t\t%s" % os.environ['MAJOR_VERSION'])
+    print("MINOR_VERSION\t\t%s" % os.environ['MINOR_VERSION'])
+    print("MICRO_VERSION\t\t%s" % os.environ['MICRO_VERSION'])
+    print("BUILD_NUMBER\t\t%s" % os.environ['BUILD_NUMBER'])
+    print("GIT_REVISION\t\t%s" % os.environ['GIT_REVISION'])
+    print("GIT_YEAR\t\t%s" % os.environ['GIT_YEAR'])
+    print("GIT_MONTH\t\t%s" % os.environ['GIT_MONTH'])
+    print("GIT_DAY\t\t%s" % os.environ['GIT_DAY'])
+    print()
+
+    make_header() # version.h
+    make_inf(driver, vs) # <driver>.inf
+    symstore_del(driver, 30)
+
+    if args.target == 'sdv':
+        do_sdv(driverlist, driver, vs)
+    elif args.target == 'free':
+        do_build(driver, vs, False)
+    elif args.target == 'checked':
+        do_build(driver, vs, True)
+
+if __name__ == '__main__':
+    main()
-- 
2.16.2.windows.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.