sdkcreationmw/sdkbuild/sdk_build.pl
changeset 0 b26acd06ea60
child 1 ac50fd48361b
equal deleted inserted replaced
-1:000000000000 0:b26acd06ea60
       
     1 #
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description:
       
    15 #
       
    16 #! /usr/bin/perl
       
    17 #
       
    18 # Series 60 SDK build script.
       
    19 #
       
    20 # Reads the configuration from sdk_build.conf file located in the same
       
    21 # directory as the build script. The comments in the configuration file
       
    22 # descripe its format.
       
    23 #
       
    24 # The important feature of this script is that it's not only part of the
       
    25 # nightly build, but also part of the SDK development environment.
       
    26 #
       
    27 #   First, it re-generates the diffs after developer has
       
    28 #   modified a platform file. It uses the diff utility
       
    29 #   provided by the Symbian build environment (as opposed
       
    30 #   to taking it from the PATH, be it MKS Toolkit, cygwin
       
    31 #   or whatever else you may have installed). That makes
       
    32 #   sure that the diff is produced in a standard format.
       
    33 #   Also, if the diff didn't really change (the script will
       
    34 #   ignore non-essential changes in the diff, such as time
       
    35 #   stamps in the header) the diff file in platform_mod
       
    36 #   doesn't get updated.
       
    37 #
       
    38 #   Second, the developers can (and do) re-run this script in
       
    39 #   their work area, and that will produce the same result as
       
    40 #   when it runs on top of a clean build area. Maybe not 100%
       
    41 #   the same, but accurate enough to provide, say 95% guarantee
       
    42 #   that if the build compiles on the developer's machine, it
       
    43 #   will do the same in the nightly build. That will help us
       
    44 #   to avoid broken builds.
       
    45 #
       
    46 #   Third, the script has minimal dependency on the
       
    47 #   environment (i.e. environment variables, where the
       
    48 #   CodeWarrior/VisualStudio/Perl are installed, etc.)
       
    49 #   A typical problem of the build scripts is that they
       
    50 #   make too many assumptions about the environment, and
       
    51 #   it's only a matter of time when one build script starts
       
    52 #   conflicting with another. Most developers build multiple
       
    53 #   products on their machines. I've been in the situations
       
    54 #   when one development environment breaks another. Very
       
    55 #   frustrating and inefficient.
       
    56 #
       
    57 
       
    58 use Cwd;
       
    59 use File::Copy;
       
    60 use File::Temp;
       
    61 use File::Path;
       
    62 use File::Find;
       
    63 use FindBin;
       
    64 use Env qw(JAVA_HOME EPOCROOT BUILD_ROOT MWCIncludes PATH);
       
    65 
       
    66 push (@INC, $FindBin::RealBin);
       
    67 
       
    68 require "sdk_env.pl";
       
    69 
       
    70 MAIN:{
       
    71   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime ();
       
    72 
       
    73 # Log levels
       
    74 $LOG_DEBUG = 2;
       
    75 $LOG_VERBOSE = 1;
       
    76 $LOG_NORMAL = 0;
       
    77 $LOG_QUIET = -1;
       
    78 $LOG_SILENT = -2;
       
    79 
       
    80 # Build types
       
    81 $BUILD_TYPE_CPP = 1;
       
    82 $BUILD_TYPE_MIDP = 2;
       
    83 $BUILD_TYPE_ALL = 3;
       
    84 
       
    85 # Editable configuration
       
    86 $LOGLEVEL = $LOG_NORMAL;
       
    87 $DO_PATCH = 0;
       
    88 $DO_DIFF = 0;
       
    89 $BUILD_PLATFORM = 0;
       
    90 $BUILD_JAVA = 0;
       
    91 $BUILD_SDK = 0;
       
    92 $LOG = 0;
       
    93 $CLEAN = 0;
       
    94 $REBUILD = 0;
       
    95 $BUILD_TYPE = $BUILD_TYPE_ALL;
       
    96 $CHECK_BUILD = 0;
       
    97 $DO_UNPATCH = 0;
       
    98 $FINALIZE_S60EX = 0;
       
    99 
       
   100 # Non-edtable configuration
       
   101 $FS = '/';  # File separator
       
   102 $PS = ';';  # Path separator
       
   103 @PLATFORMS = ("winscw");
       
   104 @VARIANTS  = ("udeb", "urel");
       
   105 @SDK_MODULES = (
       
   106   "NMIT",
       
   107  # "sdkcommonutils",
       
   108   "msgsimulation",
       
   109   "xrpcrt",
       
   110   "wsock",
       
   111   "scard",
       
   112 #  "MIDP", later needs to be enabled 
       
   113   "emumenubar",
       
   114   "bluetoothdriver",
       
   115   #"Tools",
       
   116  # "AsyStub"
       
   117 );
       
   118 
       
   119 $PATCH_LIST_FNAME = "sdk_build.conf";
       
   120 $PLATFORM = get_plat_name ();
       
   121 $SDK_PROJ_NAME = "PublicSDK/sdkcreationmw"; 
       
   122 $PATCH_DIR = "$SDK_PROJ_NAME/sdkplatformupdates/";
       
   123 $BUILD_SCRIPTS_DIR = $BUILD_ROOT . "$SDK_PROJ_NAME/sdkbuild";
       
   124 $S60_TOOLS_DIR = $BUILD_ROOT . "$SDK_PROJ_NAME/sdkruntimes";
       
   125 $BACKUP_PREFIX = ".#";
       
   126 $PATCH_EXT = "diff";
       
   127 $DIED_MSG = "ERROR!";
       
   128 $WARNING = "WARNING:";
       
   129 $NOTE = "NOTE:";
       
   130 $NULL_NAME = "NULL";
       
   131 
       
   132 $patch_list_path = "$BUILD_ROOT$PATCH_DIR/$PATCH_LIST_FNAME";
       
   133 $TMP_CONF = "$BUILD_SCRIPTS_DIR/__tmp.conf";
       
   134 
       
   135 $DIFF_EXE =  "$BUILD_SCRIPTS_DIR/diff.exe";
       
   136 $PATCH_EXE = "$BUILD_SCRIPTS_DIR/patch.exe";
       
   137 $REDIFF_CMD = "$DIFF_EXE -N -c5";
       
   138 
       
   139 $LOG_FILE = sprintf ("sdk_build-%d%02d%02d_%02d-%02d-%02d.log",
       
   140                      $year + 1900, $mon + 1, $mday, $hour, $min, $sec);
       
   141 
       
   142 # Define Java build configuration
       
   143 $JAVA_SRC_ROOT = "${BUILD_ROOT}PublicSDK/sdkcreationmw/sdkconnectivityfw/emuconnectmanager/epdt_java";
       
   144 $JAVA_BUILD_DIR = "${JAVA_SRC_ROOT}";
       
   145 $JAVA_DIST_DIR = "${JAVA_SRC_ROOT}/build/ecmt";
       
   146 $JAVA_TARGET_DIR = "${BUILD_ROOT}epoc32/tools/ecmt";
       
   147 @JAVA_CLEAN_DIRS = (
       
   148   "$JAVA_TARGET_DIR/config",
       
   149   "$JAVA_TARGET_DIR/language",
       
   150   "$JAVA_TARGET_DIR/lib",
       
   151   "$JAVA_TARGET_DIR/log",
       
   152   "$JAVA_TARGET_DIR/plugins"
       
   153 );
       
   154 
       
   155 
       
   156 # parse the command line
       
   157   parse_cmd_line (@ARGV);
       
   158 
       
   159   $BUILD_ROOT = $ENV{BUILD_ROOT};
       
   160   $EPOCROOT = $ENV{EPOCROOT};
       
   161 
       
   162   @bld_info = ();
       
   163   if ($LOG && !(open (LOG_FH, "> $LOG_FILE"))) {
       
   164     warn "Could'n open log file $LOG_FILE. Logging is turned OFF.\n";
       
   165     $LOG = 0;
       
   166   }
       
   167 
       
   168   # Make sure that the required executables are there
       
   169   if (!-e $DIFF_EXE) {
       
   170     err ($DIFF_EXE . " is missing");
       
   171     exit 1;
       
   172   }
       
   173 
       
   174   if (!-e $PATCH_EXE) {
       
   175     err ($PATCH_EXE . " is missing");
       
   176     exit 1;
       
   177   }
       
   178 
       
   179   msg ("Build script started at " . localtime());
       
   180   msg ("Cmd line: $0 @ARGV");
       
   181 
       
   182   open PATCH_LIST, $patch_list_path or die "$DIED_MSG Could not find $patch_list_path!";
       
   183 
       
   184   if ($DO_PATCH) {
       
   185 
       
   186     # IMPORTANT! SDK now maintains two startup-lists, which both are modified
       
   187     # versions of the original one, but patched differently. To achieve this
       
   188     # we have to first make a copy of the original list. The copy is made of
       
   189     # .orig, if such exists - if not (i.e. very first patch), then from then
       
   190     # original file.
       
   191     # Unfortunately there is no simple way to do this without hardcoding.
       
   192     #
       
   193     #$starter_path = "${BUILD_ROOT}sf/os/devicesrv/sysstatemgmt/starter/starterserver/data";
       
   194     #$starter_list = "starter.rss";
       
   195     #$starter_list2 = "starter_full.rss";
       
   196 
       
   197     #if (not -e "$starter_path/$starter_list2") {
       
   198      # dbg ("making a copy of the startup-list");
       
   199      # if (-e "$starter_path/$starter_list.orig") {
       
   200       #  copy_or_die ("$starter_path/$starter_list.orig", "$starter_path/$starter_list2");
       
   201      # } else {
       
   202       #  copy_or_die ("$starter_path/$starter_list", "$starter_path/$starter_list2");
       
   203      # }
       
   204    # }
       
   205     #else {
       
   206      # dbg ("full startup-list already exists");
       
   207    # }
       
   208     
       
   209    #  This starter is commented by Dhanvantri For Integration  
       
   210    # $starter_non_critical_path = "${BUILD_ROOT}sf/os/devicesrv/sysstatemgmt/starter/starterserver/data";
       
   211    # $starter_non_critical_list = "starter_non_critical_1.rss";
       
   212    # $starter_non_critical_list2 = "starter_non_critical_1_full.rss";
       
   213 
       
   214    # if (not -e "$starter_non_critical_path/$starter_non_critical_list2") {
       
   215    #   dbg ("making a copy of the startup-list");
       
   216    #   if (-e "$starter_non_critical_path/$starter_non_critical_list.orig") {
       
   217    #     copy_or_die ("$starter_non_critical_path/$starter_non_critical_list.orig", "$starter_non_critical_path/$starter_non_critical_list2");
       
   218     #  } else {
       
   219      #   copy_or_die ("$starter_non_critical_path/$starter_non_critical_list", "$starter_non_critical_path/$starter_non_critical_list2");
       
   220      # }
       
   221    # }
       
   222    # else {
       
   223     #  dbg ("full startup-list for non critical section already exists");
       
   224     #}
       
   225   }
       
   226 
       
   227   # Collect full path names for all pathes.
       
   228   @all_patches = find_all ("$BUILD_ROOT$PATCH_DIR");
       
   229   $lineno = 0;
       
   230   while (<PATCH_LIST>) {
       
   231     $lineno++;
       
   232     chomp;
       
   233     # Input lines might end in backslashes to indicate continuation
       
   234     if (s/\\$//) {
       
   235         $_ .= <PATCH_LIST>;
       
   236         redo unless eof;
       
   237     }
       
   238 
       
   239     s/\#.*$//;                 # Get rid of the comments
       
   240     next if (/^\s*$/);         # Skip empty lines
       
   241     my @fdata = split /:/;     # Split the input line
       
   242     foreach (@fdata) {         # Ignore spaces before and after delimiters
       
   243       s/^\s+//;
       
   244       s/\s+$//;
       
   245     }
       
   246 
       
   247     my $path = shift @fdata;
       
   248     next if ($path eq "");
       
   249 
       
   250     # The first field is a name of the patch file.
       
   251     # By default it's "diff"
       
   252     my $relative_path = $path;
       
   253     my $patch_file = get_patch_fname ($path, @all_patches);
       
   254 
       
   255     if ($patch_file eq "") {
       
   256       $patch_file = "$BUILD_ROOT" . "$PATCH_DIR" . "$path.$PATCH_EXT";
       
   257       dbg ("Looking for: $patch_file");
       
   258       if (not -e $patch_file) {
       
   259         # This means that there is an entry in the patch list file
       
   260         # but there is no actual patch file under patch dir.
       
   261         # If so skip the line. The exception is DO_DIFF case since do_diff
       
   262         # can create patch files.
       
   263         if ($DO_DIFF) {
       
   264           $patch_file = "";
       
   265         }
       
   266         else {
       
   267           msg("$WARNING $PATCH_LIST_FNAME:$lineno: Missing patch file for $path");
       
   268           next;
       
   269         }
       
   270       }
       
   271     }
       
   272     else {
       
   273       $patch_file .= ".$PATCH_EXT";
       
   274     }
       
   275 
       
   276     # This shouldn't happen: there is a patch file name but no name for file
       
   277     # to be patched. If so skip this line.
       
   278     next if ($path eq "");
       
   279     $path = "$BUILD_ROOT" . $path;
       
   280 
       
   281     if ($LOGLEVEL >= $LOG_VERBOSE) {
       
   282       if (-e "$patch_file") {
       
   283         dbg ("patch file: $patch_file");
       
   284       } else {
       
   285         dbg ("patch file does not exist: $patch_file");
       
   286       }
       
   287       dbg ("fdata: @fdata");
       
   288     }
       
   289 
       
   290     # Diff'ing files only. It will generate new "diff" files.
       
   291     if ($DO_DIFF) {
       
   292       chdir_or_die ($BUILD_ROOT);
       
   293       do_diff ($path, $patch_file);
       
   294       next;
       
   295     }
       
   296 
       
   297     # Patch platform files
       
   298     if ($DO_PATCH) {
       
   299       my $res_file = $patch_file;
       
   300       $res_file =~ s/\.$PATCH_EXT$//;
       
   301 
       
   302       # Make a backup copy of the current version of the patched file.
       
   303       if (-e $path) {
       
   304         my $backup_path = get_last_backup_path ($path);
       
   305         if (!run("$DIFF_EXE $res_file $path", $NULL_NAME)) {
       
   306           dbg("$path is identical to $res_file");
       
   307         }
       
   308         elsif (-e $backup_path &&
       
   309             !run("$DIFF_EXE $backup_path $path", $NULL_NAME)) {
       
   310           dbg("$path is identical to $backup_path");
       
   311         } else {
       
   312           # file has changed, create a backup copy
       
   313           my $backup_path = get_new_backup_path ($path);
       
   314           dbg ("backup to $backup_path");
       
   315           copy ("$path", "$backup_path") or
       
   316             msg("$WARNING failed to copy $path -> $backup_path");
       
   317         }
       
   318       }
       
   319 
       
   320       # If patch file does not exist, patch means a copy
       
   321       if (-e "$patch_file") {
       
   322         patch_files ($path, $patch_file);
       
   323       } else {
       
   324         copy_or_die ($res_file, $path);
       
   325         msg ("Copied $path");
       
   326       }
       
   327     }
       
   328 
       
   329 
       
   330     if ($DO_UNPATCH) {
       
   331       do_unpatch($path, $patch_file);
       
   332     }
       
   333 
       
   334     # Process build info
       
   335     if ($#fdata >= 0) {
       
   336       if ($BUILD_PLATFORM || $CHECK_BUILD) {
       
   337         process_bld_info ($path, @fdata);
       
   338       }
       
   339     }
       
   340   }
       
   341 
       
   342   close PATCH_LIST;
       
   343 
       
   344   # if temp conf-file was used (i.e. -t option given), remove tmp-file
       
   345   if ($patch_list_path == $TMP_CONF) {
       
   346     dbg("deleting $TMP_CONF");
       
   347     unlink $TMP_CONF;
       
   348   }
       
   349 
       
   350   # Build Java first
       
   351   if ($BUILD_JAVA) {
       
   352     build_java ();
       
   353   }
       
   354 
       
   355   # build SDK modules
       
   356   # NOTE: some of the hooks in the platform code depend on the headers
       
   357   # exported by, for example, MsgRelay module
       
   358   if ($BUILD_SDK) {
       
   359     foreach $m (@SDK_MODULES) {
       
   360       if ($m =~ m/^wsock$/i) {
       
   361         # hack to make EXPORT work reliably
       
   362         my $now = time;
       
   363         my $esk = "$S60_TOOLS_DIR/wsock/data/wsock.esk";
       
   364         dbg ("touching $esk");
       
   365         utime ($now, $now, $esk) or msg ("$WARNING couldn't touch $esk\n");
       
   366       }
       
   367       # the rest is a standard procedure for all modules
       
   368       build_series60_tools_component ($m); 
       
   369     }
       
   370   }
       
   371 
       
   372   if ($BUILD_PLATFORM) {
       
   373     dbg ("Build info: @bld_info");
       
   374     do_platform_build (@bld_info);
       
   375   }
       
   376 
       
   377   #rebuild Java Subsystem in S60 (System AMS) except for C++ SDK
       
   378   if($BUILD_PLATFORM && $BUILD_TYPE != $BUILD_TYPE_CPP){
       
   379   	dbg ("Building java platform:");
       
   380   	do_java_platform_build();
       
   381   }
       
   382 
       
   383   if ($CHECK_BUILD) {
       
   384     foreach $m (@SDK_MODULES) {
       
   385       check_series60_tools_component ($m);
       
   386     }
       
   387     dbg ("Build info: @bld_info");
       
   388     check_platform_build (@bld_info);
       
   389   }
       
   390 
       
   391   if($FINALIZE_S60EX && $BUILD_TYPE != $BUILD_TYPE_MIDP){
       
   392   	dbg ("Finalizing S60 C++ examples:");
       
   393   	do_s60ex_finalizing();
       
   394   	#TODO: Cleaning may not be required for 9.l check and add components in the below function
       
   395   	#do_s60_rndtools_cleaning();
       
   396   }
       
   397   
       
   398   
       
   399 	msg ("Build script finished at " . localtime());
       
   400   close ($LOG_FH) if $LOG;
       
   401 }
       
   402 
       
   403 # =======================================================================
       
   404   sub usage
       
   405 # =======================================================================
       
   406   {
       
   407     print "Usage: sdk_build [-p | --patch] [-d | --diff] [-u | --unpatch]\
       
   408                  [-b | --build] [-m | --module [mod]] [-a | --all]\
       
   409                  [-r | --rebuild] [-c | --clean] [-e | -- err] [-l | --log]\
       
   410                  [-s | --silent] [-q | --quiet] [-v | --verbose]\
       
   411                  [-f | --config <file>] [-h | --help]\
       
   412                  [-t | --target <file>]\
       
   413                  [--env] [--midp] [--cpp] [--udeb] [--urel] [--s60ex]\
       
   414 Options:\
       
   415   -p, --patch         patch the platform files\
       
   416   -d, --diff          diff the platform files and update patches\
       
   417   -u, --unpatch       undo patches and return platform to it's original state\
       
   418   -b, --build         build patched platform modules (implies -p)\
       
   419   -m, --module [mod]  build SDK modules (or one module if specified)\
       
   420   -j, --java          build Java mofules (EcmtManager, ...)\
       
   421   -a, --all           build everything (implies -b, -p, -m and -j)\
       
   422   -r, --rebuild       do complete rebuild rather than incremental build\
       
   423   -c, --clean         delete the output and intermediate files\
       
   424   -e, --err           check build errors\
       
   425   -l, --log           create log file in the current directory\
       
   426   -q, --quiet         be quiet\
       
   427   -s, --silent        be completely silent\
       
   428   -v, --verbose       be verbose (repeatable)\
       
   429   -f, --config <file> use <file> instead of patches/$PATCH_LIST_FNAME\
       
   430   -t, --target <file> patch/diff/unpatch a single target: <file>\
       
   431   -h, --help          print this help message and exit\
       
   432   --midp              MIDP build (don't build C++ specific components)\
       
   433   --cpp               C++ build (don't build MIDP specific components)\
       
   434   --udeb              only build debug (UDEB) targets\
       
   435   --urel              only build release (UREL) targets\
       
   436   --s60ex             finalize S60 C++ example applications\
       
   437   --env               print (some) build environment and exit\n";
       
   438   }
       
   439 
       
   440 # =======================================================================
       
   441   sub parse_cmd_line
       
   442 # =======================================================================
       
   443   {
       
   444     if ($#_ < 0) {
       
   445       usage ();
       
   446       exit;
       
   447     } else {
       
   448       $CONF_FILE_GIVEN = 0;
       
   449       $TARGET_FILE_GIVEN = 0;
       
   450       my $n = $#_ + 1;  # total number of options
       
   451       my $u = 0;        # number of unknown options
       
   452       while(defined (@_[0])) {
       
   453         my $arg = shift;
       
   454         if ($arg eq "-v" || $arg eq "--verbose")  { $LOGLEVEL++; }
       
   455         elsif ($arg eq "--env") {
       
   456           $LOGLEVEL = $LOG_VERBOSE;
       
   457           dbg("Environment variables:\n  JAVA_HOME: $ENV{JAVA_HOME}\n  EPOCROOT: $ENV{EPOCROOT}\n  BUILD_ROOT: $ENV{BUILD_ROOT}\n  MWCIncludes: $ENV{MWCIncludes}\n  PATH: $ENV{PATH}\n  INCLUDE: $ENV{INCLUDE}\n  LIB: $ENV{LIB}\n");
       
   458           exit;
       
   459         }
       
   460         elsif ($arg eq "--midp") {
       
   461           if ($BUILD_TYPE == $BUILD_TYPE_CPP) {
       
   462             err ("--midp and --cpp options are mutually exclusive");
       
   463             exit 1;
       
   464           }
       
   465           $BUILD_TYPE = $BUILD_TYPE_MIDP;
       
   466         }
       
   467         elsif ($arg eq "--cpp" || $arg eq "--c++") {
       
   468           if ($BUILD_TYPE == $BUILD_TYPE_MIDP) {
       
   469             err ("--midp and --cpp options are mutually exclusive");
       
   470             exit 1;
       
   471           }
       
   472           $BUILD_TYPE = $BUILD_TYPE_CPP;
       
   473         }
       
   474         elsif ($arg eq "--udeb") { @VARIANTS  = ("udeb"); }
       
   475         elsif ($arg eq "--urel") { @VARIANTS  = ("urel"); }
       
   476         elsif ($arg eq "-m" || $arg eq "--module" ) {
       
   477           $BUILD_SDK = 1;
       
   478           if ($DO_DIFF) {
       
   479             err ("--diff and --module options are mutually exclusive");
       
   480             exit 1;
       
   481           }
       
   482           # optional module name
       
   483           if (defined(@_[0])) {
       
   484             my $mod = @_[0];
       
   485             if (!($mod =~ m/^-/)) {
       
   486               @SDK_MODULES = (shift);
       
   487             }
       
   488           }
       
   489         }
       
   490         elsif ($arg eq "-b" || $arg eq "--build" ) {
       
   491           $BUILD_PLATFORM = 1;
       
   492           if (!$DO_UNPATCH) {
       
   493           $DO_PATCH = 1;
       
   494           }
       
   495           if ($DO_DIFF) {
       
   496             err ("--diff and --build options are mutually exclusive");
       
   497             exit 1;
       
   498           }
       
   499         }
       
   500         elsif ($arg eq "-p" || $arg eq "--patch" ) {
       
   501           $DO_PATCH = 1;
       
   502           if ($DO_DIFF) {
       
   503             err ("--diff and --patch options are mutually exclusive");
       
   504             exit 1;
       
   505           }
       
   506           if ($DO_UNPATCH) {
       
   507             err ("--patch and --unpatch options are mutually exclusive");
       
   508             exit 1;
       
   509           }
       
   510         }
       
   511         elsif ($arg eq "-u" || $arg eq "--unpatch") {
       
   512           $DO_UNPATCH = 1;
       
   513           if ($DO_DIFF) {
       
   514             err ("--diff and --unpatch options are mutually exclusive");
       
   515             exit 1;
       
   516           }
       
   517           if ($BUILD_PLATFORM) {
       
   518             $DO_PATCH = 0;
       
   519           }
       
   520           if ($DO_PATCH) {
       
   521             err("--patch and --unpatch options are mutually exclusive");
       
   522             exit 1;
       
   523           }
       
   524         }
       
   525         elsif ($arg eq "-d" || $arg eq "--diff") {
       
   526           $DO_DIFF = 1;
       
   527           if ($BUILD_PLATFORM) {
       
   528             err ("--diff and --build options are mutually exclusive");
       
   529             exit 1;
       
   530           }
       
   531           if ($DO_PATCH) {
       
   532             err ("--diff and --patch options are mutually exclusive");
       
   533             exit 1;
       
   534           }
       
   535           if ($DO_UNPATCH) {
       
   536             err ("--diff and --unpatch options are mutually exclusive");
       
   537             exit 1;
       
   538           }
       
   539         }
       
   540         elsif ($arg eq "-l" || $arg eq "--log") { $LOG = 1; }
       
   541         elsif ($arg eq "-q" || $arg eq "--quiet") { $LOGLEVEL = $LOG_QUIET; }
       
   542         elsif ($arg eq "-s" || $arg eq "--silent") { $LOGLEVEL = $LOG_SILENT; }
       
   543         elsif ($arg eq "-j" || $arg eq "--java") { $BUILD_JAVA = 1; }
       
   544         elsif ($arg eq "-a" || $arg eq "--all") {
       
   545           $BUILD_PLATFORM = 1;
       
   546           $BUILD_JAVA = 1;
       
   547           $BUILD_SDK = 1;
       
   548           $DO_PATCH = 1;
       
   549           if ($DO_DIFF) {
       
   550             err ("--diff and --all options are mutually exclusive");
       
   551             exit 1;
       
   552           }
       
   553           if ($DO_UNPATCH) {
       
   554             err ("--all and --unpatch options are mutually exclusive");
       
   555             exit 1;
       
   556           }
       
   557         }
       
   558         elsif ($arg eq "-r" || $arg eq "--rebuild") { $REBUILD = 1; }
       
   559         elsif ($arg eq "-c" || $arg eq "--clean") { $CLEAN = 1; }
       
   560         elsif ($arg eq "-e" || $arg eq "--err") { $CHECK_BUILD = 1; }
       
   561         elsif ($arg eq "-h" || $arg eq "--help" ) { usage (); exit; }
       
   562         elsif ($arg eq "-f" || $arg eq "--config" ) {
       
   563           $CONF_FILE_GIVEN = 1;
       
   564           if ($TARGET_FILE_GIVEN) {
       
   565             err ("--config and --target options are mutually exclusive");
       
   566             exit 1;
       
   567           }
       
   568           if (defined(@_[0])) {
       
   569             $patch_list_path = shift;
       
   570           }
       
   571           else {
       
   572             err ("-f should follow the filename");
       
   573             exit 1;
       
   574           }
       
   575         }
       
   576         elsif ($arg eq "-t" || $arg eq "--target") {
       
   577           $TARGET_FILE_GIVEN = 1;
       
   578           if ($CONF_FILE_GIVEN) {
       
   579             err ("--config and --target options are mutually exclusive");
       
   580             exit 1;
       
   581           }
       
   582           if ($BUILD_PLATFORM) {
       
   583             err ("--target can only be used with --patch, --unpatch or --diff");
       
   584             exit 1;
       
   585           }
       
   586           if (defined(@_[0])) {
       
   587             # patch or diff target-file given. create a temporary config-file
       
   588             # note, makes sense only when doing just patch, unpatch or diff
       
   589             # operation.
       
   590             my $tmp_file = shift;
       
   591             system("echo $tmp_file > $TMP_CONF");
       
   592             $patch_list_path = $TMP_CONF;
       
   593           }
       
   594           else {
       
   595             err ("--target should follow the path to the patched file");
       
   596             exit 1;
       
   597           }
       
   598         }
       
   599         elsif ($arg eq "--s60ex") { $FINALIZE_S60EX = 1; }
       
   600         else {
       
   601           warn "unrecognized commang line option $arg\n";
       
   602           $u++;
       
   603         }
       
   604       }
       
   605       if ($n == $u) {
       
   606         # not a single valid option
       
   607         usage ();
       
   608         exit;
       
   609       }
       
   610       if ($CHECK_BUILD) {
       
   611         $BUILD_SDK = 0;
       
   612         $BUILD_PLATFORM = 0;
       
   613         $DO_PATCH = 0;
       
   614         $BUILD_JAVA = 0;
       
   615       }
       
   616     }
       
   617   }
       
   618 
       
   619 
       
   620 # =======================================================================
       
   621 # Builds Java part of the SDK.
       
   622 # =======================================================================
       
   623   sub build_java
       
   624 # =======================================================================
       
   625   {
       
   626     if ($REBUILD || $CLEAN) {
       
   627       chdir_or_die ($JAVA_SRC_ROOT);
       
   628       for $i (0 .. $#JAVA_CLEAN_DIRS) {
       
   629         $dir = $JAVA_CLEAN_DIRS[$i];
       
   630         dbg ("Deleting $dir");
       
   631         rmtree($dir);
       
   632       }
       
   633 
       
   634       chdir_or_die ($JAVA_BUILD_DIR);
       
   635       run_build_cmd ("ant clean");
       
   636 
       
   637     }
       
   638 
       
   639     if (!$CLEAN) {
       
   640       chdir_or_die ($JAVA_BUILD_DIR);
       
   641       my $epdt_target = "build";
       
   642       if ($BUILD_TYPE == $BUILD_TYPE_MIDP) {
       
   643         $epdt_target = "midp";
       
   644       } elsif ($BUILD_TYPE == $BUILD_TYPE_CPP) {
       
   645         $epdt_target = "cpp";
       
   646       }
       
   647       run_build_cmd ("ant " . $epdt_target);
       
   648       xcopy ($JAVA_DIST_DIR, $JAVA_TARGET_DIR);
       
   649 
       
   650       if ($BUILD_TYPE == $BUILD_TYPE_MIDP ||
       
   651       					$BUILD_TYPE == $BUILD_TYPE_ALL) {
       
   652 				open(DUMMY_FH, ">","${JAVA_TARGET_DIR}\\MIDP.txt");
       
   653 
       
   654 				if(!copy("${BUILD_ROOT}\\sdkcreationmw\\sdkcomponents\\Common_Patch\\epoc32\\data\\sdk_info.properties",
       
   655 				"${BUILD_ROOT}\\epoc32\\data\\sdk_info.properties"))
       
   656 				{
       
   657 					msg("Couldn't copy file sdk_info.properties\n");
       
   658 					msg($!);
       
   659 				}
       
   660 
       
   661 
       
   662 			}
       
   663 
       
   664     }
       
   665   }
       
   666 
       
   667 # =======================================================================
       
   668   sub do_diff
       
   669 # =======================================================================
       
   670   {
       
   671     my $path = shift;
       
   672     my $patch_file = shift;
       
   673     my $relative_path;
       
   674     my $relative_orig;
       
   675 
       
   676     ($relative_path = $path) =~ s/^([A-Za-z])\:$FS//g;
       
   677     $relative_orig = $relative_path . ".orig";
       
   678     if (! -e $relative_path) {
       
   679       msg ("$WARNING Missing $relative_path. No diff was done.");
       
   680       return;
       
   681     }
       
   682 
       
   683     if ($patch_file eq "") {
       
   684       # if don't have patch file yet. Pehaps we running diff for a first time.
       
   685       $patch_file = $PATCH_DIR . $relative_path . ".$PATCH_EXT";
       
   686       dbg ("patch_file is empty. New patch_file is $patch_file");
       
   687       my $patch_dir = get_dir_name ($patch_file);
       
   688       if (! -e $patch_dir) {
       
   689         mkpath ($patch_dir) or die "Couldn't create $patch_dir: $@";
       
   690       }
       
   691     }
       
   692     $patch_file =~ s/^([A-Za-z])\:$FS//g;
       
   693     my $result_file;
       
   694     ($result_file = $patch_file) =~ s/\.$PATCH_EXT$//;
       
   695     my $esc_path;
       
   696     ($esc_path = $relative_path) =~ s/([\\\/\.])/\\$1/g;
       
   697     my $ignore_match = "\"^[\\*-][\\*-][\\*-] $esc_path\"";
       
   698     my $tmp_file = $patch_dir . $BACKUP_PREFIX .
       
   699                       File::Temp::mktemp (get_fname ($patch_file) . "XXXXX");
       
   700     my $cmd = $REDIFF_CMD . " $relative_orig $relative_path";
       
   701     my $res = 0;
       
   702     my $derr = 1;
       
   703 
       
   704     if (-e "$relative_orig") {
       
   705       $res = 1;
       
   706       dbg ("working on $relative_path");
       
   707       run ($cmd, $tmp_file);
       
   708       if (-e $patch_file) {
       
   709         # Let's see if we got a different patch file that we already have.
       
   710         # We don't want to just replace patch file we have with new one
       
   711         # because source save might be too picky about changing time stamp
       
   712         # and if new and old patch file are equal we will keep the old one.
       
   713         $res = run ("$DIFF_EXE -N -I $ignore_match $tmp_file $patch_file",
       
   714                     $NULL_NAME);
       
   715       }
       
   716 
       
   717       if ($res == 2) {
       
   718         die "$DIED_MSG Couldn't diff $tmp_file and $patch_file\n";
       
   719       }
       
   720       elsif ($res == 1) {
       
   721           # New patch file is differerent so replace old patch file
       
   722           # with new one.
       
   723           msg ("Diffing $relative_path");
       
   724           chmod 666, $patch_file;
       
   725           rename "$tmp_file", "$patch_file";
       
   726       }
       
   727       else {
       
   728         unlink $tmp_file;
       
   729       }
       
   730     }
       
   731 
       
   732     # check, if resulted .diff-file is zero-size. If so, abort.
       
   733     # (either patch is obsolete or you manually messed things up)
       
   734     if (-e $patch_file && not -s "$patch_file") {
       
   735         die "$DIED_MSG $patch_file size is 0!\nCheck the patch!\n";
       
   736     }
       
   737 
       
   738     $derr = run ("$DIFF_EXE $relative_path $result_file", $NULL_NAME);
       
   739     dbg ("derr: $derr, res: $res");
       
   740     if ($res == 1 || $derr > 0) {
       
   741       # Patch files are different so the result file has to be updated.
       
   742       if (-e "$relative_orig") {
       
   743         # This is normal condition, no need to display this message
       
   744         # unless verbose output is on
       
   745         dbg ("Copying $relative_path to $result_file");
       
   746       } else {
       
   747         # Or we don't have .orig file, so we just want to copy plat. file
       
   748         # to patch dir. In that case issue a normal message
       
   749         msg ("Copying $relative_path to $result_file");
       
   750       }
       
   751       copy ($relative_path, $result_file);
       
   752       chmod 666, $result_file;
       
   753     }
       
   754     else {
       
   755       msg ("Checking $relative_path ...");
       
   756     }
       
   757   }
       
   758 
       
   759 
       
   760 # =======================================================================
       
   761   sub patch_files
       
   762 # =======================================================================
       
   763   {
       
   764     my $path = shift;
       
   765     my $patch_file = shift;
       
   766 
       
   767     # remove read-only bits from all the files in the dir of the file-to-be-patched
       
   768     my $tmp_dir = get_dir_name ($path);
       
   769     my $cmd = "attrib -r /s /d $tmp_dir*.*";
       
   770     dbg($cmd);
       
   771     system($cmd);
       
   772 
       
   773     my ($p_err, $d_err) = do_patch ($path, $patch_file);
       
   774     my $res_file;
       
   775 
       
   776     ($res_file = $patch_file) =~ s/\.$PATCH_EXT$//;
       
   777 
       
   778     if ($p_err == 0) {
       
   779       msg ("Patched $path");
       
   780       if ($d_err == 2) {
       
   781         die "$DIED_MSG PATCH RESULT: Diff failed while comparing $path and $res_file\n";
       
   782       }
       
   783       elsif ($d_err == 1) {
       
   784        msg ("$WARNING PATCH RESULT: $path does not match $res_file\n");
       
   785       }
       
   786       else {
       
   787         dbg ("PATCH RESULT: res $p_err, diff res: $d_err. Proceeding");
       
   788       }
       
   789 
       
   790       # additionally check, if .diff-file is zero-size. If so, print a note.
       
   791       # (either patch is obsolete or you manually messed things up)
       
   792       # note, that we still continue.
       
   793       if (not -s "$patch_file") {
       
   794           msg ("$NOTE $patch_file size is 0!\nCheck the patch!\n");
       
   795       }
       
   796     }
       
   797     elsif ($p_err == -1) {
       
   798       die "$DIED_MSG PATCH FAILED: Couldn't start the patch command!\n";
       
   799     }
       
   800     else {
       
   801       die "$DIED_MSG PATCH FAILED for $path!\n";
       
   802     }
       
   803   }
       
   804 
       
   805 
       
   806 # =======================================================================
       
   807   sub chdir_to_build_specific_dir
       
   808 # =======================================================================
       
   809   {
       
   810     my $dir;
       
   811     if ($BUILD_TYPE == $BUILD_TYPE_MIDP) {
       
   812       $dir = "midp";
       
   813     } elsif ($BUILD_TYPE == $BUILD_TYPE_CPP) {
       
   814       $dir = "cpp";
       
   815     } else {
       
   816       return;
       
   817     }
       
   818 
       
   819     if (-f "$dir/bld.inf") {
       
   820       chdir $dir;
       
   821     }
       
   822   }
       
   823 
       
   824 # =======================================================================
       
   825   sub do_platform_build
       
   826 # =======================================================================
       
   827   {
       
   828     # Build patched platform modules
       
   829     foreach $b (@bld_info) {
       
   830       my @modules = split /,/, $b;
       
   831       my $group_dir = shift @modules;
       
   832       chdir_or_die ("$BUILD_ROOT$group_dir");
       
   833       dbg ("Building in $BUILD_ROOT$group_dir");
       
   834       run ("cmd /c bldmake.bat bldfiles");
       
   835 
       
   836       #modules are optional
       
   837       if(@modules>0)
       
   838       {
       
   839 	      foreach $m (@modules)
       
   840 	      {
       
   841 	        build_module ($m);
       
   842 	      }
       
   843 	    }
       
   844 	    else
       
   845 	    {
       
   846 	    	build_module('');
       
   847 	    }
       
   848     }
       
   849   }
       
   850  
       
   851 # =======================================================================
       
   852   sub do_java_platform_build
       
   853 # =======================================================================
       
   854   {
       
   855     # Build java system ams
       
   856   		my $java_group_dir = "sf/app/java/group";
       
   857       chdir_or_die ("$BUILD_ROOT$java_group_dir");
       
   858       dbg ("Building in $BUILD_ROOT$java_group_dir");
       
   859       run ("cmd /c bldmake.bat bldfiles");
       
   860       run ("cmd /c abld.bat export");
       
   861       run ("cmd /c pbuild build winscw udeb midp2ams");
       
   862       run ("cmd /c pbuild build winscw udeb wma");
       
   863       run ("cmd /c pbuild build winscw udeb multimedia11");
       
   864 			
       
   865 			my $s60ex_dir = $BUILD_ROOT . "$SDK_PROJ_NAME/sdkexamples/javaexamples";
       
   866 			chdir_or_die ($s60ex_dir);
       
   867 			
       
   868 			run_build_cmd("ant IAPInfoMIDlet eSWTMIDlet SystemProperties");
       
   869 			run_build_cmd("ant copy_documentation");
       
   870 		  $cmd = "unzip -o \\\\filerblr\\SP\\AM\\DT_SDK\\SDK_BIS\\Repository\\Java_API\\IAPInfoMIDlet_doc.zip -d Z\:\\PublicSDK\\sdkcreationmw\\sdkexamples\\javaexamples\\dist\\examples\\IAPInfoMIDlet";
       
   871       print ($cmd."\n"); system ($cmd);
       
   872       $cmd = "unzip -o \\\\filerblr\\SP\\AM\\DT_SDK\\SDK_BIS\\Repository\\Java_API\\eSWTMIDlet_doc.zip -d Z\:\\PublicSDK\\sdkcreationmw\\sdkexamples\\javaexamples\\dist\\examples\\eSWTMIDlet";
       
   873       print ($cmd."\n"); system ($cmd);
       
   874       $cmd = "unzip -o \\\\filerblr\\SP\\AM\\DT_SDK\\SDK_BIS\\Repository\\Java_API\\SystemPropertiesMidlet_doc.zip -d Z\:\\PublicSDK\\sdkcreationmw\\sdkexamples\\javaexamples\\dist\\examples\\SystemProperties";
       
   875       print ($cmd."\n"); system ($cmd);
       
   876       system("copy /V Z\:\\PublicSDK\\sdkcreationmw\\sdkexamples\\javaexamples\\examples\\examples.html Z\:\\PublicSDK\\sdkcreationmw\\sdkexamples\\javaexamples\\dist\\examples");
       
   877       system("copy /V \\\\filerblr\\SP\\AM\\DT_SDK\\SDK_BIS\\Repository\\Java_API\\build.xml Z\:\\PublicSDK\\sdkcreationmw\\sdkexamples\\javaexamples\\dist\\examples\\IAPInfoMIDlet\\targets");
       
   878   }
       
   879 
       
   880 # =======================================================================
       
   881   sub check_platform_build
       
   882 # =======================================================================
       
   883   {
       
   884     foreach $b (@bld_info) {
       
   885       my @modules = split /,/, $b;
       
   886       my $group_dir = shift @modules;
       
   887       if (!chdir ("$BUILD_ROOT$group_dir")) {
       
   888         msg ("$DIED_MSG missing $BUILD_ROOT$group_dir!!!!!!!!");
       
   889         return;
       
   890       };
       
   891       #modules are optional
       
   892       if(@modules>0)
       
   893       {
       
   894 	      foreach $m (@modules)
       
   895 	      {
       
   896           check_module_build ($m);
       
   897 	      }
       
   898 	    }
       
   899 	    else
       
   900 	    {
       
   901         check_module_build ('');
       
   902 	    }
       
   903 
       
   904     }
       
   905   }
       
   906 
       
   907 
       
   908 # =======================================================================
       
   909   sub check_module_build
       
   910 # =======================================================================
       
   911   {
       
   912     my $dir = getcwd;
       
   913     my $module = shift;
       
   914     dbg ("Checking $dir");
       
   915     foreach $t (@PLATFORMS) {
       
   916       if (!-e "ABLD.BAT") {
       
   917         run ("cmd /c bldmake.bat bldfiles");
       
   918       }
       
   919       run ("cmd /c abld.bat build -c $t $module");
       
   920     }
       
   921   }
       
   922 
       
   923 
       
   924 # =======================================================================
       
   925   sub build_series60_tools_component
       
   926 # =======================================================================
       
   927   {
       
   928     my $name = shift;
       
   929     my $dir = "$S60_TOOLS_DIR/$name/group";
       
   930     chdir_or_die ($dir);
       
   931     chdir_to_build_specific_dir ();
       
   932     dbg ("Building in " . getcwd);
       
   933     run ("cmd /c bldmake.bat bldfiles");
       
   934     run ("cmd /c abld.bat export");
       
   935     run ("cmd /c abld.bat makefile");
       
   936     foreach $bt (@VARIANTS) {
       
   937       if($REBUILD || $CLEAN) {
       
   938         run_build_cmd ( "cmd /c abld.bat clean $bt");
       
   939       }
       
   940       if (!$CLEAN) {
       
   941         run_build_cmd ( "cmd /c abld.bat -k build $bt");
       
   942       }
       
   943     }
       
   944   }
       
   945 
       
   946 
       
   947 # =======================================================================
       
   948   sub check_series60_tools_component
       
   949 # =======================================================================
       
   950   {
       
   951     my $name = shift;
       
   952     my $dir = "$S60_TOOLS_DIR/$name/group";
       
   953     if (!chdir ($dir)) {
       
   954       msg ("$DIED_MSG Missing $dir!!!!!!!!");
       
   955       return;
       
   956     };
       
   957     chdir_to_build_specific_dir ();
       
   958     dbg ("Checking " . getcwd);
       
   959     if (!-e "ABLD.BAT") {
       
   960       run ("cmd /c bldmake.bat bldfiles");
       
   961     }
       
   962     run ("cmd /c abld.bat build -c");
       
   963   }
       
   964 
       
   965 
       
   966 # =======================================================================
       
   967   sub build_module
       
   968 # =======================================================================
       
   969   {
       
   970     my $module = shift;
       
   971 
       
   972     foreach $t (@PLATFORMS) {
       
   973       if (!$CLEAN) 
       
   974       {
       
   975         run_build_cmd ( "cmd /c abld.bat makefile $t $module");
       
   976       }
       
   977       foreach $bt (@VARIANTS) 
       
   978       {
       
   979         if($REBUILD || $CLEAN) 
       
   980         {
       
   981           run_build_cmd ( "cmd /c abld.bat clean $t $bt $module");
       
   982         }
       
   983         if (!$CLEAN) 
       
   984         {
       
   985           	run_build_cmd ( "cmd /c abld.bat -k build $t $bt $module");
       
   986         }
       
   987       }
       
   988     }
       
   989   }
       
   990 
       
   991 
       
   992 # =======================================================================
       
   993   sub do_patch
       
   994 # =======================================================================
       
   995   {
       
   996     my $dest = shift;
       
   997     my $patch_file = shift;
       
   998     my $res_file;
       
   999     my $perr = 0;
       
  1000     my $derr = 0;
       
  1001     my $silent = ($LOGLEVEL > $LOG_NORMAL) ? "" : "-s";
       
  1002 
       
  1003     ($res_file = $patch_file) =~ s/\.diff$//;
       
  1004 
       
  1005     # Overwrite the destination file with the .orig file. If .orig file
       
  1006     # is not found, assume that it's the very first patch and create the
       
  1007     # .orig file
       
  1008     if (-e "$dest.orig") {
       
  1009       copy_or_die ("$dest.orig", "$dest");
       
  1010     } else {
       
  1011       dbg ("creating new orig file $dest.orig");
       
  1012       copy_or_die ("$dest", "$dest.orig");
       
  1013     }
       
  1014 
       
  1015     $perr = run ("$PATCH_EXE $silent -d $BUILD_ROOT -p0 -N --ignore-whitespace --no-backup-if-mismatch -i $patch_file $dest");
       
  1016     dbg ("PATCH: error $perr");
       
  1017 
       
  1018     if ($perr == 0) {
       
  1019       if ($LOGLEVEL >= $LOG_VERBOSE) {
       
  1020         $derr = run ("$DIFF_EXE $dest $res_file");
       
  1021       }
       
  1022       else {
       
  1023         $derr = run ("$DIFF_EXE $dest $res_file", $NULL_NAME);
       
  1024       }
       
  1025       dbg ("Diff for $dest and $res_file returned $derr");
       
  1026     }
       
  1027     return ($perr, $derr);
       
  1028   }
       
  1029 
       
  1030 
       
  1031 # =======================================================================
       
  1032   sub do_unpatch
       
  1033 # =======================================================================
       
  1034   {
       
  1035     my $dest = shift;
       
  1036     my $patch_file = shift;
       
  1037     my $backup_path = get_first_backup_path($dest);
       
  1038     my $res_file = $patch_file;
       
  1039     $res_file =~ s/\.$PATCH_EXT$//;
       
  1040 
       
  1041     # try to restore the original version
       
  1042     if (-e "$dest.orig") {
       
  1043       # there is a "orig file", so just rename "orig" back to $dest
       
  1044       msg("restoring $dest from \".orig\"...");
       
  1045       copy_or_die("$dest.orig", "$dest");
       
  1046     }
       
  1047     elsif (-e "$backup_path") {
       
  1048         # there is no ".orig" file but there is backup file,
       
  1049         # restore from there.
       
  1050         msg("Restoring $dest from backup file.");
       
  1051         copy_or_die("$backup_path", "$dest");
       
  1052     }
       
  1053     elsif (!-e $patch_file &&
       
  1054            !run("$DIFF_EXE $dest $res_file", $NULL_NAME)) {
       
  1055         # there are no .orig and backup files and the result
       
  1056         # file ($res_file) is the same as in the platform ($dest).
       
  1057         # This is most likely the file that was copied to the platform,
       
  1058         # so remove it.
       
  1059         msg("Removing current copy of $dest");
       
  1060         unlink $dest;
       
  1061     }
       
  1062 
       
  1063   }
       
  1064 
       
  1065 
       
  1066 # =======================================================================
       
  1067   sub process_bld_info
       
  1068 # =======================================================================
       
  1069   {
       
  1070     my $file = shift;
       
  1071     my $idx = 0;
       
  1072 
       
  1073     foreach $b (@_) {
       
  1074       @bld_data = split /,/, $b;
       
  1075       $bld_inf_path = shift @bld_data;
       
  1076 
       
  1077       die "$DIED_MSG Dir. name for bld.inf is empty. Line: $b\n" if $bld_inf_path eq "";
       
  1078 
       
  1079       # Get the index of the $bld_info element that starts with $bld_inf_path.
       
  1080       $idx = bld_info_arr_idx ($bld_inf_path);
       
  1081 
       
  1082       if ($idx < 0) {
       
  1083         # There is no such entry in the $bld_info, so just add entire line.
       
  1084         push (@bld_info, $b);
       
  1085       } else {
       
  1086         # There is an entry that starts with $bld_inf_path, so just add
       
  1087         # modules that are not there to the $idx-th line (element of $bld_info)
       
  1088         @bld_data_idx = split /,/, $bld_info[$idx];
       
  1089         shift @bld_data_idx;
       
  1090 
       
  1091         foreach $m (@bld_data) {
       
  1092           $bld_info[$idx] =~ s/\,$m\,/\,/g;
       
  1093           $bld_info[$idx] =~ s/\,$m$//g;
       
  1094           $bld_info[$idx] .= ",$m";
       
  1095         }
       
  1096       }
       
  1097     }
       
  1098   }
       
  1099 
       
  1100 
       
  1101 # =======================================================================
       
  1102   sub bld_info_arr_idx
       
  1103 # =======================================================================
       
  1104   {
       
  1105     my $val = shift;
       
  1106     my $idx = 0;
       
  1107 
       
  1108     for ($idx = 0; $idx < $#bld_info + 1; $idx++) {
       
  1109       last if ($bld_info[$idx] =~ m/^$val\,/);
       
  1110     }
       
  1111 
       
  1112     if ($idx ==  $#bld_info + 1) {$idx = -1;}
       
  1113     return $idx;
       
  1114   }
       
  1115 
       
  1116 
       
  1117 # =======================================================================
       
  1118   sub get_last_backup_path
       
  1119 # =======================================================================
       
  1120   {
       
  1121     my $orig_path = shift;
       
  1122     my $new_ver = get_last_file_ver ($orig_path);
       
  1123     my $dir = get_dir_name ($orig_path);
       
  1124     my $fname = get_fname ($orig_path);
       
  1125     my $backup_path = $dir . $BACKUP_PREFIX . $fname . ".$new_ver";
       
  1126     return $backup_path;
       
  1127   }
       
  1128 
       
  1129 # =======================================================================
       
  1130   sub get_first_backup_path
       
  1131 # =======================================================================
       
  1132   {
       
  1133     my $orig_path = shift;
       
  1134     my $dir = get_dir_name ($orig_path);
       
  1135     my $fname = get_fname ($orig_path);
       
  1136     my $backup_path = $dir . $BACKUP_PREFIX . $fname . ".1";
       
  1137     return $backup_path;
       
  1138   }
       
  1139 
       
  1140 
       
  1141 # =======================================================================
       
  1142   sub get_new_backup_path
       
  1143 # =======================================================================
       
  1144   {
       
  1145     my $orig_path = shift;
       
  1146     my $new_ver = get_last_file_ver ($orig_path) + 1;
       
  1147     my $dir = get_dir_name ($orig_path);
       
  1148     my $fname = get_fname ($orig_path);
       
  1149     my $backup_path = $dir . $BACKUP_PREFIX . $fname . ".$new_ver";
       
  1150     return $backup_path;
       
  1151   }
       
  1152 
       
  1153 
       
  1154 # =======================================================================
       
  1155   sub get_last_file_ver
       
  1156 # =======================================================================
       
  1157 # Assupmtion: if file name is "foo.cpp" the n-th version of this file would be
       
  1158 # in the same directory and would have name "#foo.cpp.n"
       
  1159   {
       
  1160     my $path = shift;
       
  1161     my $dir = get_dir_name ($path);
       
  1162     my $fname = get_fname ($path);
       
  1163     my $basename = get_basename ($fname);
       
  1164     my $postfix = 0;
       
  1165 
       
  1166     if ($dir eq "") {$dir = "."}
       
  1167     opendir (DIR, $dir);
       
  1168     @flist = grep {/^$BACKUP_PREFIX$basename.*\..*\.[0-9]+$/} readdir (DIR);
       
  1169     closedir DIR;
       
  1170 
       
  1171     if ($#flist + 1 > 0) {
       
  1172       foreach $f (@flist) {
       
  1173         my $p = unpack ("A*", get_ext ($f));
       
  1174         $postfix = $p if $postfix < $p;
       
  1175       }
       
  1176     }
       
  1177     return $postfix;
       
  1178   }
       
  1179 
       
  1180 
       
  1181 # ========================================================================
       
  1182   sub get_basename
       
  1183 # ========================================================================
       
  1184   {
       
  1185     my $orig_name = shift;
       
  1186     my $basename;
       
  1187     ($basename = $orig_name) =~ s/\..*$//g;
       
  1188     return $basename;
       
  1189   }
       
  1190 
       
  1191 
       
  1192 # ========================================================================
       
  1193   sub get_ext
       
  1194 # ========================================================================
       
  1195   {
       
  1196     my $orig_name = shift;
       
  1197     my $ext;
       
  1198     ($ext = $orig_name) =~ s/^.*\.//g;
       
  1199     return $ext;
       
  1200   }
       
  1201 
       
  1202 
       
  1203 # =======================================================================
       
  1204   sub get_fname
       
  1205 # =======================================================================
       
  1206   {
       
  1207     my $orig_name = shift;
       
  1208     my $dir = get_dir_name ($orig_name);
       
  1209     my $fname;
       
  1210     ($fname = $orig_name) =~ s/\\/\//g;
       
  1211     $fname =~ s/^$dir//g;
       
  1212     return $fname;
       
  1213   }
       
  1214 
       
  1215 
       
  1216 # =======================================================================
       
  1217   sub get_dir_name
       
  1218 # =======================================================================
       
  1219   {
       
  1220     my $orig_name = shift;
       
  1221     my $dir_name;
       
  1222     ($dir_name = $orig_name) =~ s/\\/\//g;
       
  1223     $dir_name =~ s/[^\/]+$//g;
       
  1224     return $dir_name;
       
  1225   }
       
  1226 
       
  1227 
       
  1228 # =======================================================================
       
  1229   sub err
       
  1230 # =======================================================================/
       
  1231   {
       
  1232     my $m = "ERROR: @_[0]\n";
       
  1233     print $m;
       
  1234     print LOG_FH $m if $LOG;
       
  1235     exit 1;
       
  1236   }
       
  1237 
       
  1238 
       
  1239 # =======================================================================
       
  1240   sub quiet
       
  1241 # =======================================================================/
       
  1242   {
       
  1243     if ($LOGLEVEL => $LOG_QUIET) {
       
  1244       my $m = "*** @_[0]\n";
       
  1245       print $m;
       
  1246       print LOG_FH $m if $LOG;
       
  1247     }
       
  1248   }
       
  1249 
       
  1250 
       
  1251 # =======================================================================
       
  1252   sub msg
       
  1253 # =======================================================================/
       
  1254   {
       
  1255     if ($LOGLEVEL >= $LOG_NORMAL) {
       
  1256       my $m = "*** @_[0]\n";
       
  1257       print $m;
       
  1258       print LOG_FH $m if $LOG;
       
  1259     }
       
  1260   }
       
  1261 
       
  1262 
       
  1263 # =======================================================================
       
  1264   sub dbg
       
  1265 # =======================================================================
       
  1266   {
       
  1267     if ($LOGLEVEL >= $LOG_VERBOSE) {
       
  1268       my $dbg_msg = "=== @_[0]\n";
       
  1269       print $dbg_msg;
       
  1270       print LOG_FH $dbg_msg if $LOG;
       
  1271     }
       
  1272   }
       
  1273 
       
  1274 
       
  1275 # =======================================================================
       
  1276   sub noisy
       
  1277 # =======================================================================
       
  1278   {
       
  1279     if ($LOGLEVEL > $LOG_VERBOSE) {
       
  1280       my $m = "=== @_[0]\n";
       
  1281       print $m;
       
  1282       print LOG_FH $m if $LOG;
       
  1283     }
       
  1284   }
       
  1285 
       
  1286 
       
  1287 # =======================================================================
       
  1288   sub run_build_cmd
       
  1289 # =======================================================================
       
  1290   {
       
  1291     my $cmd = shift;
       
  1292     if ($LOGLEVEL >= $LOG_NORMAL) {
       
  1293       my $dir = getcwd;
       
  1294       msg ("***********************************************************");
       
  1295       msg ("* DIR:   $dir");
       
  1296       msg ("* BUILD: $cmd");
       
  1297       msg ("***********************************************************");
       
  1298     } else {
       
  1299       msg ($cmd);
       
  1300     }
       
  1301     my $err = run ($cmd);
       
  1302     dbg ("$cmd returned $err");
       
  1303     return $err;
       
  1304   }
       
  1305 
       
  1306 
       
  1307 # =======================================================================
       
  1308   sub run
       
  1309 # =======================================================================
       
  1310   {
       
  1311     my $cmd = shift;
       
  1312     my $out_name = shift;
       
  1313     my $close_out = 0;
       
  1314     my $out;
       
  1315 
       
  1316     dbg ("Running: $cmd");
       
  1317     if (defined($out_name)) {
       
  1318       if ($out_name eq $NULL_NAME) {
       
  1319         # no output desired
       
  1320         undef $out;
       
  1321       } else {
       
  1322         open OUT, "> $out_name" or
       
  1323           die "$DIED_MSG $cmd couldn't write to output $out_name!!!\n";
       
  1324         $out = OUT;
       
  1325         $close_out = 1;
       
  1326       }
       
  1327     } elsif ($LOGLEVEL <= $LOG_SILENT) {
       
  1328       # output supressed by log level
       
  1329       undef $out;
       
  1330     } else {
       
  1331       $out = STDOUT;
       
  1332     }
       
  1333 
       
  1334     open CHILD, "$cmd 2>&1|" or die "$DIED_MSG $cmd Err: $!";
       
  1335     while (<CHILD>) {
       
  1336       if (defined ($out)) {
       
  1337         print $out $_;
       
  1338         print LOG_FH $_ if $LOG;
       
  1339       }
       
  1340     }
       
  1341     close CHILD;
       
  1342     close $out if $close_out;
       
  1343     noisy ("return code " . ($? >> 8));
       
  1344     return $? >> 8;
       
  1345   }
       
  1346 
       
  1347 
       
  1348 # =======================================================================
       
  1349 # Changes the current direcctory, dies on error
       
  1350 # =======================================================================
       
  1351   sub chdir_or_die
       
  1352 # =======================================================================
       
  1353   {
       
  1354     my $dir = shift;
       
  1355     dbg ("chdir $dir");
       
  1356     chdir $dir or die "$DIED_MSG $dir: $!";
       
  1357   }
       
  1358 
       
  1359 
       
  1360 # =======================================================================
       
  1361 # Copies a file, dies on error
       
  1362 # =======================================================================
       
  1363   sub copy_or_die
       
  1364 # =======================================================================
       
  1365   {
       
  1366     my $src = shift;
       
  1367     my $dest = shift;
       
  1368     dbg ("copying $src -> $dest");
       
  1369     #if the file exists, rename it to .orig_X - safer than overwriting
       
  1370     #note: if we neither rename nor remove existing $dest, copy gives
       
  1371     #fatal error
       
  1372     if(-e $dest)
       
  1373     {
       
  1374     	my $i = 1;
       
  1375     	while(-e "$dest.orig_$i")
       
  1376     	{
       
  1377     		$i++;
       
  1378     	}
       
  1379     	move($dest, "$dest.orig_$i");
       
  1380     }
       
  1381     copy ($src, $dest) or
       
  1382       die "$DIED_MSG : failed to copy $src -> $dest: $!";
       
  1383   }
       
  1384 
       
  1385 
       
  1386 
       
  1387 # =======================================================================
       
  1388 #
       
  1389 # Recursive copy
       
  1390 #
       
  1391 # Copies a folder, its sub folders & files therein.
       
  1392 # Paramter 1: Source folder path.
       
  1393 # Paramter 2: Destination folder path.
       
  1394 #
       
  1395 # =======================================================================
       
  1396   sub xcopy
       
  1397 # =======================================================================
       
  1398   {
       
  1399     my ($CopyFrom,$CopyTo) = @_;
       
  1400     my ($src,$RelativePath,$dest);
       
  1401 
       
  1402     # Make sure that the source directory exists, create the top level
       
  1403     # destination directory
       
  1404     if (-d $CopyFrom) {
       
  1405       eval { mkpath($CopyTo) };
       
  1406       if ($@) {
       
  1407         err("Couldn't create $_[0]: $@");
       
  1408         exit(1);
       
  1409       }
       
  1410     } else {
       
  1411       err("Directory $CopyFrom does not exist");
       
  1412       return;
       
  1413     }
       
  1414 
       
  1415     dbg("Copying $CopyFrom -> $CopyTo");
       
  1416 
       
  1417     # Traverse file tree (highest level directory first)
       
  1418     find(sub{
       
  1419       $src=$File::Find::name;
       
  1420       $RelativePath=$src;
       
  1421       $RelativePath=~s/^\Q$CopyFrom\E//;
       
  1422       $dest=$CopyTo.$RelativePath;
       
  1423       if (-f $src) {  # Copy file
       
  1424         noisy ("$dest");
       
  1425         if (!copy($src,$dest)) {
       
  1426           err("Couldn't copy $src: $@");
       
  1427         }
       
  1428       } else {  # Make a duplicate directory if necessary
       
  1429         unless($dest eq '..'||$dest eq '.') {
       
  1430           unless(-e $dest) {
       
  1431             noisy ("Creating $dest");
       
  1432             mkdir($dest,0775);
       
  1433           }
       
  1434         }
       
  1435       }
       
  1436     },$CopyFrom);
       
  1437   }
       
  1438 
       
  1439 
       
  1440 # ========================================================================
       
  1441   sub get_patch_fname
       
  1442 # ========================================================================
       
  1443   {
       
  1444     my $patch_name = shift;
       
  1445     my $res;
       
  1446 
       
  1447     foreach $f (@_) {
       
  1448       if ($f =~ m/$patch_name$/i) {
       
  1449         $res = $f;
       
  1450         last;
       
  1451       }
       
  1452     }
       
  1453     return $res;
       
  1454   }
       
  1455 
       
  1456 
       
  1457 # ========================================================================
       
  1458   sub find_all
       
  1459 # ========================================================================
       
  1460   {
       
  1461     my $base_dir = shift;
       
  1462     my @flist = ();
       
  1463 
       
  1464     find (sub {
       
  1465       if (-f $File::Find::name) {
       
  1466         push (@flist, $File::Find::name);
       
  1467       }
       
  1468     }, $base_dir);
       
  1469 
       
  1470     return @flist
       
  1471   }
       
  1472 
       
  1473 # ========================================================================
       
  1474   sub get_plat_name
       
  1475 # ========================================================================
       
  1476   {
       
  1477     return "3.0";
       
  1478   }
       
  1479 
       
  1480 # ========================================================================
       
  1481   sub do_s60ex_finalizing
       
  1482 # ========================================================================
       
  1483   {
       
  1484     my $s60ex_dir = $BUILD_ROOT . "$SDK_PROJ_NAME/ExamplesCpp/build";
       
  1485     chdir_or_die ($s60ex_dir);
       
  1486     run ("cmd /c finalize.bat");
       
  1487   }
       
  1488 
       
  1489 # ========================================================================
       
  1490 sub do_s60_rndtools_cleaning
       
  1491 # ========================================================================
       
  1492   {
       
  1493   	# List of tools that needs to be make cleaned to remove "rnd tools" from emulator menu
       
  1494     print "\n \n ======== Start Clean RnD Tools===========";
       
  1495     @rndtools_cleandirs = qw ( s:/s60/tools/commontools/group s:/s60/tools/performancetools/group s:/s60/tools/nettools/ConnTest/group s:/ppd_sw/rd_sw/prism_rnd/group  s:/ppd_sw/rd_sw/btproxy_rnd/group  s:/ppd_sw/rd_sw/bappeaprofiler/group  s:/ppd_sw/rd_sw/analyzetool/group  s:/ppd_sw/rd_sw/hti/src/HtiAdmin/group  s:/ppd_sw/rd_sw/hti/src/HtiAutoStart/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiBtCommPlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiIPCommPlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiIsaCommPlugin/HtiIsaCommEcomPlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiIsaCommPlugin/HtiIsaCommServer/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiSerialCommPlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiTraceCommPlugin/HtiTraceCommEcomPlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiTraceCommPlugin/HtiTraceCommServer/group  s:/ppd_sw/rd_sw/hti/src/HtiCommPlugins/HtiUsbSerialCommPlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiDeviceReboot  s:/ppd_sw/rd_sw/hti/src/HtiFileHlp  s:/ppd_sw/rd_sw/hti/src/HtiFramework/group  s:/ppd_sw/rd_sw/hti/src/HtiWatchDog  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiAppServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiAudioServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiEchoServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiFtpServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiIpProxyServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiIsiMsgServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiKeyEventServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiMessagesServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiPIMServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiScreenshotServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiStifTfServicePlugin/group  s:/ppd_sw/rd_sw/hti/src/HtiServicePlugins/HtiSysInfoServicePlugin/group  s:/ppd_sw/cs_salo_domain/aiemailplugin/group s:/s60/mw/securityservices/iaupdate/IAD/group );
       
  1496 
       
  1497     # Make clean to remove "rnd tools" from emulator: suggestion given by pf team
       
  1498     foreach my $rndtools_cleandirs ( @rndtools_cleandirs )
       
  1499     {     
       
  1500       print "\n\n=== Clean up of rnd tools: $rndtools_cleandirs\n\n ===";
       
  1501       chdir $rndtools_cleandirs or print  " WARNING: Can chdir to $rndtools_cleandirs: $!";
       
  1502     
       
  1503       $cmd = "call bldmake bldfiles";
       
  1504       system ($cmd); #==0 or print ($cmd."\n\n");
       
  1505 
       
  1506       $cmd = "call abld makefile";
       
  1507       system ($cmd); #==0 or print ($cmd."\n\n");
       
  1508 
       
  1509       $cmd = "call abld reallyclean";
       
  1510       system ($cmd); #==0 or print ($cmd."\n\n");
       
  1511     }
       
  1512   }