diff options
author | Jacek Antonelli | 2008-09-06 18:24:57 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-09-06 18:25:07 -0500 |
commit | 798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch) | |
tree | 1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/develop.py | |
parent | Second Life viewer sources 1.20.15 (diff) | |
download | meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2 meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz |
Second Life viewer sources 1.21.0-RC
Diffstat (limited to 'linden/indra/develop.py')
-rwxr-xr-x | linden/indra/develop.py | 676 |
1 files changed, 676 insertions, 0 deletions
diff --git a/linden/indra/develop.py b/linden/indra/develop.py new file mode 100755 index 0000000..8edfccc --- /dev/null +++ b/linden/indra/develop.py | |||
@@ -0,0 +1,676 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # | ||
3 | # @file develop.py | ||
4 | # @authors Bryan O'Sullivan, Mark Palange, Aaron Brashears | ||
5 | # @brief Fire and forget script to appropriately configure cmake for SL. | ||
6 | # | ||
7 | # $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
8 | # | ||
9 | # Copyright (c) 2007-2008, Linden Research, Inc. | ||
10 | # | ||
11 | # Second Life Viewer Source Code | ||
12 | # The source code in this file ("Source Code") is provided by Linden Lab | ||
13 | # to you under the terms of the GNU General Public License, version 2.0 | ||
14 | # ("GPL"), unless you have obtained a separate licensing agreement | ||
15 | # ("Other License"), formally executed by you and Linden Lab. Terms of | ||
16 | # the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
17 | # online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
18 | # | ||
19 | # There are special exceptions to the terms and conditions of the GPL as | ||
20 | # it is applied to this Source Code. View the full text of the exception | ||
21 | # in the file doc/FLOSS-exception.txt in this software distribution, or | ||
22 | # online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
23 | # | ||
24 | # By copying, modifying or distributing this software, you acknowledge | ||
25 | # that you have read and understood your obligations described above, | ||
26 | # and agree to abide by those obligations. | ||
27 | # | ||
28 | # ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
29 | # WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
30 | # COMPLETENESS OR PERFORMANCE. | ||
31 | # $/LicenseInfo$ | ||
32 | |||
33 | |||
34 | import errno | ||
35 | import getopt | ||
36 | import os | ||
37 | import random | ||
38 | import re | ||
39 | import shutil | ||
40 | import socket | ||
41 | import sys | ||
42 | import commands | ||
43 | |||
44 | class CommandError(Exception): | ||
45 | pass | ||
46 | |||
47 | |||
48 | def mkdir(path): | ||
49 | try: | ||
50 | os.mkdir(path) | ||
51 | return path | ||
52 | except OSError, err: | ||
53 | if err.errno != errno.EEXIST or not os.path.isdir(path): | ||
54 | raise | ||
55 | |||
56 | def quote(opts): | ||
57 | return '"' + '" "'.join([ opt.replace('"', '') for opt in opts ]) + '"' | ||
58 | |||
59 | class PlatformSetup(object): | ||
60 | generator = None | ||
61 | build_types = {} | ||
62 | for t in ('Debug', 'Release', 'RelWithDebInfo'): | ||
63 | build_types[t.lower()] = t | ||
64 | |||
65 | build_type = build_types['relwithdebinfo'] | ||
66 | standalone = 'FALSE' | ||
67 | unattended = 'FALSE' | ||
68 | distcc = True | ||
69 | cmake_opts = [] | ||
70 | |||
71 | def __init__(self): | ||
72 | self.script_dir = os.path.realpath( | ||
73 | os.path.dirname(__import__(__name__).__file__)) | ||
74 | |||
75 | def os(self): | ||
76 | '''Return the name of the OS.''' | ||
77 | |||
78 | raise NotImplemented('os') | ||
79 | |||
80 | def arch(self): | ||
81 | '''Return the CPU architecture.''' | ||
82 | |||
83 | return None | ||
84 | |||
85 | def platform(self): | ||
86 | '''Return a stringified two-tuple of the OS name and CPU | ||
87 | architecture.''' | ||
88 | |||
89 | ret = self.os() | ||
90 | if self.arch(): | ||
91 | ret += '-' + self.arch() | ||
92 | return ret | ||
93 | |||
94 | def build_dirs(self): | ||
95 | '''Return the top-level directories in which builds occur. | ||
96 | |||
97 | This can return more than one directory, e.g. if doing a | ||
98 | 32-bit viewer and server build on Linux.''' | ||
99 | |||
100 | return ['build-' + self.platform()] | ||
101 | |||
102 | def cmake_commandline(self, src_dir, build_dir, opts, simple): | ||
103 | '''Return the command line to run cmake with.''' | ||
104 | |||
105 | args = dict( | ||
106 | dir=src_dir, | ||
107 | generator=self.generator, | ||
108 | opts=quote(opts), | ||
109 | standalone=self.standalone, | ||
110 | unattended=self.unattended, | ||
111 | type=self.build_type.upper(), | ||
112 | ) | ||
113 | #if simple: | ||
114 | # return 'cmake %(opts)s %(dir)r' % args | ||
115 | return ('cmake -DCMAKE_BUILD_TYPE:STRING=%(type)s ' | ||
116 | '-DSTANDALONE:BOOL=%(standalone)s ' | ||
117 | '-DUNATTENDED:BOOL=%(unattended)s ' | ||
118 | '-G %(generator)r %(opts)s %(dir)r' % args) | ||
119 | |||
120 | def run(self, command, name=None): | ||
121 | '''Run a program. If the program fails, raise an exception.''' | ||
122 | ret = os.system(command) | ||
123 | if ret: | ||
124 | if name is None: | ||
125 | name = command.split(None, 1)[0] | ||
126 | if os.WIFEXITED(ret): | ||
127 | event = 'exited' | ||
128 | status = 'status %d' % os.WEXITSTATUS(ret) | ||
129 | elif os.WIFSIGNALED(ret): | ||
130 | event = 'was killed' | ||
131 | status = 'signal %d' % os.WTERMSIG(ret) | ||
132 | else: | ||
133 | event = 'died unexpectedly (!?)' | ||
134 | status = '16-bit status %d' % ret | ||
135 | raise CommandError('the command %r %s with %s' % | ||
136 | (name, event, status)) | ||
137 | |||
138 | def run_cmake(self, args=[]): | ||
139 | '''Run cmake.''' | ||
140 | |||
141 | # do a sanity check to make sure we have a generator | ||
142 | if not hasattr(self, 'generator'): | ||
143 | raise "No generator available for '%s'" % (self.__name__,) | ||
144 | cwd = os.getcwd() | ||
145 | created = [] | ||
146 | try: | ||
147 | for d in self.build_dirs(): | ||
148 | simple = True | ||
149 | if mkdir(d): | ||
150 | created.append(d) | ||
151 | simple = False | ||
152 | try: | ||
153 | os.chdir(d) | ||
154 | cmd = self.cmake_commandline(cwd, d, args, simple) | ||
155 | print 'Running %r in %r' % (cmd, d) | ||
156 | self.run(cmd, 'cmake') | ||
157 | finally: | ||
158 | os.chdir(cwd) | ||
159 | except: | ||
160 | # If we created a directory in which to run cmake and | ||
161 | # something went wrong, the directory probably just | ||
162 | # contains garbage, so delete it. | ||
163 | os.chdir(cwd) | ||
164 | for d in created: | ||
165 | print 'Cleaning %r' % d | ||
166 | shutil.rmtree(d) | ||
167 | raise | ||
168 | |||
169 | def parse_build_opts(self, arguments): | ||
170 | opts, targets = getopt.getopt(arguments, 'o:', ['option=']) | ||
171 | build_opts = [] | ||
172 | for o, a in opts: | ||
173 | if o in ('-o', '--option'): | ||
174 | build_opts.append(a) | ||
175 | return build_opts, targets | ||
176 | |||
177 | def run_build(self, opts, targets): | ||
178 | '''Build the default targets for this platform.''' | ||
179 | |||
180 | raise NotImplemented('run_build') | ||
181 | |||
182 | def cleanup(self): | ||
183 | '''Delete all build directories.''' | ||
184 | |||
185 | cleaned = 0 | ||
186 | for d in self.build_dirs(): | ||
187 | if os.path.isdir(d): | ||
188 | print 'Cleaning %r' % d | ||
189 | shutil.rmtree(d) | ||
190 | cleaned += 1 | ||
191 | if not cleaned: | ||
192 | print 'Nothing to clean up!' | ||
193 | |||
194 | def is_internal_tree(self): | ||
195 | '''Indicate whether we are building in an internal source tree.''' | ||
196 | |||
197 | return os.path.isdir(os.path.join(self.script_dir, 'newsim')) | ||
198 | |||
199 | |||
200 | class UnixSetup(PlatformSetup): | ||
201 | '''Generic Unixy build instructions.''' | ||
202 | |||
203 | def __init__(self): | ||
204 | super(UnixSetup, self).__init__() | ||
205 | self.generator = 'Unix Makefiles' | ||
206 | |||
207 | def os(self): | ||
208 | return 'unix' | ||
209 | |||
210 | def arch(self): | ||
211 | cpu = os.uname()[-1] | ||
212 | if cpu.endswith('386'): | ||
213 | cpu = 'i386' | ||
214 | elif cpu.endswith('86'): | ||
215 | cpu = 'i686' | ||
216 | elif cpu in ('athlon',): | ||
217 | cpu = 'i686' | ||
218 | elif cpu == 'Power Macintosh': | ||
219 | cpu = 'ppc' | ||
220 | return cpu | ||
221 | |||
222 | |||
223 | class LinuxSetup(UnixSetup): | ||
224 | def __init__(self): | ||
225 | super(LinuxSetup, self).__init__() | ||
226 | |||
227 | def os(self): | ||
228 | return 'linux' | ||
229 | |||
230 | def build_dirs(self): | ||
231 | # Only build the server code if (a) we have it and (b) we're | ||
232 | # on 32-bit x86. | ||
233 | if self.arch() == 'i686' and self.is_internal_tree(): | ||
234 | return ['viewer-' + self.platform(), 'server-' + self.platform()] | ||
235 | else: | ||
236 | return ['viewer-' + self.platform()] | ||
237 | |||
238 | def find_in_path(self, name, defval=None, basename=False): | ||
239 | for p in os.getenv('PATH', '/usr/bin').split(':'): | ||
240 | path = os.path.join(p, name) | ||
241 | if os.access(path, os.X_OK): | ||
242 | return [basename and os.path.basename(path) or path] | ||
243 | if defval: | ||
244 | return [defval] | ||
245 | return [] | ||
246 | |||
247 | def cmake_commandline(self, src_dir, build_dir, opts, simple): | ||
248 | args = dict( | ||
249 | dir=src_dir, | ||
250 | generator=self.generator, | ||
251 | opts=quote(opts), | ||
252 | standalone=self.standalone, | ||
253 | unattended=self.unattended, | ||
254 | type=self.build_type.upper() | ||
255 | ) | ||
256 | if not self.is_internal_tree(): | ||
257 | args.update({'cxx':'g++', 'server':'FALSE', 'viewer':'TRUE'}) | ||
258 | else: | ||
259 | if self.distcc: | ||
260 | distcc = self.find_in_path('distcc') | ||
261 | baseonly = True | ||
262 | else: | ||
263 | distcc = [] | ||
264 | baseonly = False | ||
265 | if 'server' in build_dir: | ||
266 | gcc33 = distcc + self.find_in_path('g++-3.3', 'g++', baseonly) | ||
267 | args.update({'cxx':' '.join(gcc33), 'server':'TRUE', | ||
268 | 'viewer':'FALSE'}) | ||
269 | else: | ||
270 | gcc41 = distcc + self.find_in_path('g++-4.1', 'g++', baseonly) | ||
271 | args.update({'cxx': ' '.join(gcc41), 'server':'FALSE', | ||
272 | 'viewer':'TRUE'}) | ||
273 | #if simple: | ||
274 | # return (('cmake %(opts)s ' | ||
275 | # '-DSERVER:BOOL=%(server)s ' | ||
276 | # '-DVIEWER:BOOL=%(viewer)s ' | ||
277 | # '%(dir)r') % args) | ||
278 | cmd = (('cmake -DCMAKE_BUILD_TYPE:STRING=%(type)s ' | ||
279 | '-G %(generator)r -DSERVER:BOOL=%(server)s ' | ||
280 | '-DVIEWER:BOOL=%(viewer)s -DSTANDALONE:BOOL=%(standalone)s ' | ||
281 | '-DUNATTENDED:BOOL=%(unattended)s ' | ||
282 | '%(opts)s %(dir)r') | ||
283 | % args) | ||
284 | if 'CXX' not in os.environ: | ||
285 | args.update({'cmd':cmd}) | ||
286 | cmd = ('CXX=%(cxx)r %(cmd)s' % args) | ||
287 | return cmd | ||
288 | |||
289 | def run_build(self, opts, targets): | ||
290 | job_count = None | ||
291 | |||
292 | for i in range(len(opts)): | ||
293 | if opts[i].startswith('-j'): | ||
294 | try: | ||
295 | job_count = int(opts[i][2:]) | ||
296 | except ValueError: | ||
297 | try: | ||
298 | job_count = int(opts[i+1]) | ||
299 | except ValueError: | ||
300 | job_count = True | ||
301 | |||
302 | def get_cpu_count(): | ||
303 | count = 0 | ||
304 | for line in open('/proc/cpuinfo'): | ||
305 | if re.match(r'processor\s*:', line): | ||
306 | count += 1 | ||
307 | return count | ||
308 | |||
309 | def localhost(): | ||
310 | count = get_cpu_count() | ||
311 | return 'localhost/' + str(count), count | ||
312 | |||
313 | def get_distcc_hosts(): | ||
314 | try: | ||
315 | hosts = [] | ||
316 | name = os.getenv('DISTCC_DIR', '/etc/distcc') + '/hosts' | ||
317 | for l in open(name): | ||
318 | l = l[l.find('#')+1:].strip() | ||
319 | if l: hosts.append(l) | ||
320 | return hosts | ||
321 | except IOError: | ||
322 | return (os.getenv('DISTCC_HOSTS', '').split() or | ||
323 | [localhost()[0]]) | ||
324 | |||
325 | def count_distcc_hosts(): | ||
326 | cpus = 0 | ||
327 | hosts = 0 | ||
328 | for host in get_distcc_hosts(): | ||
329 | m = re.match(r'.*/(\d+)', host) | ||
330 | hosts += 1 | ||
331 | cpus += m and int(m.group(1)) or 1 | ||
332 | return hosts, cpus | ||
333 | |||
334 | def mk_distcc_hosts(): | ||
335 | '''Generate a list of LL-internal machines to build on.''' | ||
336 | loc_entry, cpus = localhost() | ||
337 | hosts = [loc_entry] | ||
338 | dead = [] | ||
339 | stations = [s for s in xrange(36) if s not in dead] | ||
340 | random.shuffle(stations) | ||
341 | hosts += ['station%d.lindenlab.com/2,lzo' % s for s in stations] | ||
342 | cpus += 2 * len(stations) | ||
343 | return ' '.join(hosts), cpus | ||
344 | |||
345 | if job_count is None: | ||
346 | hosts, job_count = count_distcc_hosts() | ||
347 | if hosts == 1 and socket.gethostname().startswith('station'): | ||
348 | hosts, job_count = mk_distcc_hosts() | ||
349 | os.putenv('DISTCC_HOSTS', hosts) | ||
350 | opts.extend(['-j', str(job_count)]) | ||
351 | |||
352 | if targets: | ||
353 | targets = ' '.join(targets) | ||
354 | else: | ||
355 | targets = 'all' | ||
356 | |||
357 | for d in self.build_dirs(): | ||
358 | cmd = 'make -C %r %s %s' % (d, ' '.join(opts), targets) | ||
359 | print 'Running %r' % cmd | ||
360 | self.run(cmd) | ||
361 | |||
362 | |||
363 | class DarwinSetup(UnixSetup): | ||
364 | def __init__(self): | ||
365 | super(DarwinSetup, self).__init__() | ||
366 | self.generator = 'Xcode' | ||
367 | |||
368 | def os(self): | ||
369 | return 'darwin' | ||
370 | |||
371 | def arch(self): | ||
372 | if self.unattended == 'TRUE': | ||
373 | return 'universal' | ||
374 | else: | ||
375 | return UnixSetup.arch(self) | ||
376 | |||
377 | def cmake_commandline(self, src_dir, build_dir, opts, simple): | ||
378 | args = dict( | ||
379 | dir=src_dir, | ||
380 | generator=self.generator, | ||
381 | opts=quote(opts), | ||
382 | standalone=self.standalone, | ||
383 | unattended=self.unattended, | ||
384 | universal='', | ||
385 | type=self.build_type.upper() | ||
386 | ) | ||
387 | if self.unattended == 'TRUE': | ||
388 | args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\'' | ||
389 | #if simple: | ||
390 | # return 'cmake %(opts)s %(dir)r' % args | ||
391 | return ('cmake -G %(generator)r ' | ||
392 | '-DCMAKE_BUILD_TYPE:STRING=%(type)s ' | ||
393 | '-DSTANDALONE:BOOL=%(standalone)s ' | ||
394 | '-DUNATTENDED:BOOL=%(unattended)s ' | ||
395 | '%(universal)s ' | ||
396 | '%(opts)s %(dir)r' % args) | ||
397 | |||
398 | def run_build(self, opts, targets): | ||
399 | cwd = os.getcwd() | ||
400 | if targets: | ||
401 | targets = ' '.join(['-target ' + repr(t) for t in targets]) | ||
402 | else: | ||
403 | targets = '' | ||
404 | cmd = ('xcodebuild -parallelizeTargets ' | ||
405 | '-configuration %s %s %s' % | ||
406 | (self.build_type, ' '.join(opts), targets)) | ||
407 | for d in self.build_dirs(): | ||
408 | try: | ||
409 | os.chdir(d) | ||
410 | print 'Running %r in %r' % (cmd, d) | ||
411 | self.run(cmd) | ||
412 | finally: | ||
413 | os.chdir(cwd) | ||
414 | |||
415 | |||
416 | class WindowsSetup(PlatformSetup): | ||
417 | gens = { | ||
418 | 'vc71' : { | ||
419 | 'gen' : r'Visual Studio 7 .NET 2003', | ||
420 | 'ver' : r'7.1' | ||
421 | }, | ||
422 | 'vc80' : { | ||
423 | 'gen' : r'Visual Studio 8 2005', | ||
424 | 'ver' : r'8.0' | ||
425 | }, | ||
426 | 'vc90' : { | ||
427 | 'gen' : r'Visual Studio 9 2008', | ||
428 | 'ver' : r'9.0' | ||
429 | } | ||
430 | } | ||
431 | gens['vs2003'] = gens['vc71'] | ||
432 | gens['vs2005'] = gens['vc80'] | ||
433 | gens['vs2008'] = gens['vc90'] | ||
434 | |||
435 | def __init__(self): | ||
436 | super(WindowsSetup, self).__init__() | ||
437 | self._generator = None | ||
438 | self.incredibuild = False | ||
439 | |||
440 | def _get_generator(self): | ||
441 | if self._generator is None: | ||
442 | for version in 'vc71 vc80 vc90'.split(): | ||
443 | if self.find_visual_studio(version): | ||
444 | self._generator = version | ||
445 | print 'Building with ', self.gens[version]['gen'] | ||
446 | break | ||
447 | else: | ||
448 | print >> sys.stderr, 'Cannot find a Visual Studio installation!' | ||
449 | eys.exit(1) | ||
450 | return self._generator | ||
451 | |||
452 | def _set_generator(self, gen): | ||
453 | self._generator = gen | ||
454 | |||
455 | generator = property(_get_generator, _set_generator) | ||
456 | |||
457 | def os(self): | ||
458 | return 'win32' | ||
459 | |||
460 | def build_dirs(self): | ||
461 | return ['build-' + self.generator] | ||
462 | |||
463 | def cmake_commandline(self, src_dir, build_dir, opts, simple): | ||
464 | args = dict( | ||
465 | dir=src_dir, | ||
466 | generator=self.gens[self.generator.lower()]['gen'], | ||
467 | opts=quote(opts), | ||
468 | standalone=self.standalone, | ||
469 | unattended=self.unattended, | ||
470 | ) | ||
471 | #if simple: | ||
472 | # return 'cmake %(opts)s "%(dir)s"' % args | ||
473 | return ('cmake -G "%(generator)s" ' | ||
474 | '-DSTANDALONE:BOOL=%(standalone)s ' | ||
475 | '-DUNATTENDED:BOOL=%(unattended)s ' | ||
476 | '%(opts)s "%(dir)s"' % args) | ||
477 | |||
478 | def find_visual_studio(self, gen=None): | ||
479 | if gen is None: | ||
480 | gen = self._generator | ||
481 | gen = gen.lower() | ||
482 | try: | ||
483 | import _winreg | ||
484 | key_str = (r'SOFTWARE\Microsoft\VisualStudio\%s\Setup\VS' % | ||
485 | self.gens[gen]['ver']) | ||
486 | value_str = (r'EnvironmentDirectory') | ||
487 | print ('Reading VS environment from HKEY_LOCAL_MACHINE\%s\%s' % | ||
488 | (key_str, value_str)) | ||
489 | print key_str | ||
490 | |||
491 | reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) | ||
492 | key = _winreg.OpenKey(reg, key_str) | ||
493 | value = _winreg.QueryValueEx(key, value_str)[0] | ||
494 | print 'Found: %s' % value | ||
495 | return value | ||
496 | except WindowsError, err: | ||
497 | print >> sys.stderr, "Didn't find ", self.gens[gen]['gen'] | ||
498 | return '' | ||
499 | |||
500 | def get_build_cmd(self): | ||
501 | if self.incredibuild: | ||
502 | config = self.build_type | ||
503 | if self.gens[self.generator]['ver'] in [ r'8.0', r'9.0' ]: | ||
504 | config = '\"%s|Win32\"' % config | ||
505 | |||
506 | return "buildconsole Secondlife.sln /build %s" % config | ||
507 | |||
508 | # devenv.com is CLI friendly, devenv.exe... not so much. | ||
509 | return ('"%sdevenv.com" Secondlife.sln /build %s' % | ||
510 | (self.find_visual_studio(), self.build_type)) | ||
511 | |||
512 | # this override of run exists because the PlatformSetup version | ||
513 | # uses Unix/Mac only calls. Freakin' os module! | ||
514 | def run(self, command, name=None): | ||
515 | '''Run a program. If the program fails, raise an exception.''' | ||
516 | ret = os.system(command) | ||
517 | if ret: | ||
518 | if name is None: | ||
519 | name = command.split(None, 1)[0] | ||
520 | raise CommandError('the command %r exited with %s' % | ||
521 | (name, ret)) | ||
522 | |||
523 | def run_cmake(self, args=[]): | ||
524 | '''Override to add the vstool.exe call after running cmake.''' | ||
525 | PlatformSetup.run_cmake(self, args) | ||
526 | if self.unattended == 'FALSE': | ||
527 | for build_dir in self.build_dirs(): | ||
528 | vstool_cmd = os.path.join('tools','vstool','VSTool.exe') \ | ||
529 | + ' --solution ' \ | ||
530 | + os.path.join(build_dir,'SecondLife.sln') \ | ||
531 | + ' --config RelWithDebInfo' \ | ||
532 | + ' --startup secondlife-bin' | ||
533 | print 'Running %r in %r' % (vstool_cmd, os.getcwd()) | ||
534 | self.run(vstool_cmd) | ||
535 | |||
536 | def run_build(self, opts, targets): | ||
537 | cwd = os.getcwd() | ||
538 | build_cmd = self.get_build_cmd() | ||
539 | |||
540 | for d in self.build_dirs(): | ||
541 | try: | ||
542 | os.chdir(d) | ||
543 | if targets: | ||
544 | for t in targets: | ||
545 | cmd = '%s /project %s %s' % (build_cmd, t, ' '.join(opts)) | ||
546 | print 'Running %r in %r' % (cmd, d) | ||
547 | self.run(cmd) | ||
548 | else: | ||
549 | cmd = '%s %s' % (build_cmd, ' '.join(opts)) | ||
550 | print 'Running %r in %r' % (cmd, d) | ||
551 | self.run(cmd) | ||
552 | finally: | ||
553 | os.chdir(cwd) | ||
554 | |||
555 | class CygwinSetup(WindowsSetup): | ||
556 | def __init__(self): | ||
557 | super(CygwinSetup, self).__init__() | ||
558 | self.generator = 'vc71' | ||
559 | |||
560 | def cmake_commandline(self, src_dir, build_dir, opts, simple): | ||
561 | dos_dir = commands.getoutput("cygpath -w %s" % src_dir) | ||
562 | args = dict( | ||
563 | dir=dos_dir, | ||
564 | generator=self.gens[self.generator.lower()]['gen'], | ||
565 | opts=quote(opts), | ||
566 | standalone=self.standalone, | ||
567 | unattended=self.unattended, | ||
568 | ) | ||
569 | #if simple: | ||
570 | # return 'cmake %(opts)s "%(dir)s"' % args | ||
571 | return ('cmake -G "%(generator)s" ' | ||
572 | '-DUNATTENDED:BOOl=%(unattended)s ' | ||
573 | '-DSTANDALONE:BOOL=%(standalone)s ' | ||
574 | '%(opts)s "%(dir)s"' % args) | ||
575 | |||
576 | setup_platform = { | ||
577 | 'darwin': DarwinSetup, | ||
578 | 'linux2': LinuxSetup, | ||
579 | 'win32' : WindowsSetup, | ||
580 | 'cygwin' : CygwinSetup | ||
581 | } | ||
582 | |||
583 | |||
584 | usage_msg = ''' | ||
585 | Usage: develop.py [options] command [command-options] | ||
586 | |||
587 | Options: | ||
588 | -h | --help print this help message | ||
589 | --standalone build standalone, without Linden prebuild libraries | ||
590 | --unattended build unattended, do not invoke any tools requiring | ||
591 | a human response | ||
592 | -t | --type=NAME build type ("Debug", "Release", or "RelWithDebInfo") | ||
593 | -N | --no-distcc disable use of distcc | ||
594 | -G | --generator=NAME generator name | ||
595 | Windows: VC71 or VS2003 (default), VC80 (VS2005) or VC90 (VS2008) | ||
596 | Mac OS X: Xcode (default), Unix Makefiles | ||
597 | Linux: Unix Makefiles (default), KDevelop3 | ||
598 | Commands: | ||
599 | build configure and build default target | ||
600 | clean delete all build directories (does not affect sources) | ||
601 | configure configure project by running cmake | ||
602 | |||
603 | If you do not specify a command, the default is "configure". | ||
604 | ''' | ||
605 | |||
606 | def main(arguments): | ||
607 | setup = setup_platform[sys.platform]() | ||
608 | try: | ||
609 | opts, args = getopt.getopt( | ||
610 | arguments, | ||
611 | '?hNt:G:', | ||
612 | ['help', 'standalone', 'no-distcc', 'unattended', 'type=', 'incredibuild', 'generator=']) | ||
613 | except getopt.GetoptError, err: | ||
614 | print >> sys.stderr, 'Error:', err | ||
615 | sys.exit(1) | ||
616 | |||
617 | for o, a in opts: | ||
618 | if o in ('-?', '-h', '--help'): | ||
619 | print usage_msg.strip() | ||
620 | sys.exit(0) | ||
621 | elif o in ('--standalone',): | ||
622 | setup.standalone = 'TRUE' | ||
623 | elif o in ('--unattended',): | ||
624 | setup.unattended = 'TRUE' | ||
625 | elif o in ('-t', '--type'): | ||
626 | try: | ||
627 | setup.build_type = setup.build_types[a.lower()] | ||
628 | except KeyError: | ||
629 | print >> sys.stderr, 'Error: unknown build type', repr(a) | ||
630 | print >> sys.stderr, 'Supported build types:' | ||
631 | types = setup.build_types.values() | ||
632 | types.sort() | ||
633 | for t in types: | ||
634 | print ' ', t | ||
635 | sys.exit(1) | ||
636 | elif o in ('-G', '--generator'): | ||
637 | setup.generator = a | ||
638 | elif o in ('-N', '--no-distcc'): | ||
639 | setup.distcc = False | ||
640 | elif o in ('--incredibuild'): | ||
641 | setup.incredibuild = True | ||
642 | else: | ||
643 | print >> sys.stderr, 'INTERNAL ERROR: unhandled option', repr(o) | ||
644 | sys.exit(1) | ||
645 | if not args: | ||
646 | setup.run_cmake() | ||
647 | return | ||
648 | try: | ||
649 | cmd = args.pop(0) | ||
650 | if cmd in ('cmake', 'configure'): | ||
651 | setup.run_cmake(args) | ||
652 | elif cmd == 'build': | ||
653 | for d in setup.build_dirs(): | ||
654 | if not os.path.exists(d): | ||
655 | raise CommandError('run "develop.py cmake" first') | ||
656 | setup.run_cmake() | ||
657 | opts, targets = setup.parse_build_opts(args) | ||
658 | setup.run_build(opts, targets) | ||
659 | elif cmd == 'clean': | ||
660 | if args: | ||
661 | raise CommandError('clean takes no arguments') | ||
662 | setup.cleanup() | ||
663 | else: | ||
664 | print >> sys.stderr, 'Error: unknown subcommand', repr(cmd) | ||
665 | print >> sys.stderr, "(run 'develop.py --help' for help)" | ||
666 | sys.exit(1) | ||
667 | except CommandError, err: | ||
668 | print >> sys.stderr, 'Error:', err | ||
669 | sys.exit(1) | ||
670 | except getopt.GetoptError, err: | ||
671 | print >> sys.stderr, 'Error with %r subcommand: %s' % (cmd, err) | ||
672 | sys.exit(1) | ||
673 | |||
674 | |||
675 | if __name__ == '__main__': | ||
676 | main(sys.argv[1:]) | ||