diff options
author | Oz Linden <oz@lindenlab.com> | 2012-11-06 14:54:27 -0500 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2012-11-06 14:54:27 -0500 |
commit | d35c4f4c9dbea1805cd745725d8c62b0d7ea0ed7 (patch) | |
tree | 26d01d35f622ee0991f15ee3ee4f6149ea9c42e4 | |
parent | 18002a54be009e7cb0cbd0db4a797038b50c3a8a (diff) | |
parent | ca76f9aaf89b4a57c38d81ab6d2d91e91b2fd8a0 (diff) |
merge changes for DRTVWR-223
-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() |