1 #!/usr/bin/python 2 # 3 # Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 4 # 5 # This program and the accompanying materials 6 # are licensed and made available under the terms and conditions of the BSD License 7 # which accompanies this distribution. The full text of the license may be found at 8 # http://opensource.org/licenses/bsd-license.php 9 # 10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 # 13 14 import os 15 import re 16 import StringIO 17 import subprocess 18 import sys 19 import zipfile 20 21 is_unix = not sys.platform.startswith('win') 22 23 if not is_unix: 24 print "This script currently only supports unix-like systems" 25 sys.exit(-1) 26 27 if os.path.exists('OvmfPkgX64.dsc'): 28 os.chdir('..') 29 30 if not os.path.exists(os.path.join('OvmfPkg', 'OvmfPkgX64.dsc')): 31 print "OvmfPkg/OvmfPkgX64.dsc doesn't exist" 32 sys.exit(-1) 33 34 def run_and_capture_output(args, checkExitCode = True): 35 p = subprocess.Popen(args=args, stdout=subprocess.PIPE) 36 stdout = p.stdout.read() 37 ret_code = p.wait() 38 if checkExitCode: 39 assert ret_code == 0 40 return stdout 41 42 gcc_version = run_and_capture_output(args=('gcc', '--version')) 43 gcc_re = re.compile(r'\s*\S+\s+\([^\)]+?\)\s+(\d+(?:\.\d+)*)(?:\s+.*)?') 44 mo = gcc_re.match(gcc_version) 45 if not mo: 46 print "Unable to find GCC version" 47 sys.exit(-1) 48 gcc_version = map(lambda n: int(n), mo.group(1).split('.')) 49 50 if 'TOOLCHAIN' in os.environ: 51 TOOLCHAIN = os.environ['TOOLCHAIN'] 52 else: 53 assert(gcc_version[0] == 4) 54 minor = max(4, min(7, gcc_version[1])) 55 TOOLCHAIN = 'GCC4' + str(minor) 56 57 def git_based_version(): 58 dir = os.getcwd() 59 if not os.path.exists('.git'): 60 os.chdir('OvmfPkg') 61 stdout = run_and_capture_output(args=('git', 'log', 62 '-n', '1', 63 '--abbrev-commit')) 64 regex = re.compile(r'^\s*git-svn-id:\s+\S+@(\d+)\s+[0-9a-f\-]+$', 65 re.MULTILINE) 66 mo = regex.search(stdout) 67 if mo: 68 version = 'r' + mo.group(1) 69 else: 70 version = stdout.split(None, 3)[1] 71 os.chdir(dir) 72 return version 73 74 def svn_info(): 75 dir = os.getcwd() 76 os.chdir('OvmfPkg') 77 stdout = run_and_capture_output(args=('svn', 'info')) 78 os.chdir(dir) 79 return stdout 80 81 def svn_based_version(): 82 buf = svn_info() 83 revision_re = re.compile('^Revision\:\s*([\da-f]+)$', re.MULTILINE) 84 mo = revision_re.search(buf) 85 assert(mo is not None) 86 return 'r' + mo.group(1) 87 88 def get_revision(): 89 if os.path.exists(os.path.join('OvmfPkg', '.svn')): 90 return svn_based_version() 91 else: 92 return git_based_version() 93 94 revision = get_revision() 95 96 newline_re = re.compile(r'(\n|\r\n|\r(?!\n))', re.MULTILINE) 97 def to_dos_text(str): 98 return newline_re.sub('\r\n', str) 99 100 def gen_build_info(): 101 distro = run_and_capture_output(args=('lsb_release', '-sd')).strip() 102 103 machine = run_and_capture_output(args=('uname', '-m')).strip() 104 105 gcc_version_str = '.'.join(map(lambda v: str(v), gcc_version)) 106 107 ld_version = run_and_capture_output(args=('ld', '--version')) 108 ld_version = ld_version.split('\n')[0].split()[-1] 109 110 iasl_version = run_and_capture_output(args=('iasl'), checkExitCode=False) 111 iasl_version = filter(lambda s: s.find(' version ') >= 0, iasl_version.split('\n'))[0] 112 iasl_version = iasl_version.split(' version ')[1].strip() 113 114 sb = StringIO.StringIO() 115 print >> sb, 'edk2: ', revision 116 print >> sb, 'compiler: GCC', gcc_version_str, '(' + TOOLCHAIN + ')' 117 print >> sb, 'binutils:', ld_version 118 print >> sb, 'iasl: ', iasl_version 119 print >> sb, 'system: ', distro, machine.replace('_', '-') 120 return to_dos_text(sb.getvalue()) 121 122 def read_file(filename): 123 f = open(filename) 124 d = f.read() 125 f.close() 126 return d 127 128 LICENSE = to_dos_text( 129 '''This OVMF binary release is built from source code licensed under 130 the BSD open source license. The BSD license is documented at 131 http://opensource.org/licenses/bsd-license.php, and a copy is 132 shown below. 133 134 One sub-component of the OVMF project is a FAT filesystem driver. The FAT 135 filesystem driver code is also BSD licensed, but the code license contains 136 one additional term. This license can be found at 137 https://github.com/tianocore/tianocore.github.io/wiki/Edk2-fat-driver 138 and a copy is shown below (following the normal BSD license). 139 140 === BSD license: START === 141 142 ''') 143 144 LICENSE += read_file(os.path.join('MdePkg', 'License.txt')) 145 146 LICENSE += to_dos_text( 147 ''' 148 === BSD license: END === 149 150 === FAT filesystem driver license: START === 151 152 ''') 153 154 LICENSE += read_file(os.path.join('FatBinPkg', 'License.txt')) 155 156 LICENSE += to_dos_text( 157 ''' 158 === FAT filesystem driver license: END === 159 ''') 160 161 def build(arch): 162 args = ( 163 'OvmfPkg/build.sh', 164 '-t', TOOLCHAIN, 165 '-a', arch, 166 '-b', 'RELEASE' 167 ) 168 logname = 'build-%s.log' % arch 169 build_log = open(logname, 'w') 170 print 'Building OVMF for', arch, '(%s)' % logname, '...', 171 sys.stdout.flush() 172 p = subprocess.Popen(args=args, stdout=build_log, stderr=build_log) 173 ret_code = p.wait() 174 if ret_code == 0: 175 print '[done]' 176 else: 177 print '[error 0x%x]' % ret_code 178 return ret_code 179 180 def create_zip(arch): 181 global build_info 182 filename = 'OVMF-%s-%s.zip' % (arch, revision) 183 print 'Creating', filename, '...', 184 sys.stdout.flush() 185 if os.path.exists(filename): 186 os.remove(filename) 187 zipf = zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) 188 189 zipf.writestr('BUILD_INFO', build_info) 190 zipf.writestr('LICENSE', LICENSE) 191 zipf.write(os.path.join('OvmfPkg', 'README'), 'README') 192 FV_DIR = os.path.join( 193 'Build', 194 'Ovmf' + arch.title(), 195 'RELEASE_' + TOOLCHAIN, 196 'FV' 197 ) 198 zipf.write(os.path.join(FV_DIR, 'OVMF.fd'), 'OVMF.fd') 199 zipf.close() 200 print '[done]' 201 202 build_info = gen_build_info() 203 build('IA32') 204 build('X64') 205 create_zip('IA32') 206 create_zip('X64') 207 208 209