viewer_manifest.py

Go to the documentation of this file.
00001 #!/usr/bin/python
00002 # @file viewer_manifest.py
00003 # @author Ryan Williams
00004 # @brief Description of all installer viewer files, and methods for packaging
00005 #        them into installers for all supported platforms.
00006 #
00007 # $LicenseInfo:firstyear=2006&license=viewergpl$
00008 # 
00009 # Copyright (c) 2006-2008, Linden Research, Inc.
00010 # 
00011 # Second Life Viewer Source Code
00012 # The source code in this file ("Source Code") is provided by Linden Lab
00013 # to you under the terms of the GNU General Public License, version 2.0
00014 # ("GPL"), unless you have obtained a separate licensing agreement
00015 # ("Other License"), formally executed by you and Linden Lab.  Terms of
00016 # the GPL can be found in doc/GPL-license.txt in this distribution, or
00017 # online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
00018 # 
00019 # There are special exceptions to the terms and conditions of the GPL as
00020 # it is applied to this Source Code. View the full text of the exception
00021 # in the file doc/FLOSS-exception.txt in this software distribution, or
00022 # online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
00023 # 
00024 # By copying, modifying or distributing this software, you acknowledge
00025 # that you have read and understood your obligations described above,
00026 # and agree to abide by those obligations.
00027 # 
00028 # ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
00029 # WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
00030 # COMPLETENESS OR PERFORMANCE.
00031 # $/LicenseInfo$
00032 import sys
00033 import os.path
00034 import re
00035 import tarfile
00036 viewer_dir = os.path.dirname(__file__)
00037 # add llmanifest library to our path so we don't have to muck with PYTHONPATH
00038 sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
00039 from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
00040 
00041 class ViewerManifest(LLManifest):
00042         def construct(self):
00043                 super(ViewerManifest, self).construct()
00044                 self.exclude("*.svn*")
00045                 self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")
00046                 self.path(src="../../etc/message.xml", dst="app_settings/message.xml")
00047 
00048                 if self.prefix(src="app_settings"):
00049                         self.exclude("logcontrol.xml")
00050                         self.exclude("logcontrol-dev.xml")
00051                         self.path("*.pem")
00052                         self.path("*.ini")
00053                         self.path("*.xml")
00054                         self.path("*.vp")
00055                         self.path("*.db2")
00056 
00057                         # include the entire shaders directory recursively
00058                         self.path("shaders")
00059                         # ... and the entire windlight directory
00060                         self.path("windlight")
00061                         self.end_prefix("app_settings")
00062 
00063                 if self.prefix(src="character"):
00064                         self.path("*.llm")
00065                         self.path("*.xml")
00066                         self.path("*.tga")
00067                         self.end_prefix("character")
00068 
00069 
00070                 # Include our fonts
00071                 if self.prefix(src="fonts"):
00072                         self.path("*.ttf")
00073                         self.path("*.txt")
00074                         self.end_prefix("fonts")
00075 
00076                 # XUI
00077                 if self.prefix(src="skins"):
00078                         # include the entire textures directory recursively
00079                         self.path("textures")
00080                         self.path("paths.xml")
00081                         self.path("xui/*/*.xml")
00082                         self.path('words.*.txt')
00083 
00084                         # Local HTML files (e.g. loading screen)
00085                         if self.prefix(src="html"):
00086                                 self.path("*.png")
00087                                 self.path("*/*/*.html")
00088                                 self.path("*/*/*.gif")
00089                                 self.end_prefix("html")
00090                         self.end_prefix("skins")
00091 
00092                 self.path("releasenotes.txt")
00093                 self.path("lsl_guide.html")
00094                 self.path("gpu_table.txt")
00095 
00096         def login_channel(self):
00097                 """Channel reported for login and upgrade purposes ONLY; used for A/B testing"""
00098                 # NOTE: Do not return the normal channel if login_channel is not specified, as
00099                 # some code may branch depending on whether or not this is present
00100                 return self.args.get('login_channel')
00101 
00102         def channel(self):
00103                 return self.args['channel']
00104         def channel_unique(self):
00105                 return self.channel().replace("Second Life", "").strip()
00106         def channel_oneword(self):
00107                 return "".join(self.channel_unique().split())
00108         def channel_lowerword(self):
00109                 return self.channel_oneword().lower()
00110 
00111         def flags_list(self):
00112                 """ Convenience function that returns the command-line flags for the grid"""
00113                 channel_flags = ''
00114                 grid_flags = ''
00115                 if not self.default_grid():
00116                         if self.default_channel():
00117                                 # beta grid viewer
00118                                 channel_flags = '--settings settings_beta.xml'
00119                         grid_flags = "--grid %(grid)s --helperuri http://preview-%(grid)s.secondlife.com/helpers/" % {'grid':self.args['grid']}
00120                         
00121                 if not self.default_channel():
00122                         # some channel on some grid
00123                         channel_flags = '--settings settings_%s.xml --channel "%s"' % (self.channel_lowerword(), self.channel())
00124                 elif self.login_channel():
00125                         # Report a special channel during login, but use default channel elsewhere
00126                         channel_flags = '--channel "%s"' % (self.login_channel())
00127                         
00128                 return " ".join((channel_flags, grid_flags)).strip()
00129 
00130 
00131 class WindowsManifest(ViewerManifest):
00132         def final_exe(self):
00133                 if self.default_channel():
00134                         if self.default_grid():
00135                                 return "SecondLife.exe"
00136                         else:
00137                                 return "SecondLifePreview.exe"
00138                 else:
00139                         return ''.join(self.channel().split()) + '.exe'
00140 
00141 
00142         def construct(self):
00143                 super(WindowsManifest, self).construct()
00144                 # the final exe is complicated because we're not sure where it's coming from,
00145                 # nor do we have a fixed name for the executable
00146                 self.path(self.find_existing_file('ReleaseForDownload/Secondlife.exe', 'Secondlife.exe', 'ReleaseNoOpt/newview_noopt.exe'), dst=self.final_exe())
00147                 # need to get the kdu dll from any of the build directories as well
00148                 self.path(self.find_existing_file('ReleaseForDownload/llkdu.dll', 'llkdu.dll', '../../libraries/i686-win32/lib_release/llkdu.dll'), dst='llkdu.dll')
00149                 self.path(src="licenses-win32.txt", dst="licenses.txt")
00150 
00151                 self.path("featuretable.txt")
00152 
00153                 # For use in crash reporting (generates minidumps)
00154                 self.path("dbghelp.dll")
00155 
00156                 # For using FMOD for sound... DJS
00157                 self.path("fmod.dll")
00158 
00159                 # For textures
00160                 if self.prefix(src="../../libraries/i686-win32/lib_release", dst=""):
00161                         self.path("openjpeg.dll")
00162                         self.end_prefix()
00163 
00164                 # Mozilla appears to force a dependency on these files so we need to ship it (CP)
00165                 self.path("msvcr71.dll")
00166                 self.path("msvcp71.dll")
00167 
00168                 # Mozilla runtime DLLs (CP)
00169                 if self.prefix(src="../../libraries/i686-win32/lib_release", dst=""):
00170                         self.path("freebl3.dll")
00171                         self.path("gksvggdiplus.dll")
00172                         self.path("js3250.dll")
00173                         self.path("nspr4.dll")
00174                         self.path("nss3.dll")
00175                         self.path("nssckbi.dll")
00176                         self.path("plc4.dll")
00177                         self.path("plds4.dll")
00178                         self.path("smime3.dll")
00179                         self.path("softokn3.dll")
00180                         self.path("ssl3.dll")
00181                         self.path("xpcom.dll")
00182                         self.path("xul.dll")
00183                         self.end_prefix()
00184 
00185                 # Mozilla runtime misc files (CP)
00186                 if self.prefix(src="app_settings/mozilla"):
00187                         self.path("chrome/*.*")
00188                         self.path("components/*.*")
00189                         self.path("greprefs/*.*")
00190                         self.path("plugins/*.*")
00191                         self.path("res/*.*")
00192                         self.path("res/*/*")
00193                         self.end_prefix()
00194 
00195                 # Vivox runtimes
00196                 if self.prefix(src="vivox-runtime/i686-win32", dst=""):
00197                         self.path("SLVoice.exe")
00198                         self.path("SLVoiceAgent.exe")
00199                         self.path("libeay32.dll")
00200                         self.path("srtp.dll")
00201                         self.path("ssleay32.dll")
00202                         self.path("tntk.dll")
00203                         self.path("alut.dll")
00204                         self.path("vivoxsdk.dll")
00205                         self.path("ortp.dll")
00206                         self.path("wrap_oal.dll")
00207                         self.end_prefix()
00208 
00209 #                # pull in the crash logger and updater from other projects
00210 #                self.path(src="../win_crash_logger/win_crash_logger.exe", dst="win_crash_logger.exe")
00211                 self.path(src="../win_updater/updater.exe", dst="updater.exe")
00212 
00213         def nsi_file_commands(self, install=True):
00214                 def wpath(path):
00215                         if(path.endswith('/') or path.endswith(os.path.sep)):
00216                                 path = path[:-1]
00217                         path = path.replace('/', '\\')
00218                         return path
00219 
00220                 result = ""
00221                 dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])]
00222                 # sort deepest hierarchy first
00223                 dest_files.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
00224                 dest_files.reverse()
00225                 out_path = None
00226                 for pkg_file in dest_files:
00227                         rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,''))
00228                         installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file)))
00229                         pkg_file = wpath(os.path.normpath(pkg_file))
00230                         if installed_dir != out_path:
00231                                 if(install):
00232                                         out_path = installed_dir
00233                                         result += 'SetOutPath ' + out_path + '\n'
00234                         if(install):
00235                                 result += 'File ' + pkg_file + '\n'
00236                         else:
00237                                 result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
00238                 # at the end of a delete, just rmdir all the directories
00239                 if(not install):
00240                         deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
00241                         # find all ancestors so that we don't skip any dirs that happened to have no non-dir children
00242                         deleted_dirs = []
00243                         for d in deleted_file_dirs:
00244                                 deleted_dirs.extend(path_ancestors(d))
00245                         # sort deepest hierarchy first
00246                         deleted_dirs.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
00247                         deleted_dirs.reverse()
00248                         prev = None
00249                         for d in deleted_dirs:
00250                                 if d != prev:   # skip duplicates
00251                                         result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n'
00252                                 prev = d
00253 
00254                 return result
00255 
00256         def package_finish(self):
00257                 # a standard map of strings for replacing in the templates
00258                 substitution_strings = {
00259                         'version' : '.'.join(self.args['version']),
00260                         'version_short' : '.'.join(self.args['version'][:-1]),
00261                         'version_dashes' : '-'.join(self.args['version']),
00262                         'final_exe' : self.final_exe(),
00263                         'grid':self.args['grid'],
00264                         'grid_caps':self.args['grid'].upper(),
00265                         # escape quotes becase NSIS doesn't handle them well
00266                         'flags':self.flags_list().replace('"', '$\\"'),
00267                         'channel':self.channel(),
00268                         'channel_oneword':self.channel_oneword(),
00269                         'channel_unique':self.channel_unique(),
00270                         }
00271 
00272                 version_vars = """
00273                 !define INSTEXE  "%(final_exe)s"
00274                 !define VERSION "%(version_short)s"
00275                 !define VERSION_LONG "%(version)s"
00276                 !define VERSION_DASHES "%(version_dashes)s"
00277                 """ % substitution_strings
00278                 if self.default_channel():
00279                         if self.default_grid():
00280                                 # release viewer
00281                                 installer_file = "Second_Life_%(version_dashes)s_Setup.exe"
00282                                 grid_vars_template = """
00283                                 OutFile "%(installer_file)s"
00284                                 !define INSTFLAGS "%(flags)s"
00285                                 !define INSTNAME   "SecondLife"
00286                                 !define SHORTCUT   "Second Life"
00287                                 !define URLNAME   "secondlife"
00288                                 Caption "Second Life ${VERSION}"
00289                                 """
00290                         else:
00291                                 # beta grid viewer
00292                                 installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe"
00293                                 grid_vars_template = """
00294                                 OutFile "%(installer_file)s"
00295                                 !define INSTFLAGS "%(flags)s"
00296                                 !define INSTNAME   "SecondLife%(grid_caps)s"
00297                                 !define SHORTCUT   "Second Life (%(grid_caps)s)"
00298                                 !define URLNAME   "secondlife%(grid)s"
00299                                 !define UNINSTALL_SETTINGS 1
00300                                 Caption "Second Life %(grid)s ${VERSION}"
00301                                 """
00302                 else:
00303                         # some other channel on some grid
00304                         installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe"
00305                         grid_vars_template = """
00306                         OutFile "%(installer_file)s"
00307                         !define INSTFLAGS "%(flags)s"
00308                         !define INSTNAME   "SecondLife%(channel_oneword)s"
00309                         !define SHORTCUT   "%(channel)s"
00310                         !define URLNAME   "secondlife"
00311                         !define UNINSTALL_SETTINGS 1
00312                         Caption "%(channel)s ${VERSION}"
00313                         """
00314                 if(self.args.has_key('installer_name')):
00315                         installer_file = self.args['installer_name']
00316                 else:
00317                         installer_file = installer_file % substitution_strings
00318                 substitution_strings['installer_file'] = installer_file
00319 
00320                 tempfile = "../secondlife_setup_tmp.nsi"
00321                 # the following replaces strings in the nsi template
00322                 # it also does python-style % substitution
00323                 self.replace_in("installers/windows/installer_template.nsi", tempfile, {
00324                         "%%VERSION%%":version_vars,
00325                         "%%GRID_VARS%%":grid_vars_template % substitution_strings,
00326                         "%%INSTALL_FILES%%":self.nsi_file_commands(True),
00327                         "%%DELETE_FILES%%":self.nsi_file_commands(False)})
00328 
00329                 NSIS_path = 'C:\\Program Files\\NSIS\\makensis.exe'
00330                 self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile))
00331                 # self.remove(self.dst_path_of(tempfile))
00332                 self.created_path(installer_file)
00333 
00334 
00335 class DarwinManifest(ViewerManifest):
00336         def construct(self):
00337                 # copy over the build result (this is a no-op if run within the xcode script)
00338                 self.path("build/" + self.args['configuration'] + "/Second Life.app", dst="")
00339 
00340                 if self.prefix(src="", dst="Contents"):  # everything goes in Contents
00341                         # Expand the tar file containing the assorted mozilla bits into
00342                         #  <bundle>/Contents/MacOS/
00343                         self.contents_of_tar('mozilla-universal-darwin.tgz', 'MacOS')
00344 
00345                         # copy additional libs in <bundle>/Contents/MacOS/
00346                         self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
00347 
00348                         # replace the default theme with our custom theme (so scrollbars work).
00349                         if self.prefix(src="mozilla-theme", dst="MacOS/chrome"):
00350                                 self.path("classic.jar")
00351                                 self.path("classic.manifest")
00352                                 self.end_prefix("MacOS/chrome")
00353 
00354                         # most everything goes in the Resources directory
00355                         if self.prefix(src="", dst="Resources"):
00356                                 super(DarwinManifest, self).construct()
00357 
00358                                 if self.prefix("cursors_mac"):
00359                                         self.path("*.tif")
00360                                         self.end_prefix("cursors_mac")
00361 
00362                                 self.path("licenses-mac.txt", dst="licenses.txt")
00363                                 self.path("featuretable_mac.txt")
00364                                 self.path("secondlife.icns")
00365 
00366                                 # llkdu dynamic library
00367 #                                self.path("../../libraries/universal-darwin/lib_release/libllkdu.dylib", "libllkdu.dylib")
00368 
00369                                 # command line arguments for connecting to the proper grid
00370                                 self.put_in_file(self.flags_list(), 'arguments.txt')
00371 
00372                                 self.end_prefix("Resources")
00373 
00374                         self.end_prefix("Contents")
00375                         
00376                 # NOTE: the -S argument to strip causes it to keep enough info for
00377                 # annotated backtraces (i.e. function names in the crash log).  'strip' with no
00378                 # arguments yields a slightly smaller binary but makes crash logs mostly useless.
00379                 # This may be desirable for the final release.  Or not.
00380                 if("package" in self.args['actions'] or
00381                    "unpacked" in self.args['actions']):
00382                     self.run_command('strip -S "%(viewer_binary)s"' %
00383                                  { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
00384 
00385 
00386         def package_finish(self):
00387                 channel_standin = 'Second Life'  # hah, our default channel is not usable on its own
00388                 if not self.default_channel():
00389                         channel_standin = self.channel()
00390                         
00391                 imagename="SecondLife_" + '_'.join(self.args['version'])
00392                 if self.default_channel():
00393                         if not self.default_grid():
00394                                 # beta case
00395                                 imagename = imagename + '_' + self.args['grid'].upper()
00396                 else:
00397                         # first look, etc
00398                         imagename = imagename + '_' + self.channel_oneword().upper()
00399 
00400                 sparsename = imagename + ".sparseimage"
00401                 finalname = imagename + ".dmg"
00402                 # make sure we don't have stale files laying about
00403                 self.remove(sparsename, finalname)
00404 
00405                 self.run_command('hdiutil create "%(sparse)s" -volname "%(channel)s" -fs HFS+ -type SPARSE -megabytes 300 -layout SPUD' % {
00406                         'sparse':sparsename,
00407                         'channel':channel_standin})
00408 
00409                 # mount the image and get the name of the mount point and device node
00410                 hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"')
00411                 devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
00412                 volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
00413 
00414                 # Copy everything in to the mounted .dmg
00415                 if self.default_channel() and not self.default_grid():
00416                         app_name = "Second Life " + self.args['grid']
00417                 else:
00418                         app_name = channel_standin.strip()
00419                         
00420                 for s,d in {self.get_dst_prefix():app_name + ".app",
00421                                         "lsl_guide.html":"Linden Scripting Language Guide.html",
00422                                         "releasenotes.txt":"Release Notes.txt",
00423                                         "installers/darwin/mac_image_hidden":".hidden",
00424                                         "installers/darwin/mac_image_background.tga":"background.tga",
00425                                         "installers/darwin/mac_image_DS_Store":".DS_Store"}.items():
00426                         print "Copying to dmg", s, d
00427                         self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
00428 
00429                 # Unmount the image
00430                 self.run_command('hdiutil detach -force "' + devfile + '"')
00431 
00432                 print "Converting temp disk image to final disk image"
00433                 self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})
00434                 # get rid of the temp file
00435                 self.remove(sparsename)
00436 
00437 class LinuxManifest(ViewerManifest):
00438         def construct(self):
00439                 super(LinuxManifest, self).construct()
00440                 self.path("licenses-linux.txt","licenses.txt")
00441                 self.path("res/ll_icon.png","secondlife_icon.png")
00442                 if self.prefix("linux_tools", ""):
00443                         self.path("client-readme.txt","README-linux.txt")
00444                         self.path("client-readme-voice.txt","README-linux-voice.txt")
00445                         self.path("wrapper.sh","secondlife")
00446                         self.path("handle_secondlifeprotocol.sh")
00447                         self.path("register_secondlifeprotocol.sh")
00448                         self.end_prefix("linux_tools")
00449 
00450                 # Create an appropriate gridargs.dat for this package, denoting required grid.
00451                 self.put_in_file(self.flags_list(), 'gridargs.dat')
00452 
00453 
00454         def package_finish(self):
00455                 # stripping all the libs removes a few megabytes from the end-user package
00456                 for s,d in self.file_list:
00457                         if re.search("lib/lib.+\.so.*", d):
00458                                 self.run_command('strip -S %s' % d)
00459                         if re.search("app_settings/mozilla-runtime-.*/lib.+\.so.*", d):
00460                                 self.run_command('strip %s' % d)
00461 
00462                 if(self.args.has_key('installer_name')):
00463                         installer_name = self.args['installer_name']
00464                 else:
00465                         installer_name = '_'.join('SecondLife_', self.args.get('arch'), *self.args['version'])
00466                         if self.default_channel():
00467                                 if not self.default_grid():
00468                                         installer_name += '_' + self.args['grid'].upper()
00469                         else:
00470                                 installer_name += '_' + self.channel_oneword().upper()
00471 
00472                 # Fix access permissions
00473                 self.run_command("""
00474                 find %(dst)s -type d | xargs chmod 755;
00475                 find %(dst)s -type f -perm 0700 | xargs chmod 0755;
00476                 find %(dst)s -type f -perm 0500 | xargs chmod 0555;
00477                 find %(dst)s -type f -perm 0600 | xargs chmod 0644;
00478                 find %(dst)s -type f -perm 0400 | xargs chmod 0444;
00479                 true""" %  {'dst':self.get_dst_prefix() })
00480 
00481                 # temporarily move directory tree so that it has the right name in the tarfile
00482                 self.run_command("mv %(dst)s %(inst)s" % {'dst':self.get_dst_prefix(),'inst':self.src_path_of(installer_name)})
00483                 # --numeric-owner hides the username of the builder for security etc.
00484                 self.run_command('tar -C %(dir)s --numeric-owner -cjf %(inst_path)s.tar.bz2 %(inst_name)s' % {'dir':self.get_src_prefix(), 'inst_name': installer_name, 'inst_path':self.src_path_of(installer_name)})
00485                 self.run_command("mv %(inst)s %(dst)s" % {'dst':self.get_dst_prefix(),'inst':self.src_path_of(installer_name)})
00486 
00487 class Linux_i686Manifest(LinuxManifest):
00488         def construct(self):
00489                 super(Linux_i686Manifest, self).construct()
00490                 self.path("secondlife-i686-bin-stripped","bin/do-not-directly-run-secondlife-bin")
00491 #                self.path("../linux_crash_logger/linux-crash-logger-i686-bin-stripped","linux-crash-logger.bin")
00492                 self.path("linux_tools/launch_url.sh","launch_url.sh")
00493                 if self.prefix("res-sdl"):
00494                         self.path("*")
00495                         # recurse
00496                         self.end_prefix("res-sdl")
00497 
00498                 self.path("featuretable_linux.txt")
00499                 #self.path("secondlife-i686.supp")
00500 
00501                 self.path("app_settings/mozilla-runtime-linux-i686")
00502 
00503                 if self.prefix("../../libraries/i686-linux/lib_release_client", "lib"):
00504 #                        self.path("libkdu_v42R.so")
00505                         self.path("libfmod-3.75.so")
00506                         self.path("libapr-1.so.0")
00507                         self.path("libaprutil-1.so.0")
00508                         self.path("libdb-4.2.so")
00509                         self.path("libcrypto.so.0.9.7")
00510                         self.path("libssl.so.0.9.7")
00511 #                        self.path("libstdc++.so.6")
00512                         self.path("libuuid.so", "libuuid.so.1")
00513                         self.path("libSDL-1.2.so.0")
00514                         self.path("libELFIO.so")
00515                         self.path("libopenjpeg.so.2")
00516                         #self.path("libtcmalloc.so.0") - bugged
00517                         #self.path("libstacktrace.so.0") - probably bugged
00518 #                        self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason
00519                         self.end_prefix("lib")
00520 
00521                 # Vivox runtimes
00522                 if self.prefix(src="vivox-runtime/i686-linux", dst=""):
00523                         self.path("SLVoice")
00524                         self.end_prefix()
00525                 if self.prefix(src="vivox-runtime/i686-linux", dst="lib"):
00526                         self.path("libopenal.so.1")
00527                         self.path("libortp.so")
00528                         self.path("libvivoxsdk.so")
00529                         self.path("libalut.so")
00530                         self.end_prefix("lib")
00531 
00532 class Linux_x86_64Manifest(LinuxManifest):
00533         def construct(self):
00534                 super(Linux_x86_64Manifest, self).construct()
00535                 self.path("secondlife-x86_64-bin-stripped","bin/do-not-directly-run-secondlife-bin")
00536 #                self.path("../linux_crash_logger/linux-crash-logger-x86_64-bin-stripped","linux-crash-logger.bin")
00537                 self.path("linux_tools/launch_url.sh","launch_url.sh")
00538                 if self.prefix("res-sdl"):
00539                         self.path("*")
00540                         # recurse
00541                         self.end_prefix("res-sdl")
00542 
00543                 self.path("featuretable_linux.txt")
00544                 self.path("secondlife-i686.supp")
00545 
00546 if __name__ == "__main__":
00547         main(srctree=viewer_dir, dsttree=os.path.join(viewer_dir, "packaged"))

Generated on Fri May 16 08:34:28 2008 for SecondLife by  doxygen 1.5.5