root/juggler/branches/2.0/buildwin32.py

Revision 19814, 87.2 kB (checked in by patrick, 2 years ago)

MFT [rev 19806]: Replaced hard-coded exit values with symbolic identifiers.

Added an exit status for an invalid command line argument.

  • 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-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, os.path
37 import re
38 import shutil
39 import sys
40 import time
41 import traceback
42 import getopt
43 pj = os.path.join
44
45 EXIT_STATUS_SUCCESS           = 0
46 EXIT_STATUS_NO_MSVS           = 1
47 EXIT_STATUS_MISSING_DATA_FILE = 2
48 EXIT_STATUS_MSVS_START_ERROR  = 3
49 EXIT_STATUS_INVALID_PATH      = 4
50 EXIT_STATUS_MISSING_REQ_VALUE = 5
51 EXIT_STATUS_INVALID_ARGUMENT  = 6
52
53 gJugglerDir      = os.path.dirname(os.path.abspath(sys.argv[0]))
54 gOptionsFileName = "options.cache"
55
56 gHaveTk = False
57 try:
58    import Tkinter
59    import tkMessageBox
60    import tkFileDialog
61    import threading
62    gHaveTk = True
63 except ImportError, ex:
64    print ex
65
66 class BuildOption:
67    def __init__(self, envVar, desc, defaultValue, isDirectory = True,
68                 required = True):
69       self.envVar      = envVar
70       self.desc        = desc
71       self.default     = defaultValue
72       self.required    = required
73       self.isDirectory = isDirectory
74
75 def detectVisualStudioVersion(reattempt = False):
76    (cl_stdin, cl_stdout, cl_stderr) = os.popen3('cl')
77    cl_version_line = cl_stderr.readline()
78
79    cl_ver_match = re.compile(r'Compiler Version ((\d+)\.(\d+)\.(\d+))')
80    ver_string_match = cl_ver_match.search(cl_version_line)
81
82    if ver_string_match is not None:
83       cl_major = int(ver_string_match.group(2))
84       cl_minor = int(ver_string_match.group(3))
85
86       if cl_major == 13 and cl_minor < 10:
87          vs_ver = '.NET 2002'
88       elif cl_major == 13 and cl_minor >= 10:
89          vs_ver = '.NET 2003'
90       else:
91          vs_ver = '2005'
92
93       printStatus("It appears that we will be using Visual Studio " + vs_ver)
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                     r'C:\Program Files\Microsoft Visual Studio 8'
111                    ]
112
113          for d in vs_dirs:
114             if os.path.exists(d):
115                printStatus("NOTE: Using Visual Studio installation in")
116                printStatus("      " + d)
117                vs_path = [os.path.join(d, r'Common7\IDE'),
118                           os.path.join(d, r'VC7\BIN'),
119                           os.path.join(d, r'VC\BIN'),
120                           os.path.join(d, r'Common7\Tools'),
121                           os.path.join(d, r'Common7\Tools\bin\prerelease'),
122                           os.path.join(d, r'Common7\Tools\bin')]
123                path_add = ';'.join(vs_path)
124                os.environ['PATH'] = path_add + os.pathsep + os.getenv('PATH', '')
125
126                # Try again to guess the Visual Studio version.
127                return detectVisualStudioVersion(True)
128
129          # If execution reaches this point, our attempts to guess the
130          # location of a Visual Studio 7.x installation failed.
131          noVisualStudioError()
132
133       # If this is a reattempt to guess the Visual Studio version, then
134       # something is wrong with the user's Visual Studio installation.
135       else:
136          noVisualStudioError()
137
138 def printStatus(msg):
139    '''
140    This is a simple wrapper around the standard Python print function.
141    We will use a wrapper function for key status messages so that they
142    can be redirected either to the console or to a GUI easily.
143    '''
144    print msg
145
146 def noVisualStudioError():
147    print "ERROR: Visual Studio commands are not in your path!"
148    print "Run vsvars32.bat in this shell or update the %PATH% environment"
149    print "variable on your system."
150    sys.exit(EXIT_STATUS_NO_MSVS)
151
152 def getCacheFileName():
153    return os.path.join(gJugglerDir, gOptionsFileName)
154
155 def processInput(optionDict, envVar, inputDesc, required = False):
156    default_value = optionDict[envVar]
157    print "  %s [%s]: " % (inputDesc, default_value),
158    input_str = sys.stdin.readline().strip(" \n")
159
160    if input_str == '':
161       if required and (default_value is None or default_value == ''):
162          print "ERROR: %s value required" % inputDesc
163          sys.exit(EXIT_STATUS_MISSING_REQ_VALUE)
164       else:
165          value_str = default_value
166    else:
167       value_str = input_str
168
169    optionDict[envVar] = value_str
170    os.environ[envVar] = value_str
171
172    return value_str
173
174 def getDefaultVars():
175    detectVisualStudioVersion()
176
177    required = []
178    required.append(BuildOption('BOOST_ROOT',
179                                'Boost C++ installation directory', ''))
180    required.append(BuildOption('BOOST_VERSION', 'Boost C++ version',
181                                '1_31', False))
182    required.append(BuildOption('BOOST_INCLUDES',
183                                'Directory containing the Boost C++ header tree',
184                                ''))
185    required.append(BuildOption('NSPR_ROOT', 'NSPR installation directory', ''))
186    required.append(BuildOption('CPPDOM_ROOT', 'CppDOM installation directory',
187                                ''))
188    required.append(BuildOption('CPPDOM_INCLUDES',
189                                'Directory containing the CppDOM header tree',
190                                ''))
191    required.append(BuildOption('GMTL_ROOT', 'GMTL installation directory', ''))
192    required.append(BuildOption('GMTL_INCLUDES',
193                                'Directory containing the GMTL header tree',
194                                ''))
195
196    optional = []
197    optional.append(BuildOption('JAVA_HOME', 'Java installation directory',
198                                r'C:\java', required = False))
199    optional.append(BuildOption('JOGL_HOME', 'Jogl installation directory',
200                                os.getenv('JAVA_HOME', ''), required = False))
201    optional.append(BuildOption('JAVA3D_HOME', 'Java 3D installation directory',
202                                os.getenv('JAVA_HOME', ''), required = False))
203    optional.append(BuildOption('OMNIORB_ROOT',
204                                'omniORB installation directory', '',
205                                required = False))
206    optional.append(BuildOption('PFROOT',
207                                'OpenGL Performer installation directory',
208                                r'C:\Program Files\Silicon Graphics\OpenGL Performer',
209                                required = False))
210    optional.append(BuildOption('MS_SPEECH_SDK_ROOT',
211                                'Microsoft Speech SDK directory', '',
212                                required = False))
213    optional.append(BuildOption('VRPN_ROOT', 'VRPN installation directory', '',
214                                required = False))
215    optional.append(BuildOption('AUDIERE_ROOT',
216                                'Audiere installation directory', '',
217                                required = False))
218    optional.append(BuildOption('OPENAL_ROOT',
219                                'OpenAL SDK installation directory', '',
220                                required = False))
221    optional.append(BuildOption('ALUT_ROOT', 'ALUT 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' and \
258            options.get('BOOST_INCLUDES', '') == '':
259          boost_ver = result
260          options['BOOST_INCLUDES'] = boost_dir + r'\include\boost-' + boost_ver
261
262       # The following is a little hack to get a reasonable default set for
263       # the CPPDOM_INCLUDES variable before the user has to enter it manually.
264       if opt.envVar == 'CPPDOM_ROOT' and \
265          options.get('CPPDOM_INCLUDES', '') == '':
266          options['CPPDOM_INCLUDES'] = os.path.join(result, 'include')
267
268       # The following is a little hack to get a reasonable default set for
269       # the GMTL_INCLUDES variable before the user has to enter it manually.
270       if opt.envVar == 'GMTL_ROOT' and \
271          options.get('GMTL_INCLUDES', '') == '':
272          options['GMTL_INCLUDES'] = os.path.join(result, 'include')
273
274    print "+++ Optional Settings"
275    processInput(options, 'deps-prefix', 'Dependency installation prefix')
276
277    for opt in optional:
278       processInput(options, opt.envVar, opt.desc, opt.required)
279
280    postProcessOptions(options)
281    writeCacheFile(options)
282
283    return options
284
285 def postProcessOptions(options):
286    os.environ['instprefix'] = options['prefix'].replace('\\', '\\\\')
287
288    # If the %JAVA_HOME% setting is a valid directory, add its bin subdirectory
289    # to the path.
290    if os.environ['JAVA_HOME'] != '' and os.path.exists(os.environ['JAVA_HOME']):
291       jdk_path = os.path.join(os.environ['JAVA_HOME'], 'bin')
292       os.environ['PATH'] = jdk_path + os.pathsep + os.environ['PATH']
293       os.environ['JACORB_PATH'] = os.path.join(gJugglerDir, r'external\JacORB')
294
295    if os.environ['OMNIORB_ROOT'] != '' and os.path.exists(os.environ['OMNIORB_ROOT']):
296       omni_bin = os.path.join(os.environ['OMNIORB_ROOT'], 'bin')
297
298       if os.path.exists(os.path.join(omni_bin, 'omniidl.exe')):
299          os.environ['OMNIORB_BIN'] = omni_bin
300       else:
301          os.environ['OMNIORB_BIN'] = os.path.join(omni_bin, 'x86_win32')
302
303       # Extend the path to include omniORB's bin directory.
304       os.environ['PATH'] = os.environ['OMNIORB_BIN'] + os.pathsep + os.environ['PATH']
305
306       omni_lib = os.path.join(os.environ['OMNIORB_ROOT'], 'lib')
307
308       if os.getenv('PYTHONPATH', '') != '':
309          os.environ['PYTHONPATH'] = os.path.join(omni_lib, 'python') + os.pathsep + os.environ['PYTHONPATH']
310       else:
311          os.environ['PYTHONPATH'] = os.path.join(omni_lib, 'python')
312
313       if os.path.exists(os.path.join(omni_lib, 'omnithread.lib')):
314          os.environ['OMNIORB_LIB'] = omni_lib
315       else:
316          os.environ['OMNIORB_LIB'] = os.path.join(omni_lib, 'x86_win32')
317
318       omni_glob = os.path.join(os.environ['OMNIORB_LIB'], 'omniORB*_rt.lib')
319       libs = glob.glob(omni_glob)
320       omni_ver_re = re.compile(r'omniORB(\d\d\d)_rt.lib')
321
322       for l in libs:
323          match = omni_ver_re.search(l)
324          if match is not None:
325             os.environ['OMNIORB_VERSION'] = match.group(1)
326             break
327
328       omnithread_glob = os.path.join(os.environ['OMNIORB_LIB'],
329                                      'omnithread*_rt.lib')
330       libs = glob.glob(omnithread_glob)
331       omnithread_ver_re = re.compile(r'omnithread(\d\d)_rt.lib')
332
333       for l in libs:
334          match = omnithread_ver_re.search(l)
335          if match is not None:
336             os.environ['OMNITHREAD_VERSION'] = match.group(1)
337             break
338
339    # Determine if al.h is in the base include directory or in include\AL.
340    if os.environ['OPENAL_ROOT'] != '':
341       # TODO: Extend for Win64.
342       lib_dirs = [os.path.join(os.environ['OPENAL_ROOT'], 'libs'),
343                   os.path.join(os.environ['OPENAL_ROOT'], 'libs', 'Win32')]
344
345       for l in lib_dirs:
346          openal_lib = os.path.join(l, 'OpenAL32.lib')
347          if os.path.exists(openal_lib):
348             os.environ['OPENAL_LIB_DIR'] = l
349             break
350
351       header_file = os.path.join(os.environ['OPENAL_ROOT'], 'include', 'AL',
352                                  'al.h')
353       # If the file is include\AL\al.h, then set the environment variable
354       # %HAVE_AL_AL_H% to the preprocessor symbol 'HAVE_AL_AL_H'.
355       # See modules/sonix/plugins/OpenAL/OpenALSoundImplementation.cpp.
356       if os.path.exists(header_file):
357          os.environ['HAVE_AL_AL_H'] = 'HAVE_AL_AL_H'
358
359    # Determine if alut.h is in the base include directory or in include\AL.
360    openal_envs = ['ALUT_ROOT', 'OPENAL_ROOT']
361    for env in openal_envs:
362       if os.environ[env] != '':
363          header_file = os.path.join(os.environ[env], 'include', 'AL', 'alut.h')
364          # If the file is include\AL\alut.h, then set the environment variable
365          # %HAVE_AL_ALUT_H% to the preprocessor symbol 'HAVE_AL_ALUT_H'.
366          # See modules/sonix/plugins/OpenAL/OpenALSoundImplementation.cpp.
367          if os.path.exists(header_file):
368             os.environ['HAVE_AL_ALUT_H'] = 'HAVE_AL_ALUT_H'
369
370    # If the ALUT installation directory is not set, then assume that it is the
371    # same as the OpenAL installation directory.
372    if os.environ['ALUT_ROOT'] == '' and os.environ['OPENAL_ROOT'] != '':
373       os.environ['ALUT_ROOT'] = os.environ['OPENAL_ROOT']
374
375    if os.environ['TRACKD_API_ROOT'] != '' and os.path.exists(os.environ['TRACKD_API_ROOT']):
376       trackdapi_dir = os.environ['TRACKD_API_ROOT']
377       trackdapi_incdir = os.path.join(trackdapi_dir, 'include')
378
379       # Figure out which Trackd API header to include.
380       headers = ['trackdAPI.h', 'trackdAPI_CC.h']
381       for h in headers:
382          if os.path.exists(os.path.join(trackdapi_incdir, h)):
383             os.environ['GADGET_TRACKD_API_H'] = '<%s>' % h
384             break
385
386 def writeCacheFile(optionDict):
387    cache_file = open(getCacheFileName(), 'w')
388    for k, v in optionDict.iteritems():
389       output = "options['%s'] = r'%s'\n" % (k, v)
390       cache_file.write(output)
391    cache_file.close()
392
393 def generateVersionHeaders(vcDir):
394    class JugglerModule:
395       def __init__(self, srcDir, vcDir, projDir, genFiles = None):
396          self.source_dir     = os.path.join(gJugglerDir, srcDir)
397          self.version_params = os.path.join(self.source_dir, 'Makefile.inc.in')
398          self.version_file   = os.path.join(self.source_dir, 'VERSION')
399          self.param_files    = []
400
401          if genFiles is not None:
402             for f in genFiles:
403                output = os.path.join(gJugglerDir, vcDir, projDir, f[0])
404
405                if len(f) == 1 or f[1] is None:
406                   template = os.path.join(self.source_dir, f[0] + '.in')
407                else:
408                   template = f[1]
409
410                self.param_files.append((output, template))
411
412       def generateParamFiles(self):
413          for (output, template) in self.param_files:
414             if os.path.exists(output):
415                mtime = os.path.getmtime
416                # This test to determine if the module's param header needs to
417                # be regenerated is equivalent to that used by the UNIX build
418                # system.
419                if mtime(self.version_file) > mtime(output) or \
420                   mtime(template) > mtime(output):
421                   self.__genParamFile(output, template)
422             else:
423                self.__genParamFile(output, template)
424
425       version_re      = re.compile(r'((\d+)\.(\d+)\.(\d+)-(\d+))\s')
426       branch_re       = re.compile(r'BRANCH\s*=\s*(.+)')
427       canon_name_re   = re.compile(r'CANON_NAME\s*=\s*(\S.+)')
428       vernum_re       = re.compile(r'@VER_NUMBER@')
429       major_vernum_re = re.compile(r'@MAJOR_VER_NUMBER@')
430       minor_vernum_re = re.compile(r'@MINOR_VER_NUMBER@')
431       patch_vernum_re = re.compile(r'@PATCH_VER_NUMBER@')
432       verstr_re       = re.compile(r'@VER_STRING@')
433       zero_strip_re   = re.compile(r'^0*([^0]\d+)')
434
435       def __genParamFile(self, output, template):
436          ver_file = open(self.version_file)
437          cur_ver  = ver_file.readline()
438          ver_file.close()
439          ver_match = self.version_re.match(cur_ver)
440          version = ver_match.group(1)
441          major   = int(ver_match.group(2))
442          minor   = int(ver_match.group(3))
443          patch   = int(ver_match.group(4))
444
445          # NOTE: This will not always be identical to the UNIX version because
446          # Python does not have %e as a time formatting directive.
447          date       = time.strftime('%b %d, %Y %H:%M:%S')
448          canon_name = ''
449          branch     = ''
450
451          param_file = open(self.version_params, 'r')
452          params     = param_file.readlines()
453          param_file.close()
454
455          # This is basically a poor man's grep.  Can this be done better?
456          for line in params:
457             match = self.branch_re.match(line)
458             if match is not None:
459                branch = match.group(1)
460                continue
461
462             match = self.canon_name_re.match(line)
463             if match is not None:
464                canon_name = match.group(1)
465                continue
466
467          version_number = '%03d%03d%03d' % (major, minor, patch)
468          version_string = "\"v%s '%s' (NSPR) %s %s\"" % \
469                              (version, canon_name, branch, date)
470
471          # Strip leading zeroes from version_number.  Is there an easier way
472          # to do this?
473          version_number = self.zero_strip_re.match(version_number).group(1)
474
475          try:
476             input_file  = open(template, 'r')
477             input_lines = input_file.readlines()
478             input_file.close()
479
480             for i in xrange(len(input_lines)):
481                line = input_lines[i]
482                if self.vernum_re.search(line):
483                   input_lines[i] = self.vernum_re.sub(version_number, line)
484                elif self.major_vernum_re.search(line):
485                   input_lines[i] = self.major_vernum_re.sub(str(major), line)
486                elif self.minor_vernum_re.search(line):
487                   input_lines[i] = self.minor_vernum_re.sub(str(minor), line)
488                elif self.patch_vernum_re.search(line):
489                   input_lines[i] = self.patch_vernum_re.sub(str(patch), line)
490                elif self.verstr_re.search(line):
491                   input_lines[i] = self.verstr_re.sub(version_string, line)
492
493             printStatus("Generating updated " + output)
494             param_header = open(output, 'w')
495             param_header.writelines(input_lines)
496             param_header.close()
497          except IOError, ex:
498             printStatus("ERROR: Could not read from %s" % template)
499             printStatus(ex)
500             printStatus("Cannot continue; exiting with error status.")
501             sys.exit(EXIT_STATUS_MISSING_DATA_FILE)
502
503    mods = []
504    mods.append(JugglerModule(r'modules\vapor', vcDir, 'VPR',
505                              [(r'vpr\vprParam.h',), (r'vpr\vprParam.cpp',)]))
506    mods.append(JugglerModule(r'modules\tweek', vcDir, 'Tweek_CXX',
507                              [(r'tweek\tweekParam.h',),
508                               (r'tweek\tweekParam.cpp',)]))
509    mods.append(JugglerModule(r'modules\jackal', vcDir, 'JCCL',
510                              [(r'jccl\jcclParam.h',
511                                os.path.join(gJugglerDir,
512                                             r'modules\jackal\common\jccl\jcclParam.h.in')),
513                               (r'jccl\jcclParam.cpp',
514                                os.path.join(gJugglerDir,
515                                             r'modules\jackal\common\jccl\jcclParam.cpp.in'))
516                              ]))
517    mods.append(JugglerModule(r'modules\sonix', vcDir, 'Sonix',
518                              [(r'snx\snxParam.h',), (r'snx\snxParam.cpp',)]))
519    mods.append(JugglerModule(r'modules\gadgeteer', vcDir, 'Gadgeteer',
520                              [(r'gadget\gadgetParam.h',),
521                               (r'gadget\gadgetParam.cpp',)]))
522    mods.append(JugglerModule(r'modules\vrjuggler', vcDir, 'VRJuggler',
523                              [(r'vrj\vrjParam.h',), (r'vrj\vrjParam.cpp',)]))
524
525    for m in mods:
526       m.generateParamFiles()
527
528 def generateAntBuildFiles(vcDir):
529    class AntTarget:
530       def __init__(self, srcdir, vcDir, moduleName, outputFile = 'build.xml',
531                    topSubDir = None):
532          '''
533          __init__(srcdir, vcDir, moduleName, outputFile, topSubDir)
534          Arguments:
535          srcdir     -- The location of the Java source to be compiled.
536          vcDir      -- The root of the directory tree containing the Visual
537                        C++ build system.
538          moduleName -- The name of the Visual C++ project (under the vcDir
539                        subdirectory) associated with this Ant build.  When
540                        concatenated to vcDir, this is where the the .class
541                        file(s) and the .jar file(s) will be created.
542          outputFile -- The name of the Ant build file to generate.  If not
543                        specified, this defaults to 'build.xml'.
544          topSubDir  -- The root of the directory where all the work will be
545                        done.  This is needed for Ant builds that depend on
546                        previously constructed JAR files that will most likely
547                        exist somewhere in the vcDir directory tree.  This
548                        string is used as part of the replacment for the
549                        string @topdir@ in the source build.xml.in file.  If
550                        not specified, this defaults to whatever value is
551                        passed in for vcDir.
552          '''
553          if topSubDir is None:
554             topSubDir = vcDir
555
556          self.srcdir      = os.path.join(gJugglerDir, srcdir)
557          self.topdir      = os.path.join(gJugglerDir, topSubDir)
558          self.module_name = os.path.join(gJugglerDir, vcDir, moduleName)
559          self.output_file = os.path.join(self.module_name, outputFile)
560
561          if not os.path.exists(self.module_name):
562             os.mkdir(self.module_name)
563          elif not os.path.isdir(self.module_name):
564             printStatus("ERROR: %s exists, but it is not a directory!" % self.module_name)
565             sys.exit(EXIT_STATUS_INVALID_PATH)
566
567          self.tweek_jars = [
568             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'Tweek.jar'),
569             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'TweekBeans.jar'),
570             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'TweekEvents.jar'),
571             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'TweekNet.jar'),
572             os.path.join(gJugglerDir, vcDir, 'Tweek_Java',
573                          'TweekBeanDelivery.jar'),
574             os.path.join(gJugglerDir, vcDir, 'Tweek_Java',
575                          'TweekServices.jar'),
576             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'Viewers.jar'),
577             os.path.join(gJugglerDir, vcDir, 'Tweek_Java',
578                          'kunststoff-mod.jar')
579          ]
580
581          self.tweek_ext_jars = [
582             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'ui.jar'),
583             os.path.join(gJugglerDir, vcDir, 'Tweek_Java', 'wizard.jar')
584          ]
585
586          self.jccl_jars = [
587             os.path.join(gJugglerDir, vcDir, 'JCCL_Java', 'jccl_config.jar'),
588             os.path.join(gJugglerDir, vcDir, 'JCCL_Java', 'jccl_editors.jar')
589          ]
590
591          self.jccl_rtrc_jars = [
592             os.path.join(gJugglerDir, vcDir, 'JCCL_Java', 'RTRC_Plugin_Java',
593                          'jccl_rtrc.jar')
594          ]
595
596       # This form of regular expressions appears to be necessary because
597       # the sub() method does not handle backslashes in the replacement string
598       # the way I would like.
599       srcdir_re         = re.compile(r'^(.*)@srcdir@(.*)$')
600       topdir_re         = re.compile(r'^(.*)@topdir@(.*)$')
601       juggler_root_re   = re.compile(r'^(.*)@JUGGLERROOT_ABS@(.*)$')
602       jdom_jar_re       = re.compile(r'^(.*)@JDOM_JAR@(.*)$')
603       tweek_jars_re     = re.compile(r'^(.*)@TWEEK_JARS@(.*)$')
604       tweek_ext_jars_re = re.compile(r'^(.*)@TWEEK_EXT_JARS@(.*)$')
605       jccl_jars_re      = re.compile(r'^(.*)@JCCL_JARS@(.*)$')
606       java_orb_jar_re   = re.compile(r'^(.*)@JAVA_ORB_JAR@(.*)$')
607       jogl_jars_re      = re.compile(r'^(.*)@JOGL_JARS@(.*)$')
608       java3d_jars_re    = re.compile(r'^(.*)@JAVA3D_JAR@(.*)$')
609
610       jdom_jars = [
611          os.path.join(gJugglerDir, r'external\jdom\build\jdom.jar'),
612          os.path.join(gJugglerDir, r'external\jdom\lib\jaxen-core.jar'),
613          os.path.join(gJugglerDir, r'external\jdom\lib\xalan.jar'),
614          os.path.join(gJugglerDir, r'external\jdom\lib\jaxen-jdom.jar'),
615          os.path.join(gJugglerDir, r'external\jdom\lib\xerces.jar'),
616          os.path.join(gJugglerDir, r'external\jdom\lib\xml-apis.jar'),
617          os.path.join(gJugglerDir, r'external\jdom\lib\saxpath.jar')
618       ]
619
620       jogl_jars = [
621          os.path.join(os.environ['JOGL_HOME'], 'jogl.jar'),
622          os.path.join(os.environ['JOGL_HOME'], 'jogl-demos-util.jar')
623       ]
624
625       java3d_jars = [
626          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\j3daudio.jar'),
627          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\j3dcore.jar'),
628          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\j3dutils.jar'),
629          os.path.join(os.environ['JAVA3D_HOME'], r'jre\lib\ext\vecmath.jar')
630       ]
631
632       def generateBuildFile(self):
633          input_file = open(os.path.join(self.srcdir, 'build.xml.in'), 'r')
634          input = input_file.readlines()
635          input_file.close()
636
637          for i in xrange(len(input)):
638             line = input[i]
639
640             if self.srcdir_re.search(line):
641                match = self.srcdir_re.search(line)
642                input[i] = '%s%s%s\n' % (match.groups()[0], self.srcdir,
643                                         match.groups()[1])
644             elif self.topdir_re.search(line):
645                match = self.topdir_re.search(line)
646                input[i] = '%s%s%s\n' % (match.groups()[0], self.topdir,
647                                         match.groups()[1])
648             elif self.juggler_root_re.search(line):
649                match = self.juggler_root_re.search(line)
650                input[i] = '%s%s%s\n' % (match.groups()[0], gJugglerDir,
651                                         match.groups()[1])
652             elif self.java_orb_jar_re.search(line):
653                match = self.java_orb_jar_re.search(line)
654                input[i] = '%s%s%s\n' % (match.groups()[0], "",
655                                         match.groups()[1])
656             elif self.jdom_jar_re.search(line):
657                jars = os.pathsep.join(self.jdom_jars)
658                match = self.jdom_jar_re.search(line)
659                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
660                                         match.groups()[1])
661             elif self.tweek_jars_re.search(line):
662                jars = os.pathsep.join(self.tweek_jars + self.jdom_jars)
663                match = self.tweek_jars_re.search(line)
664                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
665                                         match.groups()[1])
666             elif self.tweek_ext_jars_re.search(line):
667                jars = os.pathsep.join(self.tweek_ext_jars)
668                match = self.tweek_ext_jars_re.search(line)
669                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
670                                         match.groups()[1])
671             elif self.jccl_jars_re.search(line):
672                jars = os.pathsep.join(self.jccl_jars + self.jccl_rtrc_jars)
673                match = self.jccl_jars_re.search(line)
674                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
675                                         match.groups()[1])
676             elif self.jogl_jars_re.search(line):
677                jars = os.pathsep.join(self.jogl_jars)
678                match = self.jogl_jars_re.search(line)
679                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
680                                         match.groups()[1])
681             elif self.java3d_jars_re.search(line):
682                jars = os.pathsep.join(self.java3d_jars)
683                match = self.java3d_jars_re.search(line)
684                input[i] = '%s%s%s\n' % (match.groups()[0], jars,
685                                         match.groups()[1])
686
687          build_file = open(self.output_file, 'w')
688          build_file.writelines(input)
689          build_file.close()
690
691    mods = []
692    mods.append(AntTarget(r'modules\tweek\java', vcDir, 'Tweek_Java'))
693    mods.append(AntTarget(r'modules\tweek\extensions\java', vcDir,
694                          'Tweek_Java', 'build-ext.xml'))
695    mods.append(AntTarget(r'modules\jackal\config', vcDir, 'JCCL_Java',
696                          'build-config.xml'))
697    mods.append(AntTarget(r'modules\jackal\editors', vcDir, 'JCCL_Java',
698                          'build-editors.xml'))
699    mods.append(AntTarget(r'modules\jackal\plugins\corba_rtrc', vcDir,
700                          r'JCCL_Java\RTRC_Plugin_Java', 'build.xml'))
701    mods.append(AntTarget(r'modules\vrjuggler\vrjconfig', vcDir, 'VRJConfig',
702