This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
2f18b9070ddccae67e7c3af4336fd813091940b0
[perl5.git] / win32 / buildext.pl
1 =head1 NAME
2
3 buildext.pl - build extensions
4
5 =head1 SYNOPSIS
6
7     buildext.pl make [-make_opts] dep directory [target] [--static|--dynamic] !ext1 !ext2
8
9 E.g.
10
11     buildext.pl nmake -nologo perldll.def ..\ext
12
13     buildext.pl nmake -nologo perldll.def ..\ext clean
14
15     buildext.pl dmake perldll.def ..\ext
16
17     buildext.pl dmake perldll.def ..\ext 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 '--static' specified, only static extensions will be built.
23 If '--dynamic' specified, only dynamic extensions will be built.
24
25 --create-perllibst-h
26     creates perllibst.h file for inclusion from perllib.c
27 --list-static-libs:
28     prints libraries for static linking and exits
29
30 =cut
31
32 use Cwd;
33 use FindExt;
34 use Config;
35
36 # @ARGV with '!' at first position are exclusions
37 my %excl = map {$_=>1} map {/^!(.*)$/} @ARGV;
38 @ARGV = grep {!/^!/} @ARGV;
39
40 # --static/--dynamic
41 my %opts = map {$_=>1} map {/^--([\w\-]+)$/} @ARGV;
42 @ARGV = grep {!/^--([\w\-]+)$/} @ARGV;
43 my ($static,$dynamic) = ((exists $opts{static}?1:0),(exists $opts{dynamic}?1:0));
44 if ("$static,$dynamic" eq "0,0") {
45   ($static,$dynamic) = (1,1);
46 }
47 if ($opts{'list-static-libs'} || $opts{'create-perllibst-h'}) {
48   my @statics = split /\s+/, $Config{static_ext};
49   if ($opts{'create-perllibst-h'}) {
50     open my $fh, ">perllibst.h";
51     my @statics1 = map {local $_=$_;s/\//__/g;$_} @statics;
52     my @statics2 = map {local $_=$_;s/\//::/g;$_} @statics;
53     print $fh "/*DO NOT EDIT\n  this file is included from perllib.c to init static extensions */\n";
54     print $fh "#ifdef STATIC1\n",(map {"    \"$_\",\n"} @statics),"#undef STATIC1\n#endif\n";
55     print $fh "#ifdef STATIC2\n",(map {"    EXTERN_C void boot_$_ (pTHX_ CV* cv);\n"} @statics1),"#undef STATIC2\n#endif\n";
56     print $fh "#ifdef STATIC3\n",(map {"    newXS(\"$statics2[$_]::bootstrap\", boot_$statics1[$_], file);\n"} 0 .. $#statics),"#undef STATIC3\n#endif\n";
57   }
58   else {
59     my %extralibs;
60     for (@statics) {
61       open my $fh, "<..\\lib\\auto\\$_\\extralibs.ld" or die "can't open <..\\lib\\auto\\$_\\extralibs.ld: $!";
62       $extralibs{$_}++ for grep {/\S/} split /\s+/, join '', <$fh>;
63     }
64     print map {s|/|\\|g;m|([^\\]+)$|;"..\\lib\\auto\\$_\\$1$Config{_a} "} @statics;
65     print map {"$_ "} sort keys %extralibs;
66   }
67   exit;
68 }
69
70 my $here = getcwd();
71 my $perl = $^X;
72 $here =~ s,/,\\,g;
73 if ($perl =~ m#^\.\.#)
74  {
75   $perl = "$here\\$perl";
76  }
77 (my $topdir = $perl) =~ s/\\[^\\]+$//;
78 # miniperl needs to find perlglob and pl2bat
79 $ENV{PATH} = "$topdir;$topdir\\win32\\bin;$ENV{PATH}";
80 #print "PATH=$ENV{PATH}\n";
81 my $pl2bat = "$topdir\\win32\\bin\\pl2bat";
82 unless (-f "$pl2bat.bat") {
83     my @args = ($perl, ("$pl2bat.pl") x 2);
84     print "@args\n";
85     system(@args) unless defined $::Cross::platform;
86 }
87 my $make = shift;
88 $make .= " ".shift while $ARGV[0]=~/^-/;
89 my $dep  = shift;
90 my $dmod = -M $dep;
91 my $dir  = shift;
92 chdir($dir) || die "Cannot cd to $dir\n";
93 my $targ  = shift;
94 (my $ext = getcwd()) =~ s,/,\\,g;
95 my $code;
96 FindExt::scan_ext($ext);
97 FindExt::set_static_extensions(split ' ', $Config{static_ext}) if $ext ne "ext";
98
99 my @ext;
100 push @ext, FindExt::static_ext() if $static;
101 push @ext, FindExt::dynamic_ext(), FindExt::nonxs_ext() if $dynamic;
102
103 foreach $dir (sort @ext)
104  {
105   if (exists $excl{$dir}) {
106     warn "Skipping extension $ext\\$dir, not ported to current platform";
107     next;
108   }
109   if (chdir("$ext\\$dir"))
110    {
111     my $mmod = -M 'Makefile';
112     if (!(-f 'Makefile') || $mmod > $dmod)
113      {
114       print "\nRunning Makefile.PL in $dir\n";
115       my @perl = ($perl, "-I$here\\..\\lib", 'Makefile.PL',
116                   'INSTALLDIRS=perl', 'PERL_CORE=1',
117                   (FindExt::is_static($dir)
118                    ? ('LINKTYPE=static') : ()), # if ext is static
119                 );
120       if (defined $::Cross::platform) {
121         @perl = (@perl[0,1],"-MCross=$::Cross::platform",@perl[2..$#perl]);
122       }
123       print join(' ', @perl), "\n";
124       $code = system(@perl);
125       warn "$code from $dir\'s Makefile.PL" if $code;
126       $mmod = -M 'Makefile';
127       if ($mmod > $dmod)
128        {
129         warn "Makefile $mmod > $dmod ($dep)\n";
130        }
131      }  
132     if ($targ)
133      {
134       print "Making $targ in $dir\n$make $targ\n";
135       $code = system("$make $targ");
136       die "Unsuccessful make($dir): code=$code" if $code!=0;
137      }
138     else
139      {
140       print "Making $dir\n$make\n";
141       $code = system($make);
142       die "Unsuccessful make($dir): code=$code" if $code!=0;
143      }
144     chdir($here) || die "Cannot cd to $here:$!";
145    }
146   else
147    {
148     warn "Cannot cd to $ext\\$dir:$!";
149    }
150  }
151