|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |