Upgrade DB_File to 1.818.
[p5sagit/p5-mst-13.2.git] / win32 / buildext.pl
1 =head1 NAME
2
3 buildext.pl - build extensions
4
5 =head1 SYNOPSIS
6
7     buildext.pl "MAKE=make [-make_opts]" --dir=directory [--target=target] [--static|--dynamic|--all] +ext2 !ext1
8
9 E.g.
10
11     buildext.pl "MAKE=nmake -nologo" --dir=..\ext
12
13     buildext.pl "MAKE=nmake -nologo" --dir=..\ext --target=clean
14
15     buildext.pl MAKE=dmake --dir=..\ext
16
17     buildext.pl MAKE=dmake --dir=..\ext --target=clean
18
19 Will skip building extensions which are marked with an '!' char.
20 Mostly because they still not ported to specified platform.
21
22 If any extensions are listed with a '+' char then only those
23 extensions will be built, but only if they arent countermanded
24 by an '!ext' and are appropriate to the type of building being done.
25
26 If '--static' specified, only static extensions will be built.
27 If '--dynamic' specified, only dynamic extensions will be built.
28
29 =cut
30
31 use strict;
32 use Cwd;
33 require FindExt;
34 use Config;
35
36 # @ARGV with '!' at first position are exclusions
37 # @ARGV with '+' at first position are inclusions
38 # -- are long options.
39
40 my (%excl, %incl, %opts, @extspec, @pass_through);
41
42 foreach (@ARGV) {
43     if (/^!(.*)$/) {
44         $excl{$1} = 1;
45     } elsif (/^\+(.*)$/) {
46         $incl{$1} = 1;
47     } elsif (/^--([\w\-]+)$/) {
48         $opts{$1} = 1;
49     } elsif (/^--([\w\-]+)=(.*)$/) {
50         $opts{$1} = $2;
51     } elsif (/=/) {
52         push @pass_through, $_;
53     } else {
54         push @extspec, $_;
55     }
56 }
57
58 my $static = $opts{static} || $opts{all};
59 my $dynamic = $opts{dynamic} || $opts{all};
60
61 my $makecmd = shift @pass_through;
62 unshift @pass_through, 'PERL_CORE=1';
63
64 my $dir  = $opts{dir} || 'ext';
65 my $target = $opts{target};
66 $target = 'all' unless defined $target;
67
68 unless(defined $makecmd and $makecmd =~ /^MAKE=(.*)$/) {
69     die "$0:  WARNING:  Please include MAKE=\$(MAKE) in \@ARGV\n";
70 }
71
72 # This isn't going to cope with anything fancy, such as spaces inside command
73 # names, but neither did what it replaced. Once there is a use case that needs
74 # it, please supply patches. Until then, I'm sticking to KISS
75 my @make = split ' ', $1 || $Config{make} || $ENV{MAKE};
76 # Using an array of 0 or 1 elements makes the subsequent code simpler.
77 my @run = $Config{run};
78 @run = () if not defined $run[0] or $run[0] eq '';
79
80 (my $here = getcwd()) =~ s{/}{\\}g;
81 my $perl = $^X;
82 if ($perl =~ m#^\.\.#) {
83     $perl = "$here\\$perl";
84 }
85 (my $topdir = $perl) =~ s/\\[^\\]+$//;
86 # miniperl needs to find perlglob and pl2bat
87 $ENV{PATH} = "$topdir;$topdir\\win32\\bin;$ENV{PATH}";
88 my $pl2bat = "$topdir\\win32\\bin\\pl2bat";
89 unless (-f "$pl2bat.bat") {
90     my @args = ($perl, ("$pl2bat.pl") x 2);
91     print "@args\n";
92     system(@args) unless defined $::Cross::platform;
93 }
94
95 print "In ", getcwd();
96 chdir($dir) || die "Cannot cd to $dir\n";
97 (my $ext = getcwd()) =~ s{/}{\\}g;
98 FindExt::scan_ext($ext);
99 FindExt::set_static_extensions(split ' ', $Config{static_ext});
100
101 my @ext;
102 push @ext, FindExt::static_ext() if $static;
103 push @ext, FindExt::dynamic_ext(), FindExt::nonxs_ext() if $dynamic;
104
105
106 foreach $dir (sort @ext)
107  {
108   if (%incl and !exists $incl{$dir}) {
109     #warn "Skipping extension $ext\\$dir, not in inclusion list\n";
110     next;
111   }
112   if (exists $excl{$dir}) {
113     warn "Skipping extension $ext\\$dir, not ported to current platform";
114     next;
115   }
116
117   build_extension($ext, "$ext\\$dir", $here, "$here\\..\\lib",
118                   [@pass_through,
119                    FindExt::is_static($dir) ? ('LINKTYPE=static') : ()]);
120  }
121
122 sub build_extension {
123     my ($ext, $ext_dir, $return_dir, $lib_dir, $pass_through) = @_;
124     unless (chdir "$ext_dir") {
125         warn "Cannot cd to $ext_dir: $!";
126         return;
127     }
128     
129     if (!-f 'Makefile') {
130         print "\nRunning Makefile.PL in $ext_dir\n";
131
132         # Presumably this can be simplified
133         my @cross;
134         if (defined $::Cross::platform) {
135             # Inherited from win32/buildext.pl
136             @cross = "-MCross=$::Cross::platform";
137         } elsif ($opts{cross}) {
138             # Inherited from make_ext.pl
139             @cross = '-MCross';
140         }
141             
142         my @perl = (@run, $perl, "-I$lib_dir", @cross, 'Makefile.PL',
143                     'INSTALLDIRS=perl', 'INSTALLMAN3DIR=none', 'PERL_CORE=1',
144                     @$pass_through);
145         print join(' ', @perl), "\n";
146         my $code = system @perl;
147         warn "$code from $ext_dir\'s Makefile.PL" if $code;
148     }
149     if (!$target or $target !~ /clean$/) {
150         # Give makefile an opportunity to rewrite itself.
151         # reassure users that life goes on...
152         my @config = (@run, @make, 'config', @$pass_through);
153         system @config and print "@config failed, continuing anyway...\n";
154     }
155     my @targ = (@run, @make, $target, @$pass_through);
156     print "Making $target in $ext_dir\n@targ\n";
157     my $code = system @targ;
158     die "Unsuccessful make($ext_dir): code=$code" if $code != 0;
159
160     chdir $return_dir || die "Cannot cd to $return_dir: $!";
161 }