1 | #!/usr/bin/env python
|
---|
2 |
|
---|
3 | ## @file
|
---|
4 | #
|
---|
5 | # Automation of instructions from:
|
---|
6 | # http://mingw-w64.svn.sourceforge.net/viewvc/mingw-w64/trunk/mingw-w64-doc/
|
---|
7 | # howto-build/mingw-w64-howto-build.txt?revision=216&view=markup
|
---|
8 | #
|
---|
9 | # Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
|
---|
10 | # This program and the accompanying materials
|
---|
11 | # are licensed and made available under the terms and conditions of the BSD License
|
---|
12 | # which accompanies this distribution. The full text of the license may be found at
|
---|
13 | # http://opensource.org/licenses/bsd-license.php
|
---|
14 | #
|
---|
15 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
---|
16 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
---|
17 | #
|
---|
18 |
|
---|
19 |
|
---|
20 | from optparse import OptionParser
|
---|
21 | import os
|
---|
22 | import shutil
|
---|
23 | import subprocess
|
---|
24 | import sys
|
---|
25 | import tarfile
|
---|
26 | import urllib
|
---|
27 | import urlparse
|
---|
28 | try:
|
---|
29 | from hashlib import md5
|
---|
30 | except Exception:
|
---|
31 | from md5 import md5
|
---|
32 |
|
---|
33 | if sys.version_info < (2, 5):
|
---|
34 | #
|
---|
35 | # This script (and edk2 BaseTools) require Python 2.5 or newer
|
---|
36 | #
|
---|
37 | print 'Python version 2.5 or later is required.'
|
---|
38 | sys.exit(-1)
|
---|
39 |
|
---|
40 | #
|
---|
41 | # Version and Copyright
|
---|
42 | #
|
---|
43 | VersionNumber = "0.01"
|
---|
44 | __version__ = "%prog Version " + VersionNumber
|
---|
45 | __copyright__ = "Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved."
|
---|
46 |
|
---|
47 | class Config:
|
---|
48 | """class Config
|
---|
49 |
|
---|
50 | Stores the configuration options for the rest of the script.
|
---|
51 |
|
---|
52 | Handles the command line options, and allows the code within
|
---|
53 | the script to easily interact with the 'config' requested by
|
---|
54 | the user.
|
---|
55 | """
|
---|
56 |
|
---|
57 | def __init__(self):
|
---|
58 | self.base_dir = os.getcwd()
|
---|
59 | (self.options, self.args) = self.CheckOptions()
|
---|
60 | self.__init_dirs__()
|
---|
61 |
|
---|
62 | def CheckOptions(self):
|
---|
63 | Parser = \
|
---|
64 | OptionParser(
|
---|
65 | description=__copyright__,
|
---|
66 | version=__version__,
|
---|
67 | prog="mingw-gcc-build",
|
---|
68 | usage="%prog [options] [target]"
|
---|
69 | )
|
---|
70 | Parser.add_option(
|
---|
71 | "--arch",
|
---|
72 | action = "store", type = "string",
|
---|
73 | default = '',
|
---|
74 | dest = "arch",
|
---|
75 | help = "Processor architecture to build gcc for."
|
---|
76 | )
|
---|
77 | Parser.add_option(
|
---|
78 | "--src-dir",
|
---|
79 | action = "store", type = "string", dest = "src_dir",
|
---|
80 | default = os.path.join(self.base_dir, 'src'),
|
---|
81 | help = "Directory to download/extract binutils/gcc sources"
|
---|
82 | )
|
---|
83 | Parser.add_option(
|
---|
84 | "--build-dir",
|
---|
85 | action = "store", type = "string", dest = "build_dir",
|
---|
86 | default = os.path.join(self.base_dir, 'build'),
|
---|
87 | help = "Directory to download/extract binutils/gcc sources"
|
---|
88 | )
|
---|
89 | Parser.add_option(
|
---|
90 | "--prefix",
|
---|
91 | action = "store", type = "string", dest = "prefix",
|
---|
92 | default = os.path.join(self.base_dir, 'install'),
|
---|
93 | help = "Prefix to install binutils/gcc into"
|
---|
94 | )
|
---|
95 | Parser.add_option(
|
---|
96 | "--skip-binutils",
|
---|
97 | action = "store_true", dest = "skip_binutils",
|
---|
98 | default = False,
|
---|
99 | help = "Will skip building binutils"
|
---|
100 | )
|
---|
101 | Parser.add_option(
|
---|
102 | "--skip-gcc",
|
---|
103 | action = "store_true", dest = "skip_gcc",
|
---|
104 | default = False,
|
---|
105 | help = "Will skip building GCC"
|
---|
106 | )
|
---|
107 | Parser.add_option(
|
---|
108 | "--symlinks",
|
---|
109 | action = "store", type = "string", dest = "symlinks",
|
---|
110 | default = os.path.join(self.base_dir, 'symlinks'),
|
---|
111 | help = "Directory to create binutils/gcc symbolic links into."
|
---|
112 | )
|
---|
113 | Parser.add_option(
|
---|
114 | "-v", "--verbose",
|
---|
115 | action="store_true",
|
---|
116 | type=None, help="Print verbose messages"
|
---|
117 | )
|
---|
118 |
|
---|
119 | (Opt, Args) = Parser.parse_args()
|
---|
120 |
|
---|
121 | self.arch = Opt.arch.lower()
|
---|
122 | allowedArchs = ('ia32', 'x64', 'ipf')
|
---|
123 | if self.arch not in allowedArchs:
|
---|
124 | Parser.error(
|
---|
125 | 'Please use --arch to specify one of: %s' %
|
---|
126 | ', '.join(allowedArchs)
|
---|
127 | )
|
---|
128 | self.target_arch = {'ia32': 'i686', 'x64': 'x86_64', 'ipf': 'ia64'}[self.arch]
|
---|
129 | self.target_sys = {'ia32': 'pc', 'x64': 'pc', 'ipf': 'pc'}[self.arch]
|
---|
130 | self.target_bin = {'ia32': 'mingw32', 'x64': 'mingw32', 'ipf': 'elf'}[self.arch]
|
---|
131 | self.target_combo = '-'.join((self.target_arch, self.target_sys, self.target_bin))
|
---|
132 |
|
---|
133 | return (Opt, Args)
|
---|
134 |
|
---|
135 | def __init_dirs__(self):
|
---|
136 | self.src_dir = os.path.realpath(os.path.expanduser(self.options.src_dir))
|
---|
137 | self.build_dir = os.path.realpath(os.path.expanduser(self.options.build_dir))
|
---|
138 | self.prefix = os.path.realpath(os.path.expanduser(self.options.prefix))
|
---|
139 | self.symlinks = os.path.realpath(os.path.expanduser(self.options.symlinks))
|
---|
140 |
|
---|
141 | def IsConfigOk(self):
|
---|
142 |
|
---|
143 | building = []
|
---|
144 | if not self.options.skip_binutils:
|
---|
145 | building.append('binutils')
|
---|
146 | if not self.options.skip_gcc:
|
---|
147 | building.append('gcc')
|
---|
148 | if len(building) == 0:
|
---|
149 | print "Nothing will be built!"
|
---|
150 | print
|
---|
151 | print "Please try using --help and then change the configuration."
|
---|
152 | return False
|
---|
153 |
|
---|
154 | print "Current directory:"
|
---|
155 | print " ", self.base_dir
|
---|
156 | print "Sources download/extraction:", self.Relative(self.src_dir)
|
---|
157 | print "Build directory :", self.Relative(self.build_dir)
|
---|
158 | print "Prefix (install) directory :", self.Relative(self.prefix)
|
---|
159 | print "Create symlinks directory :", self.Relative(self.symlinks)
|
---|
160 | print "Building :", ', '.join(building)
|
---|
161 | print
|
---|
162 | answer = raw_input("Is this configuration ok? (default = no): ")
|
---|
163 | if (answer.lower() not in ('y', 'yes')):
|
---|
164 | print
|
---|
165 | print "Please try using --help and then change the configuration."
|
---|
166 | return False
|
---|
167 |
|
---|
168 | if self.arch.lower() == 'ipf':
|
---|
169 | print
|
---|
170 | print 'Please note that the IPF compiler built by this script has'
|
---|
171 | print 'not yet been validated!'
|
---|
172 | print
|
---|
173 | answer = raw_input("Are you sure you want to build it? (default = no): ")
|
---|
174 | if (answer.lower() not in ('y', 'yes')):
|
---|
175 | print
|
---|
176 | print "Please try using --help and then change the configuration."
|
---|
177 | return False
|
---|
178 |
|
---|
179 | print
|
---|
180 | return True
|
---|
181 |
|
---|
182 | def Relative(self, path):
|
---|
183 | if path.startswith(self.base_dir):
|
---|
184 | return '.' + path[len(self.base_dir):]
|
---|
185 | return path
|
---|
186 |
|
---|
187 | def MakeDirs(self):
|
---|
188 | for path in (self.src_dir, self.build_dir,self.prefix, self.symlinks):
|
---|
189 | if not os.path.exists(path):
|
---|
190 | os.makedirs(path)
|
---|
191 |
|
---|
192 | class SourceFiles:
|
---|
193 | """class SourceFiles
|
---|
194 |
|
---|
195 | Handles the downloading of source files used by the script.
|
---|
196 | """
|
---|
197 |
|
---|
198 | def __init__(self, config):
|
---|
199 | self.config = config
|
---|
200 | self.source_files = self.source_files[config.arch]
|
---|
201 |
|
---|
202 | if config.options.skip_binutils:
|
---|
203 | del self.source_files['binutils']
|
---|
204 |
|
---|
205 | if config.options.skip_gcc:
|
---|
206 | del self.source_files['gcc']
|
---|
207 | del self.source_files['mingw_hdr']
|
---|
208 |
|
---|
209 | source_files_common = {
|
---|
210 | 'binutils': {
|
---|
211 | 'url': 'http://www.kernel.org/pub/linux/devel/binutils/' + \
|
---|
212 | 'binutils-$version.tar.bz2',
|
---|
213 | 'version': '2.20.51.0.5',
|
---|
214 | 'md5': '6d2de7cdf7a8389e70b124e3d73b4d37',
|
---|
215 | },
|
---|
216 | }
|
---|
217 |
|
---|
218 | source_files_x64 = {
|
---|
219 | 'gcc': {
|
---|
220 | 'url': 'http://ftpmirror.gnu.org/gcc/' + \
|
---|
221 | 'gcc-$version/gcc-$version.tar.bz2',
|
---|
222 | 'version': '4.3.0',
|
---|
223 | 'md5': '197ed8468b38db1d3481c3111691d85b',
|
---|
224 | },
|
---|
225 | }
|
---|
226 |
|
---|
227 | source_files_ia32 = {
|
---|
228 | 'gcc': source_files_x64['gcc'],
|
---|
229 | }
|
---|
230 |
|
---|
231 | source_files_ipf = source_files_x64.copy()
|
---|
232 | source_files_ipf['gcc']['configure-params'] = (
|
---|
233 | '--with-gnu-as', '--with-gnu-ld', '--with-newlib',
|
---|
234 | '--verbose', '--disable-libssp', '--disable-nls',
|
---|
235 | '--enable-languages=c,c++'
|
---|
236 | )
|
---|
237 |
|
---|
238 | source_files = {
|
---|
239 | 'ia32': [source_files_common, source_files_ia32],
|
---|
240 | 'x64': [source_files_common, source_files_x64],
|
---|
241 | 'ipf': [source_files_common, source_files_ipf],
|
---|
242 | }
|
---|
243 |
|
---|
244 | for arch in source_files:
|
---|
245 | mergedSourceFiles = {}
|
---|
246 | for source_files_dict in source_files[arch]:
|
---|
247 | mergedSourceFiles.update(source_files_dict)
|
---|
248 | for downloadItem in mergedSourceFiles:
|
---|
249 | fdata = mergedSourceFiles[downloadItem]
|
---|
250 | fdata['filename'] = fdata['url'].split('/')[-1]
|
---|
251 | if 'extract-dir' not in fdata:
|
---|
252 | for ext in ('.tar.gz', '.tar.bz2', '.zip'):
|
---|
253 | if fdata['filename'].endswith(ext):
|
---|
254 | fdata['extract-dir'] = fdata['filename'][:-len(ext)]
|
---|
255 | break
|
---|
256 | replaceables = ('extract-dir', 'filename', 'url')
|
---|
257 | for replaceItem in fdata:
|
---|
258 | if replaceItem in replaceables: continue
|
---|
259 | if type(fdata[replaceItem]) != str: continue
|
---|
260 | for replaceable in replaceables:
|
---|
261 | if type(fdata[replaceable]) != str: continue
|
---|
262 | if replaceable in fdata:
|
---|
263 | fdata[replaceable] = \
|
---|
264 | fdata[replaceable].replace(
|
---|
265 | '$' + replaceItem,
|
---|
266 | fdata[replaceItem]
|
---|
267 | )
|
---|
268 | source_files[arch] = mergedSourceFiles
|
---|
269 | #print 'source_files:', source_files
|
---|
270 |
|
---|
271 | def GetAll(self):
|
---|
272 |
|
---|
273 | def progress(received, blockSize, fileSize):
|
---|
274 | if fileSize < 0: return
|
---|
275 | wDots = (100 * received * blockSize) / fileSize / 10
|
---|
276 | if wDots > self.dots:
|
---|
277 | for i in range(wDots - self.dots):
|
---|
278 | print '.',
|
---|
279 | sys.stdout.flush()
|
---|
280 | self.dots += 1
|
---|
281 |
|
---|
282 | maxRetries = 1
|
---|
283 | for (fname, fdata) in self.source_files.items():
|
---|
284 | for retries in range(maxRetries):
|
---|
285 | try:
|
---|
286 | self.dots = 0
|
---|
287 | local_file = os.path.join(self.config.src_dir, fdata['filename'])
|
---|
288 | url = fdata['url']
|
---|
289 | print 'Downloading %s:' % fname, url
|
---|
290 | if retries > 0:
|
---|
291 | print '(retry)',
|
---|
292 | sys.stdout.flush()
|
---|
293 |
|
---|
294 | completed = False
|
---|
295 | if os.path.exists(local_file):
|
---|
296 | md5_pass = self.checkHash(fdata)
|
---|
297 | if md5_pass:
|
---|
298 | print '[md5 match]',
|
---|
299 | else:
|
---|
300 | print '[md5 mismatch]',
|
---|
301 | sys.stdout.flush()
|
---|
302 | completed = md5_pass
|
---|
303 |
|
---|
304 | if not completed:
|
---|
305 | urllib.urlretrieve(url, local_file, progress)
|
---|
306 |
|
---|
307 | #
|
---|
308 | # BUGBUG: Suggest proxy to user if download fails.
|
---|
309 | #
|
---|
310 | # export http_proxy=http://proxyservername.mycompany.com:911
|
---|
311 | # export ftp_proxy=http://proxyservername.mycompany.com:911
|
---|
312 |
|
---|
313 | if not completed and os.path.exists(local_file):
|
---|
314 | md5_pass = self.checkHash(fdata)
|
---|
315 | if md5_pass:
|
---|
316 | print '[md5 match]',
|
---|
317 | else:
|
---|
318 | print '[md5 mismatch]',
|
---|
319 | sys.stdout.flush()
|
---|
320 | completed = md5_pass
|
---|
321 |
|
---|
322 | if completed:
|
---|
323 | print '[done]'
|
---|
324 | break
|
---|
325 | else:
|
---|
326 | print '[failed]'
|
---|
327 | print ' Tried to retrieve', url
|
---|
328 | print ' to', local_file
|
---|
329 | print 'Possible fixes:'
|
---|
330 | print '* If you are behind a web-proxy, try setting the',
|
---|
331 | print 'http_proxy environment variable'
|
---|
332 | print '* You can try to download this file separately',
|
---|
333 | print 'and rerun this script'
|
---|
334 | raise Exception()
|
---|
335 |
|
---|
336 | except KeyboardInterrupt:
|
---|
337 | print '[KeyboardInterrupt]'
|
---|
338 | return False
|
---|
339 |
|
---|
340 | except Exception, e:
|
---|
341 | print e
|
---|
342 |
|
---|
343 | if not completed: return False
|
---|
344 |
|
---|
345 | return True
|
---|
346 |
|
---|
347 | def checkHash(self, fdata):
|
---|
348 | local_file = os.path.join(self.config.src_dir, fdata['filename'])
|
---|
349 | expect_md5 = fdata['md5']
|
---|
350 | data = open(local_file).read()
|
---|
351 | md5sum = md5()
|
---|
352 | md5sum.update(data)
|
---|
353 | return md5sum.hexdigest().lower() == expect_md5.lower()
|
---|
354 |
|
---|
355 | def GetModules(self):
|
---|
356 | return self.source_files.keys()
|
---|
357 |
|
---|
358 | def GetFilenameOf(self, module):
|
---|
359 | return self.source_files[module]['filename']
|
---|
360 |
|
---|
361 | def GetMd5Of(self, module):
|
---|
362 | return self.source_files[module]['md5']
|
---|
363 |
|
---|
364 | def GetExtractDirOf(self, module):
|
---|
365 | return self.source_files[module]['extract-dir']
|
---|
366 |
|
---|
367 | def GetAdditionalParameters(self, module, step):
|
---|
368 | key = step + '-params'
|
---|
369 | if key in self.source_files[module]:
|
---|
370 | return self.source_files[module][key]
|
---|
371 | else:
|
---|
372 | return tuple()
|
---|
373 |
|
---|
374 | class Extracter:
|
---|
375 | """class Extracter
|
---|
376 |
|
---|
377 | Handles the extraction of the source files from their downloaded
|
---|
378 | archive files.
|
---|
379 | """
|
---|
380 |
|
---|
381 | def __init__(self, source_files, config):
|
---|
382 | self.source_files = source_files
|
---|
383 | self.config = config
|
---|
384 |
|
---|
385 | def Extract(self, module):
|
---|
386 | src = self.config.src_dir
|
---|
387 | extractDst = os.path.join(src, self.config.arch)
|
---|
388 | local_file = os.path.join(src, self.source_files.GetFilenameOf(module))
|
---|
389 | moduleMd5 = self.source_files.GetMd5Of(module)
|
---|
390 | extracted = os.path.join(extractDst, os.path.split(local_file)[1] + '.extracted')
|
---|
391 | if not os.path.exists(extractDst):
|
---|
392 | os.mkdir(extractDst)
|
---|
393 |
|
---|
394 | extractedMd5 = None
|
---|
395 | if os.path.exists(extracted):
|
---|
396 | extractedMd5 = open(extracted).read()
|
---|
397 |
|
---|
398 | if extractedMd5 != moduleMd5:
|
---|
399 | print 'Extracting %s:' % self.config.Relative(local_file)
|
---|
400 | tar = tarfile.open(local_file)
|
---|
401 | tar.extractall(extractDst)
|
---|
402 | open(extracted, 'w').write(moduleMd5)
|
---|
403 | else:
|
---|
404 | pass
|
---|
405 | #print 'Previously extracted', self.config.Relative(local_file)
|
---|
406 |
|
---|
407 | def ExtractAll(self):
|
---|
408 | for module in self.source_files.GetModules():
|
---|
409 | self.Extract(module)
|
---|
410 |
|
---|
411 | class Builder:
|
---|
412 | """class Builder
|
---|
413 |
|
---|
414 | Builds and installs the GCC tool suite.
|
---|
415 | """
|
---|
416 |
|
---|
417 | def __init__(self, source_files, config):
|
---|
418 | self.source_files = source_files
|
---|
419 | self.config = config
|
---|
420 |
|
---|
421 | def Build(self):
|
---|
422 | if not self.config.options.skip_binutils:
|
---|
423 | self.BuildModule('binutils')
|
---|
424 | if not self.config.options.skip_gcc:
|
---|
425 | self.BuildModule('gcc')
|
---|
426 | self.MakeSymLinks()
|
---|
427 |
|
---|
428 | def IsBuildStepComplete(self, step):
|
---|
429 | return \
|
---|
430 | os.path.exists(
|
---|
431 | os.path.join(
|
---|
432 | self.config.build_dir, self.config.arch, step + '.completed'
|
---|
433 | )
|
---|
434 | )
|
---|
435 |
|
---|
436 | def MarkBuildStepComplete(self, step):
|
---|
437 | open(
|
---|
438 | os.path.join(
|
---|
439 | self.config.build_dir, self.config.arch, step + '.completed'
|
---|
440 | ),
|
---|
441 | "w"
|
---|
442 | ).close()
|
---|
443 |
|
---|
444 |
|
---|
445 | def BuildModule(self, module):
|
---|
446 | base_dir = os.getcwd()
|
---|
447 | build_dir = os.path.join(self.config.build_dir, self.config.arch, module)
|
---|
448 | module_dir = self.source_files.GetExtractDirOf(module)
|
---|
449 | module_dir = os.path.realpath(os.path.join('src', self.config.arch, module_dir))
|
---|
450 | configure = os.path.join(module_dir, 'configure')
|
---|
451 | prefix = self.config.prefix
|
---|
452 | if not os.path.exists(build_dir):
|
---|
453 | os.makedirs(build_dir)
|
---|
454 | os.chdir(build_dir)
|
---|
455 |
|
---|
456 | cmd = (
|
---|
457 | configure,
|
---|
458 | '--target=%s' % self.config.target_combo,
|
---|
459 | '--prefix=' + prefix,
|
---|
460 | '--with-sysroot=' + prefix,
|
---|
461 | '--disable-werror',
|
---|
462 | )
|
---|
463 | if os.path.exists('/opt/local/include/gmp.h'):
|
---|
464 | cmd += ('--with-gmp=/opt/local',)
|
---|
465 | if module == 'gcc': cmd += ('--oldincludedir=/opt/local/include',)
|
---|
466 | cmd += self.source_files.GetAdditionalParameters(module, 'configure')
|
---|
467 | self.RunCommand(cmd, module, 'config', skipable=True)
|
---|
468 |
|
---|
469 | cmd = ('make',)
|
---|
470 | if module == 'gcc':
|
---|
471 | cmd += ('all-gcc',)
|
---|
472 | self.RunCommand(cmd, module, 'build')
|
---|
473 |
|
---|
474 | cmd = ('make',)
|
---|
475 | if module == 'gcc':
|
---|
476 | cmd += ('install-gcc',)
|
---|
477 | else:
|
---|
478 | cmd += ('install',)
|
---|
479 | self.RunCommand(cmd, module, 'install')
|
---|
480 |
|
---|
481 | os.chdir(base_dir)
|
---|
482 |
|
---|
483 | print '%s module is now built and installed' % module
|
---|
484 |
|
---|
485 | def RunCommand(self, cmd, module, stage, skipable=False):
|
---|
486 | if skipable:
|
---|
487 | if self.IsBuildStepComplete('%s.%s' % (module, stage)):
|
---|
488 | return
|
---|
489 |
|
---|
490 | popen = lambda cmd: \
|
---|
491 | subprocess.Popen(
|
---|
492 | cmd,
|
---|
493 | stdin=subprocess.PIPE,
|
---|
494 | stdout=subprocess.PIPE,
|
---|
495 | stderr=subprocess.STDOUT
|
---|
496 | )
|
---|
497 |
|
---|
498 | print '%s [%s] ...' % (module, stage),
|
---|
499 | sys.stdout.flush()
|
---|
500 | p = popen(cmd)
|
---|
501 | output = p.stdout.read()
|
---|
502 | p.wait()
|
---|
503 | if p.returncode != 0:
|
---|
504 | print '[failed!]'
|
---|
505 | logFile = os.path.join(self.config.build_dir, 'log.txt')
|
---|
506 | f = open(logFile, "w")
|
---|
507 | f.write(output)
|
---|
508 | f.close()
|
---|
509 | raise Exception, 'Failed to %s %s\n' % (stage, module) + \
|
---|
510 | 'See output log at %s' % self.config.Relative(logFile)
|
---|
511 | else:
|
---|
512 | print '[done]'
|
---|
513 |
|
---|
514 | if skipable:
|
---|
515 | self.MarkBuildStepComplete('%s.%s' % (module, stage))
|
---|
516 |
|
---|
517 | def MakeSymLinks(self):
|
---|
518 | links_dir = os.path.join(self.config.symlinks, self.config.arch)
|
---|
519 | if not os.path.exists(links_dir):
|
---|
520 | os.makedirs(links_dir)
|
---|
521 | startPrinted = False
|
---|
522 | for link in ('ar', 'ld', 'gcc'):
|
---|
523 | src = os.path.join(
|
---|
524 | self.config.prefix, 'bin', self.config.target_combo + '-' + link
|
---|
525 | )
|
---|
526 | linkdst = os.path.join(links_dir, link)
|
---|
527 | if not os.path.lexists(linkdst):
|
---|
528 | if not startPrinted:
|
---|
529 | print 'Making symlinks in %s:' % self.config.Relative(links_dir),
|
---|
530 | startPrinted = True
|
---|
531 | print link,
|
---|
532 | os.symlink(src, linkdst)
|
---|
533 |
|
---|
534 | if startPrinted:
|
---|
535 | print '[done]'
|
---|
536 |
|
---|
537 | class App:
|
---|
538 | """class App
|
---|
539 |
|
---|
540 | The main body of the application.
|
---|
541 | """
|
---|
542 |
|
---|
543 | def __init__(self):
|
---|
544 | config = Config()
|
---|
545 |
|
---|
546 | if not config.IsConfigOk():
|
---|
547 | return
|
---|
548 |
|
---|
549 | config.MakeDirs()
|
---|
550 |
|
---|
551 | sources = SourceFiles(config)
|
---|
552 | result = sources.GetAll()
|
---|
553 | if result:
|
---|
554 | print 'All files have been downloaded & verified'
|
---|
555 | else:
|
---|
556 | print 'An error occured while downloading a file'
|
---|
557 | return
|
---|
558 |
|
---|
559 | Extracter(sources, config).ExtractAll()
|
---|
560 |
|
---|
561 | Builder(sources, config).Build()
|
---|
562 |
|
---|
563 | App()
|
---|
564 |
|
---|