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'
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'
21 print 'Unknown mode "%s" specified' % mode
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:
33 return platform
.architecture()[0] == '64bit'
37 print 'Downloading %s' % url
38 request
= urllib2
.Request(url
)
39 response
= urllib2
.urlopen(request
)
40 data
= response
.read()
45 def download_file(url
, download_path
):
48 print 'Failed to download %s' % url
50 file = open(download_path
, 'w+b')
54 def has_command(command
):
55 return len(os
.popen(command
).read()) > 0
58 return has_command('%s --help' % git_path
)
61 return has_command('%s --help' % scons_path
)
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
):
75 def copy_binary(source
):
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
)
84 def get_site_packages():
85 target
= 'site-packages'
87 if len(path
) > len(target
) and path
[- len(target
) : ] == target
:
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')
105 def get_scons_path():
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')
112 def get_python_path():
114 key
= _winreg
.OpenKey(_winreg
.HKEY_LOCAL_MACHINE
, 'SOFTWARE\\%sPython\\PythonCore\\2.6\\InstallPath' % get_wow_node())
115 value
, type = _winreg
.QueryValueEx(key
, '')
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
)
130 command
= '%s pull' % git_path
134 def git(url
, directory
):
135 clone(url
, directory
)
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)
149 print 'Checking if the Microsoft Visual C++ environment is set up'
152 print 'Unable to locate the Visual C++ 9.0 installation to get the path to vcvars32.bat!'
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:'
166 git_path
= get_git_path()
170 print 'Setting up msysgit'
171 target_directory
= 'git'
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
178 print 'Setup has finished'
180 git_path
= get_git_path()
182 print 'Fatal error: I was unable to detect msysgit in the registry'
185 def brutal_removal(target
):
186 execute('rmdir /q /s %s' % target
)
189 print 'Setting up the nil general purpose library for Python'
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'
199 print 'Removing old entry %s' % path
200 brutal_removal(target
)
205 print 'Moving %s to %s' % (source
, path
)
207 shutil
.move(source
, path
)
209 print 'Failed to install nil library!'
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'
222 print 'Setting up the SCons building system (written in Python)'
223 target_directory
= 'scons'
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
230 print 'Setup has finished'
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'
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
))
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
)
266 print 'Setting up the syringe injection tool'
269 git(syringe_git
, target
)
271 execute('%s boost=..\\..\\boost ail=..\\..\\ail ail_lib=..\\..\\ail\\build\\ail.lib' % scons_path
)
273 copy_binary('%s\\build\\%s.exe' % (target
, target
))
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'
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'
289 print 'Setting up the Charles Romley Alder Wright (short C.R.A.W.) Diablo II module'
292 git(craw_git
, target
)
294 python_path
= get_python_path()
295 if python_path
== False:
297 python_path
= get_python_path()
298 if python_path
== False:
299 print 'Unable to detect the 32-bit installation of Python 2.6'
303 execute('%s boost=..\\..\\boost boost_lib=..\\..\\boost\\stage\\lib ail=..\\..\\ail ail_lib=..\\ail\\build\\ail.lib python=%s' % (scons_path
, python_path
))
305 copy_binary('%s\\build\\%s.dll' % (target
, target
))
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()