root/juggler/branches/2.0_alpha_4/buildwin32.py

Revision 17547, 45.5 kB (checked in by patrickh, 4 years ago)

Protect against spaces in the path to Juggler.sln.

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