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 |
|
---|