Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / config / make-jars.pl
blob7fe40cca6424c6a2e7d21004fcdb81be9a6a3023
1 #!/perl
3 # make-jars [-f] [-v] [-l] [-x] [-a] [-e] [-d <chromeDir>] [-s <srcdir>] [-t <topsrcdir>] [-c <localedir>] [-j <jarDir>] [-z zipprog] [-o operating-system] < <jar.mn>
5 my $cygwin_mountprefix = "";
6 if ($^O eq "cygwin") {
7 $cygwin_mountprefix = $ENV{CYGDRIVE_MOUNT};
8 if ($cygwin_mountprefix eq "") {
9 $cygwin_mountprefix = `mount -p | awk '{ if (/^\\//) { print \$1; exit } }'`;
10 if ($cygwin_mountprefix eq "") {
11 print "Cannot determine cygwin mount points. Exiting.\n";
12 exit(1);
15 chomp($cygwin_mountprefix);
16 # Remove extra ^M caused by using dos-mode line-endings
17 chop $cygwin_mountprefix if (substr($cygwin_mountprefix, -1, 1) eq "\r");
18 } else {
19 # we'll be pulling in some stuff from the script directory
20 require FindBin;
21 import FindBin;
22 push @INC, $FindBin::Bin;
25 use strict;
27 use Getopt::Std;
28 use Cwd;
29 use File::stat;
30 use Time::localtime;
31 use File::Copy;
32 use File::Path;
33 use File::Spec;
34 use File::Basename;
35 use IO::File;
36 use Config;
37 require mozLock;
38 import mozLock;
40 my $objdir = getcwd;
42 # if there's a "--", everything after it goes into $defines. We don't do
43 # this with the remaining args in @ARGV after the getopts call because
44 # old versions of Getopt::Std don't understand "--".
45 my $ddindex = 0;
46 foreach my $arg (@ARGV) {
47 ++$ddindex;
48 last if ($arg eq "--");
50 my $defines = join(' ', @ARGV[ $ddindex .. $#ARGV ]);
52 getopts("d:s:t:c:j:f:avqlD:o:p:xz:e");
54 my $baseFilesDir = ".";
55 if (defined($::opt_s)) {
56 $baseFilesDir = $::opt_s;
59 my $topSrcDir;
60 if (defined($::opt_t)) {
61 $topSrcDir = $::opt_t;
64 my $localeDir;
65 if (defined($::opt_c)) {
66 $localeDir = $::opt_c;
69 my $maxCmdline = 4000;
70 if ($Config{'archname'} =~ /VMS/) {
71 $maxCmdline = 200;
74 my $chromeDir = ".";
75 if (defined($::opt_d)) {
76 $chromeDir = $::opt_d;
79 my $jarDir = $chromeDir;
80 if (defined($::opt_j)) {
81 $jarDir = $::opt_j;
84 my $verbose = 0;
85 if (defined($::opt_v)) {
86 $verbose = 1;
89 my $quiet = 0;
90 if (defined($::opt_q)) {
91 $quiet = 1;
94 my $fileformat = "jar";
95 if (defined($::opt_f)) {
96 ($fileformat = $::opt_f) =~ tr/A-Z/a-z/;
99 if ("$fileformat" ne "jar" &&
100 "$fileformat" ne "flat" &&
101 "$fileformat" ne "symlink" &&
102 "$fileformat" ne "both") {
103 print "File format specified by -f option must be one of: jar, flat, both, or symlink.\n";
104 exit(1);
107 my $zipmoveopt = "";
108 if ("$fileformat" eq "jar") {
109 $zipmoveopt = "-m -0";
111 if ("$fileformat" eq "both") {
112 $zipmoveopt = "-0";
115 my $nofilelocks = 0;
116 if (defined($::opt_l)) {
117 $nofilelocks = 1;
120 my $autoreg = 1;
121 if (defined($::opt_a)) {
122 $autoreg = 0;
125 my $useExtensionManifest = 0;
126 if (defined($::opt_e)) {
127 $useExtensionManifest = 1;
130 my $preprocessor = "";
131 if (defined($::opt_p)) {
132 $preprocessor = $::opt_p;
135 my $force_x11 = 0;
136 if (defined($::opt_x)) {
137 $force_x11 = 1;
140 my $zipprog = $ENV{ZIP};
141 if (defined($::opt_z)) {
142 $zipprog = $::opt_z;
145 if ($zipprog eq "") {
146 print "A valid zip program must be given via the -z option or the ZIP environment variable. Exiting.\n";
147 exit(1);
150 my $force_os;
151 if (defined($::opt_o)) {
152 $force_os = $::opt_o;
155 if ($verbose) {
156 print "make-jars "
157 . "-v -d $chromeDir "
158 . "-j $jarDir "
159 . "-z $zipprog "
160 . ($fileformat ? "-f $fileformat " : "")
161 . ($nofilelocks ? "-l " : "")
162 . ($baseFilesDir ? "-s $baseFilesDir " : "")
163 . "\n";
166 my $win32 = ($^O =~ /((MS)?win32)|msys|cygwin|os2/i) ? 1 : 0;
167 my $macos = ($^O =~ /MacOS|darwin/i) ? 1 : 0;
168 my $unix = !($win32 || $macos) ? 1 : 0;
169 my $vms = ($^O =~ /VMS/i) ? 1 : 0;
171 if ($force_x11) {
172 $win32 = 0;
173 $macos = 0;
174 $unix = 1;
177 if (defined($force_os)) {
178 $win32 = 0;
179 $macos = 0;
180 $unix = 0;
181 if ($force_os eq "WINNT") {
182 $win32 = 1;
183 } elsif ($force_os eq "OS2") {
184 $win32 = 1;
185 } elsif ($force_os eq "Darwin") {
186 $macos = 1;
187 } else {
188 $unix = 1;
192 sub foreignPlatformFile
194 my ($jarfile) = @_;
196 if (!$win32 && index($jarfile, "-win") != -1) {
197 return 1;
200 if (!$unix && index($jarfile, "-unix") != -1) {
201 return 1;
204 if (!$macos && index($jarfile, "-mac") != -1) {
205 return 1;
208 return 0;
211 sub foreignPlatformPath
213 my ($jarpath) = @_;
215 if (!$win32 && index($jarpath, "-platform/win") != -1) {
216 return 1;
219 if (!$unix && index($jarpath, "-platform/unix") != -1) {
220 return 1;
223 if (!$macos && index($jarpath, "-platform/mac") != -1) {
224 return 1;
227 return 0;
230 sub zipErrorCheck($$)
232 my ($err,$lockfile) = @_;
233 return if ($err == 0 || $err == 12);
234 mozUnlock($lockfile) if (!$nofilelocks);
235 die ("Error invoking zip: $err");
238 sub JarIt
240 my ($destPath, $jarPath, $jarfile, $args, $overrides) = @_;
241 my $oldDir = cwd();
242 my $jarchive = _moz_abs2rel("$jarPath/$jarfile.jar", "$destPath/$jarfile", 1);
243 chdir("$destPath/$jarfile");
245 if ("$fileformat" eq "flat" || "$fileformat" eq "symlink") {
246 unlink($jarchive) if ( -e $jarchive);
247 chdir($oldDir);
248 return 0;
251 #print "cd $destPath/$jarfile\n";
252 my $argOpt = "-X";
253 $argOpt = "-uX" if ( -e $jarchive);
255 my $lockfile = "../$jarfile.lck";
257 mozLock($lockfile) if (!$nofilelocks);
259 if (!($args eq "")) {
260 my $err = 0;
262 #print "$zipprog $zipmoveopt -uX $jarchive $args\n";
264 # Handle posix cmdline limits
265 while (length($args) > $maxCmdline) {
266 #print "Exceeding POSIX cmdline limit: " . length($args) . "\n";
267 my $subargs = substr($args, 0, $maxCmdline-1);
268 my $pos = rindex($subargs, " ");
269 $subargs = substr($args, 0, $pos);
270 $args = substr($args, $pos);
272 #print "$zipprog $zipmoveopt -uX $jarchive $subargs\n";
273 #print "Length of subargs: " . length($subargs) . "\n";
274 system("$zipprog $zipmoveopt $argOpt $jarchive $subargs") == 0 or
275 $err = $? >> 8;
276 zipErrorCheck($err,$lockfile);
278 #print "Length of args: " . length($args) . "\n";
279 #print "$zipprog $zipmoveopt -uX $jarchive $args\n";
280 system("$zipprog $zipmoveopt $argOpt $jarchive $args") == 0 or
281 $err = $? >> 8;
282 zipErrorCheck($err,$lockfile);
285 if (!($overrides eq "")) {
286 my $err = 0;
287 print "+++ overriding $overrides\n" unless $quiet;
289 while (length($overrides) > $maxCmdline) {
290 #print "Exceeding POSIX cmdline limit: " . length($overrides) . "\n";
291 my $subargs = substr($overrides, 0, $maxCmdline-1);
292 my $pos = rindex($subargs, " ");
293 $subargs = substr($overrides, 0, $pos);
294 $overrides = substr($overrides, $pos);
296 #print "$zipprog $zipmoveopt -X $jarchive $subargs\n";
297 #print "Length of subargs: " . length($subargs) . "\n";
298 system("$zipprog $zipmoveopt -X $jarchive $subargs") == 0 or
299 $err = $? >> 8;
300 zipErrorCheck($err,$lockfile);
302 #print "Length of args: " . length($overrides) . "\n";
303 #print "$zipprog $zipmoveopt -X $jarchive $overrides\n";
304 system("$zipprog $zipmoveopt -X $jarchive $overrides\n") == 0 or
305 $err = $? >> 8;
306 zipErrorCheck($err,$lockfile);
308 mozUnlock($lockfile) if (!$nofilelocks);
309 chdir($oldDir);
310 #print "cd $oldDir\n";
313 sub _moz_rel2abs
315 my ($path, $isdir) = @_;
316 $path = File::Spec->catfile(getcwd, $path)
317 unless File::Spec->file_name_is_absolute($path);
318 $path = File::Spec->canonpath($path);
319 $path =~ s|\\|/|g if $path =~ s/^([A-Z]:\\)/\L$1/;
320 my (@dirs) = reverse split(m:/:, $path);
321 shift @dirs unless $isdir;
322 my ($up) = File::Spec->updir();
323 foreach (reverse 0 .. $#dirs) {
324 splice(@dirs, $_, 2) if ($dirs[$_] eq $up);
326 return reverse @dirs;
329 sub _moz_abs2rel
331 my ($target, $basedir, $isdir) = @_;
332 my (@target) = _moz_rel2abs($target, 1);
333 my (@basedir) = _moz_rel2abs($basedir, $isdir);
334 shift @target, shift @basedir
335 while @target && @basedir && $target[0] eq $basedir[0];
336 return File::Spec->catfile((File::Spec->updir()) x @basedir, @target);
339 sub UniqIt
341 my $manifest = shift;
343 return if (scalar(@_) == 0); # no entries, don't bother
345 my %lines = map { $_ => 1 } @_;
347 my $lockfile = "$manifest.lck";
348 print "+++ updating chrome $manifest\n" unless $quiet;
350 my $dir = dirname($manifest);
351 mkpath($dir, 0, 0755);
353 mozLock($lockfile) if (!$nofilelocks);
354 if (-f $manifest) {
355 unless (open(FILE, "<$manifest")) {
356 mozUnlock($lockfile) if (!$nofilelocks);
357 die "error: can't open $manifest: $!";
360 # Read through the file: if the lines already exist, no need to write
361 # them again.
362 while (defined($_ = <FILE>)) {
363 chomp;
364 delete $lines{$_};
366 close(FILE);
369 unless (open(FILE, ">>$manifest")) {
370 mozUnlock($lockfile) if (!$nofilelocks);
371 die "error: can't open $manifest: $!";
374 print FILE map("$_\n", keys(%lines));
375 close(FILE) or my $err = 1;
376 mozUnlock($lockfile) if (!$nofilelocks);
378 if ($err) {
379 die "error: can't close $manifest: $!";
383 sub RegIt
385 my ($chromeDir, $jarFileName, $chromeType, $pkgName) = @_;\
386 chop($pkgName) if ($pkgName =~ m/\/$/);
387 #print "RegIt: $chromeDir, $jarFileName, $chromeType, $pkgName\n";
389 my $line;
390 if ($fileformat eq "flat" || $fileformat eq "symlink") {
391 $line = "$chromeType,install,url,resource:/chrome/$jarFileName/$chromeType/$pkgName/";
392 } else {
393 $line = "$chromeType,install,url,jar:resource:/chrome/$jarFileName.jar!/$chromeType/$pkgName/";
395 my $installedChromeFile = "$jarDir/installed-chrome.txt";
396 UniqIt($installedChromeFile, $line);
399 sub EnsureFileInDir
401 my ($destPath, $srcPath, $destFile, $srcFile, $override, $preproc) = @_;
402 my $objPath;
404 #print "EnsureFileInDir($destPath, $srcPath, $destFile, $srcFile, $override)\n";
406 my $src = $srcFile;
407 if (defined($src)) {
408 if ($src =~ m|^/|) {
409 # "absolute" patch from topSrcDir
410 defined($topSrcDir) || die("Command-line option -t <topsrcdir> missing.");
411 $src = $topSrcDir.$srcFile;
412 } elsif ($srcFile =~ s|^\%|/|) {
413 defined($localeDir) || die("Command-line option -c <localedir> missing.");
414 $src = $localeDir.$srcFile;
415 } elsif (! -e $src ) {
416 $src = "$srcPath/$srcFile";
419 else {
420 $src = "$srcPath/$destFile";
421 # check for the complete jar path in the dest dir
422 if (!-e $src) {
423 #else check for just the file name in the dest dir
424 my $dir = "";
425 my $file;
426 if ($destFile =~ /([\w\d.\-\_\\\/\+]+)[\\\/]([\w\d.\-\_]+)/) {
427 $dir = $1;
428 $file = $2;
430 else {
431 die "file not found: $srcPath/$destFile";
433 $src = "$srcPath/$file";
434 if (!-e $src) {
435 die "file not found: $srcPath/$destFile";
440 $srcPath = $src;
441 $destPath = "$destPath/$destFile";
443 my $srcStat = stat($srcPath);
444 my $srcMtime = $srcStat ? $srcStat->mtime : 0;
446 my $destStat = stat($destPath);
447 my $destMtime = $destStat ? $destStat->mtime : 0;
448 #print "destMtime = $destMtime, srcMtime = $srcMtime\n";
450 if (!-e $destPath || $destMtime < $srcMtime || $override) {
451 #print "copying $destPath, from $srcPath\n";
452 my $dir = "";
453 my $file;
454 if ($destPath =~ /(.+)[\\\/]([\w\d.\-\_]+)/) {
455 $dir = $1;
456 $file = $2;
458 else {
459 $file = $destPath;
462 if ($srcPath) {
463 $file = $srcPath;
465 $objPath = "$objdir/$destFile";
467 if (!-e $file) {
468 if (!-e $objPath) {
469 die "error: file '$file' doesn't exist";
470 } else {
471 $file = "$objPath";
474 if (!-e $dir) {
475 mkpath($dir, 0, 0775) || die "can't mkpath $dir: $!";
477 unlink $destPath; # in case we had a symlink on unix
478 if ($preproc) {
479 my $preproc_flags = '';
480 if ($srcPath =~ /\.css$/o) {
481 $preproc_flags = '--marker=%';
484 my $preproc_file = $file;
485 if ($^O eq 'cygwin' && $file =~ /^[a-zA-Z]:/) {
486 # convert to a cygwin path
487 $preproc_file =~ s|^([a-zA-Z]):|$cygwin_mountprefix/\1|;
489 if ($vms) {
490 # use a temporary file otherwise cmd is too long for system()
491 my $tmpFile = "$destPath.tmp";
492 open(TMP, ">$tmpFile") || die("$tmpFile: $!");
493 print(TMP "$^X $preprocessor $preproc_flags $defines $preproc_file > $destPath");
494 close(TMP);
495 print "+++ preprocessing $preproc_file > $destPath\n" unless $quiet;
496 if (system("bash \"$tmpFile\"") != 0) {
497 die "Preprocessing of $file failed (VMS): ".($? >> 8);
499 unlink("$tmpFile") || die("$tmpFile: $!");
500 } else {
501 if (system("$^X $preprocessor $preproc_flags $defines $preproc_file > $destPath") != 0) {
502 die "Preprocessing of $file failed: ".($? >> 8);
505 } elsif ("$fileformat" eq "symlink") {
506 $file = _moz_abs2rel($file, $destPath);
507 symlink($file, $destPath) || die "symlink($file, $destPath) failed: $!";
508 return 1;
509 } else {
510 copy($file, $destPath) || die "copy($file, $destPath) failed: $!";
513 # fix the mod date so we don't jar everything (is this faster than just jarring everything?)
514 my $mtime = stat($file)->mtime || die $!;
515 my $atime = stat($file)->atime;
516 $atime = $mtime if !defined($atime);
517 utime($atime, $mtime, $destPath);
519 return 1;
521 return 0;
524 my @gLines = <STDIN>;
526 while (defined($_ = shift @gLines)) {
527 chomp;
529 start:
530 if (/^([\w\d.\-\_\\\/]+).jar\:\s*$/) {
531 my $jarfile = $1;
532 my $args = "";
533 my $overrides = "";
534 my $cwd = cwd();
535 my @manifestLines;
537 print "+++ making chrome $cwd => $jarDir/$jarfile.jar\n" unless $quiet;
538 while (defined($_ = shift @gLines)) {
539 if (/^\s+([\w\d.\-\_\\\/\+]+)\s*(\(\%?[\w\d.\-\_\\\/]+\))?$\s*/) {
540 my $dest = $1;
541 my $srcPath = defined($2) ? substr($2, 1, -1) : $2;
542 EnsureFileInDir("$chromeDir/$jarfile", $baseFilesDir, $dest, $srcPath, 0, 0);
543 $args = "$args$dest ";
544 if (!foreignPlatformFile($jarfile) && !foreignPlatformPath($dest) && $autoreg &&
545 $dest =~ /([\w\d.\-\_\+]+)\/([\w\d.\-\_\\\/]+)contents.rdf/)
547 my $chrome_type = $1;
548 my $pkg_name = $2;
549 RegIt($chromeDir, $jarfile, $chrome_type, $pkg_name);
551 } elsif (/^\+\s+([\w\d.\-\_\\\/\+]+)\s*(\(\%?[\w\d.\-\_\\\/]+\))?$\s*/) {
552 my $dest = $1;
553 my $srcPath = defined($2) ? substr($2, 1, -1) : $2;
554 EnsureFileInDir("$chromeDir/$jarfile", $baseFilesDir, $dest, $srcPath, 1, 0);
555 $overrides = "$overrides$dest ";
556 if (!foreignPlatformFile($jarfile) && !foreignPlatformPath($dest) && $autoreg &&
557 $dest =~ /([\w\d.\-\_\+]+)\/([\w\d.\-\_\\\/]+)contents.rdf/)
559 my $chrome_type = $1;
560 my $pkg_name = $2;
561 RegIt($chromeDir, $jarfile, $chrome_type, $pkg_name);
563 } elsif (/^\*\+?\s+([\w\d.\-\_\\\/\+]+)\s*(\(\%?[\w\d.\-\_\\\/]+\))?$\s*/) {
564 # preprocessed (always override)
565 my $dest = $1;
566 my $srcPath = defined($2) ? substr($2, 1, -1) : $2;
567 EnsureFileInDir("$chromeDir/$jarfile", $baseFilesDir, $dest, $srcPath, 1, 1);
568 $overrides = "$overrides$dest ";
569 if (!foreignPlatformFile($jarfile) && !foreignPlatformPath($dest) && $autoreg &&
570 $dest =~ /([\w\d.\-\_\+]+)\/([\w\d.\-\_\\\/]+)contents.rdf/)
572 my $chrome_type = $1;
573 my $pkg_name = $2;
574 RegIt($chromeDir, $jarfile, $chrome_type, $pkg_name);
576 } elsif (/^\%\s+(.*)$/) {
577 my $path = $1;
579 my $jarpath = $jarfile;
580 $jarpath = "chrome/".$jarfile if $useExtensionManifest;
582 if ($fileformat eq "flat" || $fileformat eq "symlink") {
583 $path =~ s|\%|$jarpath/$1|;
584 } else {
585 $path =~ s|\%|jar:$jarpath.jar!/$1|;
588 push @manifestLines, $path;
589 } elsif (/^\s*$/) {
590 # end with blank line
591 last;
592 } else {
593 my $manifest = "$jarDir/$jarfile.manifest";
594 my $manifest = "$jarDir/../chrome.manifest" if $useExtensionManifest;
595 UniqIt($manifest, @manifestLines);
596 JarIt($chromeDir, $jarDir, $jarfile, $args, $overrides);
597 goto start;
600 my $manifest = "$jarDir/$jarfile.manifest";
601 $manifest = "$jarDir/../chrome.manifest" if $useExtensionManifest;
602 UniqIt($manifest, @manifestLines);
603 JarIt($chromeDir, $jarDir, $jarfile, $args, $overrides);
605 } elsif (/^\s*\#.*$/) {
606 # skip comments
607 } elsif (/^\s*$/) {
608 # skip blank lines
609 } else {
610 close;
611 die "bad jar rule head at: $_";