Viewer manifest cleanup/updating

This commit is contained in:
Shyotl
2014-12-09 16:13:59 -06:00
parent f014c8207c
commit d571b8be81
2 changed files with 349 additions and 190 deletions

View File

@@ -41,6 +41,14 @@ import tarfile
import errno import errno
import subprocess import subprocess
class ManifestError(RuntimeError):
"""Use an exception more specific than generic Python RuntimeError"""
pass
class MissingError(ManifestError):
"""You specified a file that doesn't exist"""
pass
def path_ancestors(path): def path_ancestors(path):
drive, path = os.path.splitdrive(os.path.normpath(path)) drive, path = os.path.splitdrive(os.path.normpath(path))
result = [] result = []
@@ -245,15 +253,25 @@ def main():
for opt in args: for opt in args:
print "Option:", opt, "=", args[opt] print "Option:", opt, "=", args[opt]
# Build base package.
touch = args.get('touch')
if touch:
print 'Creating base package'
args['package_id'] = "" # base package has no package ID
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args) wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions']) wm.do(*args['actions'])
# Store package file for later if making touched file.
base_package_file = ""
if touch:
print 'Created base package ', wm.package_file
base_package_file = "" + wm.package_file
# Write out the package file in this format, so that it can easily be called # Write out the package file in this format, so that it can easily be called
# and used in a .bat file - yeah, it sucks, but this is the simplest... # and used in a .bat file - yeah, it sucks, but this is the simplest...
touch = args.get('touch') touch = args.get('touch')
if touch: if touch:
fp = open(touch, 'w') fp = open(touch, 'w')
fp.write('set package_file=%s\n' % wm.package_file) fp.write('set package_file=%s\n' % base_package_file)
fp.close() fp.close()
print 'touched', touch print 'touched', touch
return 0 return 0
@@ -390,8 +408,8 @@ class LLManifest(object):
def run_command(self, command): def run_command(self, command):
""" Runs an external command, and returns the output. Raises """ Runs an external command, and returns the output. Raises
an exception if the command reurns a nonzero status code. For an exception if the command returns a nonzero status code. For
debugging/informational purpoases, prints out the command's debugging/informational purposes, prints out the command's
output as it is received.""" output as it is received."""
print "Running command:", command print "Running command:", command
fd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) fd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
@@ -404,7 +422,7 @@ class LLManifest(object):
print lines[-1].rstrip('\n'), print lines[-1].rstrip('\n'),
output = ''.join(lines) output = ''.join(lines)
if fd.returncode: if fd.returncode:
raise RuntimeError( raise ManifestError(
"Command %s returned non-zero status (%s) \noutput:\n%s" "Command %s returned non-zero status (%s) \noutput:\n%s"
% (command, fd.returncode, output) ) % (command, fd.returncode, output) )
return output return output
@@ -414,14 +432,24 @@ class LLManifest(object):
a) verify that you really have created it a) verify that you really have created it
b) schedule it for cleanup""" b) schedule it for cleanup"""
if not os.path.exists(path): if not os.path.exists(path):
raise RuntimeError, "Should be something at path " + path raise ManifestError, "Should be something at path " + path
self.created_paths.append(path) self.created_paths.append(path)
def put_in_file(self, contents, dst): def put_in_file(self, contents, dst, src=None):
# write contents as dst # write contents as dst
f = open(self.dst_path_of(dst), "wb") dst_path = self.dst_path_of(dst)
f.write(contents) f = open(dst_path, "wb")
f.close() try:
f.write(contents)
finally:
f.close()
# Why would we create a file in the destination tree if not to include
# it in the installer? The default src=None (plus the fact that the
# src param is last) is to preserve backwards compatibility.
if src:
self.file_list.append([src, dst_path])
return dst_path
def replace_in(self, src, dst=None, searchdict={}): def replace_in(self, src, dst=None, searchdict={}):
if dst == None: if dst == None:
@@ -569,7 +597,7 @@ class LLManifest(object):
except (IOError, os.error), why: except (IOError, os.error), why:
errors.append((srcname, dstname, why)) errors.append((srcname, dstname, why))
if errors: if errors:
raise RuntimeError, errors raise ManifestError, errors
def cmakedirs(self, path): def cmakedirs(self, path):
@@ -617,11 +645,10 @@ class LLManifest(object):
def check_file_exists(self, path): def check_file_exists(self, path):
if not os.path.exists(path) and not os.path.islink(path): if not os.path.exists(path) and not os.path.islink(path):
raise RuntimeError("Path %s doesn't exist" % ( raise MissingError("Path %s doesn't exist" % (os.path.abspath(path),))
os.path.normpath(os.path.join(os.getcwd(), path)),))
wildcard_pattern = re.compile('\*') wildcard_pattern = re.compile(r'\*')
def expand_globs(self, src, dst): def expand_globs(self, src, dst):
src_list = glob.glob(src) src_list = glob.glob(src)
src_re, d_template = self.wildcard_regex(src.replace('\\', '/'), src_re, d_template = self.wildcard_regex(src.replace('\\', '/'),
@@ -630,41 +657,72 @@ class LLManifest(object):
d = src_re.sub(d_template, s.replace('\\', '/')) d = src_re.sub(d_template, s.replace('\\', '/'))
yield os.path.normpath(s), os.path.normpath(d) 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): def path(self, src, dst=None):
sys.stdout.write("Processing %s => %s ... " % (src, dst)) sys.stdout.write("Processing %s => %s ... " % (src, dst))
sys.stdout.flush() sys.stdout.flush()
if src == None: if src == None:
raise RuntimeError("No source file, dst is " + dst) raise ManifestError("No source file, dst is " + dst)
if dst == None: if dst == None:
dst = src dst = src
dst = os.path.join(self.get_dst_prefix(), dst) dst = os.path.join(self.get_dst_prefix(), dst)
count = 0
is_glob = False
# look under each prefix for matching paths def try_path(src):
paths = set([os.path.join(self.get_src_prefix(), src), # expand globs
os.path.join(self.get_artwork_prefix(), src), count = 0
os.path.join(self.get_build_prefix(), src)]) if self.wildcard_pattern.search(src):
for path in paths: for s,d in self.expand_globs(src, dst):
if self.wildcard_pattern.search(path):
is_glob = True
for s,d in self.expand_globs(path, dst):
assert(s != d) assert(s != d)
count += self.process_file(s, d) count += self.process_file(s, d)
else: else:
# if we're specifying a single path (not a glob),
# we should error out if it doesn't exist
self.check_file_exists(src)
# if it's a directory, recurse through it # if it's a directory, recurse through it
if os.path.isdir(path): if os.path.isdir(src):
count += self.process_directory(path, dst) count += self.process_directory(src, dst)
elif os.path.exists(path): else:
count += self.process_file(path, dst) count += self.process_file(src, dst)
return count
# if we're specifying a single path (not a glob), for pfx in self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix():
# we should error out if it doesn't exist try:
if count == 0 and not is_glob: count = try_path(os.path.join(pfx, src))
raise RuntimeError("No files match %s\n" % str(paths)) except MissingError:
# If src isn't a wildcard, and if that file doesn't exist in
# this pfx, try next pfx.
count = 0
continue
# Here try_path() didn't raise MissingError. Did it process any files?
if count:
break
# Even though try_path() didn't raise MissingError, it returned 0
# files. src is probably a wildcard meant for some other pfx. Loop
# back to try the next.
print "%d files" % count 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): def do(self, *actions):
self.actions = actions self.actions = actions
self.construct() self.construct()

View File

@@ -174,6 +174,8 @@ class ViewerManifest(LLManifest):
return " ".join((channel_flags, grid_flags, setting_flags)).strip() return " ".join((channel_flags, grid_flags, setting_flags)).strip()
def icon_path(self):
return "../../indra/newview/res/"
class WindowsManifest(ViewerManifest): class WindowsManifest(ViewerManifest):
def is_win64(self): def is_win64(self):
return self.args.get('arch') == "x86_64" return self.args.get('arch') == "x86_64"
@@ -191,9 +193,9 @@ class WindowsManifest(ViewerManifest):
release_lib_dir = "Release" release_lib_dir = "Release"
# Plugin host application # Plugin host application
self.path(os.path.join(os.pardir, self.path2basename(os.path.join(os.pardir,
'llplugin', 'slplugin', self.args['configuration'], "SLPlugin.exe"), 'llplugin', 'slplugin', self.args['configuration']),
"SLPlugin.exe") "SLplugin.exe")
# Plugin volume control # Plugin volume control
if not self.is_win64() and self.prefix(src=self.args['configuration'], dst=""): if not self.is_win64() and self.prefix(src=self.args['configuration'], dst=""):
@@ -505,9 +507,10 @@ class DarwinManifest(ViewerManifest):
self.path(self.args['configuration'] + "/" + self.app_name() + ".app", dst="") self.path(self.args['configuration'] + "/" + self.app_name() + ".app", dst="")
if self.prefix(src="", dst="Contents"): # everything goes in Contents if self.prefix(src="", dst="Contents"): # everything goes in Contents
# copy additional libs in <bundle>/Contents/MacOS/ # copy additional libs in <bundle>/Contents/MacOS/
self.path("../../libraries/universal-darwin/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib") self.path("../packages/libraries/universal-darwin/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib")
self.path("../../libraries/universal-darwin/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib") self.path("../packages/libraries/universal-darwin/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib")
# most everything goes in the Resources directory # most everything goes in the Resources directory
if self.prefix(src="", dst="Resources"): if self.prefix(src="", dst="Resources"):
@@ -521,7 +524,10 @@ class DarwinManifest(ViewerManifest):
self.path("featuretable_mac.txt") self.path("featuretable_mac.txt")
self.path("SecondLife.nib") self.path("SecondLife.nib")
self.path(("../newview/res/%s_icon.icns" % self.viewer_branding_id()), dst=("%s_icon.icns" % self.viewer_branding_id())) icon_path = self.icon_path()
if self.prefix(src=icon_path, dst="") :
self.path("%s_icon.icns" % self.viewer_branding_id())
self.end_prefix(icon_path)
# Translations # Translations
self.path("English.lproj") self.path("English.lproj")
@@ -541,27 +547,55 @@ class DarwinManifest(ViewerManifest):
self.path("uk.lproj") self.path("uk.lproj")
self.path("zh-Hans.lproj") self.path("zh-Hans.lproj")
# SLVoice and vivox lols def path_optional(src, dst):
self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice") """
self.path("vivox-runtime/universal-darwin/ca-bundle.crt", "ca-bundle.crt") For a number of our self.path() calls, not only do we want
self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib") to deal with the absence of src, we also want to remember
self.path("vivox-runtime/universal-darwin/libsndfile.dylib", "libsndfile.dylib") which were present. Return either an empty list (absent)
self.path("vivox-runtime/universal-darwin/libvivoxoal.dylib", "libvivoxoal.dylib") or a list containing dst (present). Concatenate these
self.path("vivox-runtime/universal-darwin/libvivoxplatform.dylib", "libvivoxplatform.dylib") return values to get a list of all libs that are present.
self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib") """
if self.path(src, dst):
return [dst]
print "Skipping %s" % dst
return []
self.path("../llcommon/" + self.args['configuration'] + "/libllcommon.dylib", "libllcommon.dylib") libdir = "../packages/libraries/universal-darwin/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"
libfile = "lib%s.dylib" dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
libdir = "../../libraries/universal-darwin/lib/release" "llcommon",
self.args['configuration'],
libfile),
os.path.join(libdir, libfile)),
dst=libfile)
for libfile in ("libapr-1.0.dylib", for libfile in (
"libapr-1.0.dylib",
"libaprutil-1.0.dylib", "libaprutil-1.0.dylib",
"libcollada14dom.dylib", "libcollada14dom.dylib",
"libexpat.1.5.2.dylib", "libexpat.1.5.2.dylib",
"libexception_handler.dylib",
"libGLOD.dylib", "libGLOD.dylib",
"libexception_handler.dylib"): ):
self.path(os.path.join(libdir, libfile), libfile) 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',
'ca-bundle.crt',
'SLVoice',
):
self.path2basename(libdir, libfile)
# For using FMOD for sound...but, fmod is proprietary so some might not use it... # For using FMOD for sound...but, fmod is proprietary so some might not use it...
try: try:
@@ -571,40 +605,48 @@ class DarwinManifest(ViewerManifest):
print "Skipping libfmodwrapper.dylib - not found" print "Skipping libfmodwrapper.dylib - not found"
pass pass
# And now FMOD Ex!
try:
self.path("libfmodex.dylib", "libfmodex.dylib")
pass
except:
print "Skipping libfmodex.dylib - not found"
pass
# plugin launcher # dylibs that vary based on configuration
self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") if self.args['configuration'].lower() == 'debug':
for libfile in (
"libfmodexL.dylib",
):
dylibs += path_optional(os.path.join("../packages/lib/debug",
libfile), libfile)
else:
for libfile in (
"libfmodex.dylib",
):
dylibs += path_optional(os.path.join("../packages/lib/release",
libfile), libfile)
# dependencies on shared libs # our apps
slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") for app_bld_dir, app in (#("mac_crash_logger", "mac-crash-logger.app"),
for libfile in ("libllcommon.dylib", # plugin launcher
"libapr-1.0.dylib", (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
"libaprutil-1.0.dylib", ):
"libexpat.1.5.2.dylib", self.path2basename(os.path.join(os.pardir,
"libexception_handler.dylib"): app_bld_dir, self.args['configuration']),
target_lib = os.path.join('../../..', libfile) app)
self.run_command("ln -sf %(target)r %(link)r" %
{'target': target_lib, # our apps dependencies on shared libs
'link' : os.path.join(slplugin_res_path, libfile)} # for each app, for each dylib we collected in dylibs,
) # create a symlink to the real copy of the dylib.
#self.run_command("ln -sf %(target)r %(link)r" % resource_path = self.dst_path_of(os.path.join(app, "Contents", "Resources"))
# {'target': target_lib, for libfile in dylibs:
# 'link' : os.path.join(mac_crash_logger_res_path, libfile)} symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile),
# ) os.path.join(resource_path, libfile))
# plugins # plugins
if self.prefix(src="", dst="llplugin"): if self.prefix(src="", dst="llplugin"):
self.path("../plugins/filepicker/" + self.args['configuration'] + "/basic_plugin_filepicker.dylib", "basic_plugin_filepicker.dylib") self.path2basename(os.path.join(os.pardir,"plugins", "filepicker", self.args['configuration']),
self.path("../plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") "basic_plugin_filepicker.dylib")
self.path("../plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib") self.path2basename(os.path.join(os.pardir,"plugins", "quicktime", self.args['configuration']),
self.path("../../libraries/universal-darwin/lib/release/libllqtwebkit.dylib", "libllqtwebkit.dylib") "media_plugin_quicktime.dylib")
self.path2basename(os.path.join(os.pardir,"plugins", "webkit", self.args['configuration']),
"media_plugin_webkit.dylib")
self.path2basename(os.path.join(os.pardir,"packages", "libraries", "universal-darwin", "lib", "release"),
"libllqtwebkit.dylib")
self.end_prefix("llplugin") self.end_prefix("llplugin")
@@ -687,64 +729,88 @@ class DarwinManifest(ViewerManifest):
'vol':volname}) 'vol':volname})
# mount the image and get the name of the mount point and device node # mount the image and get the name of the mount point and device node
hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"') hdi_output = self.run_command('hdiutil attach -private %r' % sparsename)
devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip() try:
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip() devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
# Copy everything in to the mounted .dmg if devfile != '/dev/disk1':
# adding more debugging info based upon nat's hunches to the
# logs to help track down 'SetFile -a V' failures -brad
print "WARNING: 'SetFile -a V' command below is probably gonna fail"
if self.default_channel_for_brand() and not self.default_grid(): # Copy everything in to the mounted .dmg
app_name = self.app_name() + " " + self.args['grid']
else:
app_name = channel_standin.strip()
# Hack: if self.default_channel_for_brand() and not self.default_grid():
# Because there is no easy way to coerce the Finder into positioning app_name = self.app_name() + " " + self.args['grid']
# the app bundle in the same place with different app names, we are else:
# adding multiple .DS_Store files to svn. There is one for release, app_name = channel_standin.strip()
# one for release candidate and one for first look. Any other channels
# will use the release .DS_Store, and will look broken.
# - Ambroff 2008-08-20
# Added a .DS_Store for snowglobe - Merov 2009-06-17
# We have a single branded installer for all snowglobe channels so snowglobe logic is a bit different # Hack:
if (self.app_name()=="Snowglobe"): # Because there is no easy way to coerce the Finder into positioning
dmg_template = os.path.join ('installers', 'darwin', 'snowglobe-dmg') # the app bundle in the same place with different app names, we are
else: # adding multiple .DS_Store files to svn. There is one for release,
dmg_template = os.path.join( # one for release candidate and one for first look. Any other channels
'installers', # will use the release .DS_Store, and will look broken.
'darwin', # - Ambroff 2008-08-20
'%s-dmg' % "".join(self.channel_unique().split()).lower()) # Added a .DS_Store for snowglobe - Merov 2009-06-17
if not os.path.exists (self.src_path_of(dmg_template)): # We have a single branded installer for all snowglobe channels so snowglobe logic is a bit different
dmg_template = os.path.join ('installers', 'darwin', 'release-dmg') if (self.app_name()=="Snowglobe"):
dmg_template = os.path.join ('installers', 'darwin', 'snowglobe-dmg')
else:
dmg_template = os.path.join(
'installers',
'darwin',
'%s-dmg' % "".join(self.channel_unique().split()).lower())
for s,d in {self.get_dst_prefix():app_name + ".app", if not os.path.exists (self.src_path_of(dmg_template)):
os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns", dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
os.path.join(dmg_template, "background.jpg"): "background.jpg",
os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
print "Copying to dmg", s, d
self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
# Hide the background image, DS_Store file, and volume icon file (set their "visible" bit) for s,d in {self.get_dst_prefix():app_name + ".app",
self.run_command('SetFile -a V "' + os.path.join(volpath, ".VolumeIcon.icns") + '"') os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
self.run_command('SetFile -a V "' + os.path.join(volpath, "background.jpg") + '"') os.path.join(dmg_template, "background.jpg"): "background.jpg",
self.run_command('SetFile -a V "' + os.path.join(volpath, ".DS_Store") + '"') os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
print "Copying to dmg", s, d
self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
# Create the alias file (which is a resource file) from the .r # Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
self.run_command('rez "' + self.src_path_of("installers/darwin/release-dmg/Applications-alias.r") + '" -o "' + os.path.join(volpath, "Applications") + '"') for f in ".VolumeIcon.icns", "background.jpg", ".DS_Store":
pathname = os.path.join(volpath, f)
# We've observed mysterious "no such file" failures of the SetFile
# command, especially on the first file listed above -- yet
# subsequent inspection of the target directory confirms it's
# there. Timing problem with copy command? Try to handle.
for x in xrange(3):
if os.path.exists(pathname):
print "Confirmed existence: %r" % pathname
break
print "Waiting for %s copy command to complete (%s)..." % (f, x+1)
sys.stdout.flush()
time.sleep(1)
# If we fall out of the loop above without a successful break, oh
# well, possibly we've mistaken the nature of the problem. In any
# case, don't hang up the whole build looping indefinitely, let
# the original problem manifest by executing the desired command.
self.run_command('SetFile -a V %r' % pathname)
# Set the alias file's alias and custom icon bits # Create the alias file (which is a resource file) from the .r
self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"') self.run_command('Rez %r -o %r' %
(self.src_path_of("installers/darwin/release-dmg/Applications-alias.r"),
os.path.join(volpath, "Applications")))
# Set the disk image root's custom icon bit # Set the alias file's alias and custom icon bits
self.run_command('SetFile -a C "' + volpath + '"') self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"')
# Unmount the image # Set the disk image root's custom icon bit
self.run_command('hdiutil detach -force "' + devfile + '"') self.run_command('SetFile -a C "' + volpath + '"')
finally:
# Unmount the image
self.run_command('hdiutil detach -force "' + devfile + '"')
print "Converting temp disk image to final disk image" print "Converting temp disk image to final disk image"
self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname}) self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})
self.run_command('hdiutil internet-enable -yes "%(final)s"' % {'final':finalname})
# get rid of the temp file # get rid of the temp file
self.package_file = finalname self.package_file = finalname
self.remove(sparsename) self.remove(sparsename)
@@ -764,10 +830,12 @@ class LinuxManifest(ViewerManifest):
self.path("client-readme-voice.txt","README-linux-voice.txt") self.path("client-readme-voice.txt","README-linux-voice.txt")
self.path("client-readme-joystick.txt","README-linux-joystick.txt") self.path("client-readme-joystick.txt","README-linux-joystick.txt")
self.path("wrapper.sh",self.wrapper_name()) self.path("wrapper.sh",self.wrapper_name())
self.path("handle_secondlifeprotocol.sh") if self.prefix(src="", dst="etc"):
self.path("register_secondlifeprotocol.sh") self.path("handle_secondlifeprotocol.sh")
self.path("refresh_desktop_app_entry.sh") self.path("register_secondlifeprotocol.sh")
self.path("launch_url.sh") self.path("refresh_desktop_app_entry.sh")
self.path("launch_url.sh")
self.end_prefix("etc")
self.path("install.sh") self.path("install.sh")
self.end_prefix("linux_tools") self.end_prefix("linux_tools")
@@ -779,9 +847,11 @@ class LinuxManifest(ViewerManifest):
# self.path("secondlife-stripped","bin/"+self.binary_name()) # self.path("secondlife-stripped","bin/"+self.binary_name())
#else: #else:
# self.path("secondlife-bin","bin/"+self.binary_name()) # self.path("secondlife-bin","bin/"+self.binary_name())
self.path("secondlife-bin","bin/"+self.binary_name()) if self.prefix(src="", dst="bin"):
self.path("secondlife-bin",self.binary_name())
self.path2basename("../llplugin/slplugin", "SLPlugin")
self.end_prefix("bin")
self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
if self.prefix("res-sdl"): if self.prefix("res-sdl"):
self.path("*") self.path("*")
# recurse # recurse
@@ -789,9 +859,9 @@ class LinuxManifest(ViewerManifest):
# plugins # plugins
if self.prefix(src="", dst="bin/llplugin"): if self.prefix(src="", dst="bin/llplugin"):
self.path("../plugins/filepicker/libbasic_plugin_filepicker.so", "libbasic_plugin_filepicker.so") self.path2basename("../plugins/filepicker", "libbasic_plugin_filepicker.so")
self.path("../plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") self.path2basename("../plugins/webkit", "libmedia_plugin_webkit.so")
self.path("../plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") self.path("../plugins/gstreamer010", "libmedia_plugin_gstreamer.so")
self.end_prefix("bin/llplugin") self.end_prefix("bin/llplugin")
self.path("featuretable_linux.txt") self.path("featuretable_linux.txt")
@@ -860,10 +930,30 @@ class Linux_i686Manifest(LinuxManifest):
def construct(self): def construct(self):
super(Linux_i686Manifest, self).construct() super(Linux_i686Manifest, self).construct()
self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
if (not self.standalone()) and self.prefix("../../libraries/i686-linux/lib/release", dst="lib"): if (not self.standalone()) and self.prefix("../packages/lib/release", dst="lib"):
self.prefix("../packages/libraries/i686-linux/lib/release", dst="lib")
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
self.path("libdb*.so")
self.path("libexpat.so*")
self.path("libglod.so")
self.path("libuuid.so*")
self.path("libSDL-1.2.so*")
self.path("libdirectfb-1.*.so*")
self.path("libfusion-1.*.so*")
self.path("libdirect-1.*.so*")
self.path("libhunspell-*.so.*")
self.path("libalut.so")
self.path("libopenal.so.1")
self.path("libtcmalloc_minimal.so.0") #formerly called google perf tools
self.path("libtcmalloc_minimal.so.0.2.2")
try: try:
self.path("libfmod-3.75.so") self.path("libfmod-3.75.so")
pass pass
@@ -871,27 +961,6 @@ class Linux_i686Manifest(LinuxManifest):
print "Skipping libfmod-3.75.so - not found" print "Skipping libfmod-3.75.so - not found"
pass pass
self.path("libELFIO.so")
self.path("libSDL-1.2.so*")
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libcrypto.so*")
self.path("libdb*.so")
self.path("libdirect-1.*.so*")
self.path("libdirectfb-1.*.so*")
self.path("libfusion-1.*.so*")
self.path("libglod.so")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libexpat.so*")
self.path("libhunspell-*.so.*")
self.path("libssl.so*")
self.path("libuuid.so*")
self.path("libalut.so")
self.path("libopenal.so.1")
self.path("libtcmalloc_minimal.so.0")
self.path("libtcmalloc_minimal.so.0.2.2")
# Boost # Boost
self.path("libboost_context-mt.so.*") self.path("libboost_context-mt.so.*")
self.path("libboost_filesystem-mt.so.*") self.path("libboost_filesystem-mt.so.*")
@@ -900,6 +969,12 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libboost_signals-mt.so.*") self.path("libboost_signals-mt.so.*")
self.path("libboost_system-mt.so.*") self.path("libboost_system-mt.so.*")
self.path("libboost_thread-mt.so.*") self.path("libboost_thread-mt.so.*")
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libcrypto.so*")
self.path("libELFIO.so")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libssl.so*")
if 'extra_libraries' in self.args: if 'extra_libraries' in self.args:
path_list = self.args['extra_libraries'].split('|') path_list = self.args['extra_libraries'].split('|')
@@ -909,12 +984,13 @@ class Linux_i686Manifest(LinuxManifest):
self.path(src_path, dst_path) self.path(src_path, dst_path)
self.end_prefix("lib") self.end_prefix("lib")
self.end_prefix("lib")
# Vivox runtimes # Vivox runtimes
if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): if self.prefix(src="../packages/lib/release", dst="bin"):
self.path("SLVoice") self.path("SLVoice")
self.end_prefix() self.end_prefix("bin")
if self.prefix(src="vivox-runtime/i686-linux", dst="lib"): if self.prefix(src="../packages/lib/release", dst="lib"):
self.path("libortp.so") self.path("libortp.so")
self.path("libvivoxsdk.so") self.path("libvivoxsdk.so")
self.end_prefix("lib") self.end_prefix("lib")
@@ -924,25 +1000,23 @@ class Linux_x86_64Manifest(LinuxManifest):
def construct(self): def construct(self):
super(Linux_x86_64Manifest, self).construct() super(Linux_x86_64Manifest, self).construct()
self.path("../llcommon/libllcommon.so", "lib64/libllcommon.so") if not self.path("../llcommon/libllcommon.so", "lib64/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
if (not self.standalone()) and self.prefix("../../libraries/x86_64-linux/lib/release", dst="lib64"): if (not self.standalone()) and self.prefix("../packages/lib/release", dst="lib64"):
self.prefix("../../libraries/x86_64-linux/lib/release", dst="lib64")
self.path("libapr-1.so*") self.path("libapr-1.so*")
self.path("libaprutil-1.so*") self.path("libaprutil-1.so*")
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libdb-*.so*") self.path("libdb-*.so*")
self.path("libcrypto.so.*")
self.path("libexpat.so*") self.path("libexpat.so*")
self.path("libglod.so") self.path("libglod.so")
self.path("libhunspell-1.3.so*")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libssl.so*")
self.path("libuuid.so*") self.path("libuuid.so*")
self.path("libSDL-1.2.so*") self.path("libSDL-1.2.so*")
self.path("libELFIO.so")
self.path("libjpeg.so*") self.path("libjpeg.so*")
self.path("libpng*.so*") self.path("libhunspell-1.3.so*")
self.path("libz.so*") self.path("libalut.so*")
self.path("libopenal.so*")
# Boost # Boost
self.path("libboost_context-mt.so.*") self.path("libboost_context-mt.so.*")
@@ -953,9 +1027,13 @@ class Linux_x86_64Manifest(LinuxManifest):
self.path("libboost_system-mt.so.*") self.path("libboost_system-mt.so.*")
self.path("libboost_thread-mt.so.*") self.path("libboost_thread-mt.so.*")
# OpenAL self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libopenal.so*") self.path("libcrypto.so.*")
self.path("libalut.so*") self.path("libELFIO.so")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libpng*.so*")
self.path("libssl.so*")
self.path("libz.so*")
if 'extra_libraries' in self.args: if 'extra_libraries' in self.args:
path_list = self.args['extra_libraries'].split('|') path_list = self.args['extra_libraries'].split('|')
@@ -965,26 +1043,49 @@ class Linux_x86_64Manifest(LinuxManifest):
self.path(src_path, dst_path) self.path(src_path, dst_path)
self.end_prefix("lib64") self.end_prefix("lib64")
self.end_prefix("lib64")
# Vivox runtimes and libs # Vivox runtimes and libs
if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): if self.prefix(src="../packages/lib/release", dst="bin"):
self.path("SLVoice") self.path("SLVoice")
self.end_prefix("bin") self.end_prefix("bin")
if self.prefix(src="vivox-runtime/i686-linux", dst="lib32"): if self.prefix(src="../packages/lib/release", dst="lib32"):
#self.path("libalut.so") #self.path("libalut.so")
self.path("libortp.so") self.path("libortp.so")
self.path("libvivoxsdk.so") self.path("libvivoxsdk.so")
self.end_prefix("lib32") self.end_prefix("lib32")
# 32bit libs needed for voice # 32bit libs needed for voice
if self.prefix("../../libraries/x86_64-linux/lib/release/32bit-compat", dst="lib32"): if self.prefix("../packages/lib/32bit-compat", dst="lib32"):
self.path("libalut.so") self.path("libalut.so")
self.path("libidn.so.11") self.path("libidn.so.11")
self.path("libopenal.so.1") self.path("libopenal.so.1")
# self.path("libortp.so") # self.path("libortp.so")
self.path("libuuid.so.1") self.path("libuuid.so.1")
self.end_prefix("lib32") self.end_prefix("lib32")
################################################################
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__": if __name__ == "__main__":
main() main()