diff options
Diffstat (limited to 'tools/build_perl_modules')
-rwxr-xr-x | tools/build_perl_modules | 314 |
1 files changed, 250 insertions, 64 deletions
diff --git a/tools/build_perl_modules b/tools/build_perl_modules index 9a880ff5..5a57a471 100755 --- a/tools/build_perl_modules +++ b/tools/build_perl_modules | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/usr/bin/perl | 1 | #!/usr/bin/perl |
2 | # SYNTAX: | 2 | # SYNTAX: |
3 | # build_perl_modules -d dest_dir [-c] [-m] [-t] [-i] tarball_dir | 3 | # build_perl_modules -d dest_dir [-c] [-m] [-t] [-i] [-s <section>] tarball_dir |
4 | # | 4 | # |
5 | # DESCRIPTION: | 5 | # DESCRIPTION: |
6 | # Installs perl modules found in tarball_dir | 6 | # Installs perl modules found in tarball_dir |
@@ -8,9 +8,12 @@ | |||
8 | # Will take action against each distribution in turn | 8 | # Will take action against each distribution in turn |
9 | # -d is a necessary destination directory for the perl mods | 9 | # -d is a necessary destination directory for the perl mods |
10 | # If -c is set, will remove the module build directories and exit | 10 | # If -c is set, will remove the module build directories and exit |
11 | # If -e is set, will extract module | ||
11 | # If -m is set, will run perl Makefile.PL and make | 12 | # If -m is set, will run perl Makefile.PL and make |
12 | # If -t is set, will run make test | 13 | # If -t is set, will run make test |
13 | # If -i is set, will run make install | 14 | # If -i is set, will run make install |
15 | # If -s <section> specified will only work on that section in the | ||
16 | # install_order file - defaults to first section only | ||
14 | # Options are discrete. This is because an overall ./configure, make, make test, make install | 17 | # Options are discrete. This is because an overall ./configure, make, make test, make install |
15 | # are run in different invocations. Obviously, you can't run a -t without a -m, but there's no | 18 | # are run in different invocations. Obviously, you can't run a -t without a -m, but there's no |
16 | # checking here for that | 19 | # checking here for that |
@@ -23,82 +26,265 @@ use Getopt::Std; | |||
23 | use Cwd; | 26 | use Cwd; |
24 | use File::Path; | 27 | use File::Path; |
25 | 28 | ||
29 | # remove host site_lib directories to ensure this is a 'full & clean' build of deps | ||
30 | BEGIN: { | ||
31 | my @user_libs = split( /:/, $ENV{PERL5LIB} || "" ); | ||
32 | chomp(@user_libs); | ||
33 | |||
34 | # clear out old PERL5LIB to avoid confusion with anything preinstalled | ||
35 | foreach my $lib (@INC) { | ||
36 | next if $lib eq "."; | ||
37 | foreach my $var (qw/ sitelib_stem sitelib sitearch sitearchexp /) { | ||
38 | foreach my $user_lib (@user_libs) { | ||
39 | $lib = '' if ( $lib =~ m/$user_lib/ ); | ||
40 | } | ||
41 | $lib = '' | ||
42 | if ( ( $Config{$var} && $lib =~ m/^$Config{$var}/ ) | ||
43 | || $lib =~ m/site_perl/ ); | ||
44 | } | ||
45 | } | ||
46 | } | ||
47 | |||
48 | my $file_regexp = '(\.pm)?-v?([\d_]+\.?)*\.(?:tgz|tar\.gz)$'; | ||
49 | |||
50 | my $have_yaml = 0; | ||
51 | my $have_module_build = 0; | ||
52 | |||
26 | my $opts = {}; | 53 | my $opts = {}; |
27 | getopts('d:cmti', $opts) || die "Invalid options"; | 54 | getopts( 'd:cemtis:', $opts ) || die "Invalid options"; |
28 | my $moddir = shift @ARGV or die "Must specify a directory where tarballs exist"; | 55 | my $moddir = shift @ARGV |
56 | or die "Must specify a directory where tarballs exist"; | ||
57 | |||
58 | my $prefix = $opts->{d}; | ||
59 | die "Must set a destination directory" unless $prefix; | ||
29 | 60 | ||
30 | my $destdir = $opts->{d}; | 61 | my $destdir = ''; |
31 | die "Must set a destination directory" unless $destdir; | 62 | my $mm_destdir = ''; |
63 | my $mb_destdir = ''; | ||
64 | if ( $ENV{DESTDIR} ) { | ||
65 | $destdir = $ENV{DESTDIR}; | ||
66 | $mm_destdir = 'DESTDIR=' . $destdir; | ||
67 | $mb_destdir = '--destdir ' . $destdir; | ||
68 | } | ||
32 | 69 | ||
33 | chdir $moddir or die "Cannot change to $moddir"; | 70 | chdir $moddir or die "Cannot change to $moddir"; |
34 | open F, "install_order" or die "Cannot open install_order file"; | 71 | open F, "install_order" or die "Cannot open install_order file"; |
35 | my @files = grep { ! /^#/ && chop } <F>; | 72 | my @files = grep { !/^#/ && chop } <F>; |
36 | close F; | 73 | close F; |
37 | 74 | ||
75 | # Remove linux only perl module from Solaris systems | ||
76 | if ( $^O eq "solaris" ) { | ||
77 | @files = grep { !/Sys-Statistics-Linux/ } @files; | ||
78 | } | ||
79 | |||
80 | my @filelist; | ||
81 | opendir( DIR, "." ); | ||
82 | foreach my $found ( readdir(DIR) ) { | ||
83 | push( @filelist, $found ) | ||
84 | if ( -f $found && $found =~ m/\.(?:tgz|tar\.gz)$/ ); | ||
85 | } | ||
86 | close(DIR); | ||
87 | |||
88 | my $tag = $opts->{s} || "default"; | ||
89 | my $in_section = 0; | ||
90 | |||
38 | my @tarballs; | 91 | my @tarballs; |
39 | foreach my $f (@files) { | 92 | foreach my $f (@files) { |
40 | # Needs to be better. Also, what if there are two with same name? | 93 | next |
41 | my $tarball; | 94 | if ( !$f || $f =~ m/^\s+$/ || $f =~ m/^\s*#/ ); # ignore all blank lines |
42 | eval '$tarball = <'."$f".'*.tar.gz>'; | 95 | $f =~ s/\s+//; # remove all whitespaces from line |
43 | die unless ($tarball); | 96 | $f =~ s/\s+#.*//; # remove all comments from the line |
44 | print "Got $f, with file: $tarball",$/; | 97 | |
45 | push @tarballs, $tarball; | 98 | if ( $f =~ m/^(\w+):$/ ) { |
46 | (my $dir = $tarball) =~ s/\.tar.gz//; | 99 | if ( $tag && $1 ne $tag && $tag ne "all" ) { |
47 | # Need to do cleaning before doing each module in turn | 100 | $in_section = 0; |
48 | if ($opts->{c}) { | 101 | next; |
49 | print "Cleaning $dir",$/; | 102 | } |
50 | rmtree($dir); | 103 | $in_section = 1; |
51 | } | 104 | $tag = $1 if ( !$tag ); |
105 | last if ( $1 ne $tag && $tag ne "all" ); | ||
106 | next; | ||
107 | } | ||
108 | |||
109 | next if ( !$in_section ); | ||
110 | |||
111 | # sort fully qualified names | ||
112 | #$f =~ s/(\.pm)?-v?(\d+\.?)*\.(?:tgz|tar\.gz)//; | ||
113 | #warn("b4 f=$f"); | ||
114 | $f =~ s/$file_regexp//; | ||
115 | |||
116 | # Needs to be better. Also, what if there are two with same name? | ||
117 | #warn("f=$f"); | ||
118 | my $tarball = ( grep( /^$f$file_regexp/, @filelist ) )[0]; | ||
119 | |||
120 | #warn("got f=$f tarball=$tarball"); | ||
121 | #eval '$tarball = <' . "$f" . '[-pmv0-9.]*.tar.gz>'; | ||
122 | die("Couldn't find tarball for $f in $moddir\n") | ||
123 | unless ( $tarball && -f $tarball ); | ||
124 | push @tarballs, $tarball; | ||
125 | ( my $dir = $tarball ) =~ s/\.(?:tgz|tar.gz)$//; | ||
126 | |||
127 | # Need to do cleaning before doing each module in turn | ||
128 | if ( $opts->{c} ) { | ||
129 | print "Cleaning $dir", $/; | ||
130 | rmtree($dir) if ($dir); | ||
131 | } | ||
52 | } | 132 | } |
53 | 133 | ||
54 | if ($opts->{c}) { | 134 | if ( $opts->{c} ) { |
55 | print "Finished cleaning",$/; | 135 | print "Finished cleaning", $/; |
56 | exit; | 136 | exit; |
57 | } | 137 | } |
58 | 138 | ||
139 | my $libs = "$destdir/$prefix/lib:$destdir/$prefix/lib/$Config{archname}"; | ||
140 | |||
59 | my $topdir = cwd(); | 141 | my $topdir = cwd(); |
142 | |||
143 | # set an initial value if there isnt one already | ||
144 | # Need to use PERL5LIB to ensure we get pre-installed mods from earlier | ||
145 | # tags in the install_order file | ||
146 | $ENV{PERL5LIB} ||= q{}; | ||
147 | |||
148 | # Set Module::AutoInstall to ignore CPAN, to avoid trying to pull dependencies in | ||
149 | $ENV{PERL_AUTOINSTALL} = "--skipdeps"; | ||
150 | |||
151 | # keep a record of how many times a module build is done. This is so they may | ||
152 | # be built a second time to include optional prereq's that couldnt | ||
153 | # previously be built due to circular dependancies | ||
154 | my %built_modules; | ||
60 | foreach my $tarball (@tarballs) { | 155 | foreach my $tarball (@tarballs) { |
61 | (my $dir = $tarball) =~ s/\.tar.gz//; | 156 | ( my $dir = $tarball ) =~ s/\.(?:tgz|tar.gz)$//; |
62 | if ($opts->{m}) { | 157 | |
63 | # Don't compile if already done - this is because of invocating this | 158 | die if ( $dir eq "exit" ); |
64 | # script at different stages | 159 | |
65 | print "******************** $tarball\n"; | 160 | if ( $opts->{e} ) { |
66 | unless (-e $dir) { | 161 | unless ( -e $dir ) { |
67 | system("gunzip -c $tarball | tar -xf -") == 0 or die "Cannot extract $tarball"; | 162 | print 'Extracting ', $tarball, $/; |
68 | chdir $dir or die "Can't chdir into $dir"; | 163 | system("gunzip -c $tarball | tar -xf -") == 0 |
69 | if (-e "Makefile.PL") { | 164 | or die "Cannot extract $tarball"; |
70 | system("perl Makefile.PL PREFIX=$destdir INSTALLDIRS=site LIB=$destdir/lib") == 0 | 165 | } |
71 | or die "Can't run perl Makefile.PL"; | 166 | next unless ( $opts->{m} || $opts->{t} || $opts->{i} ); |
72 | system("make") == 0 or die "Can't run make"; | 167 | } |
73 | } else { | 168 | |
74 | system("perl Build.PL --prefix $destdir --installdirs site --install_path lib=$destdir/lib") == 0 | 169 | # Need to add this so all modules is are for subsequent ones |
75 | or die "Can't run perl Build.PL"; | 170 | # Done here to partial previous builds can be continued |
76 | system("./Build") == 0 or die "Can't run ./Build"; | 171 | $ENV{PERL5LIB} = "$topdir/$dir/blib/arch:" . $ENV{PERL5LIB}; # Required for IO-Compress, I think |
77 | } | 172 | $ENV{PERL5LIB} = "$topdir/$dir/blib/lib:" . $ENV{PERL5LIB}; |
78 | chdir $topdir or die "Can't chdir to top";; | 173 | |
79 | } | 174 | # PathTools does something weird where it removes blib from @INC. We manually force ExtUtils::MakeMaker to be included |
80 | } | 175 | $ENV{PERL5LIB} = "$topdir/$dir/lib:" . $ENV{PERL5LIB} if ($dir =~/ExtUtils-MakeMaker/); |
81 | 176 | ||
82 | chdir $dir or die "Can't chdir into $dir"; | 177 | # warn("PERL5LIB=$ENV{PERL5LIB}"); |
83 | 178 | ||
84 | # Need to add this so this module is found for subsequent ones | 179 | if ( !$have_yaml ) { |
85 | my @dirs = split(":", $ENV{PERL5LIB} || ""); | 180 | $have_yaml = 0; |
86 | unshift @dirs, "$topdir/$dir/blib/lib"; | 181 | } |
87 | $ENV{PERL5LIB}=join(":", @dirs); | 182 | |
88 | 183 | if ( !$have_module_build ) { | |
89 | if ($opts->{t}) { | 184 | $have_module_build = check_for_module('Module::Build'); |
90 | if (-e "Makefile") { | 185 | } |
91 | system("make test") == 0 or die "Can't run make test failed"; | 186 | |
92 | } else { | 187 | if ( $opts->{m} ) { |
93 | system("./Build test") == 0 or die "./Build test failed"; | 188 | |
94 | } | 189 | # Don't compile if already done - this is because of invocating this |
95 | } | 190 | # script at different stages |
96 | if ($opts->{i}) { | 191 | print "******************** $tarball\n"; |
97 | if (-e "Makefile") { | 192 | if ( $built_modules{$dir} || !-f "$dir/Makefile" && !-f "$dir/Build" ) { |
98 | system("make install SITEPREFIX=$destdir") == 0 or die "Can't run make install"; | 193 | $built_modules{$dir}++; |
99 | } else { | 194 | my @missing; |
100 | system("./Build install") == 0 or die "Can't run ./Build install"; | 195 | chdir "$topdir/$dir" or die "Can't chdir into $dir"; |
101 | } | 196 | warn("\nWorking in: $topdir/$dir\n\n"); |
102 | } | 197 | |
103 | chdir $topdir or die "Can't go back to $topdir"; | 198 | # Another horrible hack. XML-Parser uses special Makefile variables, so we add these on here for Solaris only |
199 | my $extra_args = ""; | ||
200 | if ( $^O eq "solaris" && $dir =~ /^XML-Parser-/ ) { | ||
201 | $extra_args = "EXPATLIBPATH=/usr/sfw/lib EXPATINCPATH=/usr/sfw/share/src/expat/lib/"; | ||
202 | } | ||
203 | |||
204 | #warn("PERL5LIB=$ENV{PERL5LIB}\n"); | ||
205 | |||
206 | if ( -f "Build.PL" && $have_module_build ) { | ||
207 | warn("Using Build.PL\n"); | ||
208 | } | ||
209 | elsif ( -f 'Makefile.PL' ) { | ||
210 | warn("Using Makefile.PL\n"); | ||
211 | |||
212 | # Horribly hacky - remove xdefine if this is Time-HiRes | ||
213 | # because the subsequent perl Makefile.PL will fail | ||
214 | if ( $dir =~ /Time-HiRes/ ) { | ||
215 | unlink "xdefine"; | ||
216 | } | ||
217 | } | ||
218 | else { | ||
219 | die "No Makefile.PL nor Build.PL found"; | ||
220 | } | ||
221 | |||
222 | my $command; | ||
223 | if ( -f "Build.PL" && $have_module_build ) { | ||
224 | open( CMD, "|-", "perl Build.PL $mb_destdir --install_base=$prefix --install_path lib=$prefix/lib --install_path arch=$prefix/lib/$Config{archname} --install_path bin=$prefix/bin --install_path script=$prefix/bin --install_path bindoc=$prefix/man/man1 --install_path libdoc=$prefix/man/man3" ) || die "Can't run perl Build.PL"; | ||
225 | $command = "./Build"; | ||
226 | } | ||
227 | elsif ( -f 'Makefile.PL' ) { | ||
228 | open( CMD, "|-", "perl Makefile.PL $mm_destdir INSTALL_BASE=$prefix INSTALLDIRS=site INSTALLSITELIB=$prefix/lib INSTALLSITEARCH=$prefix/lib/$Config{archname} $extra_args" ) || die "Can't run perl Makefile.PL"; | ||
229 | $command = "make"; | ||
230 | } | ||
231 | else { | ||
232 | die "No Makefile.PL nor Build.PL found"; | ||
233 | } | ||
234 | close(CMD); | ||
235 | system($command) == 0 | ||
236 | or die "Can't run $command. Please\n\trm -rf $topdir/$dir\nto remake from this point)"; | ||
237 | |||
238 | chdir $topdir or die "Can't chdir to top"; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | chdir $dir or die "Can't chdir into $dir"; | ||
243 | |||
244 | if ( $opts->{t} ) { | ||
245 | warn("****** Testing $dir ****** \n"); | ||
246 | if ( -f "Build.PL" ) { | ||
247 | system("./Build test") == 0 | ||
248 | or die "'Build test' failed in $dir: $!\n"; | ||
249 | } | ||
250 | else { | ||
251 | system("make test") == 0 | ||
252 | or die "'make test' failed in $dir: $!\n"; | ||
253 | } | ||
254 | } | ||
255 | if ( $opts->{i} && !-f 'installed' ) { | ||
256 | |||
257 | # Need to set this so that XML::SAX will install ParserDetails.ini by finding the right XML::SAX copy | ||
258 | # Also makes sense to do this anyway, as I guess CPAN must be doing this for it to usually work | ||
259 | my $saved_PERL5LIB = $ENV{PERL5LIB}; | ||
260 | $ENV{PERL5LIB} = "$destdir/$prefix/lib:$saved_PERL5LIB"; | ||
261 | if ( -f "Build" ) { | ||
262 | system("./Build install") == 0 | ||
263 | or die "Can't run make install: $!\n"; | ||
264 | } | ||
265 | else { | ||
266 | system("make install") == 0 | ||
267 | or die "Can't run make install: $!\n"; | ||
268 | } | ||
269 | $ENV{PERL5LIB} = $saved_PERL5LIB; | ||
270 | open my $install_flag_file, '>', 'installed' | ||
271 | or die 'Unable to touch "installed": ', $!, $/; | ||
272 | close $install_flag_file | ||
273 | or die 'Unable to close "installed": ', $!, $/; | ||
274 | } | ||
275 | chdir $topdir or die "Can't go back to $topdir"; | ||
276 | } | ||
277 | |||
278 | sub check_for_module { | ||
279 | my ($module) = @_; | ||
280 | |||
281 | warn 'Checking if ', $module, ' is available yet...', $/; | ||
282 | if ( system("$^X -M$module -e 0 2>/dev/null") == 0 ) { | ||
283 | warn '... yes!', $/; | ||
284 | return 1; | ||
285 | } | ||
286 | |||
287 | warn '... no!', $/; | ||
288 | return 0; | ||
289 | |||
104 | } | 290 | } |