src/builder.py
changeset 0 ca70ae20a155
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/builder.py	Tue Feb 16 10:07:05 2010 +0530
@@ -0,0 +1,1008 @@
+# Copyright (c) 2008-2009 Nokia Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import os
+import sys
+import os.path
+import shutil
+import time
+import re
+from optparse import OptionParser
+sys.path.append(os.path.join(os.getcwd(), 'tools'))
+import code_size
+from shellutil import *
+import build_utils
+
+
+topdir = os.getcwd()
+
+# Variables needed to create the package
+installshield_dir = "c:\\Program Files\\InstallShield\\2009\\System"
+installer_dir = topdir + '\\tools\\installer\\'
+#.ism file is the project file for InstallShield
+ism_path = installer_dir + "PythonForS60.ism"
+release_name = "Beta"
+project_configuration = "PythonForS60"
+
+
+PROJ_DIR = "..\\build_dep"
+
+# SDK install paths used by junction tool to swap SDK epoc32 folders
+epoc_3_0 = 'C:\\Symbian\\9.1\\S60_3rd_MR\\epoc32'
+epoc_3_1 = 'C:\\Symbian\\9.1\\S60_3_1\\epoc32'
+epoc_3_2 = 'C:\\Symbian\\9.1\\S60_3rd_FP2_SDK\\epoc32'
+epoc_5_0 = 'C:\\Symbian\\9.4\\S60_5th_Edition_SDK_v1.0\\epoc32'
+
+# Please update this dictionary with all the informations required
+# to configure the source for a particular flavor
+variants = {'unsigned_devcert': {
+                        'capas': 'LocalServices NetworkServices ReadUserData' +
+                                 ' WriteUserData UserEnvironment Location' +
+                                 ' PowerMgmt ProtServ SwEvent SurroundingsDD' +
+                                 ' ReadDeviceData WriteDeviceData TrustedUI'},
+                'unsigned_alabs': {
+                        'capas': '''ALL -TCB -DRM -AllFiles''',
+                        'exe_capas': 'LocalServices NetworkServices' +
+                                 ' ReadUserData WriteUserData' +
+                                 ' UserEnvironment'},
+                'alabs_pythonteam': {
+                        'capas': '''ALL -TCB -DRM -AllFiles''',
+                         'key': 'pythonteam'},
+                'selfsigned': {
+                        'capas': 'LocalServices NetworkServices' +
+                                 ' ReadUserData WriteUserData' +
+                                 ' UserEnvironment',
+                        'key': "selfsigned"},
+                'unsigned_3_0': {
+                        'capas': 'LocalServices NetworkServices' +
+                                 ' ReadUserData WriteUserData' +
+                                 ' UserEnvironment',
+                        'uid': '0x20022EED'},
+                'unsigned_3_2': {
+                        'capas': 'LocalServices NetworkServices' +
+                                 ' ReadUserData WriteUserData' +
+                                 ' UserEnvironment Location',
+                        'uid': '0x20022EEC'},
+                'white_choco': {
+                        'capas': '''ALL -TCB''',
+                        'key': "pythonteam"},
+                'dark_choco': {
+                        'capas': '''ALL -TCB''',
+                        'key': "rd02"},
+                'unsigned_high_capas': {
+                    'capas': 'LocalServices NetworkServices ReadUserData' +
+                             ' WriteUserData UserEnvironment Location' +
+                             ' WriteDeviceData ReadDeviceData SwEvent',
+                    'uid': '0x20022EE9'},
+                'high_capas_pythonteam': {
+                    'capas': 'LocalServices NetworkServices ReadUserData' +
+                             ' WriteUserData UserEnvironment Location' +
+                             ' WriteDeviceData ReadDeviceData SwEvent',
+                    'key': 'pythonteam',
+                    'uid': '0x20022EE9'}}
+
+# Update the below dictionary to change the deliverables name
+deliverables_name = {
+  '30armv5': {'python_dll_sis_name': ['Python25_3rdEd.SIS',
+                                      'Python_%s%s_3rdEd_%s.sis',
+                                      '\\newcore\\symbian\\group'],
+              'testapp_sis_name': ['testapp_3rdEd.SIS',
+                                   'testapp_%s%s_3rdEd_%s.sis',
+                                   '\\ext\\test\\testapp\\group', 'test'],
+              'sdk_zip_name': ['Python_SDK_3rdEd.zip',
+                               'Python_%s%s_SDK_3rdEd.zip'],
+              'run_testapp_sis_name': ['run_testapp_3rdEd.SIS',
+                                       'run_testapp_%s%s_3rdEd_%s.sis',
+                                       '\\ext\\test\\run_testapp\\group',
+                                       'test'],
+              'run-interpretertimer_sis_name':
+                                  ['run-interpretertimer_3rdEd.SIS',
+                                   'run-interpretertimer_%s%s_3rdEd_%s.sis',
+                                   '\\ext\\test\\run-interpretertimer\\group',
+                                   'test'],
+              'interpreter-startup_sis_name':
+                                  ['interpreter-startup_3rdEd.SIS',
+                                   'interpreter-startup_%s%s_3rdEd_%s.sis',
+                                   '\\ext\\test\\interpreter-startup\\group',
+                                   'test']},
+  '50armv5': {'python_dll_sis_name': ['Python25_5thEd.SIS',
+                                 'Python_%s%s_5thEd_%s.sis',
+                                 '\\newcore\\symbian\\group'],
+         'testapp_sis_name': ['testapp_5thEd.SIS',
+                              'testapp_%s%s_5thEd_%s.sis',
+                              '\\ext\\test\\testapp\\group',
+                              'test'],
+         'run_testapp_sis_name': ['run_testapp_5thEd.SIS',
+                                  'run_testapp_%s%s_5thEd_%s.sis',
+                                  '\\ext\\test\\run_testapp\\group',
+                                  'test'],
+         'run-interpretertimer_sis_name':
+                                ['run-interpretertimer_5thEd.SIS',
+                                 'run-interpretertimer_%s%s_5thEd_%s.sis',
+                                 '\\ext\\test\\run-interpretertimer\\group',
+                                 'test'],
+         'interpreter-startup_sis_name':
+                                ['interpreter-startup_5thEd.SIS',
+                                 'interpreter-startup_%s%s_5thEd_%s.sis',
+                                 '\\ext\\test\\interpreter-startup\\group',
+                                 'test'],
+         'sdk_zip_name': ['Python_SDK_5thEd.zip',
+                          'Python_%s%s_SDK_5thEd.zip']},
+  '31': {'sdk_zip_name': ['Python_SDK_3rdEd.zip',
+                          'Python_%s%s_SDK_3rdEdFP1.zip']},
+  '32': {'python_dll_sis_name': ['Python25_3rdEdFP2.SIS',
+                                 'Python_%s%s_3rdEd_%s.sis',
+                                 '\\newcore\\symbian\\group'],
+         'testapp_sis_name': ['testapp_3rdEdFP2.SIS',
+                              'testapp_%s%s_3rdEd_%s.sis',
+                              '\\ext\\test\\testapp\\group', 'test'],
+         'sdk_zip_name': ['Python_SDK_3rdEdFP2.zip',
+                          'Python_%s%s_SDK_3rdEdFP2.zip'],
+         'run_testapp_sis_name': ['run_testapp_3rdEdFP2.SIS',
+                                  'run_testapp_%s%s_3rdEd_%s.sis',
+                                  '\\ext\\test\\run_testapp\\group',
+                                  'test'],
+         'run-interpretertimer_sis_name':
+                                  ['run-interpretertimer_3rdEdFP2.SIS',
+                                   'run-interpretertimer_%s%s_3rdEd_%s.sis',
+                                   '\\ext\\test\\run-interpretertimer\\group',
+                                   'test'],
+         'interpreter-startup_sis_name':
+                                  ['interpreter-startup_3rdEdFP2.SIS',
+                                   'interpreter-startup_%s%s_3rdEd_%s.sis',
+                                   '\\ext\\test\\interpreter-startup\\group',
+                                   'test']}}
+# TO-Do
+# Generic method to log the PyS60 build errors
+
+
+def generic_errors(args, __func__):
+    try:
+        __func__(path)
+    except OSError, (errno, strerror):
+        print ERROR_STR % {'*** Error': strerror}
+
+
+def create_readybuild_dirs():
+    # Method that create a clean directory to store the deliverables
+    # --work-area option can be used in command to change the deliverable path
+    # Ex- builder.py --work-area c:\\temp\\readybuild
+    dir_path = os.path.abspath(python_readybuild_dir)
+    deltree_if_exists(dir_path)
+    os.makedirs(dir_path + '\\test')
+
+
+def move_deliverable_to_readybuild_dir(platform, flavor):
+    # Method that renames all the deliverables to PyS60 standard and moves to
+    # deliverable directory
+    platform_name = deliverables_name[platform]
+    for deliverable in platform_name.keys():
+        if deliverable == 'sdk_zip_name':
+            continue
+        sis_name = platform_name[deliverable][0]
+        final_sis_name = platform_name[deliverable][1] \
+        %(version, version_tag, flavor)
+        os.chdir(topdir + platform_name[deliverable][2])
+        if os.path.exists(sis_name):
+            rename_file(sis_name, final_sis_name)
+        else:
+            continue
+        if 'test' in platform_name[deliverable]:
+            output_dir = python_readybuild_dir + '\\test'
+        else:
+            output_dir = python_readybuild_dir
+        shutil.move(final_sis_name,
+                 '%s\\%s' % (output_dir, final_sis_name))
+    os.chdir(topdir)
+
+
+def do_clean_and_build_emu(flavor, platforms, run_regrtest=True):
+    # Method that compiles source for emulator environment
+    # for given list of flavors
+    global setup_configure
+    for platform in platforms:
+        run_cmd('python setup.py clean', exception_on_error=0)
+        do_setupdotpy_configure(flavor, platform)
+        run_cmd('python setup.py build --emu')
+
+        if run_regrtest:
+            run_cmd('python setup.py test --testset-size 350')
+
+
+def create_and_move_device_deliverables(platform, flavor):
+    # Method that compiles source for device environment for
+    # given list of flavors and moves the sis files to work area directory
+    if not 'key' in variants[flavor]:
+        run_cmd('python setup.py bdist_sis')
+    else:
+        run_cmd('python setup.py bdist_sis --keydir %s --key %s' \
+         % (key_dir, '%(key)s' % variants[flavor]))
+    if flavor == 'unsigned_alabs':
+        cert = os.path.join(topdir, key_dir, 'pythonteam.crt')
+        key = os.path.join(topdir, key_dir, 'pythonteam.key')
+        passphrase = ''
+        os.chdir(topdir +
+                 deliverables_name[platform]['python_dll_sis_name'][2])
+        final_name = deliverables_name[platform]['python_dll_sis_name'][1] %\
+                    (version, version_tag, 'alabs_pythonteam')
+        run_cmd('signsis ' +
+                deliverables_name[platform]['python_dll_sis_name'][0] + ' ' +
+                final_name + ' %s %s %s' %
+               (cert, key, passphrase))
+        shutil.move(final_name,
+                 '%s\\%s' % (python_readybuild_dir, final_name))
+        os.chdir(topdir)
+    move_deliverable_to_readybuild_dir(platform, flavor)
+
+
+def do_setupdotpy_configure(flavor, platform):
+    # Method that calls setup.py configure with arguments based on arguments
+    # passed to builder.py
+    global setup_configure
+    setup_configure = "python setup.py configure --sdk %s --version %s \
+        --version-tag %s --build-profile %s" \
+        % (platform, version, version_tag, build_profile)
+    if include_internal_src:
+        setup_configure += " --include-internal-src"
+    setup_configure += " --compression-type=" + compression_type
+    if profiler:
+        setup_configure += " --profile_log "
+    if compiler_flags:
+        setup_configure += ' --compiler-flags "' + compiler_flags + '"'
+    if not 'key' in variants[flavor]:
+        setup_configure += ' --caps="' + variants[flavor]['capas'] + '"'
+        if 'exe_capas' in variants[flavor]:
+            setup_configure += " --exe-caps " + variants[flavor]['exe_capas']
+    else:
+        setup_configure += " --keydir " + key_dir + " --key " \
+        + variants[flavor]['key']
+    if internal_proj:
+        # Add the internal projects to the build
+        setup_configure += " --internal-projects"
+    run_cmd(setup_configure)
+    log('''builder.py - Building platform: %s and flavor: %s''' %
+        (platform, flavor))
+
+
+def create_deliverables_using_elftran(platform, flavors, create_sis):
+    # Creates the different flavors of PyS60, using postlinker tool ELFTRAN
+    for flavor in flavors:
+        log('builder.py - Using ELFTRAN to generate flavor: %s' % flavor)
+        cmd = 'python setup.py setcaps -c "%(capas)s"' % variants[flavor]
+        if 'exe_capas' in variants[flavor]:
+            cmd += ' --exe-caps "' + variants[flavor]['exe_capas'] + '"'
+        run_cmd(cmd)
+        if create_sis:
+            create_and_move_device_deliverables(platform, flavor)
+
+
+def build_device_and_move_sis(flavors, platforms, create_sis=True):
+    # Builds the source for device(unsigned_high_capas variant) and creates
+    # the flavors specified using elftran
+    for platform in platforms:
+        do_setupdotpy_configure('unsigned_high_capas', platform)
+        run_cmd('python setup.py build --device')
+        create_deliverables_using_elftran(platform, flavors, create_sis)
+
+
+def create_and_move_zip(platforms):
+    global create_temp_sdk_zip
+
+    def create_sdk_zip(platforms, armv5_pyds=False):
+        # Creates the sdk zip and moves it to work area directory
+        pyds_opt = ""
+        final_sdk_zip_name = ""
+        if armv5_pyds:
+            pyds_opt = " --create-temp-sdk-zip"
+            final_sdk_zip_name = 'Python_SDK_3rdEd_temp.zip'
+        else:
+            final_sdk_zip_name = deliverables_name[platforms]['sdk_zip_name'][1]\
+                                                  % (version, version_tag)
+
+        run_cmd('python setup.py bdist_sdk' + pyds_opt)
+        sdk_zip_name = deliverables_name[platforms]['sdk_zip_name'][0]
+        rename_file(sdk_zip_name, final_sdk_zip_name)
+        shutil.move(final_sdk_zip_name,
+                     '%s\\%s' % (python_readybuild_dir, final_sdk_zip_name))
+
+    if create_temp_sdk_zip and platforms == '30armv5':
+       create_sdk_zip(platforms)
+       create_sdk_zip(platforms, True)
+    else:
+       create_sdk_zip(platforms)
+
+def init_args(params):
+    # Parse all the arguments using optparse module
+    global platforms
+    global target
+    global version
+    global version_tag
+    global platforms
+    global python_readybuild_dir
+    global key_dir
+    global gflavors
+    global generate_docs
+    global grelease
+    global profiler
+    global compiler_flags
+    global integration_bld
+    global compression_type
+    global internal_proj
+    global without_src_zip
+    global without_ensymble
+    global installer
+    global include_internal_src
+    global build_profile
+    global create_temp_sdk_zip
+
+    # Set default build profile to 'integration'
+    build_profile = 'integration'
+
+    parser = OptionParser()
+    default_version_tag = 'svn' + get_svn_revision()
+    parser.add_option("-p", "--profile_log", dest="profiler",
+                        action="store_true", default=False,
+                        help="Profile log generator" +
+                        "for python[default: %default]")
+    parser.add_option("-v", "--version", dest="version", default='2.0.0',
+                        help="Python release version [default: %default]")
+    parser.add_option("-r", "--version-tag", dest="version_tag",
+                        default=default_version_tag,
+                        help="Release tag [default: %default]")
+    parser.add_option("--compiler-flags", dest="compiler_flags",
+                        default='',
+                        help="Compiler flags to be used while building the" +
+                        " python interpreter core [default: %default]")
+    parser.add_option("-t", "--targets", dest="targets", default='all',
+                        help="Build target emu/device [default: %default]")
+    parser.add_option("-s", "--sdk", dest="platforms", default='50armv5',
+                        help="Configure the source for a given SDK." +
+                        "Options : %s"%', '.join(deliverables_name.keys())+
+                        ' [default: %default]')
+    parser.add_option("-f", "--flavors", dest="flavors",
+                        help="Choose any set of flavors for build " +
+                        "%s [default: all the flavors]" \
+                        % ','.join(variants.keys()))
+    parser.add_option("--work-area", dest="work_area", default='build',
+                        help="Path for deliverables [default: %default]")
+    parser.add_option("--keydir", dest="key", default='..\\keys',
+                        help="Key path")
+    parser.add_option("-d", "--docs", action="store_true", dest="doc",
+                        default=False,
+                        help="Compiles the documentation and moves the html" +
+                        "files to work_area\docs [default: %default]" +
+                        "Read README.txt for more information.")
+    parser.add_option("--include-internal-src", action = 'store_true',
+                        dest = "include_internal_src", default = False,
+                        help = "Include the source under ..\internal-src for" +
+                        " build. [default: %default]")
+    parser.add_option("--integration-build", action="store_true",
+                        dest="integ_bld", default=False,
+                        help="Does an integration build. This also sets the" +
+                        " --include-internal-src option. " +
+                        "[default: %default]")
+    parser.add_option("--internal-projects", action="store_true",
+                        dest="internal_proj", default=False,
+                        help="Builds internal projects like " +
+                        "interpreter-startup, run_testapp " +
+                        "etc... [default: %default]")
+    parser.add_option("--release-build", action="store_true",
+                        dest="release", default=False,
+                        help="Build all the deliverables required for " +
+                        "releasing 1.9.x. This also sets the" +
+                        " --include-internal-src option. " +
+                        "[default: %default]")
+    parser.add_option("--compression-type", dest="compression_type",
+                        default='',
+                        help="Modify the compression type of all the " +
+                        "E32Image files generated, using 'elftran " +
+                        "-compressionmethod'. Refer elftran help for valid " +
+                        "compression types. If the type is given as '', " +
+                        "elftran is not invoked for modifying the " +
+                        "compression type. [default: '']")
+    parser.add_option("--without-src-zip", action="store_true",
+                        dest="without_src", default=False,
+                        help="Does not create a source zip when doing a " +
+                        "--release-build [default: %default]")
+    parser.add_option("--without-ensymble", action="store_true",
+                        dest="without_ensymble", default=False,
+                        help="Disables the ensymble build [default: %default]")
+    parser.add_option("--installer", action="store_true",
+                        dest="installer", default=False,
+                        help="Builds and creates a Setup.exe for PYS60 " +
+                        "[default: %default]")
+    parser.add_option("--create-temp-sdk-zip", action="store_true",
+                        dest="create_temp_sdk_zip", default=False,
+                        help="Creates an sdkzip with all armv5 binaries" +
+                        "[default: %default]")
+
+    (options, args) = parser.parse_args()
+    target = options.targets
+    version = options.version
+    version_tag = options.version_tag
+
+    platforms = options.platforms.split(',')
+    #python_readybuild_dir = options.work_area
+    python_readybuild_dir = topdir + '\\build'
+    key_dir = options.key
+    generate_docs = options.doc
+    grelease = options.release
+    if options.flavors:
+        gflavors = options.flavors.split(',')
+    else:
+        gflavors = variants.keys()
+    profiler = options.profiler
+    compiler_flags = options.compiler_flags
+    without_src_zip = options.without_src
+    integration_bld = options.integ_bld
+    internal_proj = options.internal_proj
+    without_ensymble = options.without_ensymble
+    installer = options.installer
+    compression_type = options.compression_type
+    create_temp_sdk_zip = options.create_temp_sdk_zip
+
+    include_internal_src = False
+    if options.include_internal_src:
+        include_internal_src = True
+
+    if integration_bld:
+    #platforms, gflavors, version_tag needs to be updated for this build
+        set_integration_env()
+
+
+class RunBuildCmd(Thread):
+
+    def __init__(self, build_cmd):
+        Thread.__init__(self)
+        self.build_cmd = build_cmd
+
+    def run(self):
+        run_cmd('python setup.py ' + self.build_cmd)
+
+
+class BuildInstaller(Thread):
+
+    def __init__(self):
+        Thread.__init__(self)
+
+    def run(self):
+        print "Building the Installer Package ..."
+
+        package_files = \
+                {'..\\tools\\py2sis\\ensymble\\':
+                              ['ensymble.py', 'templates', 'README',
+                               'module-repo'],
+                 '..\\tools\\py2sis\\ensymble_ui\\images\\':
+                              ['python_logo.gif'],
+                 '..\\tools\\py2sis\\ensymble_ui\\':
+                              ['ensymble_gui.pyw', 'ensymble_ui_help.html'],
+                 topdir + '\\tools\\installer\\doc\\':
+                              ['Quickguide.html', 'python_logo.PNG']}
+
+        package_dir = topdir + "\\build\\PythonForS60"
+
+        # Files which are present in the Windows Installer setup but which
+        # should not be present in the Linux/Mac package
+        files_not_in_pys60_archive = {topdir +
+                               '\\build\\PythonForS60_package\\PythonForS60\\':
+                               ['Quickguide.html', 'ensymble_gui.pyw',
+                                'ensymble_ui_help.html',
+                                'python_logo.PNG']}
+        package_dependencies_dir = "C:\\Installer_Dependency\\PyS60Dependencies"
+        # These files are copied to the local directory pointed
+        # by `PyS60Dependencies` for packaging as dependency files.
+        package_dependencies = [
+            'Python_%s%s_3rdEd_alabs_pythonteam.sis' % (version, version_tag),
+            'Python_%s%s_3rdEd_unsigned_alabs.sis' % (version, version_tag),
+            'PythonScriptShell_%s_unsigned_3_0.sis' % version,
+            'PythonScriptShell_%s_unsigned_3_2.sis' % version,
+            'PythonScriptShell_%s_unsigned_high_capas.sis' % version,
+            'PythonScriptShell_%s_high_capas_pythonteam.sis' % version,
+            'PythonScriptShell_%s_unsigned_devcert.sis' % version]
+
+        if not os.path.exists(package_dir):
+            print "Creating the temporary PythonForS60 folder"
+            os.mkdir(package_dir)
+
+        # Copy all the files that will be part of either Installer or the zip
+        # package to the PythonForS60 folder under 'src\Build'
+        print "Copying the files to PythonForS60 to be picked by Installer"
+        current_dir = os.getcwd()
+        os.chdir(topdir + '\\build')
+        for path in package_files:
+            for entry in package_files[path]:
+                entry_path = path + entry
+                if os.path.isdir(entry_path):
+                    shutil.copytree(entry_path,
+                                    os.path.join(package_dir, entry))
+                else:
+                    shutil.copy(entry_path, package_dir)
+        os.chdir(current_dir)
+
+        # Copy the sis files to `PyS60Dependencies` folder in
+        # c:\\Installer_Dependency.
+        for deps in package_dependencies:
+            deps_path = topdir + '\\build\\'
+            shutil.copy(deps_path + deps,
+                        package_dependencies_dir + '\\' + deps)
+
+        def generate_setup():
+            # Installshield setup is created by calling 'IsCmdBld.exe'and then
+            # moved to build folder
+            os.chdir(installshield_dir)
+            print "Build the setup.exe by passing command line option"
+            installer_build_cmd = 'IsCmdBld.exe -p "%s" -r "%s" -c \
+                COMP -a "%s"' % (ism_path, release_name, project_configuration)
+            os.system(installer_build_cmd)
+            os.chdir(current_dir)
+            setup_file = 'PythonForS60_%s_%s_Setup.exe' % (version, version_tag)
+            setup_dir = 'PythonForS60\\%s\\Beta\\DiskImages\\DISK1' \
+                        % project_configuration
+            os.rename(installer_dir + '%s\\setup.exe' % setup_dir,
+                    installer_dir + '%s\\%s' % (setup_dir, setup_file))
+            shutil.copy(installer_dir +
+                'PythonForS60\\%s\\Beta\\DiskImages\\DISK1\\%s'
+                % (project_configuration, setup_file),
+                os.path.join(topdir, 'build', setup_file))
+            print "Installer Package Built"
+
+        def build_pys60_package():
+            # Create a Python for S60 package for Linux/Mac users
+            print "Building PythonForS60 package for Linux/Mac ..."
+            pys60_archive_dir = topdir + '\\build\\PythonForS60_package'
+            if not os.path.exists(pys60_archive_dir):
+                os.mkdir(pys60_archive_dir)
+
+            # Make a copy of both the PythonForS60 folder and PyS60Dependencies
+            # folder to create an archive
+            shutil.copytree(package_dir, pys60_archive_dir + '\\' +
+                                                 os.path.basename(package_dir))
+            shutil.copytree(package_dependencies_dir, pys60_archive_dir +
+               '\\PythonForS60\\' + os.path.basename(package_dependencies_dir))
+            for path in files_not_in_pys60_archive:
+                for entry in files_not_in_pys60_archive[path]:
+                    entry_path = path + entry
+                    os.remove(entry_path)
+            create_archive_from_directory(topdir +
+                '\\build\\PythonForS60_%s_%s.tar.gz' % (version, version_tag),
+                pys60_archive_dir, archive_type='tar.gz')
+            print "PythonForS60 package built"
+            shutil.rmtree(pys60_archive_dir)
+
+        try:
+            generate_setup()
+            build_pys60_package()
+        finally:
+            print "Cleaning the folders after Installer generation is complete"
+            os.chdir(package_dependencies_dir)
+            for files in package_dependencies:
+                os.remove(files)
+
+            os.chdir(current_dir)
+            if os.path.exists(package_dir):
+                os.system("rmdir /S/Q " + package_dir)
+
+
+def call_ensymble(tmp_dir, ensymble_options, flavour):
+    sign_cert = "..\\..\..\\..\\keys\\pythonteam.crt"
+    sign_key = "..\\..\..\\..\\keys\\pythonteam.key"
+    ensymble_cmd = "python ensymble.py py2sis %s %s" \
+                    % (tmp_dir, ensymble_options)
+    # The first string in 'ensymble_options' has the scriptshell sis name
+    sis_name = ensymble_options.split(' ')[0]
+    try:
+        run_cmd(ensymble_cmd)
+        merge_example_scripts(sis_name)
+        if flavour == 'high_capas_pythonteam':
+            run_cmd("signsis %s %s %s %s"
+                    % (sis_name, sis_name, sign_cert, sign_key))
+    except:
+        print "Error generating PythonScriptShell sis file."
+        raise
+    else:
+        print "PythonScriptShell sis file generated."
+        shutil.move(sis_name, topdir + "\\build")
+
+
+def merge_example_scripts(sis_name):
+    run_cmd("dumpsis -x " + sis_name)
+
+    prev_dir = os.getcwd()
+    scriptshell_dir = os.path.join(prev_dir, sis_name.replace(".sis", ""))
+    os.chdir(os.path.join(prev_dir, scriptshell_dir))
+
+    scriptshell_pkg = sis_name.replace(".sis", ".pkg")
+    temp_pkg_file = "scriptshell.pkg"
+
+    # The pkg file generated by dumpsis command contains some non ascii
+    # characters, hence copying the pkg file content to a temporary file
+    # excluding those non ascii characters
+    type_cmd = "type %s > %s" % (scriptshell_pkg, temp_pkg_file)
+    run_cmd(type_cmd)
+
+    f = open(temp_pkg_file, 'a')
+    f.write('\n\n@"..\\..\\..\\..\\..\\internal-src\\' \
+            'dependency_sis_files\\PyS60ExampleScripts.sis"' \
+            ', (0x20022EEA)')
+    f.close()
+
+    delete_file(scriptshell_pkg)
+    rename_file(temp_pkg_file, scriptshell_pkg)
+
+    run_cmd("makesis " + scriptshell_pkg)
+    shutil.move(sis_name, prev_dir)
+
+    os.chdir(prev_dir)
+    deltree_if_exists(scriptshell_dir)
+
+
+def populate_scriptshell_scripts(tmp_dir):
+    scriptshell_dir = topdir + "\\ext\\amaretto\\scriptshell\\"
+    scriptshell_src = ['default.py', 'consolidated_imports.py']
+
+    deltree_if_exists(tmp_dir)
+    os.makedirs(tmp_dir)
+
+    for f in scriptshell_src:
+        print "Copying %s to %s" % (scriptshell_dir + f, tmp_dir)
+        shutil.copy(scriptshell_dir + f, tmp_dir)
+    # filebrowser.py imports dir_iter.py. So moving this file to scriptshell's
+    # private directory.
+    ex_file = topdir + "\\extras\\" + 'dir_iter.py'
+    shutil.copy(ex_file, tmp_dir)
+
+
+def create_sdk_zip_31():
+    print "Creating sdk zip for 3.1 .."
+    platforms = ['30armv5']
+    build_utils.create_clean_env('\\Epoc32_3.1.zip')
+    sdk_zip_name = deliverables_name['32']['sdk_zip_name'][1] % \
+                                          (version, version_tag)
+    build_utils.unzip_file_into_dir(topdir + '\\build\\' + sdk_zip_name, '\\')
+    # Building only the socket
+    do_setupdotpy_configure('unsigned_high_capas', platforms[0])
+    run_cmd('python setup.py build ext\\amaretto\\socket\\group')
+    create_and_move_zip('31')
+    test_sdk_zip('_3_1')
+    shutil.rmtree("\\epoc32")
+
+
+def generate_scriptshell_sis():
+    print "Building the PythonScriptShell sis files ..."
+    prev_dir = os.getcwd()
+    os.chdir(topdir + '\\tools\\py2sis\\ensymble')
+
+    app_name = "PythonScriptShell"
+    heap_size = "100K,16M"
+    vendor = "Nokia"
+    short_caption = "Python" + version
+    caption = "PythonScriptShell"
+    tmp_dir = "scriptshell_dir"
+
+    if integration_bld:
+        flavours = ['high_capas_pythonteam']
+    else:
+        flavours = ['unsigned_3_0', 'unsigned_3_2', 'unsigned_devcert',
+                    'high_capas_pythonteam', 'unsigned_high_capas']
+
+    populate_scriptshell_scripts(tmp_dir)
+
+    for flavour in flavours:
+        if flavour in ['unsigned_3_0', 'unsigned_3_2',
+                       'high_capas_pythonteam', 'unsigned_high_capas']:
+            uid = variants[flavour]['uid']
+        else:
+            uid = None
+
+        common_opt = "-v --appname=%s --version=%s --heapsize=%s " + \
+                     "--vendor=%s --shortcaption=%s --caption=%s "
+
+        common_opt = common_opt % (app_name, version, heap_size, vendor,
+                           short_caption, caption)
+        if uid is not None:
+            common_opt += ' --uid=' + uid
+        caps = variants[flavour]['capas'].replace(' ', '+')
+        if integration_bld:
+            sis_name = "PythonScriptShell_%s%s_%s.sis" % \
+                                                (version, version_tag, flavour)
+        else:
+            sis_name = "PythonScriptShell_%s_%s.sis" % (version, flavour)
+        options_for_ensymble = "%s --caps=%s %s" % (sis_name, caps, common_opt)
+        if integration_bld:
+            options_for_ensymble += " --ignore-missing-deps"
+        try:
+            call_ensymble(tmp_dir, options_for_ensymble, flavour)
+        except:
+            raise
+
+    deltree_if_exists(tmp_dir)
+    os.chdir(prev_dir)
+
+
+def generate_ensymble_zip():
+    package_files = {'tools\\py2sis\\ensymble\\':
+                     ['ensymble.py', 'templates', 'README', 'module-repo']}
+    package_dir = topdir + '\\build\\ensymble_zip'
+    prev_dir = os.getcwd()
+    os.mkdir(package_dir)
+    for path in package_files:
+            for entry in package_files[path]:
+                entry_path = path + entry
+                if os.path.isdir(entry_path):
+                    shutil.copytree(entry_path,
+                                    os.path.join(package_dir, entry))
+                else:
+                    shutil.copy(entry_path, package_dir)
+    create_archive_from_directory(topdir + '\\build\\ensymble_%s_%s.zip' %
+                                  (version, version_tag), package_dir)
+    deltree_if_exists(package_dir)
+    os.chdir(prev_dir)
+
+
+def test_sdk_zip(sdk_version):
+    sign_cert = "..\\..\..\\..\\keys\\pythonteam.crt"
+    sign_key = "..\\..\..\\..\\keys\\pythonteam.key"
+    caps_opt = ""
+
+    if sdk_version == '_3_0':
+        elemlist_sis_name = "elemlist_%s%s_3rdEd_alabs_pythonteam.sis" \
+                                                      % (version, version_tag)
+        build_utils.create_clean_env('\\Epoc32_3.0.zip')
+        sdk_zip_name = 'Python_%s%s_SDK_3rdEdFP2.zip' % (version, version_tag)
+        caps_opt = ' --caps "%s"' % variants['alabs_pythonteam']['capas']
+    elif sdk_version == '_3_1':
+        elemlist_sis_name = "elemlist_%s%s_3rdEdFP1_alabs_pythonteam.sis" \
+                                                      % (version, version_tag)
+        build_utils.create_clean_env('\\Epoc32_3.1.zip')
+        sdk_zip_name = 'Python_%s%s_SDK_3rdEdFP1.zip' % (version, version_tag)
+        caps_opt = ' --caps "%s"' % variants['alabs_pythonteam']['capas']
+    elif sdk_version == '_3_2':
+        elemlist_sis_name = "elemlist_%s%s_3rdEdFP2_alabs_pythonteam.sis" % \
+                                                        (version, version_tag)
+        build_utils.create_clean_env('\\Epoc32_3.2.zip')
+        caps_opt = ' --caps "%s"' % variants['alabs_pythonteam']['capas']
+        sdk_zip_name = 'Python_%s%s_SDK_3rdEdFP2.zip' % (version, version_tag)
+
+    build_utils.unzip_file_into_dir(topdir + '\\build\\' + sdk_zip_name, '\\')
+    cmd_test = 'python setup.py test --testset-size 350 --sdk-version %s' % \
+                                                            sdk_version
+    run_cmd(cmd_test, exception_on_error=0)
+    run_cmd('python setup.py configure --sdk 30armv5')
+    run_cmd('python setup.py build extras\\elemlist\\group')
+    run_cmd('python setup.py configure --sdk 30gcce' + caps_opt)
+    run_cmd('python setup.py build extras\\elemlist\\group')
+
+    os.chdir('extras\\elemlist\\group')
+    try:
+        run_cmd('makesis elemlist.pkg')
+        run_cmd('signsis elemlist.sis %s %s %s' % (elemlist_sis_name,
+                                                   sign_cert, sign_key))
+        shutil.copy(elemlist_sis_name, '%s\\test\\%s' %
+                                   (python_readybuild_dir, elemlist_sis_name))
+    finally:
+        os.chdir(topdir)
+
+
+def release_build():
+    global platforms
+    global gflavors
+    global without_src_zip
+    global installer
+    global variants
+    global internal_proj
+    global build_profile
+
+    build_profile = 'release'
+    #Build for emu first and then build for device
+    gflavors = ['unsigned_alabs', 'alabs_pythonteam']
+    platforms = ['30armv5']
+    do_clean_and_build_emu('white_choco', platforms, run_regrtest=False)
+
+    # When run-interpretertimer is built using GCCE on 3.0SDK the compilation
+    # fails as it complains that the application is nested too deeply in the
+    # drive. The same error is not seen on 3.2SDK. To workaround this 3.0SDK
+    # quirk we don't build internal projects instead of the arduous task of
+    # either renaming the exe or moving the project somewhere else.
+    orig_internal_proj_value = internal_proj
+    internal_proj = False
+    build_device_and_move_sis(gflavors, ['30gcce'], create_sis=False)
+    internal_proj = orig_internal_proj_value
+
+    build_device_and_move_sis(gflavors, platforms, False)
+
+    run_cmd('python setup.py generate_ensymble')
+
+    create_and_move_zip('30armv5')
+
+    # Building for 3.2 sdk
+    platforms = ['32']
+    build_utils.create_clean_env('\\Epoc32_3.2.zip')
+    sdk_zip_name = deliverables_name['30armv5']['sdk_zip_name'][1] % \
+                                          (version, version_tag)
+    final_sdk_zip_name = deliverables_name['32']['sdk_zip_name'][1] % \
+                                          (version, version_tag)
+    os.rename(topdir + '\\build\\' + sdk_zip_name,
+              topdir + '\\build\\' + final_sdk_zip_name)
+    build_utils.unzip_file_into_dir(topdir + '\\build' +
+                                    '\\Python_SDK_3rdEd_temp.zip',
+                                    '\\')
+
+    # Building only scriptext, sensorfw and iad_client on 3.2
+    proj = ['..\\internal-src\\scriptext\\group', 'ext\\sensorfw\\group',
+            '..\\internal-src\\iad_client\\group']
+    # Configure for 3.2 sdk
+    do_setupdotpy_configure('unsigned_alabs', platforms[0])
+    for x in proj:
+        run_cmd('python setup.py build ' + x)
+
+    create_deliverables_using_elftran(platforms[0], gflavors, True)
+    code_size.updatelog("3.0", python_readybuild_dir + "\\" +
+            deliverables_name['30armv5']['python_dll_sis_name'][1] %
+            (version, version_tag, gflavors[0]),
+            "C:\\Program Files\\CruiseControl\\logs\\codesize_metrics.log")
+    delete_file(topdir + '\\build\\Python_SDK_3rdEd_temp.zip')
+
+    pyd_path = '\\epoc32\\release\\winscw\\udeb\\'
+    zip_object = zipfile.ZipFile(topdir + '\\build\\' + final_sdk_zip_name,
+                                 'a')
+    zip_object.write(pyd_path + 'kf_scriptext.pyd',
+                     pyd_path + 'kf_scriptext.pyd')
+    zip_object.close()
+
+    run_cmd('python setup.py generate_ensymble')
+    generate_scriptshell_sis()
+    test_sdk_zip('_3_2')
+    thread_pool = []
+    cmd_remote_buid = 'test_device_remote --work-area ' + \
+                       python_readybuild_dir
+    build_commands = ['generate_docs', 'coverage', cmd_remote_buid]
+
+    for x, command in enumerate(build_commands):
+        thread_pool.append(RunBuildCmd(command))
+        thread_pool[x].setName(command)
+    for threads in thread_pool:
+        threads.start()
+    for threads in thread_pool:
+        threads.join()
+        if threads.getName() == 'generate_docs':
+            t = BuildInstaller()
+            t.start()
+            t.join()
+    create_sdk_zip_31()
+    build_utils.create_clean_env('\\Epoc32_3.0.zip')
+    if without_src_zip == False:
+        # Create src zip
+        zipname = '%s\\' % (python_readybuild_dir) + \
+                  'pys60-%s%s_src.zip' % (version, version_tag)
+        create_archive_from_directory(zipname, os.getcwd(), 'src')
+
+
+def set_integration_env():
+    global gflavors
+    global version_tag
+    global variants
+    # 3.2 devices have 'Location' capability as user-grantable using selfsigned
+    # certificate
+    if '30armv5' not in platforms:
+        variants['selfsigned']['capas'] += ' Location'
+    gflavors = ['alabs_pythonteam', 'unsigned_alabs']
+    svn_revision = get_svn_revision()
+    version_tag = 'svn' + svn_revision + '-integration'
+
+
+def get_svn_revision():
+    out_put = run_shell_command('svnversion ' + PROJ_DIR)
+    [version, n] = out_put['stdout'].rsplit("\r")
+    return version
+
+
+def del_mod_repo(topdir):
+    deltree_if_exists(os.path.abspath('tools\\py2sis\\ensymble\\module-repo'))
+
+
+def integration_build():
+    global build_profile
+    del_mod_repo(topdir)
+
+    build_profile = 'integration'
+
+    do_clean_and_build_emu('white_choco', platforms)
+    build_device_and_move_sis(gflavors, platforms)
+    thread_pool = []
+    build_commands = []
+    if generate_docs:
+        build_commands.append('generate_docs')
+    if not without_ensymble:
+        build_commands.append('generate_ensymble')
+    for command in build_commands:
+        thread_pool.append(RunBuildCmd(command))
+    for threads in thread_pool:
+            threads.start()
+    for threads in thread_pool:
+            threads.join()
+    generate_ensymble_zip()
+    generate_scriptshell_sis()
+    for platform in platforms:
+        create_and_move_zip(platform)
+    if installer:
+        t = BuildInstaller()
+        t.start()
+        t.join()
+
+
+def main():
+    if grelease:
+        release_build()
+    elif integration_bld:
+        integration_build()
+    else:
+        if target == 'emu':
+            do_clean_and_build_emu(gflavors, platforms)
+        elif target == 'device':
+            build_device_and_move_sis(gflavors, platforms)
+        else:
+            do_clean_and_build_emu(gflavors, platforms)
+            build_device_and_move_sis(gflavors, platforms)
+
+    log('builder.py - Please find the deliverables in directory: %s'
+        % python_readybuild_dir)
+
+
+def show_configuration():
+    log('builder.py : The following values are considered for this build.\n'+
+         'Target -----------------> %s \n' % target +
+         'Version ----------------> %s \n' % version +
+         'Version tag ------------> %s \n' % version_tag +
+         'Build profile ----------> %s \n' % build_profile +
+         'Sdk --------------------> %s \n' % platforms +
+         'Work area --------------> %s \n' % python_readybuild_dir +
+         'Key dir ----------------> %s \n' % key_dir +
+         'Flavors ----------------> %s \n' % gflavors +
+         'Compile Docs flag ------> %s \n' % generate_docs +
+         'Integration build flag--> %s \n' % integration_bld +
+         'Release flag -----------> %s \n' % grelease +
+         'Compression type--------> %s \n' % compression_type +
+         'Profile log-------------> %s \n' % profiler +
+         'Include ..\internal_src-> %s \n' % include_internal_src +
+         'Without src zip---------> %s \n' % without_src_zip +
+         'Internal Projects-------> %s \n' % internal_proj +
+         'Without Ensymble--------> %s \n' % without_ensymble +
+         'Create Installer--------> %s \n' % installer)
+
+
+if __name__=="__main__":
+    global target
+    global version
+    global version_tag
+    global platforms
+    global python_readybuild_dir
+    global key_dir
+    global gflavors
+    global generate_docs
+    global grelease
+    global integration_bld
+
+    working_dir = os.getcwd()
+    init_args(sys.argv)
+    create_readybuild_dirs()
+    temp = time.strftime(python_readybuild_dir +
+                         "\\test\\pys60_build_log_%Y%m%d_%H%M.log")
+    log_file = tee(temp, 'w')
+    print time.strftime("Start Time: %a, %d %b %Y %H:%M:%S")
+    show_configuration()
+    main()
+    print time.strftime("End Time: %a, %d %b %Y %H:%M:%S")
+    log_file.close()
+    del tee