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

Revision 17596, 80.3 kB (checked in by patrickh, 3 years ago)

Fixed the Windows build by ensuring that VJ_ROOT_DIR is defined correctly
where it is needed. BTW, whoever decided that it would be a good idea to
use '\' as a directory separator when it was already widely used as the
start of an escape sequence should be smacked.

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