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