diff -r 000000000000 -r ca70ae20a155 src/builder.py --- /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