1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
import os, os.path, shutil, sys, subprocess
from .utils import *
from .config import *
class Batch(object):
def __init__(self, bconf):
self.bconf = bconf
self.commands = []
self.add(self.vcvars_cmd)
self.add('echo on')
if self.bconf.vc_version == 'vc14':
# I don't know why vcvars doesn't configure this under vc14
self.add('set include=%s\\include;%%include%%' % self.bconf.windows_sdk_path)
if self.bconf.bitness == 32:
self.add('set lib=%s\\lib;%%lib%%' % self.bconf.windows_sdk_path)
self.add('set path=%s\\bin;%%path%%' % self.bconf.windows_sdk_path)
else:
self.add('set lib=%s\\lib\\x64;%%lib%%' % self.bconf.windows_sdk_path)
self.add('set path=%s\\bin\\x64;%%path%%' % self.bconf.windows_sdk_path)
self.add(self.nasm_cmd)
self.add('set path=%s;%%path%%' % self.bconf.extra_bin_paths[self.bconf.bitness]['rc_bin'])
def add(self, cmd):
self.commands.append(cmd)
# if patch fails to apply hunks, it exits with nonzero code.
# if patch doesn't find the patch file to apply, it exits with a zero code!
ERROR_CHECK = 'IF %ERRORLEVEL% NEQ 0 exit %errorlevel%'
def batch_text(self):
return ("\n" + self.ERROR_CHECK + "\n").join(self.commands)
@property
def vcvars_bitness_parameter(self):
params = {
32: 'x86',
64: 'amd64',
}
return params[self.bconf.bitness]
@property
def vcvars_relative_path(self):
return 'vc/vcvarsall.bat'
@property
def vc_path(self):
if self.bconf.vc_version in self.bconf.vc_paths and self.bconf.vc_paths[self.bconf.vc_version]:
path = self.bconf.vc_paths[self.bconf.vc_version]
if not os.path.join(path, self.vcvars_relative_path):
raise Exception('vcvars not found in specified path')
return path
else:
for path in self.bconf.default_vc_paths[self.bconf.vc_version]:
if os.path.exists(os.path.join(path, self.vcvars_relative_path)):
return path
raise Exception('No usable vc path found')
@property
def vcvars_path(self):
return os.path.join(self.vc_path, self.vcvars_relative_path)
@property
def vcvars_cmd(self):
# https://msdn.microsoft.com/en-us/library/x4d2c09s.aspx
return "call \"%s\" %s" % (
self.vcvars_path,
self.vcvars_bitness_parameter,
)
@property
def nasm_cmd(self):
return "set path=%s;%%path%%\n" % self.bconf.nasm_path
class Builder(object):
def __init__(self, **kwargs):
self.bconf = kwargs.pop('bconf')
self.use_dlls = False
@contextlib.contextmanager
def execute_batch(self):
batch = Batch(self.bconf)
yield batch
with open('doit.bat', 'w') as f:
f.write(batch.batch_text())
if False:
print("Executing:")
with open('doit.bat', 'r') as f:
print(f.read())
sys.stdout.flush()
rv = subprocess.call(['doit.bat'])
if rv != 0:
print("\nFailed to execute the following commands:\n")
with open('doit.bat', 'r') as f:
print(f.read())
sys.stdout.flush()
exit(3)
class StandardBuilder(Builder):
@property
def state_tag(self):
return self.output_dir_path
@property
def bin_path(self):
return os.path.join(self.bconf.archives_path, self.output_dir_path, 'dist', 'bin')
@property
def include_path(self):
return os.path.join(self.bconf.archives_path, self.output_dir_path, 'dist', 'include')
@property
def lib_path(self):
return os.path.join(self.bconf.archives_path, self.output_dir_path, 'dist', 'lib')
@property
def dll_paths(self):
raise NotImplementedError
@property
def builder_name(self):
return self.__class__.__name__.replace('Builder', '').lower()
@property
def my_version(self):
return getattr(self.bconf, '%s_version' % self.builder_name)
@property
def output_dir_path(self):
return '%s-%s-%s' % (self.builder_name, self.my_version, self.bconf.vc_tag)
def standard_fetch_extract(self, url_template):
url = url_template % dict(
my_version=self.my_version,
)
fetch(url)
archive_basename = os.path.basename(url)
archive_name = archive_basename.replace('.tar.gz', '')
untar(self.bconf, archive_name)
suffixed_dir = self.output_dir_path
if os.path.exists(suffixed_dir):
shutil.rmtree(suffixed_dir)
os.rename(archive_name, suffixed_dir)
return suffixed_dir
|