root/juggler/tags/2.0_beta_1/buildwin32.py

Revision 16443, 76.6 kB (checked in by patrickh, 4 years ago)

Fixed a run-time exception caused by a missing argument when calling
postProcessOptions().

  • Property svn:eol-style set to native
  • 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-2003 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 # -----------------------------------------------------------------
28 # File:          $RCSfile$
29 # Date modified: $Date$
30 # Version:       $Revision$
31 # -----------------------------------------------------------------
32 #
33 # *************** <auto-copyright.pl END do not edit this line> ***************
34
35 import glob
36 import os
37 import re
38 import shutil
39 import sys
40 import time
41 import traceback
42 import getopt
43
44 EXIT_STATUS_SUCCESS           = 0
45 EXIT_STATUS_NO_MSVS           = 1
46 EXIT_STATUS_MISSING_DATA_FILE = 2
47 EXIT_STATUS_MSVS_START_ERROR  = 3
48 EXIT_STATUS_INVALID_PATH      = 4
49 EXIT_STATUS_MISSING_REQ_VALUE = 5
50
51 gJugglerDir      = os.path.dirname(os.path.abspath(sys.argv[0]))
52 gOptionsFileName = "options.cache"
53
54 gHaveTk = False
55 try:
56    import Tkinter
57    import tkMessageBox
58    import tkFileDialog
59    import threading
60    gHaveTk = True
61 except ImportError, ex:
62    print ex
63
64 class BuildOption:
65    def __init__(self, envVar, desc, defaultValue, isDirectory = True,
66                 required = True):
67       self.envVar      = envVar
68       self.desc        = desc
69       self.default     = defaultValue
70       self.required    = required
71       self.isDirectory = isDirectory
72
73 def guessBoostToolset(reattempt = False):
74    (cl_stdin, cl_stdout, cl_stderr) = os.popen3('cl')
75    cl_version_line = cl_stderr.readline()
76
77    cl_ver_match = re.compile(r'Compiler Version ((\d+)\.(\d+)\.(\d+)) for')
78    ver_string_match = cl_ver_match.search(cl_version_line)
79
80    if ver_string_match is not None:
81       cl_major = int(ver_string_match.group(2))
82       cl_minor = int(ver_string_match.group(3))
83
84       if cl_major == 13 and cl_minor < 10:
85          vs_ver = '.NET 2002'
86          boost_tool_guess = 'vc7'
87       else:
88          vs_ver = '.NET 2003'
89          boost_tool_guess = 'vc71'
90
91       printStatus("It appears that we will be using Visual Studio " + vs_ver)
92    else:
93       boost_tool_guess = ''
94
95    in_status  = cl_stdin.close()
96    out_status = cl_stdout.close()
97    err_status = cl_stderr.close()
98
99    # If there was an error closing any of the streams returned by
100    # os.popen3(), then the command was not opened correctly.  That means
101    # that CL.EXE is not in the user's path.
102    if in_status is not None or out_status is not None or err_status is not None:
103       # If this is not a reattempt to guess the Visual Studio version, then
104       # be nice and extend the user's path to include their Visual Studio
105       # installation.
106       if not reattempt:
107          # Common installation directories for Visual Studio 7.x.
108          vs_dirs = [r'C:\Program Files\Microsoft Visual Studio .NET',
109                     r'C:\Program Files\Microsoft Visual Studio .NET 2003']
110
111          for d in vs_dirs:
112             if os.path.exists(d):
113                printStatus("NOTE: Using Visual Studio installation in")
114                printStatus("      " + d)
115                vs_path = [os.path.join(d, r'Common7\IDE'),
116                           os.path.join(d, r'VC7\BIN'),
117                           os.path.join(d, r'Common7\Tools'),
118                           os.path.join(d, r'Common7\Tools\bin\prerelease'),
119                           os.path.join(d, r'Common7\Tools\bin')]
120                path_add = ';'.join(vs_path)
121                os.environ['PATH'] = path_add + os.pathsep + os.getenv('PATH', '')
122
123                # Try again to guess the Visual Studio version.
124                return guessBoostToolset(True)
125
126          # If execution reaches this point, our attempts to guess the
127          # location of a Visual Studio 7.x installation failed.
128          noVisualStudioError()
129
130       # If this is a reattempt to guess the Visual Studio version, then
131       # something is wrong with the user's Visual Studio installation.
132       else:
133          noVisualStudioError()
134
135    return boost_tool_guess
136
137 def printStatus(msg):
138    '''
139    This is a simple wrapper around the standard Python print function.
140    We will use a wrapper function for key status messages so that they
141    can be redirected either to the console or to a GUI easily.
142    '''
143    print msg
144
145 def noVisualStudioError():
146    print "ERROR: Visual Studio commands are not in your path!"
147    print "Run vsvars32.bat in this shell or update the %PATH% environment"
148    print "variable on your system."
149    sys.exit(EXIT_STATUS_NO_MSVS)
150
151 def getCacheFileName():
152    return os.path.join(gJugglerDir, gOptionsFileName)
153
154 def processInput(optionDict, envVar, inputDesc, required = False):
155    default_value = optionDict[envVar]
156    print "  %s [%s]: " % (inputDesc, default_value),
157    input_str = sys.stdin.readline().strip(" \n")
158
159    if input_str == '':
160       if required and (default_value is None or default_value == ''):
161          print "ERROR: %s value required" % inputDesc
162          sys.exit(EXIT_STATUS_MISSING_REQ_VALUE)
163       else:
164          value_str = default_value
165    else:
166       value_str = input_str
167
168    optionDict[envVar] = value_str
169    os.environ[envVar] = value_str
170
171    return value_str
172
173 def getDefaultVars():
174    boost_tool_fallback = guessBoostToolset()
175
176    required = []
177    required.append(BuildOption('BOOST_ROOT',
178                                'Boost C++ installation directory', ''))
179    required.append(BuildOption('BOOST_VERSION', 'Boost C++ version',
180                                '1_31', False))
181    required.append(BuildOption('BOOST_INCLUDES',
182                                'Directory containing the Boost C++ header tree',
183                                ''))
184    required.append(BuildOption('BOOST_TOOL',
185                                'The Boost.Build toolset used to compile Boost C++',
186                                boost_tool_fallback, False))
187    required.append(BuildOption('NSPR_ROOT', 'NSPR installation directory', ''))
188    required.append(BuildOption('CPPDOM_ROOT', 'CppDOM installation directory',
189                                ''))
190    required.append(BuildOption('GMTL_ROOT', 'GMTL installation directory', ''))
191
192    optional = []
193    optional.append(BuildOption('JAVA_HOME', 'Java installation directory',
194                                r'C:\java', required = False))
195    optional.append(BuildOption('JOGL_HOME', 'Jogl installation directory',
196                                os.getenv('JAVA_HOME', ''), required = False))
197    optional.append(BuildOption('JAVA3D_HOME', 'Java 3D installation directory',
198                                os.getenv('JAVA_HOME', ''), required = False))
199    optional.append(BuildOption('OMNIORB_ROOT',
200                                'omniORB installation directory', '',
201                                required = False))
202    optional.append(BuildOption('PFROOT',
203                                'OpenGL Performer installation directory',
204                                r'C:\Program Files\Silicon Graphics\OpenGL Performer',
205                                required = False))
206    optional.append(BuildOption('VRPN_ROOT', 'VRPN installation directory', '',
207                                required = False))
208    optional.append(BuildOption('AUDIERE_ROOT',
209                                'Audiere installation directory', '',
210                                required = False))
211    optional.append(BuildOption('OPENAL_ROOT',
212                                'OpenAL SDK installation directory', '',
213                                required = False))
214    optional.append(BuildOption('TRACKD_API_ROOT',
215                                'TrackdAPI installation directory', '',
216                                required = False))
217
218    options = {
219       'prefix'      : r'C:\vrjuggler',
220       'deps-prefix' : r'C:\vrjuggler-deps'
221    }
222
223    for opt in required + optional:
224       options[opt.envVar] = os.getenv(opt.envVar, opt.default)
225
226    # If there are cached options, read them in.
227    cache_file = getCacheFileName()
228    if os.path.exists(cache_file):
229       execfile(cache_file)
230
231    return required, optional, options
232
233 def setVars():
234    required, optional, options = getDefaultVars()
235
236    print "+++ Required Settings"
237    processInput(options, 'prefix', 'Installation prefix')
238
239    boost_dir = ''
240    boost_ver = ''
241    for opt in required:
242       result = processInput(options, opt.envVar, opt.desc, opt.required)
243
244       # The following is a little hack to get a reasonable default set for
245       # the BOOST_INCLUDES variable before the user has to enter it manually.
246       if opt.envVar == 'BOOST_ROOT':
247          boost_dir = result
248       elif opt.envVar == 'BOOST_VERSION':
249          boost_ver = result
250          options['BOOST_INCLUDES'] = boost_dir + r'\include\boost-' + boost_ver
251
252    print "+++ Optional Settings"
253    processInput(options, 'deps-prefix', 'Dependency installation prefix')
254
255    for opt in optional:
256       processInput(options, opt.envVar, opt.desc, opt.required)
257
258    postProcessOptions(options)
259    writeCacheFile(options)
260
261    return options
262
263 def postProcessOptions(options):
264    # Check for Boost 1.32 Visual C++ toolset names.
265    match = re.compile(r'vc-(\d)_(\d)').match(options['BOOST_TOOL'])
266
267    if match is not None:
268       os.environ['BOOST_TOOL'] = 'vc%s%s' % (match.group(1), match.group(2))
269
270    # If the %JAVA_HOME% setting is a valid directory, add its bin subdirectory
271    # to the path.
272    if os.environ['JAVA_HOME'] != '' and os.path.exists(os.environ['JAVA_HOME']):
273       jdk_path = os.path.join(os.environ['JAVA_HOME'], 'bin')
274       os.environ['PATH'] = jdk_path + os.pathsep + os.environ['PATH']
275       os.environ['JACORB_PATH'] = os.path.join(gJugglerDir, r'external\JacORB')
276
277    if os.environ['OMNIORB_ROOT'] != '' and os.path.exists(os.environ['OMNIORB_ROOT']):
278       omni_bin = os.path.join(os.environ['OMNIORB_ROOT'], 'bin')
279
280       if os.path.exists(os.path.join(omni_bin, 'omniidl.exe')):
281          os.environ['OMNIORB_BIN'] = omni_bin
282       else:
283          os.environ['OMNIORB_BIN'] = os.path.join(omni_bin, 'x86_win32')
284
285       # Extend the path to include omniORB's bin directory.
286       os.environ['PATH'] = os.environ['OMNIORB_BIN'] + os.pathsep + os.environ['PATH']
287
288       omni_lib = os.path.join(os.environ['OMNIORB_ROOT'], 'lib')
289
290       if os.getenv('PYTHONPATH', '') != '':
291          os.environ['PYTHONPATH'] = os.path.join(omni_lib, 'python') + os.pathsep + os.environ['PYTHONPATH']
292       else:
293          os.environ['PYTHONPATH'] = os.path.join(omni_lib, 'python')
294
295       if os.path.exists(os.path.join(omni_lib, 'omnithread.lib')):
296          os.environ['OMNIORB_LIB'] = omni_lib
297       else:
298          os.environ['OMNIORB_LIB'] = os.path.join(omni_lib, 'x86_win32')
299
300       omni_glob = os.path.join(os.environ['OMNIORB_LIB'], 'omniORB*_rt.lib')
301       libs = glob.glob(omni_glob)
302       omni_ver_re = re.compile(r'omniORB(\d\d\d)_rt.lib')
303
304       for l in libs:
305          match = omni_ver_re.search(l)
306          if match is not None:
307             os.environ['OMNIORB_VERSION'] = match.group(1)
308             break
309
310 def writeCacheFile(optionDict):
311    cache_file = open(getCacheFileName(), 'w')
312    for k, v in optionDict.iteritems():
313       output = "options['%s'] = r'%s'\n" % (k, v)
314       cache_file.write(output)
315    cache_file.close()
316
317 def generateVersionHeaders():
318    class JugglerModule:
319       def __init__(self, srcDir, projDir, genFiles = None):
320          self.source_dir     = os.path.join(gJugglerDir, srcDir)
321          self.version_params = os.path.join(self.source_dir, 'Makefile.inc.in')
322          self.version_file   = os.path.join(self.source_dir, 'VERSION')
323          self.param_files    = []
324
325          if genFiles is not None:
326             for f in genFiles:
327                output = os.path.join(gJugglerDir, 'vc7', projDir, f[0])
328
329                if len(f) == 1 or f[1] is None:
330                   template = os.path.join(self.source_dir, f[0] + '.in')
331                else:
332                   template = f[1]
333
334                self.param_files.append((output, template))
335
336       def generateParamFiles(self):
337          for (output, template) in self.param_files:
338             if os.path.exists(output):
339                mtime = os.path.getmtime
340                # This test to determine if the module's param header needs to
341                # be regenerated is equivalent to that used by the UNIX build
342                # system.
343                if mtime(self.version_file) > mtime(output) or \
344                   mtime(template) > mtime(output):
345                   self.__genParamFile(output, template)
346             else:
347                self.__genParamFile(output, template)
348
349       version_re      = re.compile(r'((\d+)\.(\d+)\.(\d+)-(\d+))\s')
350       branch_re       = re.compile(r'BRANCH\s*=\s*(\w+)')
351       canon_name_re   = re.compile(r'CANON_NAME\s*=\s*(\S.+)')
352       vernum_re       = re.compile(r'@VER_NUMBER@')
353       major_vernum_re = re.compile(r'@MAJOR_VER_NUMBER@')
354       minor_vernum_re = re.compile(r'@MINOR_VER_NUMBER@')
355       patch_vernum_re = re.compile(r'@PATCH_VER_NUMBER@')
356       verstr_re       = re.compile(r'@VER_STRING@')
357       zero_strip_re   = re.compile(r'^0*([^0]\d+)')
358
359       def __genParamFile(self, output, template):
360          ver_file = open(self.version_file)
361          cur_ver  = ver_file.readline()
362          ver_file.close()
363          ver_match = self.version_re.match(cur_ver)
364          version = ver_match.group(1)
365          major   = int(ver_match.group(2))
366          minor   = int(ver_match.group(3))
367          patch   = int(ver_match.group(4))
368
369          # NOTE: This will not always be identical to the UNIX version because
370          # Python does not have %e as a time formatting directive.
371          date       = time.strftime('%b %d, %Y %H:%M:%S')
372          canon_name = ''
373          branch     = ''
374
375          param_file = open(self.version_params, 'r')
376          params     = param_file.readlines()
377          param_file.close()
378
379          # This is basically a poor man's grep.  Can this be done better?
380          for line in params:
381             match = self.branch_re.match(line)
382             if match is not None:
383                branch_name = match.group(1)
384                continue
385
386             match = self.canon_name_re.match(line)
387             if match is not None:
388                canon_name = match.group(1)
389                continue
390
391          version_number = '%03d%03d%03d' % (major, minor, patch)
392          version_string = "\"v%s '%s' (NSPR) %s %s\"" % \
393                              (version, canon_name, branch, date)
394
395          # Strip leading zeroes from version_number.  Is there an easier way
396          # to do this?
397          version_number = self.zero_strip_re.match(version_number).group(1)
398
399          try:
400             input_file  = open(template, 'r')
401             input_lines = input_file.readlines()
402             input_file.close()
403
404             for i in xrange(len(input_lines)):
405                line = input_lines[i]
406                if self.vernum_re.search(line):
407                   input_lines[i] = self.vernum_re.sub(version_number, line)
408                elif self.major_vernum_re.search(line):
409                   input_lines[i] = self.major_vernum_re.sub(str(major), line)
410                elif self.minor_vernum_re.search(line):
411                   input_lines[i] = self.minor_vernum_re.sub(str(minor), line)
412                elif self.patch_vernum_re.search(line):
413                   input_lines[i] = self.patch_vernum_re.sub(str(patch), line)
414                elif self.verstr_re.search(line):
415                   input_lines[i] = self.verstr_re.sub(version_string, line)
416
417             printStatus("Generating updated " + output)
418             param_header = open(output, 'w')
419             param_header.writelines(input_lines)
420             param_header.close()
421          except IOError, ex:
422             printStatus("ERROR: Could not read from %s" % template)
423             printStatus(ex)
424             printStatus("Cannot continue; exiting with error status.")
425             sys.exit(EXIT_STATUS_MISSING_DATA_FILE)
426
427    mods = []
428    mods.append(JugglerModule(r'modules\vapor', 'VPR',
429                              [(r'vpr\vprParam.h',), (r'vpr\vprParam.cpp',)]))
430    mods.append(JugglerModule(r'modules\tweek', 'Tweek_CXX',
431                              [(r'tweek\tweekParam.h',),
432                               (r'tweek\tweekParam.cpp',)]))
433    mods.append(JugglerModule(r'modules\jackal', 'JCCL',
434                              [(r'jccl\jcclParam.h',
435                                os.path.join(gJugglerDir,
436                                             r'modules\jackal\common\jccl\jcclParam.h.in')),
437                               (r'jccl\jcclParam.cpp',
438                                os.path.join(gJugglerDir,
439                                             r'modules\jackal\common\jccl\jcclParam.cpp.in'))
440                              ]))
441    mods.append(JugglerModule(r'modules\sonix', 'Sonix',
442                              [(r'snx\snxParam.h',), (r'snx\snxParam.cpp',)]))
443    mods.append(JugglerModule(r'modules\gadgeteer', 'Gadgeteer',
444                              [(r'gadget\gadgetParam.h',),
445                               (r'gadget\gadgetParam.cpp',)]))
446    mods.append(JugglerModule(r'modules\vrjuggler', 'VRJuggler',
447                              [(r'vrj\vrjParam.h',), (r'vrj\vrjParam.cpp',)]))
448
449    for m in mods:
450       m.generateParamFiles()
451
452 def generateAntBuildFiles():
453    class AntTarget:
454       def __init__(self, srcdir, moduleName, outputFile = 'build.xml'):
455          self.srcdir      = os.path.join(gJugglerDir, srcdir)
456          self.topdir      = os.path.join(gJugglerDir, r'vc7')
457          self.module_name = os.path.join(self.topdir, moduleName)
458          self.output_file = os.path.join(self.module_name, outputFile)
459
460          if not os.path.exists(self.module_name):
461             os.mkdir(self.module_name)
462          elif not os.path.isdir(self.module_name):
463             printStatus("ERROR: %s exists, but it is not a directory!" % self.module_name)
464             sys.exit(EXIT_STATUS_INVALID_PATH)
465
466       # This form of regular expressions appears to be necessary because
467       # the sub() method does not handle backslashes in the replacement string
468       # the way I would like.
469       srcdir_re         = re.compile(r'^(.*)@srcdir@(.*)$')
470       topdir_re         = re.compile(r'^(.*)@topdir@(.*)$')
471       juggler_root_re   = re.compile(r'^(.*)@JUGGLERROOT_ABS@(.*)$')
472       jdom_jar_re       = re.compile(r'^(.*)@JDOM_JAR@(.*)$')
473       tweek_jars_re     = re.compile(r'^(.*)@TWEEK_JARS@(.*)$')
474       tweek_ext_jars_re = re.compile(r'^(.*)@TWEEK_EXT_JARS@(.*)$')
475       jccl_jars_re      = re.compile(r'^(.*)@JCCL_JARS@(.*)$')
476       java_orb_jar_re   = re.compile(r'^(.*)@JAVA_ORB_JAR@(.*)$')
477       jogl_jars_re      = re.compile(r'^(.*)@JOGL_JARS@(.*)$')
478       java3d_jars_re    = re.compile(r'^(.*)@JAVA3D_JAR@(.*)$')
479
480       jdom_jars = [
481          os.path.join(gJugglerDir, r'external\jdom\build\jdom.jar'),
482          os.path.join(gJugglerDir, r'external\jdom\lib\jaxen-core.jar'),
483          os.path.join(gJugglerDir, r'external\jdom\lib\xalan.jar'),
484          os.path.join(gJugglerDir, r'external\jdom\lib\jaxen-jdom.jar'),
485          os.path.join(gJugglerDir, r'external\jdom\lib\xerces.jar'),
486          os.path.join(gJugglerDir, r'external\jdom\lib\xml-apis.jar'),
487          os.path.join(gJugglerDir, r'external\jdom\lib\saxpath.jar')
488       ]
489
490       tweek_jars = [
491          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'Tweek.jar'),
492          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'TweekBeans.jar'),
493          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'TweekEvents.jar'),
494          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'TweekNet.jar'),
495          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'TweekBeanDelivery.jar'),
496          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'TweekServices.jar'),
497          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'Viewers.jar'),
498          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'kunststoff-mod.jar')
499       ]
500
501       tweek_ext_jars = [
502          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'ui.jar'),
503          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'wizard.jar'),
504          os.path.join(gJugglerDir, r'vc7\Tweek_Java', 'WizardBuilder.jar')
505       ]
506
507       jccl_jars = [
508          os.path.join(gJugglerDir, r'vc7\JCCL_Java', 'jccl_config.jar'),
509          os.path.join(gJugglerDir, r'vc7\JCCL_Java', 'jccl_editors.jar')
510       ]
511
512       jccl_rtrc_jars = [
513          os.path.join(gJugglerDir, r'vc7\JCCL_Java\RTRC_Plugin_Java',
514                       'jccl_rtrc.jar')
515       ]
516
517       jogl_jars = [
518          os.path.join(os.environ['JOGL_HOME'], 'jogl.jar'),
519          os.path.join(os.environ['JOGL_HOME'], 'jogl-demos-util.jar')
520       ]
521
522       java3d_jars = [
523          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\j3daudio.jar'),
524          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\j3dcore.jar'),
525          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\j3dutils.jar'),
526          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\vecmath.jar')
527       ]
528
529       def generateBuildFile(self):
530          input_file = open(os.path.join(self.srcdir, 'build.xml.in'), 'r')
531          input = input_file.readlines()
532          input_file.close()
533
534          for i in xrange(len(input)):
535             line = input[i]
536
537             if self.srcdir_re.search(line):
538                match = self.srcdir_re.search(line)
539                input[i] = '%s%s%s\n' % (match.groups()[0], self.srcdir,
540                                         match.groups()[1])
541             elif self.topdir_re.search(line):
542                match = self.topdir_re.search(line)
543                input[i] = '%s%s%s\n' % (match.groups()[0], self.topdir,
544                                         match.groups()[1])
545             elif self.juggler_root_re.search(line):
546                match = self.juggler_root_re.search(line)
547                input[i] = '%s%s%s\n' % (match.groups()[0], gJugglerDir,
548                                         match.groups()[1])
549             elif self.java_orb_jar_re.search(line):
550                match = self.java_orb_jar_re.search(line)
551                input[i] = '%s%s%s\n' % (match.groups()[0], "",
552                                         match.groups()[1])
553             elif self.jdom_jar_re.search(line):
554                jars = os.pathsep.join(self.jdom_jars)
555                match = self.jdom_jar_re.search(line)
556                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
557                                         match.groups()[1])
558             elif self.tweek_jars_re.search(line):
559                jars = os.pathsep.join(self.tweek_jars + self.jdom_jars)
560                match = self.tweek_jars_re.search(line)
561                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
562                                         match.groups()[1])
563             elif self.tweek_ext_jars_re.search(line):
564                jars = os.pathsep.join(self.tweek_ext_jars)
565                match = self.tweek_ext_jars_re.search(line)
566                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
567                                         match.groups()[1])
568             elif self.jccl_jars_re.search(line):
569                jars = os.pathsep.join(self.jccl_jars + self.jccl_rtrc_jars)
570                match = self.jccl_jars_re.search(line)
571                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
572                                         match.groups()[1])
573             elif self.jogl_jars_re.search(line):
574                jars = os.pathsep.join(self.jogl_jars)
575                match = self.jogl_jars_re.search(line)
576                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
577                                         match.groups()[1])
578             elif self.java3d_jars_re.search(line):
579                jars = os.pathsep.join(self.java3d_jars)
580                match = self.java3d_jars_re.search(line)
581                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
582                                         match.groups()[1])
583
584          build_file = open(self.output_file, 'w')
585          build_file.writelines(input)
586          build_file.close()
587
588    mods = []
589    mods.append(AntTarget(r'modules\tweek\java', 'Tweek_Java'))
590    mods.append(AntTarget(r'modules\tweek\extensions\java', 'Tweek_Java',
591                          'build-ext.xml'))
592    mods.append(AntTarget(r'modules\jackal\config', 'JCCL_Java',
593                          'build-config.xml'))
594    mods.append(AntTarget(r'modules\jackal\editors', 'JCCL_Java',
595                          'build-editors.xml'))
596    mods.append(AntTarget(r'modules\jackal\plugins\corba_rtrc',
597                          r'JCCL_Java\RTRC_Plugin_Java', 'build.xml'))
598    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig', 'VRJConfig',
599                          'build.xml'))
600    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig\commoneditors',
601                          r'VRJConfig\commoneditors',
602                          'build-commoneditors.xml'))
603    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig\customeditors\display_window',
604                          'VRJConfig', 'build-display_window.xml'))
605    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig\customeditors\intersense',
606                          'VRJConfig', 'build-intersense.xml'))
607    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig\customeditors\pinchglove',
608                          'VRJConfig', 'build-pinchglove.xml'))
609    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig\customeditors\proxyeditor',
610                          'VRJConfig', 'build-proxyeditor.xml'))
611    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig\customeditors\surfacedisplayeditor',
612                          'VRJConfig', 'build-surfacedisplayeditor.xml'))
613    mods.append(AntTarget(r'modules\vrjuggler\plugins\corba_perf_mon',
614                          r'VRJugglerPlugins\Perf_Plugin_Java', 'build.xml'))
615
616    for m in mods:
617       m.generateBuildFile()
618
619 def doInstall(prefix):
620    makeTree(prefix)
621    installExternal(prefix)
622    installVPR(prefix)
623    installTweek(prefix)
624    installTweekJava(prefix)
625    installJCCL(prefix)
626    installJCCLJava(prefix)
627    installJCCLPlugins(prefix)
628    installJCCLPluginsJava(prefix)
629    installSonix(prefix)
630    installSonixPlugins(prefix)
631    installGadgeteer(prefix)
632    installGadgeteerDrivers(prefix)
633    installGadgeteerPlugins(prefix)
634    installVRJuggler(prefix)
635    installVRJConfig(prefix)
636    installVRJugglerPlugins(prefix)
637    installVRJugglerPluginsJava(prefix)
638    installMsvcRT(prefix)
639
640 def mkinstalldirs(dir):
641 #   print "Checking for", dir
642    if not os.path.exists(dir):
643       (head, tail) = os.path.split(dir)
644       mkinstalldirs(head)
645       os.mkdir(dir)
646
647 def makeTree(prefix):
648    mkinstalldirs(os.path.join(prefix, 'bin'))
649    mkinstalldirs(os.path.join(prefix, 'include'))
650    mkinstalldirs(os.path.join(prefix, 'lib'))
651    mkinstalldirs(os.path.join(prefix, 'share'))
652
653 def installDir(startDir, destDir, allowedExts = None, disallowedExts = None,
654                disallowedFiles = None):
655    cwd = os.getcwd()
656    mkinstalldirs(destDir)
657
658    os.chdir(startDir)
659    contents = os.listdir(startDir)
660
661    if disallowedExts is None:
662       disallowedExts = []
663
664    if disallowedFiles is None:
665       disallowedFiles = []
666
667    # Add some extensions that should always be disallowed.  This relieves the
668    # caller from having to add these repeatedly.
669    disallowedExts.append('.ilk')
670    disallowedExts.append('.ncb')
671    disallowedExts.append('.pdb')
672    disallowedExts.append('.suo')
673
674    skip_dirs = ['CVS', 'autom4te.cache']
675    for f in contents:
676       if os.path.isdir(f):
677          if f in skip_dirs:
678             continue
679
680          start_dir = os.path.join(startDir, f)
681          dest_dir  = os.path.join(destDir, f)
682          installDir(start_dir, dest_dir, allowedExts, disallowedExts)
683       else:
684          (root, f_ext) = os.path.splitext(f)
685          if allowedExts is None:
686             if f_ext not in disallowedExts:
687                shutil.copy2(f, destDir)
688          elif f_ext in allowedExts:
689             (head, tail) = os.path.split(f)
690             if f not in disallowedFiles:
691                shutil.copy2(f, destDir)
692
693    os.chdir(cwd)
694
695 def installLibs(srcRoot, destdir,
696                 buildTypes = ['ReleaseDLL', 'DebugDLL', 'Release', 'Debug'],
697                 extensions = ['.dll', '.lib']):
698    for t in buildTypes:
699       srcdir = os.path.join(srcRoot, t)
700       if os.path.exists(srcdir):
701          installDir(srcdir, destdir, extensions)
702
703 def installExternal(prefix):
704    # Install Doozer (even though it probably won't be used).
705    printStatus("Installing Doozer ...")
706    destdir = os.path.join(prefix, 'share', 'Doozer')
707    srcdir  = os.path.join(gJugglerDir, 'external', 'Doozer')
708    installDir(srcdir, destdir, ['.mk'])
709
710 def installVPR(prefix):
711    printStatus("Installing VPR headers and libraries ...")
712
713    destdir = os.path.join(prefix, 'include', 'vpr')
714    srcdir  = os.path.join(gJugglerDir, 'modules', 'vapor', 'vpr')
715    installDir(srcdir, destdir, ['.h'])
716
717    srcdir  = os.path.join(gJugglerDir, 'vc7', 'VPR', 'vpr')
718    installDir(srcdir, destdir, ['.h'])
719
720    destdir = os.path.join(prefix, 'lib')
721    srcroot = os.path.join(gJugglerDir, 'vc7', 'VPR')
722    installLibs(srcroot, destdir)
723
724    destdir = os.path.join(prefix, 'share', 'vpr', 'test')
725    srcdir  = os.path.join(gJugglerDir, 'modules', 'vapor', 'test')
726    installDir(srcdir, destdir, None, ['.in'])
727
728    # Install additional files into <prefix>\share\vpr
729    destdir = os.path.join(prefix, 'share', 'vpr')
730    srcroot = os.path.join(gJugglerDir, 'modules', 'vapor')
731
732    shutil.copy2(os.path.join(gJugglerDir, 'COPYING.txt'), destdir)
733    extra_files = ['ChangeLog', 'README.txt', 'RELEASE_NOTES.txt']
734    for f in extra_files:
735       shutil.copy2(os.path.join(srcroot, f), destdir)
736
737 def installTweek(prefix):
738    printStatus("Installing Tweek C++ headers, libraries, and data files ...")