root/juggler/branches/2.2/build_windows.py

Revision 21074, 103.4 kB (checked in by patrick, 3 months ago)

MFT r21072: Generate boost_system.fpc.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #python
2
3 # ************** <auto-copyright.pl BEGIN do not edit this line> **************
4 #
5 # VR Juggler is (C) Copyright 1998-2007 by Iowa State University
6 #
7 # Original Authors:
8 #   Allen Bierbaum, Christopher Just,
9 #   Patrick Hartling, Kevin Meinert,
10 #   Carolina Cruz-Neira, Albert Baker
11 #
12 # This library is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU Library General Public
14 # License as published by the Free Software Foundation; either
15 # version 2 of the License, or (at your option) any later version.
16 #
17 # This library is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 # Library General Public License for more details.
21 #
22 # You should have received a copy of the GNU Library General Public
23 # License along with this library; if not, write to the
24 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 # Boston, MA 02111-1307, USA.
26 #
27 # *************** <auto-copyright.pl END do not edit this line> ***************
28
29 import glob
30 import os, os.path
31 import re
32 import shutil
33 import sys
34 import time
35 import traceback
36 import getopt
37 pj = os.path.join
38
39 EXIT_STATUS_SUCCESS              = 0
40 EXIT_STATUS_NO_MSVS              = 1
41 EXIT_STATUS_MISSING_DATA_FILE    = 2
42 EXIT_STATUS_MSVS_START_ERROR     = 3
43 EXIT_STATUS_INVALID_PATH         = 4
44 EXIT_STATUS_MISSING_REQ_VALUE    = 5
45 EXIT_STATUS_UNSUPPORTED_COMPILER = 6
46 EXIT_STATUS_INVALID_ARGUMENT     = 7
47
48 gJugglerDir      = os.path.dirname(os.path.abspath(sys.argv[0]))
49 gOptionsFileName = "options.cache"
50 gBuild64         = False
51
52 gJdomJars = [
53    'jdom.jar',
54    'jaxen-core.jar',
55    'jar',
56    'jaxen-jdom.jar',
57    'xerces.jar',
58    'xml-apis.jar',
59    'saxpath.jar'
60 ]
61
62 gTweekJars = [
63    'Tweek.jar',
64    'TweekBeanDelivery.jar',
65    'TweekBeans.jar',
66    'TweekEvents.jar',
67    'TweekNet.jar',
68    'TweekServices.jar',
69    'kunststoff-mod.jar'
70 ]
71
72 gTweekExtJars = [
73    'ui.jar',
74    'wizard.jar'
75 ]
76
77 gJcclJars = [
78    'jccl_config.jar',
79    'jccl_editors.jar'
80 ]
81
82 gJcclRtrcJars = [
83    'jccl_rtrc.jar'
84 ]
85
86 gHaveTk = False
87 try:
88    import Tkinter
89    import tkMessageBox
90    import tkFileDialog
91    import threading
92    gHaveTk = True
93 except ImportError, ex:
94    print ex
95
96 class BuildOption:
97    def __init__(self, envVar, desc, defaultValue, isDirectory = True,
98                 required = True):
99       self.envVar      = envVar
100       self.desc        = desc
101       self.default     = defaultValue
102       self.required    = required
103       self.isDirectory = isDirectory
104
105 def detectVisualStudioVersion(reattempt = False):
106    (cl_stdin, cl_stdout, cl_stderr) = os.popen3('cl')
107    cl_version_line = cl_stderr.readline()
108
109    cl_ver_match = re.compile(r'Compiler Version ((\d+)\.(\d+)\.(\d+))')
110    ver_string_match = cl_ver_match.search(cl_version_line)
111
112    cl_major = 0
113    cl_minor = 0
114
115    if ver_string_match is not None:
116       cl_major = int(ver_string_match.group(2))
117       cl_minor = int(ver_string_match.group(3))
118
119       if cl_major == 13 and cl_minor < 10:
120          printStatus("Visual Studio .NET 2002 is not supported")
121          sys.exit(EXIT_STATUS_UNSUPPORTED_COMPILER)
122       elif cl_major == 13 and cl_minor >= 10:
123          vs_ver = '.NET 2003'
124       else:
125          vs_ver = '2005'
126
127       printStatus("It appears that we will be using Visual Studio %s"%vs_ver)
128       #printStatus("   compiler version: %s.%s"%(cl_major,cl_minor))
129
130    in_status  = cl_stdin.close()
131    out_status = cl_stdout.close()
132    err_status = cl_stderr.close()
133
134    # If there was an error closing any of the streams returned by
135    # os.popen3(), then the command was not opened correctly.  That means
136    # that CL.EXE is not in the user's path.
137    if in_status is not None or out_status is not None or err_status is not None:
138       # If this is not a reattempt to guess the Visual Studio version, then
139       # be nice and extend the user's path to include their Visual Studio
140       # installation.
141       if not reattempt:
142          printStatus("Visual studio not in path, attempting to find...")
143          # Common installation directories for Visual Studio.
144          vs_dirs = [r'C:\Program Files\Microsoft Visual Studio 8',
145                     r'C:\Program Files\Microsoft Visual Studio .NET 2003'
146                    ]
147
148          for d in vs_dirs:
149             printStatus("Trying path: %s"%d)
150             if not os.path.exists(d):
151                printStatus("  does not exist.")
152             else:
153                printStatus("   Using: %s"%d)
154                printStatus("      " + d)
155                vs_path = [os.path.join(d, r'Common7\IDE'),
156                           os.path.join(d, r'VC7\BIN'),
157                           os.path.join(d, r'VC\BIN'),
158                           os.path.join(d, r'Common7\Tools'),
159                           os.path.join(d, r'Common7\Tools\bin\prerelease'),
160                           os.path.join(d, r'Common7\Tools\bin')]
161                path_add = ';'.join(vs_path)
162                os.environ['PATH'] = path_add + os.pathsep + os.getenv('PATH', '')
163
164                # Try again to guess the Visual Studio version.
165                return detectVisualStudioVersion(True)               
166
167          # If execution reaches this point, our attempts to guess the
168          # location of a Visual Studio 7.x installation failed.
169          noVisualStudioError()
170
171       # If this is a reattempt to guess the Visual Studio version, then
172       # something is wrong with the user's Visual Studio installation.
173       else:
174          noVisualStudioError()
175
176    return (cl_major, cl_minor)
177
178 def chooseVisualStudioDir():
179    (cl_ver_major, cl_ver_minor) = detectVisualStudioVersion()
180
181    # For Visual Studio .NET 2003 (version 7.1), we will use the solution in
182    # the vc7 subtree.
183    if cl_ver_major == 13:
184       vc_dir = 'vc7'
185    # Otherwise, we use the solution in the vc8 subtree.
186    else:
187       vc_dir = 'vc8'
188
189    return (cl_ver_major, cl_ver_minor, vc_dir)
190
191 def printStatus(msg):
192    '''
193    This is a simple wrapper around the standard Python print function.
194    We will use a wrapper function for key status messages so that they
195    can be redirected either to the console or to a GUI easily.
196    '''
197    print msg
198
199 def noVisualStudioError():
200    print "ERROR: Visual Studio commands are not in your path!"
201    print "Run vsvars32.bat in this shell or update the %PATH% environment"
202    print "variable on your system."
203    sys.exit(EXIT_STATUS_NO_MSVS)
204
205 def getCacheFileName():
206    return os.path.join(gJugglerDir, gOptionsFileName)
207
208 def processInput(optionDict, envVar, inputDesc, required = False):
209    default_value = optionDict[envVar]
210    print "  %s [%s]: " % (inputDesc, default_value),
211    input_str = sys.stdin.readline().strip(" \n")
212
213    if input_str == '':
214       if required and (default_value is None or default_value == ''):
215          print "ERROR: %s value required" % inputDesc
216          sys.exit(EXIT_STATUS_MISSING_REQ_VALUE)
217       else:
218          value_str = default_value
219    else:
220       value_str = input_str
221
222    optionDict[envVar] = value_str
223    os.environ[envVar] = value_str
224
225    return value_str
226
227 def getDefaultVars(clVerMajor, clVerMinor):
228    required = []
229    required.append(BuildOption('BOOST_ROOT',
230                                'Boost C++ installation directory', ''))
231    required.append(BuildOption('BOOST_VERSION', 'Boost C++ version',
232                                '1_31', False))
233    required.append(BuildOption('BOOST_INCLUDES',
234                                'Directory containing the Boost C++ header tree',
235                                ''))
236    required.append(BuildOption('NSPR_ROOT', 'NSPR installation directory', ''))
237    required.append(BuildOption('NSPR_INCLUDES', 'Directory containing nspr.h',
238                                ''))
239    required.append(BuildOption('CPPDOM_ROOT', 'CppDOM installation directory',
240                                ''))
241    required.append(BuildOption('CPPDOM_INCLUDES',
242                                'Directory containing the CppDOM header tree',
243                                ''))
244    required.append(BuildOption('GMTL_ROOT', 'GMTL installation directory', ''))
245    required.append(BuildOption('GMTL_INCLUDES',
246                                'Directory containing the GMTL header tree',
247                                ''))
248
249    optional = []
250    optional.append(BuildOption('JAVA_HOME', 'Java installation directory',
251                                r'C:\java', required = False))
252    optional.append(BuildOption('JOGL_HOME', 'Jogl installation directory',
253                                os.getenv('JAVA_HOME', ''), required = False))
254    optional.append(BuildOption('JAVA3D_HOME', 'Java 3D installation directory',
255                                os.getenv('JAVA_HOME', ''), required = False))
256    optional.append(BuildOption('OMNIORB_ROOT',
257                                'omniORB installation directory', '',
258                                required = False))
259    optional.append(BuildOption('PFROOT',
260                                'OpenGL Performer installation directory',
261                                r'C:\Program Files\Silicon Graphics\OpenGL Performer',
262                                required = False))
263    optional.append(BuildOption('MS_SPEECH_SDK_ROOT',
264                                'Microsoft Speech SDK directory', '',
265                                required = False))
266    optional.append(BuildOption('VRPN_ROOT', 'VRPN installation directory', '',
267                                required = False))
268    optional.append(BuildOption('AUDIERE_ROOT',
269                                'Audiere installation directory', '',
270                                required = False))
271    optional.append(BuildOption('OPENAL_ROOT',
272                                'OpenAL SDK installation directory', '',
273                                required = False))
274    optional.append(BuildOption('ALUT_ROOT', 'ALUT SDK installation directory',
275                                '', required = False))
276    optional.append(BuildOption('TRACKD_API_ROOT',
277                                'TrackdAPI installation directory', '',
278                                required = False))
279    optional.append(BuildOption('FTD2XX_ROOT',
280                                'FTD2XX SDK installation directory', '',
281                                required = False))
282    optional.append(BuildOption('MOTION_NODE_SDK_ROOT',
283                                'MotionNode SDK installation directory', '',
284                                required = False))
285    optional.append(BuildOption('DOOZER_ROOT',
286                                'Doozer installation directory', '',
287                                required = False))
288
289    options = {
290       'prefix'      : r'C:\vrjuggler',
291       'deps-prefix' : r'C:\vrjuggler-deps'
292    }
293
294    for opt in required + optional:
295       options[opt.envVar] = os.getenv(opt.envVar, opt.default)
296
297    # If there are cached options, read them in.
298    cache_file = getCacheFileName()
299    if os.path.exists(cache_file):
300       execfile(cache_file)
301
302    return required, optional, options
303
304 def setVars(clVerMajor, clVerMinor):
305    required, optional, options = getDefaultVars(clVerMajor, clVerMinor)
306
307    print "+++ Required Settings"
308    processInput(options, 'prefix', 'Installation prefix')
309
310    boost_dir = ''
311    boost_ver = ''
312    for opt in required:
313       result = processInput(options, opt.envVar, opt.desc, opt.required)
314
315       # The following is a little hack to get a reasonable default set for
316       # the BOOST_INCLUDES variable before the user has to enter it manually.
317       if opt.envVar == 'BOOST_ROOT':
318          boost_dir = result
319       elif opt.envVar == 'BOOST_VERSION' and \
320            options.get('BOOST_INCLUDES', '') == '':
321          boost_ver = result
322          options['BOOST_INCLUDES'] = boost_dir + r'\include\boost-' + boost_ver
323
324       # The following is a little hack to get a reasonable default set for
325       # the NSPR_INCLUDES variable before the user has to enter it manually.
326       if opt.envVar == 'NSPR_ROOT' and \
327          options.get('NSPR_INCLUDES', '') == '':
328          options['NSPR_INCLUDES'] = os.path.join(result, 'include')
329
330       # The following is a little hack to get a reasonable default set for
331       # the CPPDOM_INCLUDES variable before the user has to enter it manually.
332       if opt.envVar == 'CPPDOM_ROOT' and \
333          options.get('CPPDOM_INCLUDES', '') == '':
334          options['CPPDOM_INCLUDES'] = os.path.join(result, 'include')
335
336       # The following is a little hack to get a reasonable default set for
337       # the GMTL_INCLUDES variable before the user has to enter it manually.
338       if opt.envVar == 'GMTL_ROOT' and \
339          options.get('GMTL_INCLUDES', '') == '':
340          options['GMTL_INCLUDES'] = os.path.join(result, 'include')
341
342    print "+++ Optional Settings"
343    processInput(options, 'deps-prefix', 'Dependency installation prefix')
344
345    for opt in optional:
346       processInput(options, opt.envVar, opt.desc, opt.required)
347
348    postProcessOptions(options)
349    writeCacheFile(options)
350
351    return options
352
353 def postProcessOptions(options):
354    os.environ['instprefix'] = options['prefix'].replace('\\', '\\\\')
355
356    # If the %JAVA_HOME% setting is a valid directory, add its bin subdirectory
357    # to the path.
358    if os.environ['JAVA_HOME'] != '' and os.path.exists(os.environ['JAVA_HOME']):
359       jdk_path = os.path.join(os.environ['JAVA_HOME'], 'bin')
360       os.environ['PATH'] = jdk_path + os.pathsep + os.environ['PATH']
361       os.environ['JACORB_PATH'] = os.path.join(gJugglerDir, r'external\JacORB')
362
363    if os.environ['OMNIORB_ROOT'] != '' and os.path.exists(os.environ['OMNIORB_ROOT']):
364       # A 64-bit build of omniORB has to have been compiled against a 64-bit
365       # build of Python. Unfortunately, when omniidl.exe acts as the Python
366       # interpreter, it doesn't take care of setting PYTHONHOME, and this
367       # prevents it from being able to find core modules (such as sys.py or
368       # os.py). We'll assume that a 64-bit Python interpreter is being used
369       # to run this script and use its installation prefix as PYTHONHOME to
370       # help out omniidl.exe.
371       if gBuild64 and not os.environ.has_key('PYTHONHOME'):
372          os.environ['PYTHONHOME'] = sys.prefix
373
374       omni_bin = os.path.join(os.environ['OMNIORB_ROOT'], 'bin')
375
376       if os.path.exists(os.path.join(omni_bin, 'omniidl.exe')):
377          os.environ['OMNIORB_BIN'] = omni_bin
378       else:
379          os.environ['OMNIORB_BIN'] = os.path.join(omni_bin, 'x86_win32')
380
381       # Extend the path to include omniORB's bin directory.
382       os.environ['PATH'] = os.environ['OMNIORB_BIN'] + os.pathsep + os.environ['PATH']
383
384       omni_lib = os.path.join(os.environ['OMNIORB_ROOT'], 'lib')
385
386       if os.getenv('PYTHONPATH', '') != '':
387          os.environ['PYTHONPATH'] = os.path.join(omni_lib, 'python') + os.pathsep + os.environ['PYTHONPATH']
388       else:
389          os.environ['PYTHONPATH'] = os.path.join(omni_lib, 'python')
390
391       if os.path.exists(os.path.join(omni_lib, 'omnithread.lib')):
392          os.environ['OMNIORB_LIB'] = omni_lib
393       else:
394          os.environ['OMNIORB_LIB'] = os.path.join(omni_lib, 'x86_win32')
395
396       omni_glob = os.path.join(os.environ['OMNIORB_LIB'], 'omniORB*_rt.lib')
397       libs = glob.glob(omni_glob)
398       omni_ver_re = re.compile(r'omniORB(\d\d\d)_rt.lib')
399
400       for l in libs:
401          match = omni_ver_re.search(l)
402          if match is not None:
403             os.environ['OMNIORB_VERSION'] = match.group(1)
404             break
405
406       omnithread_glob = os.path.join(os.environ['OMNIORB_LIB'],
407                                      'omnithread*_rt.lib')
408       libs = glob.glob(omnithread_glob)
409       omnithread_ver_re = re.compile(r'omnithread(\d\d)_rt.lib')
410
411       for l in libs:
412          match = omnithread_ver_re.search(l)
413          if match is not None:
414             os.environ['OMNITHREAD_VERSION'] = match.group(1)
415             break
416
417    # Determine if al.h is in the base include directory or in include\AL.
418    if os.environ['OPENAL_ROOT'] != '':
419       if gBuild64:
420          subdir = 'Win64'
421       else:
422          subdir = 'Win32'
423
424       lib_dirs = [os.path.join(os.environ['OPENAL_ROOT'], 'libs'),
425                   os.path.join(os.environ['OPENAL_ROOT'], 'libs', subdir)]
426
427       for l in lib_dirs:
428          openal_lib = os.path.join(l, 'OpenAL32.lib')
429          if os.path.exists(openal_lib):
430             os.environ['OPENAL_LIB_DIR'] = l
431             break
432
433       header_file = os.path.join(os.environ['OPENAL_ROOT'], 'include', 'AL',
434                                  'al.h')
435       # If the file is include\AL\al.h, then set the environment variable
436       # %HAVE_AL_AL_H% to the preprocessor symbol 'HAVE_AL_AL_H'.
437       # See modules/sonix/plugins/OpenAL/OpenALSoundImplementation.cpp.
438       if os.path.exists(header_file):
439          os.environ['HAVE_AL_AL_H'] = 'HAVE_AL_AL_H'
440
441    # Determine if alut.h is in the base include directory or in include\AL.
442    openal_envs = ['ALUT_ROOT', 'OPENAL_ROOT']
443    for env in openal_envs:
444       if os.environ[env] != '':
445          header_file = os.path.join(os.environ[env], 'include', 'AL', 'alut.h')
446          # If the file is include\AL\alut.h, then set the environment variable
447          # %HAVE_AL_ALUT_H% to the preprocessor symbol 'HAVE_AL_ALUT_H'.
448          # See modules/sonix/plugins/OpenAL/OpenALSoundImplementation.cpp.
449          if os.path.exists(header_file):
450             os.environ['HAVE_AL_ALUT_H'] = 'HAVE_AL_ALUT_H'
451
452    # If the ALUT installation directory is not set, then assume that it is the
453    # same as the OpenAL installation directory.
454    if os.environ['ALUT_ROOT'] == '' and os.environ['OPENAL_ROOT'] != '':
455       os.environ['ALUT_ROOT'] = os.environ['OPENAL_ROOT']
456
457    if os.environ['TRACKD_API_ROOT'] != '' and os.path.exists(os.environ['TRACKD_API_ROOT']):
458       trackdapi_dir = os.environ['TRACKD_API_ROOT']
459       trackdapi_incdir = os.path.join(trackdapi_dir, 'include')
460
461       # Figure out which Trackd API header to include.
462       headers = ['trackdAPI.h', 'trackdAPI_CC.h']
463       for h in headers:
464          if os.path.exists(os.path.join(trackdapi_incdir, h)):
465             os.environ['GADGET_TRACKD_API_H'] = '<%s>' % h
466             break
467
468 def writeCacheFile(optionDict):
469    cache_file = open(getCacheFileName(), 'w')
470    for k, v in optionDict.iteritems():
471       output = "options['%s'] = r'%s'\n" % (k, v)
472       cache_file.write(output)
473    cache_file.close()
474
475 def getBoostVersion():
476    boost_ver_re = re.compile(r'#define\s+BOOST_LIB_VERSION\s+"(.+)"')
477
478    info = ('0', '0', '0')
479    if os.environ.has_key('BOOST_INCLUDES'):
480       ver_file = open(os.path.join(os.environ['BOOST_INCLUDES'], 'boost',
481                                    'version.hpp'))
482       lines = ver_file.readlines()
483       ver_file.close()
484       for l in lines:
485          match = boost_ver_re.search(l)
486          if match is not None:
487             ver_info = match.group(1).split('_')
488             info = tuple(ver_info)
489             break
490
491    return info
492
493 def buildVersion(inputFile, exps):
494    ver_file = open(inputFile)
495    lines = ver_file.readlines()
496    ver_file.close()
497
498    nums = [0 for e in exps]
499
500    for l in lines:
501       i = 0
502       while i < len(exps):
503          match = exps[i].search(l)
504          if match is not None:
505             nums[i] = match.group(1)
506             break
507          i = i + 1
508
509    return tuple(nums)
510
511 def getCppDOMVersion():
512    exps = [
513       re.compile(r'#define\s+CPPDOM_VERSION_MAJOR\s+(\d+)'),
514       re.compile(r'#define\s+CPPDOM_VERSION_MINOR\s+(\d+)'),
515       re.compile(r'#define\s+CPPDOM_VERSION_PATCH\s+(\d+)')
516    ]
517
518    info = (0, 0, 0)
519    if os.environ.has_key('CPPDOM_INCLUDES'):
520       info = buildVersion(os.path.join(os.environ['CPPDOM_INCLUDES'], 'cppdom',
521                                        'version.h'),
522                           exps)
523
524    return info
525
526 def getGMTLVersion():
527    exps = [
528       re.compile(r'#define\s+GMTL_VERSION_MAJOR\s+(\d+)'),
529       re.compile(r'#define\s+GMTL_VERSION_MINOR\s+(\d+)'),
530       re.compile(r'#define\s+GMTL_VERSION_PATCH\s+(\d+)')
531    ]
532
533    nums = [0, 0, 0]
534    if os.environ.has_key('GMTL_INCLUDES'):
535       info = buildVersion(os.path.join(os.environ['GMTL_INCLUDES'], 'gmtl',
536                                        'Version.h'),
537                           exps)
538
539    return info
540
541 def updateVersions(vcDir, options):
542    class JugglerModule:
543       def __init__(self, srcDir, vcDir, projDir, versionEnvVar, substVars,
544                    genFiles = None):
545          self.source_dir          = os.path.join(gJugglerDir, srcDir)
546          self.version_params      = os.path.join(self.source_dir,
547                                                  'Makefile.inc.in')
548          self.version_file        = os.path.join(self.source_dir, 'VERSION')
549          self.version_env_var     = versionEnvVar
550          self.version_env_var_dot = versionEnvVar + '_DOT'
551          self.subst_vars          = substVars
552          self.param_files         = []
553          self.proj_dir            = os.path.join(gJugglerDir, vcDir, projDir)
554
555          if genFiles is not None:
556             for f in genFiles:
557                output = os.path.join(self.proj_dir, f[0])
558
559                if len(f) == 1 or f[1] is None:
560                   template = os.path.join(self.source_dir, f[0] + '.in')
561                else:
562                   template = f[1]
563
564                self.param_files.append((output, template))
565
566       def updateParamFiles(self):
567          for (output, template) in self.param_files:
568             if os.path.exists(output):
569                mtime = os.path.getmtime
570                # This test to determine if the module's param header needs to
571                # be regenerated is equivalent to that used by the UNIX build
572                # system.
573                if mtime(self.version_file) > mtime(output) or \
574                   mtime(template) > mtime(output):
575                   self.__genParamFile(output, template)
576             else:
577                self.__genParamFile(output, template)
578
579       def getVersion(self, joinStr, versionInfo = None):
580          if versionInfo is None:
581             (version, major, minor, patch, build) = self.__getVersionInfo()
582          else:
583             (version, major, minor, patch, build) = versionInfo
584          return '%d%s%d' % (major, joinStr, minor)
585
586       def setVersionEnvVar(self):
587          vi = self.__getVersionInfo()
588          os.environ[self.version_env_var]     = self.getVersion('_', vi)
589          os.environ[self.version_env_var_dot] = self.getVersion('.', vi)
590
591       def removeOldVersions(self):
592          output_files = []
593          for ext in ['lib', 'dll', 'exp', 'ilk', 'pdb']:
594             output_files += glob.glob(os.path.join(self.proj_dir, '*', '*',
595                                                    '*.' + ext))
596
597          mtime = os.path.getmtime
598          for f in output_files:
599             if mtime(self.version_file) > mtime(f):
600                try:
601                   os.remove(f)
602                except:
603                   print "Failed to remove", f
604
605       version_re      = re.compile(r'((\d+)\.(\d+)\.(\d+)-(\d+))\s')
606       branch_re       = re.compile(r'BRANCH\s*=\s*(.+)')
607       canon_name_re   = re.compile(r'CANON_NAME\s*=\s*(\S.+)')
608       subst_re        = re.compile(r'@(\w+)@')
609       zero_strip_re   = re.compile(r'^0*([^0]\d+)')
610
611       def __getVersionInfo(self):
612          ver_file = open(self.version_file)
613          cur_ver  = ver_file.readline()
614          ver_file.close()
615          ver_match = self.version_re.match(cur_ver)
616          version = ver_match.group(1)
617          major   = int(ver_match.group(2))
618          minor   = int(ver_match.group(3))
619          patch   = int(ver_match.group(4))
620          build   = int(ver_match.group(5))
621
622          return (version, major, minor, patch, build)
623
624       def __genParamFile(self, output, template):
625          (version, major, minor, patch, build) = self.__getVersionInfo()
626
627          # NOTE: This will not always be identical to the UNIX version because
628          # Python does not have %e as a time formatting directive.
629          date       = time.strftime('%b %d, %Y %H:%M:%S')
630          canon_name = ''
631          branch     = ''
632
633          param_file = open(self.version_params, 'r')
634          params     = param_file.readlines()
635          param_file.close()
636
637          # This is basically a poor man's grep.  Can this be done better?
638          for line in params:
639             match = self.branch_re.match(line)
640             if match is not None:
641                branch = match.group(1)
642                continue
643
644             match = self.canon_name_re.match(line)
645             if match is not None:
646                canon_name = match.group(1)
647                continue
648
649          version_number = '%03d%03d%03d' % (major, minor, patch)
650          version_string = "\"v%s '%s' (NSPR) %s %s\"" % \
651                              (version, canon_name, branch, date)
652
653          # Strip leading zeroes from version_number.  Is there an easier way
654          # to do this?
655          version_number = self.zero_strip_re.match(version_number).group(1)
656
657          subst_vars = self.subst_vars
658          subst_vars['VER_NUMBER']         = version_number
659          subst_vars['MAJOR_VER_NUMBER']   = str(major)
660          subst_vars['MAJOR_VERSION']      = str(major)
661          subst_vars['MINOR_VER_NUMBER']   = str(minor)
662          subst_vars['MINOR_VERSION']      = str(minor)
663          subst_vars['PATCH_VER_NUMBER']   = str(patch)
664          subst_vars['MICRO_VERSION']      = str(patch)
665          subst_vars['BUILD_VER_NUMBER']   = str(build)
666          subst_vars['VER_STRING']         = version_string
667          subst_vars['VERSION_DOT']        = '%d.%d.%d' % (major, minor, patch)
668          subst_vars['SUBSYSTEM']          = 'NSPR'
669          subst_vars['PLATFORM']           = 'Windows'
670          subst_vars['data_subdir']        = 'share'
671          subst_vars['USE_GCC']            = 'no'
672          subst_vars['includedir']         = r'"${prefix}\include"'
673          subst_vars['libdir']             = r'${exec_prefix}\lib'
674
675          try:
676             input_file  = open(template, 'r')
677             input_lines = input_file.readlines()
678             input_file.close()
679
680             for i in xrange(len(input_lines)):
681                input_lines[i] = \
682                   self.subst_re.sub(lambda m: subst_vars.get(m.group(1), ''),
683                                     input_lines[i])
684
685             printStatus("Generating updated " + output)
686             param_header = open(output, 'w')
687             param_header.writelines(input_lines)
688             param_header.close()
689          except IOError, ex:
690             printStatus("ERROR: Could not read from %s" % template)
691             printStatus(ex)
692             printStatus("Cannot continue; exiting with error status.")
693             sys.exit(EXIT_STATUS_MISSING_DATA_FILE)
694
695    mods = []
696    rt_part = ""
697
698    vpr_subst_vars = {}
699    vpr_subst_vars['vpr_cxxflags'] = '/DBOOST_ALL_DYN_LINK /DCPPDOM_DYN_LINK /EHsc /GR'
700    vpr_subst_vars['vpr_ldflags'] = r'/libpath:"$libdir"'
701    vpr_subst_vars['vpr_libs'] = ''
702    vpr_subst_vars['subsystem_libs'] = 'libnspr4.lib libplc4.lib'
703    vpr_subst_vars['BOOST_ROOT'] = r'${fp_file_cwd}\..\..'
704    vpr_subst_vars['BOOST_VERSION_DOT'] = '.'.join(getBoostVersion())
705    vpr_subst_vars['BOOST_INCLUDES'] = r'/I"${prefix}\include"'
706    vpr_subst_vars['BOOST_LDFLAGS'] = r'/libpath:"${prefix}\lib"'
707    vpr_subst_vars['CPPDOM_VERSION'] = '.'.join(getCppDOMVersion())
708    vpr_module = JugglerModule(r'modules\vapor', vcDir, 'VPR', 'VPR_VERSION',
709                               vpr_subst_vars,
710                               [(r'vpr\vprParam.h',), ('vpr.fpc',),
711                                ('boost.fpc',), ('boost_system.fpc',),
712                                ('boost_filesystem.fpc',),
713                                ('boost_signals.fpc',),
714                                (r'vpr\version.rc',
715                                 os.path.join(gJugglerDir, 'version.rc.in'))])
716    mods.append(vpr_module)
717
718    # XXX: These are pretty weak assumptions.
719    tweek_have_cxx  = options.get('OMNIORB_ROOT', '') != ''
720    tweek_have_java = options.get('JAVA_HOME', '') != ''
721
722    tweek_jars = []
723    hack_jars = ['looks.jar', 'liquidlnf.jar', 'metouia.jar']
724    for j in gTweekJars + hack_jars + gJdomJars:
725       tweek_jars.append(os.path.join('${prefix}', 'share', 'tweek', 'java', j))
726
727    tweek_ext_jars = []
728    for j in gTweekExtJars:
729       tweek_ext_jars.append(os.path.join('${prefix}', 'share', 'tweek',
730                                          'java', j))
731
732    tweek_subst_vars = {}
733    tweek_subst_vars['tweek_cxxflags'] = '/EHsc /GR'
734