bin/createpackage.pl
branchRCL_3
changeset 7 3f74d0d4af4c
parent 4 3b1da2848fc7
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
    52 use Getopt::Long;
    52 use Getopt::Long;
    53 # Use file name parsing module
    53 # Use file name parsing module
    54 use File::Basename;
    54 use File::Basename;
    55 # Use File::Spec services mainly rel2abs
    55 # Use File::Spec services mainly rel2abs
    56 use File::Spec;
    56 use File::Spec;
       
    57 # Use File::Path - to make stub sis target directory
       
    58 use File::Path;
    57 # use CWD abs_bath, which is exported only on request
    59 # use CWD abs_bath, which is exported only on request
    58 use Cwd 'abs_path';
    60 use Cwd 'abs_path';
    59 
    61 
    60 
    62 
    61 sub Usage() {
    63 sub Usage() {
    62     print <<ENDUSAGESTRING;
    64     print <<ENDUSAGESTRING;
    63 
    65 
    64 ==============================================================================================
    66 ==============================================================================================
    65 Convenience script for creating signed packages you can install on your phone.
    67 Convenience script for creating signed packages you can install on your phone.
    66 
    68 
    67 Usage: createpackage.pl [options] templatepkg target-platform [certificate key [passphrase]]
    69 Usage: createpackage.pl [options] templatepkg [target]-[platform] [certificate key [passphrase]]
    68 
    70 
    69 Where supported optiobns are as follows:
    71 Where supported optiobns are as follows:
    70      [-i|install]            = Install the package right away using PC suite
    72      [-i|install]            = Install the package right away using PC suite
    71      [-p|preprocess]         = Only preprocess the template .pkg file.
    73      [-p|preprocess]         = Only preprocess the template .pkg file.
    72      [-c|certfile=<file>]    = The file containing certificate information for signing.
    74      [-c|certfile=<file>]    = The file containing certificate information for signing.
    73                                The file can have several certificates, each specified in
    75                                The file can have several certificates, each specified in
    74                                separate line. The certificate, key and passphrase in line
    76                                separate line. The certificate, key and passphrase in line
    75                                must be ';' separated. Lines starting with '#' are treated 
    77                                must be ';' separated. Lines starting with '#' are treated
    76                                as a comments. Also empty lines are ignored. The paths in 
    78                                as a comments. Also empty lines are ignored. The paths in
    77                                <file> can be absolute or relative to <file>.
    79                                <file> can be absolute or relative to <file>.
       
    80      [-u|unsigned]           = Preserves the unsigned package
    78 Where parameters are as follows:
    81 Where parameters are as follows:
    79      templatepkg             = Name of .pkg file template
    82      templatepkg             = Name of .pkg file template
    80      target                  = Either debug or release
    83      target                  = Either debug or release
    81      platform                = One of the supported platform
    84      platform                = One of the supported platform
    82                                winscw | gcce | armv5 | armv6 | armv7
    85                                winscw | gcce | armv5 | armv6 | armv7
    84      key                     = The certificate's private key file
    87      key                     = The certificate's private key file
    85      passphrase              = The certificate's private key file's passphrase
    88      passphrase              = The certificate's private key file's passphrase
    86 
    89 
    87 Example:
    90 Example:
    88      createpackage.pl fluidlauncher_template.pkg release-armv5
    91      createpackage.pl fluidlauncher_template.pkg release-armv5
    89      
    92 
    90 Example with certfile:
    93 Example with certfile:
    91      createpackage.pl -c=mycerts.txt fluidlauncher_template.pkg release-armv5
    94      createpackage.pl -c=mycerts.txt fluidlauncher_template.pkg release-armv5
    92      
    95 
    93      Content of 'mycerts.txt' must be something like this:
    96      Content of 'mycerts.txt' must be something like this:
    94         # This is comment line, also the empty lines are ignored
    97         # This is comment line, also the empty lines are ignored
    95         rd.cer;rd-key.pem
    98         rd.cer;rd-key.pem
    96         .\\cert\\mycert.cer;.\\cert\\mykey.key;yourpassword
    99         .\\cert\\mycert.cer;.\\cert\\mykey.key;yourpassword
    97         X:\\QtS60\\selfsigned.cer;X:\\QtS60\\selfsigned.key
   100         X:\\QtS60\\s60installs\\selfsigned.cer;X:\\QtS60\\s60installs\\selfsigned.key
    98 
   101 
    99 If no certificate and key files are provided, either a RnD certificate or
   102 If no certificate and key files are provided, either a RnD certificate or
   100 a self-signed certificate from Qt installation root directory is used.
   103 a self-signed certificate from QtDir\\src\\s60installs directory is used.
   101 ==============================================================================================
   104 ==============================================================================================
   102 
   105 
   103 ENDUSAGESTRING
   106 ENDUSAGESTRING
   104 
   107 
   105     exit();
   108     exit();
   107 
   110 
   108 # Read given options
   111 # Read given options
   109 my $install = "";
   112 my $install = "";
   110 my $preprocessonly = "";
   113 my $preprocessonly = "";
   111 my $certfile = "";
   114 my $certfile = "";
   112 
   115 my $preserveUnsigned = "";
   113 unless (GetOptions('i|install' => \$install, 'p|preprocess' => \$preprocessonly, 'c|certfile=s' => \$certfile)){
   116 my $stub = "";
       
   117 
       
   118 unless (GetOptions('i|install' => \$install,
       
   119                    'p|preprocess' => \$preprocessonly,
       
   120                    'c|certfile=s' => \$certfile,
       
   121                    'u|unsigned' => \$preserveUnsigned,
       
   122                    's|stub' => \$stub,)){
   114     Usage();
   123     Usage();
   115 }
   124 }
   116 
   125 
   117 my $certfilepath = abs_path(dirname($certfile));
   126 my $certfilepath = abs_path(dirname($certfile));
   118 
   127 
   132 my $key = $ARGV[3];
   141 my $key = $ARGV[3];
   133 my $passphrase = $ARGV[4];
   142 my $passphrase = $ARGV[4];
   134 
   143 
   135 # Generate output pkg basename (i.e. file name without extension)
   144 # Generate output pkg basename (i.e. file name without extension)
   136 my $pkgoutputbasename = $templatepkg;
   145 my $pkgoutputbasename = $templatepkg;
   137 $pkgoutputbasename =~ s/_template\.pkg/_$targetplatform/g;
   146 my $preservePkgOutput = "";
       
   147 $pkgoutputbasename =~ s/_template/_$targetplatform/g;
       
   148 if ($pkgoutputbasename eq $templatepkg) {
       
   149     $preservePkgOutput = "1";
       
   150 }
       
   151 $pkgoutputbasename =~ s/\.pkg//g;
   138 $pkgoutputbasename = lc($pkgoutputbasename);
   152 $pkgoutputbasename = lc($pkgoutputbasename);
   139 
   153 
   140 # Store output file names to variables
   154 # Store output file names to variables
   141 my $pkgoutput = lc($pkgoutputbasename.".pkg");
   155 my $pkgoutput = lc($pkgoutputbasename.".pkg");
   142 my $unsigned_sis_name = $pkgoutputbasename."_unsigned.sis";
   156 my $sisoutputbasename = lc($pkgoutputbasename);
   143 my $signed_sis_name = $pkgoutputbasename.".sis";
   157 $sisoutputbasename =~ s/_$targetplatform//g;
       
   158 my $unsigned_sis_name = $sisoutputbasename."_unsigned.sis";
       
   159 my $signed_sis_name = $sisoutputbasename.".sis";
       
   160 my $stub_sis_name = $sisoutputbasename."_stub.sis";
   144 
   161 
   145 # Store some utility variables
   162 # Store some utility variables
   146 my $scriptpath = dirname(__FILE__);
   163 my $scriptpath = dirname(__FILE__);
   147 my $certtext = $certificate;
   164 my $certtext = $certificate;
   148 my $certpath = $scriptpath;
   165 my $certpath = $scriptpath;
   149 $certpath =~ s-^(.*[^\\])$-$1\\-o;          # ensure path ends with a backslash
   166 $certpath =~ s-^(.*[^\\])$-$1\\-o;          # ensure path ends with a backslash
   150 $certpath =~ s-/-\\-go;                     # for those working with UNIX shells
   167 $certpath =~ s-/-\\-go;                     # for those working with UNIX shells
   151 $certpath =~ s-bin\\$-src\\s60installs\\-;  # certificates are one step up in hierarcy
   168 $certpath =~ s-bin\\$-src\\s60installs\\-;  # certificates are one step up in hierarcy
   152 
   169 
   153 # Check some pre-conditions and print error messages if needed
   170 # Check some pre-conditions and print error messages if needed.
   154 unless (length($templatepkg) && length($platform) && length($target)) {
   171 unless (length($templatepkg)) {
   155     print "\nError: Template PKG filename, platform or target is not defined!\n";
   172     print "\nError: Template PKG filename is not defined!\n";
   156     Usage();
   173     Usage();
       
   174 }
       
   175 
       
   176 # If the pkg file is not actually a template, there is no need for plaform or target.
       
   177 if ($templatepkg =~ m/_template\.pkg/i) {
       
   178     unless (length($platform) && length($target)) {
       
   179         print "\nError: Platform or target is not defined!\n";
       
   180         Usage();
       
   181     }
   157 }
   182 }
   158 
   183 
   159 # Check template exist
   184 # Check template exist
   160 stat($templatepkg);
   185 stat($templatepkg);
   161 unless( -e _ ) {
   186 unless( -e _ ) {
   190     while(<CERTFILE>){
   215     while(<CERTFILE>){
   191         s/#.*//;                            # ignore comments by erasing them
   216         s/#.*//;                            # ignore comments by erasing them
   192         next if /^(\s)*$/;                  # skip blank lines
   217         next if /^(\s)*$/;                  # skip blank lines
   193         chomp;                              # remove trailing newline characters
   218         chomp;                              # remove trailing newline characters
   194         my @certinfo = split(';', $_);      # split row to certinfo
   219         my @certinfo = split(';', $_);      # split row to certinfo
   195         
   220 
   196         # Trim spaces
   221         # Trim spaces
   197         for(@certinfo) {
   222         for(@certinfo) {
   198             s/^\s+//;
   223             s/^\s+//;
   199             s/\s+$//;
   224             s/\s+$//;
   200         }        
   225         }
   201         
   226 
   202         # Do some validation
   227         # Do some validation
   203         unless(scalar(@certinfo) >= 2 && scalar(@certinfo) <= 3 && length($certinfo[0]) && length($certinfo[1]) ) {    
   228         unless(scalar(@certinfo) >= 2 && scalar(@certinfo) <= 3 && length($certinfo[0]) && length($certinfo[1]) ) {
   204             print "\nError: $certfile line '$_' does not contain valid information!\n";
   229             print "\nError: $certfile line '$_' does not contain valid information!\n";
   205             Usage();            
   230             Usage();
   206         }   
   231         }
   207 
   232 
   208         push @certificates, [@certinfo];    # push data to two dimensional array
   233         push @certificates, [@certinfo];    # push data to two dimensional array
   209     }
   234     }
   210 }
   235 }
   211 
   236 
   212 # Remove any existing .sis packages
   237 # Remove any existing .sis packages
   213 unlink $unsigned_sis_name;
   238 unlink $unsigned_sis_name;
   214 unlink $signed_sis_name;
   239 unlink $signed_sis_name;
   215 unlink $pkgoutput;
   240 if (!$preservePkgOutput) {
       
   241     unlink $pkgoutput;
       
   242 }
   216 
   243 
   217 # Preprocess PKG
   244 # Preprocess PKG
   218 local $/;
   245 local $/;
   219 # read template file
   246 # read template file
   220 open( TEMPLATE, $templatepkg) or die "Error '$templatepkg': $!\n";
   247 open( TEMPLATE, $templatepkg) or die "Error '$templatepkg': $!\n";
   232 
   259 
   233 if ($preprocessonly) {
   260 if ($preprocessonly) {
   234     exit;
   261     exit;
   235 }
   262 }
   236 
   263 
   237 # Create SIS.
   264 if($stub) {
   238 system ("makesis $pkgoutput $unsigned_sis_name");
   265     if(!($ENV{EPOCROOT})) { die("EPOCROOT must be set to create stub sis files"); }
   239 
   266     my $systeminstall = "$ENV{EPOCROOT}epoc32/data/z/system/install";
   240 # Sign SIS with certificate info given as an argument.
   267     mkpath($systeminstall);
   241 system ("signsis $unsigned_sis_name $signed_sis_name $certificate $key $passphrase");
   268     my $stub_sis_name = $systeminstall."/".$stub_sis_name;
   242 
   269     # Create stub SIS.
   243 # Check if creating signed SIS Succeeded
   270     system ("makesis -s $pkgoutput $stub_sis_name");
   244 stat($signed_sis_name);
       
   245 if( -e _ ) {
       
   246     print ("\nSuccessfully created $signed_sis_name using certificate: $certtext!\n");
       
   247 
       
   248     # Sign with additional certificates & keys
       
   249     for my $row ( @certificates ) {
       
   250         # Get certificate absolute file names, relative paths are relative to certfilepath
       
   251         my $abscert = File::Spec->rel2abs( $row->[0], $certfilepath);
       
   252         my $abskey = File::Spec->rel2abs( $row->[1], $certfilepath);
       
   253 
       
   254         system ("signsis $signed_sis_name $signed_sis_name $abscert $abskey $row->[2]");
       
   255         print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n");
       
   256     }
       
   257     
       
   258     # remove temporary pkg and unsigned sis
       
   259     unlink $pkgoutput;
       
   260     unlink $unsigned_sis_name;
       
   261 
       
   262     # Install the sis if requested
       
   263     if ($install) {
       
   264         print ("\nInstalling $signed_sis_name...\n");
       
   265         system ("$signed_sis_name");
       
   266     }
       
   267 } else {
   271 } else {
   268     # Lets leave the generated PKG for problem solving purposes
   272     # Create SIS.
   269     print ("\nSIS creation failed!\n");
   273     system ("makesis $pkgoutput $unsigned_sis_name");
   270 }
   274     print("\n");
   271 
   275 
       
   276     # Sign SIS with certificate info given as an argument.
       
   277     system ("signsis $unsigned_sis_name $signed_sis_name $certificate $key $passphrase");
       
   278 
       
   279     # Check if creating signed SIS Succeeded
       
   280     stat($signed_sis_name);
       
   281     if( -e _ ) {
       
   282         my $targetInsert = "";
       
   283         if ($targetplatform ne "-") {
       
   284             $targetInsert = "for $targetplatform ";
       
   285         }
       
   286         print ("Successfully created $signed_sis_name ${targetInsert}using certificate: $certtext!\n");
       
   287 
       
   288         # Sign with additional certificates & keys
       
   289         for my $row ( @certificates ) {
       
   290             # Get certificate absolute file names, relative paths are relative to certfilepath
       
   291             my $abscert = File::Spec->rel2abs( $row->[0], $certfilepath);
       
   292             my $abskey = File::Spec->rel2abs( $row->[1], $certfilepath);
       
   293 
       
   294             system ("signsis $signed_sis_name $signed_sis_name $abscert $abskey $row->[2]");
       
   295             print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n");
       
   296         }
       
   297 
       
   298         # remove temporary pkg and unsigned sis
       
   299         if (!$preservePkgOutput) {
       
   300             unlink $pkgoutput;
       
   301         }
       
   302         if (!$preserveUnsigned) {
       
   303             unlink $unsigned_sis_name;
       
   304         }
       
   305 
       
   306         # Install the sis if requested
       
   307         if ($install) {
       
   308             print ("\nInstalling $signed_sis_name...\n");
       
   309             system ("$signed_sis_name");
       
   310         }
       
   311     } else {
       
   312         # Lets leave the generated PKG for problem solving purposes
       
   313         print ("\nSIS creation failed!\n");
       
   314     }
       
   315 }
   272 
   316 
   273 #end of file
   317 #end of file