Opera 12.15 Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

package_builder.pm 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. #!perl
  2. use strict;
  3. use warnings;
  4. ###############################################################################
  5. #
  6. # package_builder.pm
  7. #
  8. # Perl module which puts together all the resources needed for the windows
  9. # installer package, then builds said package
  10. #
  11. # Author: julienp@opera.com
  12. #
  13. ###############################################################################
  14. package package_builder;
  15. # Include modules
  16. use File::Basename;
  17. use File::Copy;
  18. use File::Path;
  19. use File::Spec;
  20. use Cwd;
  21. use lib qw(../../../common/package);
  22. use Shipping;
  23. use feature_scanner;
  24. use skin_builder;
  25. sub new
  26. {
  27. my $class = shift;
  28. my $self = {};
  29. bless $self, $class;
  30. return $self;
  31. }
  32. sub SetSettings
  33. {
  34. my $self = shift;
  35. my ($args) = @_;
  36. $self->{_build_nr} = $args->{build_nr} if (defined($args->{build_nr}));
  37. $self->{_version} = $args->{version} if (defined($args->{version}));
  38. $self->{_product} = $args->{product} if (defined($args->{product}));
  39. $self->{_labs_name} = $args->{labs_name} if (defined($args->{labs_name}));
  40. $self->{_build_output} = $args->{build_output} if (defined($args->{build_output}));
  41. $self->{_platform} = $args->{platform} if (defined($args->{platform}));
  42. $self->{_languages} = $args->{languages} if (defined($args->{languages}));
  43. $self->{_lang_options} = $args->{lang_options} if (defined($args->{lang_options}));
  44. $self->{_regions} = $args->{regions} if (defined($args->{regions}));
  45. $self->{_package_name} = $args->{package_name};
  46. $self->{_autoupdate_package_name} = $args->{autoupdate_package_name};
  47. $self->{_source_dir} = $args->{source_dir} if (defined($args->{source_dir}));
  48. $self->{_target_dir} = $args->{target_dir} if (defined($args->{target_dir}));
  49. $self->{_temp_dir} = $args->{temp_dir} if (defined($args->{temp_dir}));
  50. $self->{_packaging_dir} = $args->{packaging_dir} if (defined($args->{packaging_dir}));
  51. $self->{_sign} = $args->{sign} if (defined($args->{sign}));
  52. $self->{log_object} = $args->{log_object} if (defined($args->{log_object}));
  53. $self->{_files_list} = File::Spec->catfile($self->{_target_dir}, "files_list");
  54. $self->{_operaprefs_package} = File::Spec->catfile($self->{_target_dir}, "operaprefs_default.ini");
  55. $self->{_installer_archive} = File::Spec->catfile($self->{_target_dir}, File::Spec->updir(), "Opera.7z");
  56. $self->{_installer_package} = defined($self->{_package_name})?File::Spec->catfile($self->{_target_dir}, File::Spec->updir(), $self->{_package_name}):undef;
  57. $self->{_autoupdate_package} = defined($self->{_autoupdate_package_name})?File::Spec->catfile($self->{_target_dir}, File::Spec->updir(), $self->{_autoupdate_package_name}):undef;
  58. $self->{_i18ndata_dir} = File::Spec->catdir($self->{_source_dir}, "data", "i18ndata");
  59. $self->{_i18ndata_tables_dir} = File::Spec->catdir($self->{_i18ndata_dir}, "tables");
  60. $self->{_local_encoding_bin} = File::Spec->catfile($self->{_i18ndata_tables_dir}, "encoding.bin");
  61. $self->{_package_encoding_bin} = File::Spec->catfile($self->{_target_dir}, "encoding.bin");
  62. $self->{_setup_dir} = File::Spec->catdir($self->{_source_dir}, "adjunct", "quick", "setup");
  63. $self->{_common_dir} = File::Spec->catdir($self->{_source_dir}, "platforms", "ubscommon");
  64. $self->{_temp_shipping_dir} = File::Spec->catdir($self->{_temp_dir}, "shipping_build");
  65. $self->{_package_xml} = File::Spec->catfile($self->{_source_dir}, "adjunct", "resources", "package.xml");
  66. $self->{_binaries_package_xml} = File::Spec->catfile($self->{_source_dir}, "platforms", "windows", "packaging", "binaries_package_2010.xml");
  67. $self->{_platform_dirs} = File::Spec->catfile($self->{_source_dir}, "platforms", "windows", "packaging", "windirs.xml");
  68. $self->{_custom_features} = File::Spec->catfile($self->{_source_dir}, "adjunct", "quick", "custombuild-features.h");
  69. $self->{_platform_features} = File::Spec->catfile($self->{_source_dir}, "platforms", "windows", "features.h");
  70. $self->{_quick_features} = File::Spec->catfile($self->{_source_dir}, "adjunct", "quick", "quick-features.h");
  71. $self->{_generated_features} = File::Spec->catfile($self->{_source_dir}, "modules", "hardcore", "features", "profile_desktop.h");
  72. if (!defined($self->{_product}) || $self->{_product} == 0)
  73. {
  74. $self->{_sfxmodule} = File::Spec->catfile($self->{_packaging_dir}, "packaging", "tools", "7zSfx", "7zsd.sfx");
  75. }
  76. else
  77. {
  78. $self->{_sfxmodule} = File::Spec->catfile($self->{_packaging_dir}, "packaging", "tools", "7zSfx", "7zsd_Next.sfx");
  79. }
  80. $self->{_sfxconfig} = File::Spec->catfile($self->{_packaging_dir}, "packaging", "tools", "7zSfx", "config.txt");
  81. $self->{_sfxconfig_autoupdate} = File::Spec->catfile($self->{_packaging_dir}, "packaging", "tools", "7zSfx", "config_autoupdate.txt");
  82. $self->{_success} = 1;
  83. }
  84. sub Build
  85. {
  86. my $self = shift;
  87. # Build the files/folders we use all the time
  88. # Save the current directory so we can go back at the end!
  89. my $cwd = getcwd;
  90. $self->{log_object}->inf("Packaging script beginning") if (defined($self->{log_object}));
  91. # Check if the destination dir exists, if not create it
  92. if (!(-e $self->{_target_dir}))
  93. {
  94. print "Creates: $self->{_target_dir}\n";
  95. File::Path::mkpath($self->{_target_dir});
  96. }
  97. else
  98. {
  99. print "Will not create: $self->{_target_dir}\n";
  100. }
  101. open FILESLIST, '>', $self->{_files_list};
  102. # Create the default target set for packaging
  103. my @shipping_targets = ("windows", "embedded");
  104. # List of file to check and in the order of preference
  105. my @features_files = ($self->{_custom_features}, $self->{_platform_features}, $self->{_quick_features}, $self->{_generated_features});
  106. # Debug
  107. #foreach my $features_file (@features_files)
  108. #{
  109. # print "Files: ".$features_file."\n";
  110. #}
  111. # Create the feature scanner object
  112. my $fs = feature_scanner->new(@features_files);
  113. # Add the release/debug target
  114. if ($self->{_build_output} =~ /debug/i)
  115. {
  116. push(@shipping_targets, "debug");
  117. }
  118. else
  119. {
  120. push(@shipping_targets, "release");
  121. }
  122. # Add the x64/i386 target
  123. if ($self->{_platform} =~ /x64/i)
  124. {
  125. push(@shipping_targets, "x64");
  126. }
  127. else
  128. {
  129. push(@shipping_targets, "i386");
  130. }
  131. # Add any targets from the features
  132. push(@shipping_targets, $fs->GetPackagingTargets(@features_files));
  133. # Debug
  134. #foreach my $shipping_target (@shipping_targets)
  135. #{
  136. # print $shipping_target."\n";
  137. #}
  138. # Setup the shipping object
  139. my $ship = new Shipping($self->{_platform_dirs}, $self->{_source_dir}, $self->{_temp_shipping_dir}, $fs, $self->{_languages}, $self->{_regions}, @shipping_targets);
  140. print $self->{_i18ndata_dir}."\n";
  141. # Is there a i18ndata checkout so we can create the chartable?
  142. if (-e $self->{_i18ndata_dir})
  143. {
  144. # Change to the tables folder
  145. chdir($self->{_i18ndata_tables_dir});
  146. # Generate the chartable
  147. system("python make.py tables-all.txt");
  148. # Generate the encodings.bin
  149. system("perl utilities\\gettablelist.pl -e .");
  150. # Go back to the same directory we earlier
  151. chdir($cwd);
  152. # Copy the chartable into the package
  153. if (-e $self->{_local_encoding_bin})
  154. {
  155. if (copy($self->{_local_encoding_bin}, $self->{_package_encoding_bin}))
  156. {
  157. print FILESLIST File::Spec->abs2rel($self->{_package_encoding_bin}, $self->{_target_dir})."\n";
  158. }
  159. else
  160. {
  161. print "Warning : Failed copying $self->{_local_encoding_bin} to $self->{_package_encoding_bin}. $!\n";
  162. $self->{log_object}->err("Failed copying $self->{_local_encoding_bin} to $self->{_package_encoding_bin}. $!") if (defined($self->{log_object}));
  163. $self->{_success} = 0;
  164. }
  165. }
  166. else
  167. {
  168. print "Warning: Failed creating encoding.bin \n";
  169. $self->{log_object}->err("Failed creating encoding.bin") if (defined($self->{log_object}));
  170. $self->{_success} = 0;
  171. }
  172. }
  173. # Copy executables using the shipping object and the package.xml
  174. if (!$ship->parseManifest($self->{_binaries_package_xml}, $self))
  175. {
  176. print "Warning: Failed parsing $self->{_binaries_package_xml} \n";
  177. $self->{log_object}->err("Failed parsing $self->{_binaries_package_xml}") if (defined($self->{log_object}));
  178. $self->{_success} = 0;
  179. }
  180. # Copy everything using the shipping object and the package.xml
  181. if (!$ship->parseManifest($self->{_package_xml}, $self))
  182. {
  183. print "Warning: Failed parsing $self->{_package_xml} \n";
  184. $self->{log_object}->err("Failed parsing $self->{_package_xml}") if (defined($self->{log_object}));
  185. $self->{_success} = 0;
  186. }
  187. close FILESLIST;
  188. if ($self->{_product})
  189. {
  190. open OPERAPREFS, '>', $self->{_operaprefs_package};
  191. print OPERAPREFS "[System]\n";
  192. print OPERAPREFS "Opera Product=".$self->{_product}."\n";
  193. if (defined ($self->{_labs_name}))
  194. {
  195. print OPERAPREFS "Opera Labs Name=".$self->{_labs_name}."\n";
  196. }
  197. close OPERAPREFS;
  198. }
  199. chdir ($self->{_target_dir});
  200. unlink($self->{_installer_archive});
  201. my $signtool_command = "signtool sign /n \"Opera Software ASA\" /d \"Opera web browser\" /du \"http://www.opera.com\" /t \"http://timestamp.verisign.com/scripts/timstamp.dll\" ";
  202. if (defined ($self->{_installer_package}) || defined ($self->{_autoupdate_package_name}))
  203. {
  204. print "7Zipping the Opera Installer:\n";
  205. $self->{log_object}->inf("7Zipping the Opera Installer") if (defined($self->{log_object}));
  206. system("7z a -t7z -mx9 -y \"$self->{_installer_archive}\" . -xr!profile -xr!thumbs.db -xr!debug_log.txt -xr!debug.txt -xr!7z.log > 7z.log");
  207. if ($? != 0)
  208. {
  209. print "Warning: Failed 7zipping $self->{_installer_archive}.\n";
  210. $self->{log_object}->err("Failed 7zipping $self->{_installer_archive}.") if (defined($self->{log_object}));
  211. $self->{_success} = 0;
  212. }
  213. }
  214. if (defined ($self->{_installer_package}))
  215. {
  216. print "Adding 7-zip SFX header to build $self->{_installer_package}\n";
  217. $self->{log_object}->inf("Adding 7-zip SFX header to build $self->{_installer_package}.") if (defined($self->{log_object}));
  218. system("copy /b \"$self->{_sfxmodule}\" + \"$self->{_sfxconfig}\" + \"$self->{_installer_archive}\" \"$self->{_installer_package}\"");
  219. if ($? != 0)
  220. {
  221. print "Warning: Failed writing $self->{_installer_package}.\n";
  222. $self->{log_object}->err("Failed writing $self->{_installer_package}.") if (defined($self->{log_object}));
  223. $self->{_success} = 0;
  224. }
  225. elsif ($self->{_sign})
  226. {
  227. system("$signtool_command \"$self->{_installer_package}\"");
  228. if ($? != 0)
  229. {
  230. print "Warning: Failed signing $self->{_installer_package}.\n";
  231. $self->{log_object}->err("Failed signing $self->{_installer_package}.") if (defined($self->{log_object}));
  232. $self->{_success} = 0;
  233. }
  234. }
  235. }
  236. if (defined ($self->{_autoupdate_package}))
  237. {
  238. print "Adding 7-zip SFX header to build $self->{_autoupdate_package}\n";
  239. $self->{log_object}->inf("Adding 7-zip SFX header to build $self->{_autoupdate_package}.") if (defined($self->{log_object}));
  240. system("copy /b \"$self->{_sfxmodule}\" + \"$self->{_sfxconfig_autoupdate}\" + \"$self->{_installer_archive}\" \"$self->{_autoupdate_package}\"");
  241. if ($? != 0)
  242. {
  243. print "Warning: Failed writing $self->{_autoupdate_package}.\n";
  244. $self->{log_object}->err("Failed writing $self->{_autoupdate_package}.") if (defined($self->{log_object}));
  245. $self->{_success} = 0;
  246. }
  247. elsif ($self->{_sign})
  248. {
  249. system("$signtool_command \"$self->{_autoupdate_package}\"");
  250. if ($? != 0)
  251. {
  252. print "Warning: Failed signing $self->{_autoupdate_package}.\n";
  253. $self->{log_object}->err("Failed signing $self->{_autoupdate_package}.") if (defined($self->{log_object}));
  254. $self->{_success} = 0;
  255. }
  256. }
  257. }
  258. chdir($cwd);
  259. return $self->{_success};
  260. }
  261. sub shipFile ($$$$)
  262. {
  263. ( my $self, my $name, my $dest, my $each ) = @_;
  264. $name =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  265. $dest =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  266. # This is hack of the century and should be removed, but legacy from the old system!!!!
  267. $dest =~ s/^Opera[\\\/]//; # Remove the "Opera" folder it just represents the INSTALLDIR.
  268. my $s = $name;
  269. my $d = File::Spec->catfile($self->{_target_dir}, $dest);
  270. # Create the dest directory if it doesn't exist
  271. my $dest_dir = File::Basename::dirname($d);
  272. if (!(-e $dest_dir))
  273. {
  274. File::Path::mkpath($dest_dir);
  275. }
  276. $self->{log_object}->inf("Copying $s to $d.") if (defined($self->{log_object}));
  277. # Copy file $s, $d
  278. if (File::Copy::copy($s, $d))
  279. {
  280. print FILESLIST $dest."\n";
  281. }
  282. else
  283. {
  284. print "Warning : Failed copying $s to $d. $!\n";
  285. $self->{log_object}->err("Failed copying $s to $d. $!") if (defined($self->{log_object}));
  286. $self->{_success} = 0;
  287. }
  288. }
  289. sub zipFile ($$$$)
  290. {
  291. ( my $self, my $path, my $dest, my $each ) = @_;
  292. $path =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  293. $dest =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  294. # This is hack of the century and should be removed, but legacy from the old system!!!!
  295. $dest =~ s/^Opera[\\\/]//; # Remove the "Opera" folder it just represents the INSTALLDIR.
  296. my $s = $path;
  297. my $d = File::Spec->catfile($self->{_target_dir}, $dest);
  298. # Create the dest directory if it doesn't exist
  299. my $dest_dir = File::Basename::dirname($d);
  300. #print $dest_dir."\n";
  301. if (!(-e $dest_dir))
  302. {
  303. File::Path::mkpath($dest_dir);
  304. }
  305. print "Zipping $s to $d\n";
  306. $self->{log_object}->inf("Zipping $s to $d.") if (defined($self->{log_object}));
  307. # Save the current directory so we can go back at the end!
  308. my $cwd = Cwd::getcwd;
  309. # We need to change into the folder so that the zip file has the
  310. # correct paths internally
  311. if (-e $s)
  312. {
  313. chdir ($s);
  314. unlink($d);
  315. system("7z a -tzip -y \"$d\" . -xr!CVS -xr!thumbs.db -xr!7z.log > 7z.log");
  316. if ($? != 0)
  317. {
  318. print "Warning: Failed zipping $d.\n";
  319. $self->{log_object}->err("Failed zipping $d.") if (defined($self->{log_object}));
  320. $self->{_success} = 0;
  321. }
  322. # Go back to the same directory we earlier
  323. chdir($cwd);
  324. print FILESLIST $dest."\n";
  325. }
  326. }
  327. sub concatFiles ($$$$) {
  328. ( my $self, my $path, my $dest, my $each ) = @_;
  329. $path =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  330. $dest =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  331. # This is hack of the century and should be removed, but legacy from the old system!!!!
  332. $dest =~ s/^Opera[\\\/]//; # Remove the "Opera" folder it just represents the INSTALLDIR.
  333. my $s = $path;
  334. my $d = File::Spec->catfile($self->{_target_dir}, $dest);
  335. # Create the dest directory if it doesn't exist
  336. my $dest_dir = File::Basename::dirname($d);
  337. #print $dest_dir."\n";
  338. if (!(-e $dest_dir))
  339. {
  340. File::Path::mkpath($dest_dir);
  341. }
  342. print "Concatenating $s to $d\n";
  343. $self->{log_object}->inf("Concatenating $s to $d.") if (defined($self->{log_object}));
  344. unlink($d);
  345. system("copy /b /y \"$s\" \"$d\"");
  346. if ($? != 0)
  347. {
  348. print "Warning: Failed concatenating $d.\n";
  349. $self->{log_object}->err("Failed concatenating $d.") if (defined($self->{log_object}));
  350. $self->{_success} = 0;
  351. }
  352. print FILESLIST $dest."\n";
  353. }
  354. sub canSkipRebuild($$)
  355. {
  356. ( my $self, my $dest, my $last_change_time) = @_;
  357. $dest =~ s/\//\\/g; # If the path contains unix /-es, replace with windows \-es.
  358. # This is hack of the century and should be removed, but legacy from the old system!!!!
  359. $dest =~ s/^Opera[\\\/]//; # Remove the "Opera" folder it just represents the INSTALLDIR.
  360. my $d = File::Spec->catfile($self->{_target_dir}, $dest);
  361. if ( -e $d && (stat($d))[9] > $last_change_time)
  362. {
  363. print FILESLIST $dest."\n";
  364. return 1;
  365. }
  366. return 0;
  367. }
  368. sub getMakelangArgs()
  369. {
  370. my $self = shift;
  371. return "-E -p Win,$self->{_version},$self->{_build_nr} $self->{_lang_options}";
  372. }
  373. sub getSystemLanguage($)
  374. {
  375. ( my $self, my $lang ) = @_;
  376. return $lang;
  377. }
  378. sub replacePathVariables($)
  379. {
  380. ( my $self, my $path ) = @_;
  381. $path =~ s/\[CONFIGURATION\]/$self->{_build_output}/g;
  382. return $path;
  383. }
  384. sub fixSigPaths ($$$)
  385. {
  386. return 0;
  387. }
  388. sub fixRegionIni($$$) { return 0; }
  389. return 1;