CRAW now runs on Windows 7 too - the problem was that Windows 7 has moved some functi...
[craw.git] / setup / setup.py
blobfad9b855b7006287d560cd4d419cc9149968b8fd
1 import subprocess, os, sys, urllib2, platform, shutil, time, winsound, _winreg
3 #All the external sources are defined here:
5 git_url = 'http://msysgit.googlecode.com/files/Git-1.6.3.2-preview20090608.exe'
6 scons_url = 'http://surfnet.dl.sourceforge.net/sourceforge/scons/scons-1.2.0.d20090223.win32.exe'
7 python_url = 'http://www.python.org/ftp/python/2.6.2/python-2.6.2.msi'
9 if len(sys.argv) == 2:
10 mode = sys.argv[1]
11 if mode == 'http':
12 boost_git = 'http://git.gitorious.org/boost/svn.git'
14 nil_git = 'http://repo.or.cz/r/nil.git'
15 ail_git = 'http://repo.or.cz/r/ail.git'
16 syringe_git = 'http://repo.or.cz/r/syringe.git'
17 craw_git = 'http://repo.or.cz/r/craw.git'
19 print 'Using http git URLs instead of the git ones'
20 else:
21 print 'Unknown mode "%s" specified' % mode
22 else:
23 boost_git = 'git://gitorious.org/boost/svn.git'
25 nil_git = 'git://repo.or.cz/nil.git'
26 ail_git = 'git://repo.or.cz/ail.git'
27 syringe_git = 'git://repo.or.cz/syringe.git'
28 craw_git = 'git://repo.or.cz/craw.git'
30 #Functions used by the setup:
32 def is_64_bit():
33 return platform.architecture()[0] == '64bit'
35 def download(url):
36 try:
37 print 'Downloading %s' % url
38 request = urllib2.Request(url)
39 response = urllib2.urlopen(request)
40 data = response.read()
41 return data
42 except:
43 return None
45 def download_file(url, download_path):
46 data = download(url)
47 if data == None:
48 print 'Failed to download %s' % url
49 sys.exit(1)
50 file = open(download_path, 'w+b')
51 file.write(data)
52 file.close()
54 def has_command(command):
55 return len(os.popen(command).read()) > 0
57 def has_git():
58 return has_command('%s --help' % git_path)
60 def has_scons():
61 return has_command('%s --help' % scons_path)
63 def has_bjam():
64 return has_command('boost\\bjam.exe --help')
66 def string_filter(filter_string, lines):
67 return filter(lambda line: line.find(filter_string) != -1, lines)
69 def make_directory(directory):
70 try:
71 os.mkdir(directory)
72 except:
73 pass
75 def copy_binary(source):
76 try:
77 target_directory = 'binaries'
78 make_directory(target_directory)
79 destination = os.path.join(target_directory, os.path.basename(source))
80 shutil.copy(source, destination)
81 except:
82 pass
84 def get_site_packages():
85 target = 'site-packages'
86 for path in sys.path:
87 if len(path) > len(target) and path[- len(target) : ] == target:
88 return path
89 return None
91 def get_wow_node():
92 wow = ''
93 if is_64_bit():
94 wow = 'Wow6432Node\\'
95 return wow
97 def get_git_path():
98 try:
99 key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\%sMicrosoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1' % get_wow_node())
100 value, type = _winreg.QueryValueEx(key, 'InstallLocation')
101 return '"%s"' % os.path.join(value, 'bin', 'git.exe')
102 except:
103 return None
105 def get_scons_path():
106 target = 'lib'
107 for path in sys.path:
108 if os.path.basename(path).lower() == target:
109 return os.path.join(path[0 : - len(target)], 'Scripts', 'scons.bat')
110 return None
112 def get_python_path():
113 try:
114 key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\%sPython\\PythonCore\\2.6\\InstallPath' % get_wow_node())
115 value, type = _winreg.QueryValueEx(key, '')
116 return value
117 except:
118 return None
120 def execute(command):
121 print 'Executing [%s] in directory %s' % (command, os.getcwd())
122 return os.system(command)
124 def clone(url, diretory):
125 command = '%s clone %s %s' % (git_path, url, diretory)
126 execute(command)
128 def pull(directory):
129 os.chdir(directory)
130 command = '%s pull' % git_path
131 execute(command)
132 os.chdir('..')
134 def git(url, directory):
135 clone(url, directory)
136 pull(directory)
138 def vcvars():
139 try:
140 key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\%sMicrosoft\\VisualStudio\\9.0\\Setup' % get_wow_node())
141 value, type = _winreg.QueryValueEx(key, 'Dbghelp_path')
142 path = value + '..\\..\\VC\\bin\\vcvars32.bat'
143 #execute('"%s"' % path)
144 return path
145 except:
146 return None
148 def vcvars_check():
149 print 'Checking if the Microsoft Visual C++ environment is set up'
150 path = vcvars()
151 if path == None:
152 print 'Unable to locate the Visual C++ 9.0 installation to get the path to vcvars32.bat!'
153 sys.exit(1)
154 if not has_command('cl'):
155 print 'The Microsoft Visual C++ environment has not been set up!'
156 print 'You need to manually execute the following batch file in this prompt:'
157 print '"%s"' % path
158 sys.exit(1)
160 def setup_git():
161 global git_path
162 git_path = 'git'
163 if has_git():
164 return
166 git_path = get_git_path()
167 if git_path != None:
168 return
170 print 'Setting up msysgit'
171 target_directory = 'git'
172 url = git_url
173 path = os.path.join(target_directory, os.path.basename(url))
174 make_directory(target_directory)
175 download_file(url, path)
176 print 'Successfully downloaded the msysgit setup to %s, running it' % path
177 execute(path)
178 print 'Setup has finished'
180 git_path = get_git_path()
181 if git_path == None:
182 print 'Fatal error: I was unable to detect msysgit in the registry'
183 sys.exit(1)
185 def brutal_removal(target):
186 execute('rmdir /q /s %s' % target)
188 def setup_nil():
189 print 'Setting up the nil general purpose library for Python'
190 target = 'nil'
191 git(nil_git, target)
192 path = os.path.join(get_site_packages(), target)
193 print 'Creating a symbolic link to the library at %s' % path
194 source = '%s\\%s' % (target, target)
195 if execute('mklink /D %s %s' % (path, source)) != 0:
196 print 'Failed to create symbolic link, this is probably not Vista/Windows 7'
197 print 'Deleting the old library and moving the new one there'
198 try:
199 print 'Removing old entry %s' % path
200 brutal_removal(target)
201 brutal_removal(path)
202 git(nil_git, target)
203 except:
204 pass
205 print 'Moving %s to %s' % (source, path)
206 try:
207 shutil.move(source, path)
208 except:
209 print 'Failed to install nil library!'
210 sys.exit(1)
212 def setup_scons():
213 global scons_path
214 scons_path = get_scons_path()
215 if scons_path == None:
216 print 'Unable to get the Python library directory to determine the SCons path'
217 sys.exit(1)
219 if has_scons():
220 return
222 print 'Setting up the SCons building system (written in Python)'
223 target_directory = 'scons'
224 url = scons_url
225 path = os.path.join(target_directory, os.path.basename(url))
226 make_directory(target_directory)
227 download_file(url, path)
228 print 'Successfully downloaded the SCons setup to %s, running it' % path
229 execute(path)
230 print 'Setup has finished'
232 def setup_boost():
233 print 'Setting up the mighty boost C++ library'
234 target_directory = 'boost'
236 git(boost_git, target_directory)
238 os.chdir(target_directory)
240 bjam_binary = 'bjam.exe'
242 execute(vcvars())
244 if not os.path.exists(bjam_binary):
245 print 'Compiling bjam'
246 execute('bootstrap.bat')
247 if not os.path.exists(bjam_binary):
248 sys.exit('Failed to build bjam.')
249 #download_file(prebuilt_bjam_url, bjam_binary)
251 print 'Compiling boost'
252 cpus = int(os.environ.get('NUMBER_OF_PROCESSORS', 2))
253 print 'Number of CPUs detected: %d' % cpus
254 execute('%s toolset=%s variant=release threading=multi runtime-link=static link=static stage -j %d --without-graph --without-graph_parallel --without-iostreams --without-math --without-mpi --without-python --without-program_options --without-python --without-serialization --without-signals --without-test --without-wave' % (bjam_binary, toolset, cpus))
255 os.chdir('..')
257 def setup_ail():
258 print 'Setting up the ail C++ general purpose library'
259 target_directory = 'ail'
260 git(ail_git, target_directory)
261 os.chdir(target_directory)
262 execute('%s boost=..\\..\\boost' % scons_path)
263 os.chdir('..')
265 def setup_syringe():
266 print 'Setting up the syringe injection tool'
268 target = 'syringe'
269 git(syringe_git, target)
270 os.chdir(target)
271 execute('%s boost=..\\..\\boost ail=..\\..\\ail ail_lib=..\\..\\ail\\build\\ail.lib' % scons_path)
272 os.chdir('..')
273 copy_binary('%s\\build\\%s.exe' % (target, target))
275 def setup_python():
276 print 'Setting up the 32-bit version of Python (the 64-bit library/DLL is of no use to us because Diablo II is 32-bit)'
278 target_directory = 'python'
279 url = python
280 base = os.path.basename(url)
281 path = os.path.join(target_directory, base)
282 make_directory(target_directory)
283 download_file(url, path)
284 print 'Successfully downloaded the Python 32-bit setup to %s, attempting to perform an unattended MSI installation' % path
285 execute('msiexec /package %s\\%s /passive' % (target_directory, base))
286 print 'Setup has finished'
288 def setup_craw():
289 print 'Setting up the Charles Romley Alder Wright (short C.R.A.W.) Diablo II module'
291 target = 'craw'
292 git(craw_git, target)
294 python_path = get_python_path()
295 if python_path == False:
296 setup_python()
297 python_path = get_python_path()
298 if python_path == False:
299 print 'Unable to detect the 32-bit installation of Python 2.6'
300 sys.exit(1)
302 os.chdir(target)
303 execute('%s boost=..\\..\\boost boost_lib=..\\..\\boost\\stage\\lib ail=..\\..\\ail ail_lib=..\\ail\\build\\ail.lib python=%s' % (scons_path, python_path))
304 os.chdir('..')
305 copy_binary('%s\\build\\%s.dll' % (target, target))
307 toolset = 'msvc-9.0'
309 start = time.time()
311 vcvars_check()
312 setup_git()
313 setup_nil()
314 setup_scons()
315 setup_boost()
316 setup_ail()
317 setup_syringe()
318 setup_craw()
320 seconds_per_minute = 60
321 seconds_passed = int(time.time() - start)
322 print 'Setup finished after %d:%02d minute(s)' % (seconds_passed / seconds_per_minute, seconds_passed % seconds_per_minute)
323 winsound.MessageBeep()