# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: unixinstaller.py,v 1.1.2.4 2004/07/09 02:02:53 hubbe Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 or later (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****

#
# unixinstaller.py - unix installer class
#
#######################################################################

execfile(os.path.join(project.inst_script_dir, "installer.py"))

class UnixInstaller(Installer):

    def __init__(self):
        Installer.__init__(self)

        self.symbols_dir = "symbols"
        self.symbols_file = "symbols.tar.gz"

        self.tar_command = "tar"
        self.zip_command = "gzip"
        self.nm_command = "nm"
        self.nm_flags = ""

        # use native tar on aix to avoid errors when the build box 
        # has gnu tar but the install target does not.
        if(platform.name == "aix4"):
            self.tar_command = "/usr/bin/tar"
            self.nm_flags = "-xB"
        elif (platform.name in ["hp-uxB", "sunos5"]):
            self.nm_flags = "-px"
        elif (platform.name == "osf1V5"):
            self.nm_flags = "-B"

        if project.BuildOption("release") and \
            not project.BuildOption("relsymbl"):
            self.strip_symbols = 1
        else:
            self.strip_symbols = 0
            
            
    #######################################################################
    # SetArchiveType: sets the archive type
    def SetArchiveType(self, archive_type):
        Installer.SetArchiveType(self, archive_type)
        if (self.archive_type == "bz2"):
            self.include_archive_prog = 1

    ############################################################
    # NativePath: converts a path to the native separator format
    def NativePath(self, path):
        return string.replace(path, '\\', '/')

    
    ############################################################
    # Chmod: changes the file permissions to those specified
    def Chmod(self, path, permissions):
        # path is a subdirectory of the temp dir
        if (path == ""):
            path = self.tempdir
        else:
            path = os.path.join(self.tempdir, self.NativePath(path))

        # write the chmod command
        project.writeln("\t-chmod %s %s" % (permissions, path))


    ############################################################
    # MakeSymbols: Creates symbol directory
    def MakeSymbols(self, *files):
        project.writeln("all:")
        self.CleanSymbols()
        project.writeln("\t%s" % platform.mkdir.execute(self.symbols_dir))
        project.writeln("\t%s" % platform.mkdir.execute(self.inst_output_dir))

        for file in files:
            self.GetSymbols(file)
            if(self.strip_symbols):
                self.StripSymbols(file)

        self.ZipSymbols()

        project.writeln("copy:")
        project.writeln("\t" + platform.mkdir.execute(self.copy_dir))
        project.writeln("\t%s %s %s" % (platform.copy.cmd, 
            os.path.join(self.inst_output_dir, self.symbols_file),
            self.copy_dir))

        project.writeln("depend:")
        self.CleanSymbols()

        project.writeln("clean:")
        self.CleanSymbols()

    ############################################################
    # CleanSymbols: Cleans up symbol directory and zip file
    def CleanSymbols(self):
        project.writeln("\t%s %s" % (platform.rmdir.cmd, self.symbols_dir))
        project.writeln("\t%s %s" % (platform.rm.cmd,
            os.path.join(self.inst_output_dir, self.symbols_file)))
        
    ############################################################
    # GetSymbols: Creates symbol files
    def GetSymbols(self, file):
        file_path = os.path.join(self.tempdir, self.NativePath(file))

        # recurse through all files matching file_path,
        # list symbols, and output to symbols/<filename>.txt.
        # then remove symbols file if empty (no symbols)
        # for file in <descriptor>; do symfile=symbols/`basename $file`.txt;
        # if [ ! -s $symfile ]; then rm -f $symfile; fi; done
        project.writeln( \
            "\t-for file in %s; do " \
            "symfile=%s; " \
            "%s %s $$file > $$symfile; " \
            "if [ ! -s $$symfile ]; then %s $$symfile; fi; " \
            "done" % (file_path, 
            os.path.join(self.symbols_dir, "`basename $$file`.txt"),
            self.nm_command, self.nm_flags, platform.rm.cmd))

    ############################################################
    # ZipSymbols: tar and gzip the symbols files
    def ZipSymbols(self):
        project.writeln("\t%s -cf - %s | %s > %s" % \
            (self.tar_command, self.symbols_dir, self.zip_command, 
            os.path.join(self.inst_output_dir, self.symbols_file)))

    ############################################################
    # StripSymbols: Strips symbols
    def StripSymbols(self, file):
        project.writeln("\t-strip %s" % \
            os.path.join(self.tempdir, self.NativePath(file)))


    ############################################################
    # MakeArchive: Writes the makefile to create the archive file.
    def MakeArchive(self):
        project.writeln("all:")

        #for bz2
        if (self.archive_type == "bz2"):
            project.writeln("\t(cd %s; %s cvhf - .) | %s -zvc >%s" % \
                (self.tempdir, self.tar_command, self.archive_prog, 
                self.archive_file))

        #for tar.gz
        elif (self.archive_type == "tgz"):
            project.writeln("\t(cd %s; %s cvhf - .) | gzip >%s" % \
                (self.tempdir, self.tar_command, self.archive_file))

        #for zip
        #untested
        elif (self.archive_type == "zip"):
            project.writeln("\tzip -r %s %s" % (self.archive_file, 
                os.path.join(self.tempdir, "*")))
        
        #for tar.Z
        elif (self.archive_type == "tz"):
            project.writeln("\t(cd %s; %s cvhf - .) | compress >%s" % \
                (self.tempdir, self.tar_command, self.archive_file))

        self.CreateInfoHeader()

        project.writeln("depend:")
        project.writeln("\t" + platform.rm.cmd + " " + self.archive_file)
        project.writeln("")
        project.writeln("clean:")
        project.writeln("\t" + platform.rm.cmd + " " + self.archive_file)
        project.writeln("")

    #######################################################################
    # CreateInfoHeader: Writes the archive_info header
    def CreateInfoHeader(self):
        extractor_arg = ""
        if self.include_archive_prog:
            extractor_arg = "-e %s" % self.archive_prog
	project.writeln("\tpython %s %s -a %s -t %s > %s" %
			(os.path.join(project.src_root_path, "installer",
				      "common", "scripts", "preparchive.py"),
			 extractor_arg, self.archive_file, 
			 self.archive_type, self.archive_info_header))


    #######################################################################
    # MakeInstaller: Writes the makefile to create the final installer.
    # Combines stage1 app with archive and (if necessary) the archive prog.
    def MakeInstaller(self, stage1_path = None):
        if not stage1_path:
            stage1_path = os.path.join(self.inst_output_dir, self.stage1_name)
        installer_path = os.path.join(self.inst_output_dir, self.installer_name)
        project.writeln("all:")

	# make sure the dbg/rel directory is present
	project.writeln("\t" + platform.mkdir.execute(project.output_dir))

        if (self.include_archive_prog):
            test_cmds = "-f %s -a -f %s -a -f %s" % \
                (stage1_path, self.archive_prog, self.archive_file)
            file_list = "%s %s %s" % \
                (stage1_path, self.archive_prog, self.archive_file)
        else:
            test_cmds = "-f %s -a -f %s" % \
                (stage1_path, self.archive_file)
            file_list = "%s %s %s" % \
                (stage1_path, self.archive_file)

        project.writeln("\t(if test " + test_cmds + "; then " \
            "cat " + file_list + " > " + installer_path + "; " + \
            "chmod 0755 " + installer_path  + "; " + \
            "else echo \"ERROR: Files missing, " + installer_path + \
            " not created.\"; fi)")
            
        project.writeln("")
        project.writeln("copy:")
        project.writeln("\t" + platform.mkdir.execute(self.copy_dir))
        project.writeln("\t%s %s %s" % (platform.copy.cmd, 
            installer_path, self.copy_dir))
        project.writeln("depend:")
        project.writeln("clean:")
        project.writeln("\t%s %s" % (platform.rm.cmd, installer_path))


    #######################################################################
    # CleanTempFiles: clean up temp files
    def CleanTempFiles(self):
        Installer.CleanTempFiles(self)
        project.writeln("\t%s %s" % (platform.rmdir.cmd, self.symbols_dir))


