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():
113 sources
= [_winreg
.HKEY_CURRENT_USER
, _winreg
.HKEY_LOCAL_MACHINE
]
114 for source
in sources
:
116 key
= _winreg
.OpenKey(source
, 'Software\\%sPython\\PythonCore\\2.6\\InstallPath' % get_wow_node())
117 value
, type = _winreg
.QueryValueEx(key
, '')
123 def execute(command
):
124 print 'Executing [%s] in directory %s' % (command
, os
.getcwd())
125 return os
.system(command
)
127 def clone(url
, diretory
):
128 command
= '%s clone %s %s' % (git_path
, url
, diretory
)
133 command
= '%s pull' % git_path
137 def git(url
, directory
):
138 clone(url
, directory
)
143 key
= _winreg
.OpenKey(_winreg
.HKEY_LOCAL_MACHINE
, 'SOFTWARE\\%sMicrosoft\\VisualStudio\\9.0\\Setup' % get_wow_node())
144 value
, type = _winreg
.QueryValueEx(key
, 'Dbghelp_path')
145 path
= value
+ '..\\..\\VC\\bin\\vcvars32.bat'
146 #execute('"%s"' % path)
152 print 'Checking if the Microsoft Visual C++ environment is set up'
155 print 'Unable to locate the Visual C++ 9.0 installation to get the path to vcvars32.bat!'
157 if not has_command('cl'):
158 print 'The Microsoft Visual C++ environment has not been set up!'
159 print 'You need to manually execute the following batch file in this prompt:'
169 git_path
= get_git_path()
173 print 'Setting up msysgit'
174 target_directory
= 'git'
176 path
= os
.path
.join(target_directory
, os
.path
.basename(url
))
177 make_directory(target_directory
)
178 download_file(url
, path
)
179 print 'Successfully downloaded the msysgit setup to %s, running it' % path
181 print 'Setup has finished'
183 git_path
= get_git_path()
185 print 'Fatal error: I was unable to detect msysgit in the registry'
188 def brutal_removal(target
):
189 execute('rmdir /q /s %s' % target
)
192 print 'Setting up the nil general purpose library for Python'
195 path
= os
.path
.join(get_site_packages(), target
)
196 print 'Creating a symbolic link to the library at %s' % path
197 source
= '%s\\%s' % (target
, target
)
198 if execute('mklink /D %s %s' % (path
, source
)) != 0:
199 print 'Failed to create symbolic link, this is probably not Vista/Windows 7'
200 print 'Deleting the old library and moving the new one there'
202 print 'Removing old entry %s' % path
203 brutal_removal(target
)
208 print 'Moving %s to %s' % (source
, path
)
210 shutil
.move(source
, path
)
212 print 'Failed to install nil library!'
217 scons_path
= get_scons_path()
218 if scons_path
== None:
219 print 'Unable to get the Python library directory to determine the SCons path'
225 print 'Setting up the SCons building system (written in Python)'
226 target_directory
= 'scons'
228 path
= os
.path
.join(target_directory
, os
.path
.basename(url
))
229 make_directory(target_directory
)
230 download_file(url
, path
)
231 print 'Successfully downloaded the SCons setup to %s, running it' % path
233 print 'Setup has finished'
236 print 'Setting up the mighty boost C++ library'
237 target_directory
= 'boost'
239 git(boost_git
, target_directory
)
241 os
.chdir(target_directory
)
243 bjam_binary
= 'bjam.exe'
247 if not os
.path
.exists(bjam_binary
):
248 print 'Compiling bjam'
249 execute('bootstrap.bat')
250 if not os
.path
.exists(bjam_binary
):
251 sys
.exit('Failed to build bjam.')
252 #download_file(prebuilt_bjam_url, bjam_binary)
254 print 'Compiling boost'
255 cpus
= int(os
.environ
.get('NUMBER_OF_PROCESSORS', 2))
256 print 'Number of CPUs detected: %d' % cpus
257 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
))
261 print 'Setting up the ail C++ general purpose library'
262 target_directory
= 'ail'
263 git(ail_git
, target_directory
)
264 os
.chdir(target_directory
)
265 execute('%s boost=..\\..\\boost' % scons_path
)
269 print 'Setting up the syringe injection tool'
272 git(syringe_git
, target
)
274 execute('%s boost=..\\..\\boost ail=..\\..\\ail ail_lib=..\\..\\ail\\build\\ail.lib' % scons_path
)
276 copy_binary('%s\\build\\%s.exe' % (target
, target
))
279 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)'
281 target_directory
= 'python'
283 base
= os
.path
.basename(url
)
284 path
= os
.path
.join(target_directory
, base
)
285 make_directory(target_directory
)
286 download_file(url
, path
)
287 print 'Successfully downloaded the Python 32-bit setup to %s, attempting to perform an unattended MSI installation' % path
288 execute('msiexec /package %s\\%s /passive' % (target_directory
, base
))
289 print 'Setup has finished'
292 print 'Setting up the Charles Romley Alder Wright (short C.R.A.W.) Diablo II module'
295 git(craw_git
, target
)
297 python_path
= get_python_path()
298 if python_path
== None:
300 python_path
= get_python_path()
301 if python_path
== None:
302 print 'Unable to detect the 32-bit installation of Python 2.6'
306 execute('%s boost=..\\..\\boost boost_lib=..\\..\\boost\\stage\\lib ail=..\\..\\ail ail_lib=..\\ail\\build\\ail.lib python=%s' % (scons_path
, python_path
))
308 copy_binary('%s\\build\\%s.dll' % (target
, target
))
323 seconds_per_minute
= 60
324 seconds_passed
= int(time
.time() - start
)
325 print 'Setup finished after %d:%02d minute(s)' % (seconds_passed
/ seconds_per_minute
, seconds_passed
% seconds_per_minute
)
326 winsound
.MessageBeep()