diff options
| -rwxr-xr-x | .hgtags | 1 | ||||
| -rw-r--r-- | indra/lib/python/indra/util/llmanifest.py | 21 | ||||
| -rw-r--r-- | indra/newview/viewer_manifest.py | 233 | 
3 files changed, 143 insertions, 112 deletions
@@ -347,3 +347,4 @@ e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release  32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217  704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1  d799593b53ed733862e9a13871e318e886469377 DRTVWR-208 +e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223 diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index bfcb259709..97cc31bba0 100644 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -626,6 +626,23 @@ class LLManifest(object):              d = src_re.sub(d_template, s.replace('\\', '/'))              yield os.path.normpath(s), os.path.normpath(d) +    def path2basename(self, path, file): +        """ +        It is a common idiom to write: +        self.path(os.path.join(somedir, somefile), somefile) + +        So instead you can write: +        self.path2basename(somedir, somefile) + +        Note that this is NOT the same as: +        self.path(os.path.join(somedir, somefile)) + +        which is the same as: +        temppath = os.path.join(somedir, somefile) +        self.path(temppath, temppath) +        """ +        return self.path(os.path.join(path, file), file) +      def path(self, src, dst=None):          sys.stdout.write("Processing %s => %s ... " % (src, dst))          sys.stdout.flush() @@ -671,6 +688,10 @@ class LLManifest(object):          print "%d files" % count +        # Let caller check whether we processed as many files as expected. In +        # particular, let caller notice 0. +        return count +      def do(self, *actions):          self.actions = actions          self.construct() diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 99dcc90f8f..b962b6b044 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -28,6 +28,7 @@ $/LicenseInfo$  """  import sys  import os.path +import errno  import re  import tarfile  import time @@ -74,20 +75,20 @@ class ViewerManifest(LLManifest):                  # include the list of Lindens (if any)                  #   see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits                  linden_names_path = os.getenv("LINDEN_CREDITS") -                if linden_names_path : +                if not linden_names_path : +                    print "No 'LINDEN_CREDITS' specified in environment, using built-in list" +                else:                      try:                          linden_file = open(linden_names_path,'r') +                    except IOError: +                        print "No Linden names found at '%s', using built-in list" % linden_names_path +                    else:                           # all names should be one line, but the join below also converts to a string                          linden_names = ', '.join(linden_file.readlines())                          self.put_in_file(linden_names, "lindens.txt")                          linden_file.close()                          print "Linden names extracted from '%s'" % linden_names_path                          self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")]) -                    except IOError: -                        print "No Linden names found at '%s', using built-in list" % linden_names_path -                        pass -                else : -                    print "No 'LINDEN_CREDITS' specified in environment, using built-in list"                  # ... and the entire windlight directory                  self.path("windlight") @@ -149,14 +150,9 @@ class ViewerManifest(LLManifest):              self.path("gpu_table.txt")              # The summary.json file gets left in the base checkout dir by -            # build.sh. It's only created for a build.sh build, therefore we -            # have to check whether it exists.  :-P -            summary_json = "summary.json" -            summary_json_path = os.path.join(os.pardir, os.pardir, summary_json) -            if os.path.exists(os.path.join(self.get_src_prefix(), summary_json_path)): -                self.path(summary_json_path, summary_json) -            else: -                print "No %s" % os.path.join(self.get_src_prefix(), summary_json_path) +            # build.sh. It's only created for a build.sh build. +            if not self.path2basename(os.path.join(os.pardir, os.pardir), "summary.json"): +                print "No summary.json file"      def login_channel(self):          """Channel reported for login and upgrade purposes ONLY; @@ -327,13 +323,13 @@ class WindowsManifest(ViewerManifest):              self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())          # Plugin host application -        self.path(os.path.join(os.pardir, -                               'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"), -                  "slplugin.exe") +        self.path2basename(os.path.join(os.pardir, +                                        'llplugin', 'slplugin', self.args['configuration']), +                           "slplugin.exe")          #self.disable_manifest_check() -        self.path(src="../viewer_components/updater/scripts/windows/update_install.bat", dst="update_install.bat") +        self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat")          # Get shared libs from the shared libs staging directory          if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),                         dst=""): @@ -367,9 +363,7 @@ class WindowsManifest(ViewerManifest):              # Get fmod dll, continue if missing -            try: -                self.path("fmod.dll") -            except: +            if not self.path("fmod.dll"):                  print "Skipping fmod.dll"              # For textures @@ -711,85 +705,82 @@ class DarwinManifest(ViewerManifest):                  self.path("uk.lproj")                  self.path("zh-Hans.lproj") -                libdir = "../packages/lib/release" -                dylibs = {} +                def path_optional(src, dst): +                    """ +                    For a number of our self.path() calls, not only do we want +                    to deal with the absence of src, we also want to remember +                    which were present. Return either an empty list (absent) +                    or a list containing dst (present). Concatenate these +                    return values to get a list of all libs that are present. +                    """ +                    if self.path(src, dst): +                        return [dst] +                    print "Skipping %s" % dst +                    return [] -                # Need to get the llcommon dll from any of the build directories as well -                lib = "llcommon" -                libfile = "lib%s.dylib" % lib -                try: -                    self.path(self.find_existing_file(os.path.join(os.pardir, -                                                                    lib, -                                                                    self.args['configuration'], -                                                                    libfile), -                                                      os.path.join(libdir, libfile)), -                                                      dst=libfile) -                except RuntimeError: -                    print "Skipping %s" % libfile -                    dylibs[lib] = False -                else: -                    dylibs[lib] = True - -                if dylibs["llcommon"]: -                    for libfile in ("libapr-1.0.dylib", -                                    "libaprutil-1.0.dylib", -                                    "libexpat.1.5.2.dylib", -                                    "libexception_handler.dylib", -                                    "libGLOD.dylib", -                                    "libcollada14dom.dylib" -                                    ): -                        self.path(os.path.join(libdir, libfile), libfile) - -                # SLVoice and vivox lols -                for libfile in ('libsndfile.dylib', 'libvivoxoal.dylib', 'libortp.dylib', \ -                    'libvivoxsdk.dylib', 'libvivoxplatform.dylib', 'SLVoice') : -                     self.path(os.path.join(libdir, libfile), libfile) +                libdir = "../packages/lib/release" +                # dylibs is a list of all the .dylib files we expect to need +                # in our bundled sub-apps. For each of these we'll create a +                # symlink from sub-app/Contents/Resources to the real .dylib. +                # Need to get the llcommon dll from any of the build directories as well. +                libfile = "libllcommon.dylib" +                dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir, +                                                               "llcommon", +                                                               self.args['configuration'], +                                                               libfile), +                                                               os.path.join(libdir, libfile)), +                                       dst=libfile) + +                for libfile in ( +                                "libapr-1.0.dylib", +                                "libaprutil-1.0.dylib", +                                "libcollada14dom.dylib", +                                "libexpat.1.5.2.dylib", +                                "libexception_handler.dylib", +                                "libGLOD.dylib", +                                ): +                    dylibs += path_optional(os.path.join(libdir, libfile), libfile) + +                # SLVoice and vivox lols, no symlinks needed +                for libfile in ( +                                'libortp.dylib', +                                'libsndfile.dylib', +                                'libvivoxoal.dylib', +                                'libvivoxsdk.dylib', +                                'libvivoxplatform.dylib', +                                'SLVoice', +                                ): +                     self.path2basename(libdir, libfile) -                try: -                    # FMOD for sound -                    self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") -                except: -                    print "Skipping FMOD - not found" +                # FMOD for sound +                libfile = "libfmodwrapper.dylib" +                path_optional(os.path.join(self.args['configuration'], libfile), libfile)                  # our apps -                self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") -                self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") - -                # plugin launcher -                self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") - -                # our apps dependencies on shared libs -                if dylibs["llcommon"]: -                    mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") -                    mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") -                    slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") -                    for libfile in ("libllcommon.dylib", -                                    "libapr-1.0.dylib", -                                    "libaprutil-1.0.dylib", -                                    "libexpat.1.5.2.dylib", -                                    "libexception_handler.dylib", -                                    "libGLOD.dylib", -                                    "libcollada14dom.dylib" -                                    ): -                        target_lib = os.path.join('../../..', libfile) -                        self.run_command("ln -sf %(target)r %(link)r" %  -                                         {'target': target_lib, -                                          'link' : os.path.join(mac_crash_logger_res_path, libfile)} -                                         ) -                        self.run_command("ln -sf %(target)r %(link)r" %  -                                         {'target': target_lib, -                                          'link' : os.path.join(mac_updater_res_path, libfile)} -                                         ) -                        self.run_command("ln -sf %(target)r %(link)r" %  -                                         {'target': target_lib, -                                          'link' : os.path.join(slplugin_res_path, libfile)} -                                         ) +                for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), +                                         ("mac_updater", "mac-updater.app"), +                                         # plugin launcher +                                         (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), +                                         ): +                    self.path2basename(os.path.join(os.pardir, +                                                    app_bld_dir, self.args['configuration']), +                                       app) + +                    # our apps dependencies on shared libs +                    # for each app, for each dylib we collected in dylibs, +                    # create a symlink to the real copy of the dylib. +                    resource_path = self.dst_path_of(os.path.join(app, "Contents", "Resources")) +                    for libfile in dylibs: +                        symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile), +                                 os.path.join(resource_path, libfile))                  # plugins                  if self.prefix(src="", dst="llplugin"): -                    self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") -                    self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib") -                    self.path("../packages/lib/release/libllqtwebkit.dylib", "libllqtwebkit.dylib") +                    self.path2basename("../media_plugins/quicktime/" + self.args['configuration'], +                                       "media_plugin_quicktime.dylib") +                    self.path2basename("../media_plugins/webkit/" + self.args['configuration'], +                                       "media_plugin_webkit.dylib") +                    self.path2basename("../packages/lib/release", "libllqtwebkit.dylib")                      self.end_prefix("llplugin") @@ -956,20 +947,25 @@ class LinuxManifest(ViewerManifest):              self.path("client-readme-voice.txt","README-linux-voice.txt")              self.path("client-readme-joystick.txt","README-linux-joystick.txt")              self.path("wrapper.sh","secondlife") -            self.path("handle_secondlifeprotocol.sh", "etc/handle_secondlifeprotocol.sh") -            self.path("register_secondlifeprotocol.sh", "etc/register_secondlifeprotocol.sh") -            self.path("refresh_desktop_app_entry.sh", "etc/refresh_desktop_app_entry.sh") -            self.path("launch_url.sh","etc/launch_url.sh") +            if self.prefix(src="", dst="etc"): +                self.path("handle_secondlifeprotocol.sh") +                self.path("register_secondlifeprotocol.sh") +                self.path("refresh_desktop_app_entry.sh") +                self.path("launch_url.sh") +                self.end_prefix("etc")              self.path("install.sh")              self.end_prefix("linux_tools")          # Create an appropriate gridargs.dat for this package, denoting required grid.          self.put_in_file(self.flags_list(), 'etc/gridargs.dat') -        self.path("secondlife-bin","bin/do-not-directly-run-secondlife-bin") -        self.path("../linux_crash_logger/linux-crash-logger","bin/linux-crash-logger.bin") -        self.path("../linux_updater/linux-updater", "bin/linux-updater.bin") -        self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") +        if self.prefix(src="", dst="bin"): +            self.path("secondlife-bin","do-not-directly-run-secondlife-bin") +            self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") +            self.path("../linux_updater/linux-updater", "linux-updater.bin") +            self.path2basename("../llplugin/slplugin", "SLPlugin") +            self.path2basename("../viewer_components/updater/scripts/linux", "update_install") +            self.end_prefix("bin")          if self.prefix("res-sdl"):              self.path("*") @@ -985,17 +981,13 @@ class LinuxManifest(ViewerManifest):                  self.end_prefix("res-sdl")              self.end_prefix(icon_path) -        self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install") -          # plugins          if self.prefix(src="", dst="bin/llplugin"): -            self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") +            self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so")              self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")              self.end_prefix("bin/llplugin") -        try: -            self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") -        except: +        if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):              print "Skipping llcommon.so (assuming llcommon was linked statically)"          self.path("featuretable_linux.txt") @@ -1079,11 +1071,8 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libopenjpeg.so*")              self.path("libdirectfb-1.4.so.5")              self.path("libfusion-1.4.so.5") -            self.path("libdirect-1.4.so.5.0.4") -            self.path("libdirect-1.4.so.5") -            self.path("libhunspell-1.3.so") -            self.path("libhunspell-1.3.so.0") -            self.path("libhunspell-1.3.so.0.0.0") +            self.path("libdirect-1.4.so.5*") +            self.path("libhunspell-1.3.so*")              self.path("libalut.so")              self.path("libopenal.so", "libopenal.so.1")              self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname @@ -1146,5 +1135,25 @@ class Linux_x86_64Manifest(LinuxManifest):  ################################################################ +def symlinkf(src, dst): +    """ +    Like ln -sf, but uses os.symlink() instead of running ln. +    """ +    try: +        os.symlink(src, dst) +    except OSError, err: +        if err.errno != errno.EEXIST: +            raise +        # We could just blithely attempt to remove and recreate the target +        # file, but that strategy doesn't work so well if we don't have +        # permissions to remove it. Check to see if it's already the +        # symlink we want, which is the usual reason for EEXIST. +        if not (os.path.islink(dst) and os.readlink(dst) == src): +            # Here either dst isn't a symlink or it's the wrong symlink. +            # Remove and recreate. Caller will just have to deal with any +            # exceptions at this stage. +            os.remove(dst) +            os.symlink(src, dst) +  if __name__ == "__main__":      main()  | 
