This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
The $@ was actually a botched conversion from $make $targ, rather than an
[perl5.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 my $make;
69 if (defined($makecmd) and $makecmd =~ /^MAKE=(.*)$/) {
70         $make = $1;
71 }
72 else {
73         print "$0:  WARNING:  Please include MAKE=\$(MAKE)\n";
74         print "\tin your call to buildext.pl.  See buildext.pl for details.\n";
75         exit(1);
76 }
77
78 # Strip whitespace at end of $make to ease passing of (potentially empty) parameters
79 $make =~ s/\s+$//;
80
81 # fallback to config.sh's MAKE
82 $make ||= $Config{make} || $ENV{MAKE};
83 my @run = $Config{run};
84 @run = () if not defined $run[0] or $run[0] eq '';
85
86 (my $here = getcwd()) =~ s{/}{\\}g;
87 my $perl = $^X;
88 if ($perl =~ m#^\.\.#) {
89     $perl = "$here\\$perl";
90 }
91 (my $topdir = $perl) =~ s/\\[^\\]+$//;
92 # miniperl needs to find perlglob and pl2bat
93 $ENV{PATH} = "$topdir;$topdir\\win32\\bin;$ENV{PATH}";
94 my $pl2bat = "$topdir\\win32\\bin\\pl2bat";
95 unless (-f "$pl2bat.bat") {
96     my @args = ($perl, ("$pl2bat.pl") x 2);
97     print "@args\n";
98     system(@args) unless defined $::Cross::platform;
99 }
100
101 print "In ", getcwd();
102 chdir($dir) || die "Cannot cd to $dir\n";
103 (my $ext = getcwd()) =~ s{/}{\\}g;
104 FindExt::scan_ext($ext);
105 FindExt::set_static_extensions(split ' ', $Config{static_ext});
106
107 my @ext;
108 push @ext, FindExt::static_ext() if $static;
109 push @ext, FindExt::dynamic_ext(), FindExt::nonxs_ext() if $dynamic;
110
111
112 foreach $dir (sort @ext)
113  {
114   if (%incl and !exists $incl{$dir}) {
115     #warn "Skipping extension $ext\\$dir, not in inclusion list\n";
116     next;
117   }
118   if (exists $excl{$dir}) {
119     warn "Skipping extension $ext\\$dir, not ported to current platform";
120     next;
121   }
122
123   build_extension($ext, "$ext\\$dir", $here, "$here\\..\\lib",
124                   [@pass_through,
125                    FindExt::is_static($dir) ? ('LINKTYPE=static') : ()]);
126  }
127
128 sub build_extension {
129     my ($ext, $ext_dir, $return_dir, $lib_dir, $pass_through) = @_;
130     unless (chdir "$ext_dir") {
131         warn "Cannot cd to $ext_dir: $!";
132         return;
133     }
134     
135     if (!-f 'Makefile') {
136         print "\nRunning Makefile.PL in $ext_dir\n";
137
138         # Presumably this can be simplified
139         my @cross;
140         if (defined $::Cross::platform) {
141             # Inherited from win32/buildext.pl
142             @cross = "-MCross=$::Cross::platform";
143         } elsif ($opts{cross}) {
144             # Inherited from make_ext.pl
145             @cross = '-MCross';
146         }
147             
148         my @perl = (@run, $perl, "-I$lib_dir", @cross, 'Makefile.PL',
149                     'INSTALLDIRS=perl', 'INSTALLMAN3DIR=none', 'PERL_CORE=1',
150                     @$pass_through);
151         print join(' ', @perl), "\n";
152         my $code = system @perl;
153         warn "$code from $ext_dir\'s Makefile.PL" if $code;
154     }
155     if (!$target or $target !~ /clean$/) {
156         # Give makefile an opportunity to rewrite itself.
157         # reassure users that life goes on...
158         my @config = (@run, $make, 'config', @$pass_through);
159         system @config and print "@config failed, continuing anyway...\n";
160     }
161     my @targ = (@run, $make, $target, @$pass_through);
162     print "Making $target in $ext_dir\n@targ\n";
163     my $code = system @targ;
164     die "Unsuccessful make($ext_dir): code=$code" if $code != 0;
165
166     chdir $return_dir || die "Cannot cd to $return_dir: $!";
167 }