#!/usr/bin/perl -w # -*- Mode: perl; indent-tabs-mode: nil -*- # # First attempt at using module-graph.pl to generate # a cvs checkout list, and building the resulting tree. # # bootstrap.pl starts with an "all.dot" requires map file # and nothing else, and does the following: # * Figures out the module dependencies for the module # you want to build, via module-graph.pl. # * Creates a list of directories from the modules via # modules2dir.pl. # * Checks out core config files, nspr, and module directories. # * Based on this resulting tree, allmakefiles.sh is generated # on the fly with a module name "bootstrap". modules.mk file # generated with DIRS in leaf-first order. # * A build is attempted with this configure option: # --enable-standalone-modules=bootstrap --disable-ldap --disable-tests # # Example usage, to build xpcom: # # cvs co mozilla/tools/module-deps/bootstrap.pl # mozilla/tools/module-deps/bootstrap.pl --module=xpcom # use strict; use English; use File::Find(); use File::Copy; # For --option1, --option2, ... use Getopt::Long; Getopt::Long::Configure("bundling_override"); Getopt::Long::Configure("auto_abbrev"); use Cwd; my $debug = 0; sub PrintUsage { die < \$root_modules, 'modules=s' => \$root_modules, 'skip-cvs' => \$skip_cvs, 'skip-core-cvs' => \$skip_core_cvs, 'module-file-only' => \$modfile_only, 'topsrcdir=s' => \$topsrcdir); if ($root_modules) { print "root_modules = $root_modules\n"; # Test for last tree, or remember what tree we're doing. if (-e "last_module.txt") { open LAST_MODULE, "last_module.txt"; while() { # Assume module name is first line unless($_ eq $root_modules) { print "Error: Last module pulled ($_) doesn't match \"$root_modules\", remove last_module.txt and mozilla tree, then try again.\n"; exit 1; } else { print "Checking out same module...\n"; } } close LAST_MODULE; } else { # Save off file to remember which tree we're using open LAST_MODULE, ">last_module.txt"; print LAST_MODULE $root_modules; close LAST_MODULE; } } $topsrcdir = "mozilla" if (!$topsrcdir); chdir($topsrcdir) || die("chdir($topsrcdir): $!\n"); $topsrcdir = get_system_cwd(); $toolsdir = "$topsrcdir/tools/module-deps"; } # Run shell command, return output string. sub run_shell_command { my ($shell_command, $echo) = @_; local $_; my $status = 0; my $output = ""; chomp($shell_command); print "cmd = $shell_command\n" if ($debug); open CMD, "$shell_command 2>&1|" or die "command failed: $!"; while() { if($echo) { print $_; } chomp($_); $output .= "$_ "; } close CMD or $status = 1; if($status) { print "Warning, cmd exited with status $status.\n"; } return $output; } # Global and Compare routines for Find() my @foundMakefiles; sub FindMakefiles { # Don't descend into CVS dirs. /CVS/ and $File::Find::prune = 1; if($_ eq "Makefile.in") { #print "$File::Find::dir $_\n"; $_ =~ s/.in//; # Strip off the ".in" $File::Find::dir =~ s/^mozilla\///; # Strip off mozilla/ #$_ =~ s/mozilla//; push(@foundMakefiles, "$File::Find::dir/$_"); } else { #print " $File::Find::dir $_\n"; } } # Return directory list for module sub get_dirs_for_module($) { my ($root_modules, $silence) = @_; # Figure out the modules list. my @modules; my $modules_string = ""; my $num_modules = 0; my $modules_cmd = "$toolsdir/module-graph\.pl --file $toolsdir/meta\.dot --start-module $root_modules --list-only --force-order $toolsdir/force_order\.txt"; $modules_string = run_shell_command($modules_cmd, 0); $silence = 0 if (!defined($silence)); @modules = split(' ', $modules_string); #$num_modules = $#modules + 1; print "modules = $num_modules\n" if (!$silence); # Map modules list to directories list. my @dirs; my $dirs_string = ""; my $dirs_string_no_mozilla = ""; # dirs_string, stripping off mozilla/ my $dirs_cmd = "echo $modules_string | $topsrcdir/config/module2dir\.pl --list-only"; print "\nGenerating directories list for $root_modules\n" if (!$silence); $dirs_string = run_shell_command($dirs_cmd, 0); print "dirs_string = $dirs_string\n" if ($debug); return $dirs_string; } # Create stub version of modules.mk sub create_stub_modules_mk() { # Look for previously generated modules.mk file. my $generated_modulesmk_file = 0; if(-e "$topsrcdir/build/unix/modules.mk" && !$modfile_only) { open MODULESMK, "$topsrcdir/build/unix/modules.mk"; while() { if(/# Generated by bootstrap.pl/) { $generated_modulesmk_file = 1; } } close MODULESMK; if($generated_modulesmk_file == 0) { print "Error: non-generated $topsrcdir/build/unix/modules.mk found.\n"; exit 1; } } # Stomp on generated file, or open a new one. print "\nGenerating stub modules.mk ...\n"; copy("$toolsdir/modules.mk.stub", "$topsrcdir/build/unix/modules.mk"); } sub add_modules_mk_footer() { print "Adding modules.mk footer\n"; open(FOOTER, "$toolsdir/modules.mk.footer") || die ("modules.mk.footer: $!\n"); open(MK, ">>$topsrcdir/build/unix/modules.mk") || die ("modules.mk: $!\n"); while (