|
1 # |
|
2 # Copyright (c) 2008 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 the License "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: Creates SIS installation packages for S60 Browser that |
|
15 # meets Arrow/IAD program requirements for delivery to end-user devices. |
|
16 # Also generates R&D signed SIS packages for Nokia R&D internal use. |
|
17 # |
|
18 |
|
19 # TODOs |
|
20 # Baseline whatlog and build whatlog need to be processed and compared |
|
21 |
|
22 # Notes for maintainers: |
|
23 # Versioning guide: |
|
24 # http://s60wiki.nokia.com/S60Wiki/How_to_guide_for_versioning |
|
25 # Eclipsing ROM files using installers |
|
26 # http://s60wiki.nokia.com/S60Wiki/How_to_guide_for_eclipsing_ROM_files |
|
27 # Installers basics |
|
28 # http://s60wiki.nokia.com/S60Wiki/How_to_guide_for_creating/signing_sis_files |
|
29 # SIS file naming convention for IAD delivery |
|
30 # http://s60wiki.nokia.com/S60Wiki/How_to_guide_for_uploading_sis_packages_to_IAD_server |
|
31 |
|
32 use strict; |
|
33 use warnings; |
|
34 use Getopt::Long; |
|
35 use Data::Dumper; |
|
36 use File::Path; |
|
37 use Benchmark; |
|
38 |
|
39 my $usage = q{ |
|
40 Usage: buildIADsis.pl -opmode dev -appversion 7.1.2 -binversion 10.1 -variant 01 -nocache -verbose |
|
41 |
|
42 Mandatory arguments: |
|
43 -opmode : either dev or integration. If integration, use filelist argument below |
|
44 -appversion: Browser version as a string e.g 7.1.420 (major.minor.build). Minor must be 1 digit. |
|
45 -variant: S60 platform specific variant code. E.g for 3.23: 01->English, 22->Chinese etc. |
|
46 |
|
47 Optional arguments: |
|
48 -filelist: A text file containing list of files to include in the PKG |
|
49 File paths must be of the form \epoc32\dir\urel\file.ext |
|
50 -binversion: version to inject inside all EXEs and DLLs. Must be 10.0 or higher. |
|
51 -nocache: does everything cleanly, no old data used |
|
52 -verbose: Turns on debug statements |
|
53 -webkey: Web signing key filename |
|
54 -webcert: Web signing certificate filename |
|
55 -cenrepkey: Cenrep signing key filename |
|
56 -cenrepcert: Cenrep signing certificate filename |
|
57 |
|
58 }; |
|
59 |
|
60 my ($rawFilelist,$appVersion, $binVersion, $variant,$opmode,$lang_code); |
|
61 my (@variants); |
|
62 my $langgroup; |
|
63 my $type = "rnd"; |
|
64 my $brExe_UID3 = "0x10008D39"; #Unique ID for Browser application |
|
65 my $packageTypeMajor = "RU"; # even though we use SA,RU, mention the RU in filename since it sounds more important |
|
66 #TODO: We should be able to query the S60 platform by parsing some file in epoc32. Dunno how to do this. This should NOT be hardcoded. |
|
67 my $s60platform = "S60.323"; |
|
68 my $cenrepPkg = ".\\pkg\\BrowserNG_Cenrep.pkg"; |
|
69 my $cenrepSis = "BrowserNG_Cenrep.sis"; |
|
70 my $finalBrowserPkg = ".\\pkg\\BrowserNG.pkg"; |
|
71 my $debug_printing = 1; |
|
72 my $nocache = 0; |
|
73 #TODO: We might want to pass this as a command-line argument? Note that unsigned SIS is also generated and can always |
|
74 # be signed separately. |
|
75 my $webkey = ".\\cert\\RDTest_02.key"; |
|
76 my $webcert = ".\\cert\\RDTest_02.der"; |
|
77 my $cenrepkey = ".\\cert\\RDTest_02.key"; |
|
78 my $cenrepcert = ".\\cert\\RDTest_02.der"; |
|
79 |
|
80 my @cleanupList = (); |
|
81 |
|
82 GetOptions( "appversion=s",\$appVersion, |
|
83 "binversion=s",\$binVersion, |
|
84 "variant=s",\$variant, |
|
85 "opmode=s",\$opmode, |
|
86 "nocache",\$nocache, |
|
87 "verbose",\$debug_printing, |
|
88 "filelist=s",\$rawFilelist, |
|
89 "webkey=s", \$webkey, |
|
90 "webcert=s", \$webcert, |
|
91 "cenrepkey=s", \$cenrepkey, |
|
92 "cenrepcert=s", \$cenrepcert |
|
93 ); |
|
94 |
|
95 |
|
96 #### START OF ARG CHECKS |
|
97 if ( !defined $appVersion ) { print STDERR "\nBad argument: missing appversion\n $usage"; exit; } |
|
98 # Parse major.minor.build format string and choke if not well formed |
|
99 # We will later insert the parsed values inside the PKG file. |
|
100 my @parsedAppVer = checkAppVersion($appVersion); |
|
101 if (!$parsedAppVer[3]) { print STDERR "\nBad argument: malformed appversion string ($appVersion) \n $usage"; exit; } |
|
102 |
|
103 #By default ROM EXEs/DLLs have a version of 10.0, so you want the newDLLs to have equal or higher minor version. See IAD Eclipsing guide for details |
|
104 if ( !defined $binVersion ) { print STDOUT "\n Missing binary version, using default\n"; $binVersion = "10.1"; } |
|
105 my @parsedBinVer = checkBinaryVersion($binVersion); |
|
106 if (!$parsedBinVer[2]) { print STDERR "\nBad argument or default: malformed binversion string ($binVersion). \n $usage"; exit; } |
|
107 |
|
108 if ( !defined $variant ) { print STDERR "\nBad argument: missing variant\n $usage"; exit; } |
|
109 |
|
110 if ( !defined $opmode || !($opmode =~ /^dev/ || $opmode =~ /^int/)) { print STDERR "\nBad argument: Can't grok opmode\n $usage"; exit; } |
|
111 |
|
112 if (defined $rawFilelist && (! -e $rawFilelist) ) { print STDERR "\nBad argument: File is missing: $rawFilelist\n $usage"; exit; } |
|
113 |
|
114 print "no cache flag = $nocache \n" if $debug_printing; |
|
115 #print "verbose = $debug_printing \n"; |
|
116 #### END OF ARG CHECKS |
|
117 |
|
118 # IAD-compliant SIS file naming convention |
|
119 # ComponentName_<package UID>_v<package version>_<package type>_<platform>_<variant>.sis |
|
120 # Example: TestApplication_0x12345678_v1.2.3_SA_S60.32_Euro1.sis |
|
121 # Reference: http://s60wiki.nokia.com/S60Wiki/How_to_guide_for_uploading_sis_packages_to_IAD_server |
|
122 # Where: |
|
123 #package version: major.minor.build |
|
124 #package type: SIS package type (SA, SP,..) |
|
125 #platform: S60 Platform (S60.xx where xx = 32, 50,..) |
|
126 #variant: Language/operator variant |
|
127 |
|
128 my $browserSIS = "BrowserNG_${brExe_UID3}_v${appVersion}_${packageTypeMajor}_${s60platform}_${variant}.sis"; |
|
129 # For 323 we limit the number of IAD to Chinese, Western and Japan |
|
130 if ( $s60platform eq "S60.323" ) |
|
131 { |
|
132 if ( $variant == 50 ) { |
|
133 $browserSIS = "BrowserNG_${brExe_UID3}_v${appVersion}_${packageTypeMajor}_${s60platform}_western.sis"; |
|
134 } |
|
135 elsif ( $variant == 51 ) { |
|
136 $browserSIS = "BrowserNG_${brExe_UID3}_v${appVersion}_${packageTypeMajor}_${s60platform}_china.sis"; |
|
137 } |
|
138 elsif ( $variant == 16 ) { |
|
139 $browserSIS = "BrowserNG_${brExe_UID3}_v${appVersion}_${packageTypeMajor}_${s60platform}_japan.sis"; |
|
140 } |
|
141 else { |
|
142 print STDOUT "\n build variant $variant for RnD purpose \n"; |
|
143 } |
|
144 print STDOUT "\n=== SIS filename: $browserSIS \n" ; |
|
145 } |
|
146 |
|
147 ### Call pkg generation perl script |
|
148 system("CreateIADpackages.pl -v $variant -p armv5 -r urel -bmajor $parsedAppVer[0] -bminor $parsedAppVer[1] -bnumber $parsedAppVer[2]"); |
|
149 |
|
150 # Pick up any files from the WHAT output that match any of these regex patterns |
|
151 my $filenameRegEx = join '|', qw( |
|
152 [.]dll$ |
|
153 [.]exe$ |
|
154 [.]mif$ |
|
155 [.]r..$); |
|
156 |
|
157 # These type of files need to be stamped with a version number >= 10.0 so that the |
|
158 # original files on ROM may be eclipsed. |
|
159 my $binariesRegEx = join '|', qw( |
|
160 [.]dll$ |
|
161 [.]exe$); |
|
162 |
|
163 |
|
164 my $buildType = "urel"; |
|
165 |
|
166 |
|
167 |
|
168 # In any mode, use a $rawFilelist is passed from the command line |
|
169 if (defined $rawFilelist) { |
|
170 print STDOUT "\n=== Caller supplied list of files: $rawFilelist === \n" ; |
|
171 } else { |
|
172 # If no file list passed from command-line, we know how to generate one in DEV mode only |
|
173 if ($opmode =~ /^dev/) { |
|
174 $rawFilelist = "what_$buildType.log"; |
|
175 if ($nocache || (! -e $rawFilelist) ) { |
|
176 print STDOUT "\n=== Generating WHAT log, may take a while.. [",scalar(localtime),"] ===\n"; |
|
177 makeWhatLog($buildType, $rawFilelist); |
|
178 print STDOUT "\n=== Finished generating WHAT log ",scalar(localtime)," ===\n"; |
|
179 } else { |
|
180 print STDOUT "\n=== Will use cached WHAT log : $rawFilelist ===\n"; |
|
181 } |
|
182 } else { |
|
183 die("\nBad argument: File is missing: $rawFilelist\n $usage"); |
|
184 } |
|
185 |
|
186 } |
|
187 |
|
188 #Reduce list of files to those of interest |
|
189 my @rawList = getRawFileList($rawFilelist); |
|
190 my @filteredFiles = grep(/$filenameRegEx/i, @rawList); |
|
191 #print Dumper(@filteredFiles) if $debug_printing; |
|
192 |
|
193 print "Changing binary files with version\n" if $debug_printing; |
|
194 my @binariesOnly = grep(/$binariesRegEx/i, @filteredFiles); |
|
195 # print Dumper(@binariesOnly) if $debug_printing; |
|
196 for my $binaryFile (@binariesOnly) { |
|
197 print STDOUT "Fixing version to $binVersion for file: $binaryFile..\n" if $debug_printing; |
|
198 changeBinaryVersionAndMore("elftran", $binaryFile, $binVersion); |
|
199 if ( $? == -1 || ($? >> 8) != 0 ) { cleanDeath("Elftran failed to modify : $binaryFile "); } |
|
200 } |
|
201 |
|
202 |
|
203 print STDOUT "Creating CenRep installer\n" if $debug_printing; |
|
204 # No need to cleanup the sis file since it might be certificated differently |
|
205 # push(@cleanupList, "$cenrepSis"); |
|
206 system("makesis $cenrepPkg $cenrepSis"); |
|
207 if ( $? == -1 || ($? >> 8) != 0 ) { cleanDeath("Makesis on CenRep installer failed"); } else { |
|
208 #printf "\nOK %d\n", $? >> 8; |
|
209 } |
|
210 push(@cleanupList, "${cenrepSis}x"); |
|
211 print STDOUT "\nSigning CenRep installer\n" if $debug_printing; |
|
212 system("signsis -v $cenrepSis ${cenrepSis}x $cenrepcert $cenrepkey"); |
|
213 if ( $? == -1 || ($? >> 8) != 0 ) { cleanDeath("Signsis on CenRep installer failed"); } else { |
|
214 #printf "\nOK %d\n", $? >> 8; |
|
215 } |
|
216 |
|
217 print STDOUT "Creating main Browser installer with filename: $browserSIS\n" if $debug_printing; |
|
218 system("makesis $finalBrowserPkg $browserSIS"); |
|
219 if ( $? == -1 || ($? >> 8) != 0 ) { cleanDeath("Makesis on main Browser installer failed"); } else { |
|
220 #printf "\nOK %d\n", $? >> 8; |
|
221 } |
|
222 |
|
223 print STDOUT "\nSigning main Browser installer\n" if $debug_printing; |
|
224 system("signsis $browserSIS ${browserSIS}x $webcert $webkey"); |
|
225 if ( $? == -1 || ($? >> 8) != 0 ) { cleanDeath("Signsis on main Browser installer failed"); } else { |
|
226 #printf "OK %d\n", $? >> 8; |
|
227 } |
|
228 |
|
229 #cleanup all transient files |
|
230 cleanup(); |
|
231 |
|
232 |
|
233 # Helps us generate list of DLLs EXEs and resource files to be packaged in SIS package |
|
234 sub makeWhatLog |
|
235 { |
|
236 my $buildType = shift; |
|
237 my $file_whatLog = shift; |
|
238 |
|
239 system("\\gb_cmds\\gb_aurora_32_what.cmd armv5 $buildType > $file_whatLog"); |
|
240 } |
|
241 |
|
242 # Returns an in-memory list of all binary and resource files that the build process generates (WHAT output) |
|
243 sub getRawFileList |
|
244 { |
|
245 my $filename = shift; |
|
246 my @array = 0; |
|
247 #print "\n == Loading file with list of all assets : $filename == \n" if $debug_printing; |
|
248 open(HANDLE, $filename) || cleanDeath("Failed to open WHAT command output: $filename\n"); |
|
249 @array=<HANDLE>; |
|
250 close (HANDLE); |
|
251 #print Dumper(@rawList) if $debug_printing; |
|
252 |
|
253 return @array; |
|
254 } |
|
255 |
|
256 # |
|
257 sub changeBinaryVersionAndMore |
|
258 { |
|
259 my $elfCmd = shift; |
|
260 my $file = shift; |
|
261 my $binaryVersion = shift; |
|
262 |
|
263 system("$elfCmd -version $binaryVersion -compressionmethod bytepair $file"); |
|
264 } |
|
265 # Dies after doing cleanup |
|
266 sub cleanDeath { |
|
267 my $reason = shift; |
|
268 cleanup(); |
|
269 die($reason); |
|
270 } |
|
271 |
|
272 # Removes unwanted files from disk |
|
273 sub cleanup { |
|
274 for my $file (@cleanupList) { |
|
275 print "Cleaning up: $file\n"; |
|
276 unlink($file); |
|
277 } |
|
278 } |
|
279 |
|
280 # Checks for a well formed Binary Version string in major.minor format and that it is >= 10.0 |
|
281 # 10.0 is the default version of in-ROM binaries that must be eclipsed by our installation. |
|
282 sub checkBinaryVersion { |
|
283 my ($ver) = shift; |
|
284 |
|
285 my ($valid, $major, $minor) = (0, 0, 0); |
|
286 if ($ver =~ /^(\d+)\.(\d+)$/) { |
|
287 $valid = 1; |
|
288 ($major, $minor) = ($1, $2); |
|
289 # {=leading-zeros-ignored} |
|
290 $major =~ s/^0+//; |
|
291 $minor =~ s/^0+//; |
|
292 |
|
293 } |
|
294 |
|
295 my $intMajor = int($major || 0); |
|
296 my $intMinor = int($minor || 0); |
|
297 |
|
298 $valid = 0; |
|
299 if ( $intMajor >= 10 && $intMinor >=0 ) { |
|
300 $valid = 1; # enforce 10.0 or higher rule for IAD |
|
301 } |
|
302 |
|
303 my @binVerArray = ( |
|
304 $intMajor, |
|
305 $intMinor, |
|
306 $valid |
|
307 ); |
|
308 |
|
309 #print Dumper(@binVerArray) if $debug_printing; |
|
310 return @binVerArray; |
|
311 } |
|
312 |
|
313 # Checks for a well formed Application Version string in major.minor.build format |
|
314 # See the IAD versioning HOWTO (link above) for acceptable format |
|
315 sub checkAppVersion { |
|
316 my ($ver) = shift; |
|
317 |
|
318 my ($valid, $major, $minor, $build) = (0, 0, 0, 0); |
|
319 if ($ver =~ /^(\d+)\.(\d+).(\d+)$/) { |
|
320 $valid = 1; |
|
321 ($major, $minor, $build) = ($1, $2, $3); |
|
322 # {=leading-zeros-ignored} |
|
323 $major =~ s/^0+//; |
|
324 $minor =~ s/^0+//; |
|
325 $build =~ s/^0+//; |
|
326 } |
|
327 |
|
328 my $intMajor = int($major || 0); |
|
329 my $intMinor = int($minor || 0); |
|
330 my $intBuild = int($build || 0); |
|
331 |
|
332 if ($intMinor < 0 || $intMinor > 9) { |
|
333 $valid = 0; # enforce single digit minor rule for IAD |
|
334 } |
|
335 |
|
336 my @appVerArray = ( |
|
337 $intMajor, |
|
338 $intMinor, |
|
339 $intBuild, |
|
340 $valid |
|
341 ); |
|
342 #print Dumper(@appVerArray) if $debug_printing; |
|
343 return @appVerArray; |
|
344 } |
|
345 |