Make PerlLIOUtime()'s filename const
[p5sagit/p5-mst-13.2.git] / symbian / xsbuild.pl
CommitLineData
27da23d5 1#!/usr/bin/perl -w
2
3use strict;
4
5use Getopt::Long;
6use File::Basename;
7use Cwd;
8
9do "sanity.pl";
10
11my $CoreBuild = -d "ext" && -f "perl.h" && -d "symbian" && -f "perl.c";
12
25ca88e0 13my $SymbianVersion;
14
15if (exists $ENV{EPOCROOT}) {
16 if ($ENV{EPOCROOT} =~ m!\\Symbian\\UIQ_21\\$!i) {
17 $SymbianVersion = '7.0s'; # TODO: other UIQ versions
18 } elsif ($ENV{EPOCROOT} =~ m!\\Symbian\\(.+?)\\!i) {
19 $SymbianVersion = $1;
20 }
21}
22
23$SymbianVersion = $ENV{XSBUILD_SYMBIAN_VERSION}
24 if exists $ENV{XSBUILD_SYMBIAN_VERSION};
25
27da23d5 26my $PerlVersion = $ENV{XSBUILD_PERL_VERSION};
27my $CSuffix = '.c';
28my $CPlusPlus;
29my $Config;
30my $Build;
31my $Clean;
32my $DistClean;
33my $Sis;
34
35sub usage {
36 die <<__EOF__;
37$0: Usage: $0 [--symbian=version] [--perl=version]
38 [--csuffix=csuffix] [--cplusplus]
39 [--win=win] [--arm=arm]
40 [--config|--build|--clean|--distclean|--sis] ext
41__EOF__
42}
43
44my $CWD;
45my $SDK;
46my $VERSION;
47my $R_V_SV;
48my $PERLSDK;
c8f896e5 49my $WIN = 'wins';
50my $ARM = 'thumb';
c1c0c258 51my $BUILDROOT = getcwd();
27da23d5 52
53if ( !defined $PerlVersion && $0 =~ m:\\symbian\\perl\\(.+)\\bin\\xsbuild.pl:i )
54{
55 $PerlVersion = $1;
56}
57
58if ( !defined $SymbianVersion) {
25ca88e0 59 ($SymbianVersion) = ($ENV{PATH} =~ m!\\Symbian\\(.+?)\\!i);
27da23d5 60}
61
ed76c0e4 62my ($SYMBIAN_ROOT, $SYMBIAN_VERSION, $SDK_NAME, $SDK_VARIANT, $SDK_VERSION);
63
27da23d5 64if ($CoreBuild) {
65 unshift @INC, "symbian";
66 do "sanity.pl";
67 my %VERSION = %{ do "version.pl" };
ed76c0e4 68 ($SYMBIAN_ROOT, $SYMBIAN_VERSION, $SDK_NAME, $SDK_VARIANT, $SDK_VERSION) =
69 @{ do "sdk.pl" };
27da23d5 70 $VERSION = "$VERSION{REVISION}$VERSION{VERSION}$VERSION{SUBVERSION}";
71 $R_V_SV = "$VERSION{REVISION}.$VERSION{VERSION}.$VERSION{SUBVERSION}";
c1c0c258 72 $BUILDROOT = do "cwd.pl";
27da23d5 73 $PerlVersion = $R_V_SV;
27da23d5 74}
75
76usage()
77 unless GetOptions(
78 'symbian=s' => \$SymbianVersion,
79 'perl=s' => \$PerlVersion,
80 'csuffix=s' => \$CSuffix,
81 'cplusplus' => \$CPlusPlus,
82 'win=s' => \$WIN,
83 'arm=s' => \$ARM,
84 'config' => \$Config,
85 'build' => \$Build,
86 'clean' => \$Clean,
87 'distclean' => \$DistClean,
88 'sis' => \$Sis
89 );
90
91usage() unless @ARGV;
92
93$CSuffix = '.cpp' if $CPlusPlus;
94$Build = !( $Config || $Clean || $DistClean ) || $Sis unless defined $Build;
95
96die "$0: Symbian version undefined\n" unless defined $SymbianVersion;
97
98$SymbianVersion =~ s:/:\\:g;
99
100die "$0: Symbian version '$SymbianVersion' not found\n"
101 unless -d "\\Symbian\\$SymbianVersion";
102
103die "$0: Perl version undefined\n" unless defined $PerlVersion;
104
105die "$0: Perl version '$PerlVersion' not found\n"
106 if !$CoreBuild && !-d "\\Symbian\\Perl\\$PerlVersion";
107
108print "Configuring with Symbian $SymbianVersion and Perl $PerlVersion...\n";
109
27da23d5 110$PERLSDK = "\\Symbian\\Perl\\$PerlVersion";
111
112$R_V_SV = $PerlVersion;
113
c8f896e5 114$VERSION = $PerlVersion unless defined $VERSION;
115
116$VERSION =~ tr/.//d if defined $VERSION;
27da23d5 117
ed76c0e4 118$ENV{SDK} = $SYMBIAN_ROOT; # For the Errno extension
119$ENV{CROSS} = 1; # For the Encode extension (unbuilt now)
27da23d5 120
c8f896e5 121my $UARM = 'urel';
ed76c0e4 122my $UREL = "$SYMBIAN_ROOT\\epoc32\\release\\-ARM-\\$UARM";
c8f896e5 123my $SRCDBG;
124if (exists $ENV{UREL}) {
125 $UREL = $ENV{UREL}; # from sdk.pl
126 $UREL =~ s/-ARM-/$ARM/;
127 $UARM = $ENV{UARM}; # from sdk.pl
128 $SRCDBG = $UARM eq 'udeb' ? "SRCDBG" : "";
129}
27da23d5 130
131my %CONF;
132my %EXTCFG;
133
134sub write_bld_inf {
135 my ($base) = @_;
136 print "\tbld.inf\n";
137 open( BLD_INF, ">bld.inf" ) or die "$0: bld.inf: $!\n";
138 print BLD_INF <<__EOF__;
139PRJ_MMPFILES
140$base.mmp
141PRJ_PLATFORMS
142$WIN $ARM
143__EOF__
144 close(BLD_INF);
145}
146
147sub system_echo {
148 my $cmd = shift;
149 print "xsbuild: ", $cmd, "\n";
150 return system($cmd);
151}
152
153sub run_PL {
154 my ( $PL, $dir, $file ) = @_;
155 if ( defined $file ) {
156 print "\t(Running $dir\\$PL to create $file)\n";
157 unlink($file);
158 }
159 else {
160 print "\t(Running $dir\\$PL)\n";
161 }
162 my $cmd;
163 if ($CoreBuild) {
c1c0c258 164 # Problem: the Config.pm we have in $BUILDROOT\\lib carries the
27da23d5 165 # version number of the Perl we are building, while the Perl
166 # we are running might have some other version. Solution:
167 # temporarily replace the Config.pm with a patched version.
168 my $V = sprintf "%vd", $^V;
c1c0c258 169 unlink("$BUILDROOT\\lib\\Config.pm.bak");
170 print "(patching $BUILDROOT\\lib\\Config.pm)\n";
171 system_echo("perl -pi.bak -e \"s:\\Q$R_V_SV:$V:\" $BUILDROOT\\lib\\Config.pm");
27da23d5 172 }
1215b447 173 system_echo("perl -I$BUILDROOT\\lib -I$BUILDROOT\\xlib\\symbian -I$BUILDROOT\\t\\lib $PL") == 0
27da23d5 174 or warn "$0: $PL failed.\n";
175 if ($CoreBuild) {
c1c0c258 176 system_echo("copy $BUILDROOT\\lib\\Config.pm.bak $BUILDROOT\\lib\\Config.pm");
27da23d5 177 }
178 if ( defined $file ) { -s $file or die "$0: No $file created.\n" }
179}
180
181sub read_old_multi {
182 my ( $conf, $k ) = @_;
183 push @{ $conf->{$k} }, split( ' ', $1 ) if /^$k\s(.+)$/;
184}
185
186sub uniquefy_filenames {
187 my $b = [];
188 my %c = ();
189 for my $i (@{$_[0]}) {
190 $i =~ s!/!\\!g;
191 $i = lc $i if $i =~ m!\\!;
192 $i =~ s!^c:!!;
193 push @$b, $i unless $c{$i}++;
194 }
195 return $b;
196}
197
198sub read_mmp {
199 my ( $conf, $mmp ) = @_;
200 if ( -r $mmp && open( MMP, "<$mmp" ) ) {
201 print "\tReading $mmp...\n";
202 while (<MMP>) {
203 chomp;
204 $conf->{TARGET} = $1 if /^TARGET\s+(.+)$/;
205 $conf->{TARGETPATH} = $1 if /^TARGETPATH\s+(.+)$/;
206 $conf->{EXTVERSION} = $1 if /^EXTVERSION\s+(.+)$/;
207 read_old_multi( $conf, "SOURCE" );
208 read_old_multi( $conf, "SOURCEPATH" );
209 read_old_multi( $conf, "USERINCLUDE" );
210 read_old_multi( $conf, "SYSTEMINCLUDE" );
211 read_old_multi( $conf, "LIBRARY" );
212 read_old_multi( $conf, "MACRO" );
213 }
214 close(MMP);
215 }
216}
217
218sub write_mmp {
5c271e25 219 my ( $ext, $base, $userinclude, @src ) = @_;
220
221 my $extdash = $ext; $extdash =~ s!\\!-!g;
27da23d5 222
223 print "\t$base.mmp\n";
5c271e25 224 $CONF{TARGET} = "perl$VERSION-$extdash.dll";
27da23d5 225 $CONF{TARGETPATH} = "\\System\\Libs\\Perl\\$R_V_SV";
226 $CONF{SOURCE} = [@src];
c1c0c258 227 $CONF{SOURCEPATH} = [ $CWD, $BUILDROOT ];
228 $CONF{USERINCLUDE} = [ $CWD, $BUILDROOT ];
27da23d5 229 $CONF{SYSTEMINCLUDE} = ["$PERLSDK\\include"] unless $CoreBuild;
25ca88e0 230 $CONF{SYSTEMINCLUDE} = [ $BUILDROOT, "$BUILDROOT\\symbian" ] if $CoreBuild;
27da23d5 231 $CONF{LIBRARY} = [];
232 $CONF{MACRO} = [];
233 read_mmp( \%CONF, "_init.mmp" );
234 read_mmp( \%CONF, "$base.mmp" );
235
0added8b 236 if ($base eq 'Zlib') {
237 push @{$CONF{USERINCLUDE}}, "$CWD\\zlib-src";
238 }
239
27da23d5 240 for my $ui ( @{$userinclude} ) {
241 $ui =~ s!/!\\!g;
242 if ( $ui =~ m!^(?:[CD]:)?\\! ) {
243 push @{ $CONF{USERINCLUDE} }, $ui;
244 }
245 else {
c1c0c258 246 push @{ $CONF{USERINCLUDE} }, "$BUILDROOT\\$ui";
27da23d5 247 }
248 }
249 push @{ $CONF{SYSTEMINCLUDE} }, "\\epoc32\\include";
250 push @{ $CONF{SYSTEMINCLUDE} }, "\\epoc32\\include\\libc";
251 push @{ $CONF{LIBRARY} }, "euser.lib";
252 push @{ $CONF{LIBRARY} }, "estlib.lib";
253 push @{ $CONF{LIBRARY} }, "perl$VERSION.lib";
254 push @{ $CONF{MACRO} }, "SYMBIAN" unless $CoreBuild;
255 push @{ $CONF{MACRO} }, "PERL_EXT" if $CoreBuild;
256 push @{ $CONF{MACRO} }, "MULTIPLICITY";
257 push @{ $CONF{MACRO} }, "PERL_IMPLICIT_CONTEXT";
258 push @{ $CONF{MACRO} }, "PERL_GLOBAL_STRUCT";
259 push @{ $CONF{MACRO} }, "PERL_GLOBAL_STRUCT_PRIVATE";
260
25ca88e0 261 if ($SDK_VARIANT eq 'S60') {
262 push @{ $CONF{MACRO} }, '__SERIES60__'
263 unless grep { $_ eq '__SERIES60__' } @{ $CONF{MACRO} };
264 }
265 if ($SDK_VARIANT eq 'S80') {
266 push @{ $CONF{MACRO} }, '__SERIES80__'
267 unless grep { $_ eq '__SERIES80__' } @{ $CONF{MACRO} };
268 }
269 if ($SDK_VARIANT eq 'UIQ') {
270 push @{ $CONF{MACRO} }, '__UIQ__'
271 unless grep { $_ eq '__UIQ__' } @{ $CONF{MACRO} };
272 }
273
27da23d5 274 for my $u (qw(SOURCE SOURCEPATH SYSTEMINCLUDE USERINCLUDE LIBRARY MACRO)) {
275 $CONF{$u} = uniquefy_filenames( $CONF{$u} );
276 }
277 open( BASE_MMP, ">$base.mmp" ) or die "$0: $base.mmp: $!\n";
278
279 print BASE_MMP <<__EOF__;
280TARGET $CONF{TARGET}
281TARGETTYPE dll
282TARGETPATH $CONF{TARGETPATH}
283SOURCE @{$CONF{SOURCE}}
284$SRCDBG
285__EOF__
286 for my $u (qw(SOURCEPATH SYSTEMINCLUDE USERINCLUDE)) {
287 for my $v ( @{ $CONF{$u} } ) {
288 print BASE_MMP "$u\t$v\n";
289 }
290 }
291 # OPTION does not work in MMPs for pre-2.0 SDKs?
292 print BASE_MMP <<__EOF__;
293LIBRARY @{$CONF{LIBRARY}}
294MACRO @{$CONF{MACRO}}
25ca88e0 295// OPTION MSVC /P // Uncomment for creating .i (cpp'ed .cpp)
296// OPTION GCC -E // Uncomment for creating .i (cpp'ed .cpp)
27da23d5 297__EOF__
25ca88e0 298# if (-f "$base.rss") {
299# print BASE_MMP "RESOURCE\t$base.rss\n";
300# }
27da23d5 301 close(BASE_MMP);
302
303}
304
305sub write_makefile {
306 my ( $base, $build ) = @_;
307
308 print "\tMakefile\n";
309
ed76c0e4 310 my $windef1 = "$SYMBIAN_ROOT\\Epoc32\\Build$CWD\\$base\\$WIN\\$base.def";
27da23d5 311 my $windef2 = "..\\BWINS\\${base}u.def";
ed76c0e4 312 my $armdef1 = "$SYMBIAN_ROOT\\Epoc32\\Build$CWD\\$base\\$ARM\\$base.def";
27da23d5 313 my $armdef2 = "..\\BMARM\\${base}u.def";
314
25ca88e0 315 my $wrap = $SYMBIAN_ROOT && defined $SDK_VARIANT eq 'S60' && $SDK_VERSION eq '1.2' && $SYMBIAN_ROOT !~ /_CW$/;
27da23d5 316 my $ABLD = $wrap ? 'perl b.pl' : 'abld';
317
318 open( MAKEFILE, ">Makefile" ) or die "$0: Makefile: $!\n";
319 print MAKEFILE <<__EOF__;
320WIN = $WIN
321ARM = $ARM
322ABLD = $ABLD
323
324all: build freeze
325
326sis: build_arm freeze_arm
327
328build: abld.bat build_win build_arm
329
330abld.bat:
331 bldmake bldfiles
332
333build_win: abld.bat
334 bldmake bldfiles
335 \$(ABLD) build \$(WIN) udeb
336
337build_arm: abld.bat
338 bldmake bldfiles
339 \$(ABLD) build \$(ARM) $UARM
340
341win: build_win freeze_win
342
343arm: build_arm freeze_arm
344
345freeze: freeze_win freeze_arm
346
347freeze_win:
348 bldmake bldfiles
349 \$(ABLD) freeze \$(WIN) $base
350
351freeze_arm:
352 bldmake bldfiles
353 \$(ABLD) freeze \$(ARM) $base
354
355defrost: defrost_win defrost_arm
356
357defrost_win:
358 -del /f $windef1
359 -del /f $windef2
360
361defrost_arm:
362 -del /f $armdef1
363 -del /f $armdef2
364
365clean: clean_win clean_arm
366
367clean_win:
368 \$(ABLD) clean \$(WIN)
369
370clean_arm:
371 \$(ABLD) clean \$(ARM)
372
373realclean: clean realclean_win realclean_arm
374 -del /f _init.c b.pl
375 -del /f $base.c $base.mmp
376
377realclean_win:
378 \$(ABLD) reallyclean \$(WIN)
379
380realclean_arm:
381 \$(ABLD) reallyclean \$(ARM)
382
383distclean: defrost realclean
384 -rmdir ..\\BWINS ..\\BMARM
385 -del /f const-c.inc const-xs.inc
386 -del /f Makefile abld.bat bld.inf
387__EOF__
388 close(MAKEFILE);
389 if ($wrap) {
390 if(open(B,">b.pl")) {
391 print B <<'__EOF__';
392# abld.pl wrapper.
393
394# nmake doesn't like MFLAGS and MAKEFLAGS being set to -w and w.
395delete $ENV{MFLAGS};
396delete $ENV{MAKEFLAGS};
397
398print "abld @ARGV\n";
c1c0c258 399system_echo("abld @ARGV");
27da23d5 400__EOF__
401 close(B);
402 } else {
403 warn "$0: failed to create b.pl: $!\n";
404 }
405 }
406}
407
408sub update_dir {
409 print "[chdir from ", getcwd(), " to ";
410 chdir(shift) or return;
411 update_cwd();
412 print getcwd(), "]\n";
413}
414
415sub xsconfig {
416 my ( $ext, $dir ) = @_;
c8f896e5 417 print "Configuring for $ext, directory '$dir'...\n";
c1c0c258 418 my $extu = $CoreBuild ? "$BUILDROOT\\lib\\ExtUtils" : "$PERLSDK\\lib\\ExtUtils";
27da23d5 419 update_dir($dir) or die "$0: chdir '$dir': $!\n";
420 my $build = dirname($ext);
421 my $base = basename($ext);
422 my $basexs = "$base.xs";
423 my $basepm = "$base.pm";
424 my $basec = "$base$CSuffix";
425 my $extdir = ".";
426 if ( $dir =~ m:^ext\\(.+): ) {
427 $extdir = $1;
428 }
429 elsif ( $dir ne "." ) {
430 $extdir = $dir;
431 }
432 my $extdirdir = dirname($extdir);
433 my $targetroot = "\\System\\Libs\\Perl\\$R_V_SV";
434 write_bld_inf($base) if -f $basexs;
435
436 my %src;
437 $src{$basec}++;
438
439 $extdirdir = $extdirdir eq "." ? "" : "$extdirdir\\";
440
5c271e25 441 my $extdash = $ext; $extdash =~ s!\\!-!g;
442
27da23d5 443 my %lst;
5c271e25 444 $lst{"$UREL\\perl$VERSION-$extdash.dll"} =
27da23d5 445 "$targetroot\\$ARM-symbian\\$base.dll"
446 if -f $basexs;
447 $lst{"$dir\\$base.pm"} = "$targetroot\\$extdirdir$base.pm"
448 if -f $basepm && $base ne 'XSLoader';
449
450 my %incdir;
451 my $ran_PL;
452 if ( -d 'lib' ) {
453 use File::Find;
454 my @found;
455 find( sub { push @found, $File::Find::name if -f $_ }, 'lib' );
456 for my $found (@found) {
5c271e25 457 next if $found =~ /\.bak$/i; # Zlib
27da23d5 458 my ($short) = ( $found =~ m/^lib.(.+)/ );
459 $short =~ s!/!\\!g;
460 $found =~ s!/!\\!g;
461 $lst{"$dir\\$found"} = "$targetroot\\$short";
462 }
463 }
464 if ( my @pm = glob("*.pm */*.pm") ) {
465 for my $pm (@pm) {
466 next if $pm =~ m:^t/:;
467 $pm =~ s:/:\\:g;
468 $lst{"$dir\\$pm"} = "$targetroot\\$extdirdir$pm";
469 }
470 }
471 if ( my @c = glob("*.c *.cpp */*.c */*.cpp") ) {
0added8b 472 @c = grep { ! m:^zlib-src/: } @c if $ext eq 'ext\Compress\Zlib';
27da23d5 473 for my $c (@c) {
474 $c =~ s:/:\\:g;
475 $src{$c}++;
476 }
477 }
478 if ( my @h = glob("*.h */*.h") ) {
c042ae3a 479 @h = grep { ! m:^zlib-src/: } @h if $ext eq 'ext\Compress\Zlib';
27da23d5 480 for my $h (@h) {
481 $h =~ s:/:\\:g;
482 $h = dirname($h);
483 $incdir{"$dir\\$h"}++ unless $h eq ".";
484 }
485 }
486 if ( exists $EXTCFG{$ext} ) {
487 for my $cfg ( @{ $EXTCFG{$ext} } ) {
488 if ( $cfg =~ /^([-+])?(.+\.(c|cpp|h))$/ ) {
489 my $o = defined $1 ? $1 : '+';
490 my $f = $2;
491 $f =~ s:/:\\:g;
492 for my $f ( glob($f) ) {
493 if ( $o eq '+' ) {
494 warn "$0: no source file $dir\\$f\n" unless -f $f;
495 $src{$f}++ unless $cfg =~ /\.h$/;
496 if ( $f =~ m:^(.+)\\[^\\]+$: ) {
497 $incdir{$1}++;
498 }
499 }
500 elsif ( $o eq '-' ) {
501 delete $src{$f};
502 }
503 }
504 }
505 if ( $cfg =~ /^([-+])?(.+\.(pm|pl|inc))$/ ) {
506 my $o = defined $1 ? $1 : '+';
507 my $f = $2;
508 $f =~ s:/:\\:g;
509 for my $f ( glob($f) ) {
510 if ( $o eq '+' ) {
511 warn "$0: no Perl file $dir\\$f\n" unless -f $f;
512 $lst{"$dir\\$f"} = "$targetroot\\$extdir\\$f";
513 }
514 elsif ( $o eq '-' ) {
515 delete $lst{"$dir\\$f"};
516 }
517 }
518 }
519 if ( $cfg eq 'CONST' && !$ran_PL++ ) {
520 run_PL( "Makefile.PL", $dir, "const-xs.inc" );
521 }
522 }
523 }
524 unless ( $ran_PL++ ) {
525 run_PL( "Makefile.PL", $dir ) if -f "Makefile.PL";
526 }
527 if ( $dir eq "ext\\Errno" ) {
528 run_PL( "Errno_pm.PL", $dir, "Errno.pm" );
529 $lst{"$dir\\Errno.pm"} = "$targetroot\\Errno.pm";
530 }
531 elsif ( $dir eq "ext\\Devel\\PPPort" ) {
532 run_PL( "ppport_h.PL", $dir, "ppport.h" );
533 }
534 elsif ( $dir eq "ext\\DynaLoader" ) {
535 run_PL( "XSLoader_pm.PL", $dir, "XSLoader.pm" );
536 $lst{"ext\\DynaLoader\\XSLoader.pm"} = "$targetroot\\XSLoader.pm";
537 }
538 elsif ( $dir eq "ext\\Encode" ) {
539 system_echo("perl bin\\enc2xs -Q -O -o def_t.c -f def_t.fnm") == 0
540 or die "$0: running enc2xs failed: $!\n";
541 }
542
543 my @lst = sort keys %lst;
544
545 read_mmp( \%CONF, "_init.mmp" );
546 read_mmp( \%CONF, "$base.mmp" );
547
548 if ( -f $basexs ) {
549 my %MM; # MakeMaker results
550 my @MM = qw(VERSION XS_VERSION);
551 if ( -f "Makefile" ) {
552 print "\tReading MakeMaker Makefile...\n";
553 if ( open( MAKEFILE, "Makefile" ) ) {
554 while (<MAKEFILE>) {
555 for my $m (@MM) {
556 if (m!^$m = (.+)!) {
557 $MM{$m} = $1;
558 print "\t$m = $1\n";
559 }
560 }
561 }
562 close(MAKEFILE);
563 }
564 else {
565 warn "$0: Makefile: $!";
566 }
567 print "\tDeleting MakeMaker Makefile.\n";
568 unlink("Makefile");
569 }
570
571 unlink($basec);
572 print "\t$basec\n";
573 if ( defined $CONF{EXTVERSION} ) {
574 my $EXTVERSION = $CONF{EXTVERSION};
575 print "\tUsing $EXTVERSION for version...\n";
576 $MM{VERSION} = $MM{XS_VERSION} = $EXTVERSION;
577 }
25ca88e0 578 die "$0: VERSION or XS_VERSION undefined\n"
27da23d5 579 unless defined $MM{VERSION} && defined $MM{XS_VERSION};
580 if ( open( BASE_C, ">$basec" ) ) {
581 print BASE_C <<__EOF__;
582#ifndef VERSION
583#define VERSION "$MM{VERSION}"
584#endif
585#ifndef XS_VERSION
586#define XS_VERSION "$MM{XS_VERSION}"
587#endif
588__EOF__
589 close(BASE_C);
590 }
591 else {
592 warn "$0: $basec: $!";
593 }
594 unless (
c1c0c258 595 system_echo(
596"perl -I$BUILDROOT\\lib -I$PERLSDK\\lib $extu\\xsubpp -csuffix .cpp -typemap $extu\\typemap -noprototypes $basexs >> $basec"
27da23d5 597 ) == 0
598 && -s $basec
599 )
600 {
601 die "$0: perl xsubpp failed: $!\n";
602 }
603
604 print "\t_init.c\n";
605 open( _INIT_C, ">_init.c" ) or die "$!: _init.c: $!\n";
606 print _INIT_C <<__EOF__;
607 #include "EXTERN.h"
608 #include "perl.h"
609 EXPORT_C void _init(void *handle) {
610 }
611__EOF__
612 close(_INIT_C);
613
614 my @src = ( "_init.c", sort keys %src );
615
616 if ( $base eq "Encode" ) { # Currently unused.
617 for my $submf ( glob("*/Makefile") ) {
618 my $d = dirname($submf);
619 print "Configuring Encode::$d...\n";
620 if ( open( SUBMF, $submf ) ) {
621 if ( update_dir($d) ) {
622 my @subsrc;
623 while (<SUBMF>) {
624 next if 1 .. /postamble/;
625 if (m!^(\w+_t)\.c : !) {
c1c0c258 626 system_echo(
27da23d5 627 "perl ..\\bin\\enc2xs -Q -o $1.c -f $1.fnm")
628 == 0
629 or warn "$0: enc2xs: $!\n";
630 push @subsrc, "$1.c";
631 }
632 }
633 close(SUBMF);
634 unlink($submf);
635 my $subbase = $d;
636 $subbase =~ s!/!::!g;
5c271e25 637 write_mmp( $ext, $subbase, ["..\\Encode"], "$subbase.c",
27da23d5 638 @subsrc );
639 write_makefile( $subbase, $build );
640 write_bld_inf($subbase);
641
642 unless (
c1c0c258 643 system_echo(
644"perl -I$BUILDROOT\\lib ..\\$extu\\xsubpp -csuffix .cpp -typemap ..\\$extu\\typemap -noprototypes $subbase.xs > $subbase.c"
27da23d5 645 ) == 0
646 && -s "$subbase.c"
647 )
648 {
649 die "$0: perl xsubpp failed: $!\n";
650 }
651 update_dir("..");
652 }
653 else {
654 warn "$0: chdir $d: $!\n";
655 }
656 }
657 else {
658 warn "$0: $submf: $!";
659 }
660 }
661 print "Configuring Encode...\n";
662 }
663
5c271e25 664 write_mmp( $ext, $base, [ keys %incdir ], @src );
27da23d5 665 write_makefile( $base, $build );
666 }
667 my $lstname = $ext;
668 $lstname =~ s:^ext\\::;
669 $lstname =~ s:\\:-:g;
670 print "\t$lstname.lst\n";
671 my $lstout =
c1c0c258 672 $CoreBuild ? "$BUILDROOT/symbian/$lstname.lst" : "$BUILDROOT/$lstname.lst";
27da23d5 673 if ( open( my $lst, ">$lstout" ) ) {
674 for my $f (@lst) { print $lst qq["$f"-"!:$lst{$f}"\n] }
675 close($lst);
676 }
677 else {
678 die "$0: $lstout: $!\n";
679 }
c1c0c258 680 update_dir($BUILDROOT);
27da23d5 681}
682
683sub update_cwd {
684 $CWD = getcwd();
685 $CWD =~ s!^[CD]:!!i;
686 $CWD =~ s!/!\\!g;
687}
688
689for my $ext (@ARGV) {
690
691 $ext =~ s!::!\\!g;
5c271e25 692 my $extdash = "ext\\$ext"; $extdash =~ s!\\!-!g;
27da23d5 693 $ext =~ s!/!\\!g;
694
695 my $cfg;
696
697 $cfg = $2 if $ext =~ s/(.+?),(.+)/$1/;
698
699 my $dir;
700
701 unless ( -e $ext ) {
702 if ( $ext =~ /\.xs$/ && !-f $ext ) {
703 if ( -f "ext\\$ext" ) {
704 $ext = "ext\\$ext";
705 $dir = dirname($ext);
706 }
707 }
708 elsif ( !-d $ext ) {
709 if ( -d "ext\\$ext" ) {
710 $ext = "ext\\$ext";
711 $dir = $ext;
712 }
713 }
714 $dir = "." unless defined $dir;
715 }
716 else {
717 if ( $ext =~ /\.xs$/ && -f $ext ) {
718 $ext = dirname($ext);
719 $dir = $ext;
720 }
721 elsif ( -d $ext ) {
722 $dir = $ext;
723 }
724 }
725
726 if ( $ext eq "XSLoader" ) {
727 $ext = "ext\\XSLoader";
728 }
729 if ( $ext eq "ext\\XSLoader" ) {
730 $dir = "ext\\DynaLoader";
731 }
732
733 $EXTCFG{$ext} = [ split( /,/, $cfg ) ] if defined $cfg;
734
735 die "$0: no lib\\Config.pm\n"
736 if $CoreBuild && $Build && !-f "lib\\Config.pm";
737
738 if ($CoreBuild) {
739 open( my $cfg, "symbian/install.cfg" )
740 or die "$0: symbian/install.cfg: $!\n";
741 my $extdir = $dir;
742 $extdir =~ s:^ext\\::;
743 while (<$cfg>) {
744 next unless /^ext\s+(.+)/;
745 chomp;
746 my $ext = $1;
747 my @ext = split( ' ', $ext );
748 $EXTCFG{"ext\\$ext[0]"} = [@ext];
749 }
750 close($cfg);
751 }
752
753 if ( $Config || $Build ) {
754 xsconfig( $ext, $dir ) or die "$0: xsconfig '$ext' failed\n";
755 next if $Config;
756 }
757
1215b447 758 if ($dir eq ".") {
759 warn "$0: No directory for $ext, skipping...\n";
760 next;
761 }
762
27da23d5 763 my $chdir = $ext eq "ext\\XSLoader" ? "ext\\DynaLoader" : $dir;
764 die "$0: no directory '$chdir'\n" unless -d $chdir;
765 update_dir($chdir) or die "$0: chdir '$chdir' failed: $!\n";
766
767 my %CONF;
768
769 my @ext = split( /\\/, $ext );
770 my $base = $ext[-1];
771
772 if ( $Clean || $DistClean ) {
773 print "Cleaning $ext...\n";
774 unlink("bld.inf");
775 unlink("$base.mmp");
776 unlink("_init.c");
777 unlink("const-c.inc");
778 unlink("const-xs.inc");
779 rmdir("..\\bmarm");
780 }
781
782 if ( $Build && $ext ne "ext\\XSLoader" && $ext ne "ext\\Errno" ) {
783
784 # We compile the extension three (3) times.
785 # (1) Only the _init.c to get _init() as the ordinal 1 function in the DLL.
786 # (2) With the rest and the _init.c to get ordinals for the rest.
787 # (3) With an updated _init.c that carries the symbols from step (2).
788
c1c0c258 789 system_echo("make clean");
c8f896e5 790 system_echo("make defrost") == 0 or warn "$0: make defrost failed\n";
27da23d5 791
792 my @TARGET;
793
794 push @TARGET, 'sis' if $Sis;
795
796 # Compile #1.
797 # Hide all but the _init.c.
798 print "\n*** $ext - Compile 1 of 3.\n\n";
c1c0c258 799 print "(patching $base.mmp)\n";
27da23d5 800 system(
801"perl -pi.bak -e \"s:^SOURCE\\s+_init.c:SOURCE\\t_init.c // :\" $base.mmp"
802 );
c1c0c258 803 system_echo("bldmake bldfiles");
804 system_echo("make @TARGET") == 0 or die "$0: make #1 failed\n";
27da23d5 805
806 # Compile #2.
807 # Reveal the rest again.
808 print "\n*** $ext - Compile 2 of 3.\n\n";
c1c0c258 809 print "(patching $base.mmp)\n";
27da23d5 810 system(
811"perl -pi.bak -e \"s:^SOURCE\\t_init.c // :SOURCE\\t_init.c :\" $base.mmp"
812 );
c1c0c258 813 system_echo("make @TARGET") == 0 or die "$0: make #2 failed\n";
27da23d5 814 unlink("$base.mmp.bak");
815
816 open( _INIT_C, ">_init.c" ) or die "$0: _init.c: $!\n";
817 print _INIT_C <<'__EOF__';
818#include "EXTERN.h"
819#include "perl.h"
820
821/* This is a different but matching definition from in dl_symbian.xs. */
822typedef struct {
823 void* handle;
824 int error;
825 HV* symbols;
826} PerlSymbianLibHandle;
827
828EXPORT_C void _init(void* handle) {
829__EOF__
830
831 my %symbol;
832 my $def;
833 my $basef;
ed76c0e4 834 for my $f ("$SYMBIAN_ROOT\\Epoc32\\Build$CWD\\$base\\WINS\\perl$VERSION-$extdash.def",
5c271e25 835 "..\\BMARM\\perl$VERSION-${extdash}u.def") {
27da23d5 836 print "\t($f - ";
837 if ( open( $def, $f ) ) {
838 print "OK)\n";
839 $basef = $f;
840 last;
841 } else {
842 print "no)\n";
843 }
844 }
845 unless (defined $basef) {
846 die "$0: failed to find .def for $base\n";
847 }
848 while (<$def>) {
849 next while 1 .. /^EXPORTS/;
850 if (/^\s*(\w+) \@ (\d+) /) {
851 $symbol{$1} = $2;
852 }
853 }
854 close($def);
855
856 my @symbol = sort keys %symbol;
857 if (@symbol) {
858 print _INIT_C <<'__EOF__';
859 dTHX;
860 PerlSymbianLibHandle* h = (PerlSymbianLibHandle*)handle;
861 if (!h->symbols)
862 h->symbols = newHV();
863 if (h->symbols) {
864__EOF__
865 for my $sym (@symbol) {
866 my $len = length($sym);
867 print _INIT_C <<__EOF__;
868 hv_store(h->symbols, "$sym", $len, newSViv($symbol{$sym}), 0);
869__EOF__
870 }
871 }
872 else {
873 die "$0: $basef: no exports found\n";
874 }
875
876 print _INIT_C <<'__EOF__';
877 }
878}
879__EOF__
880 close(_INIT_C);
881
882 # Compile #3. This is for real.
883 print "\n*** $ext - Compile 3 of 3.\n\n";
c1c0c258 884 system_echo("make @TARGET") == 0 or die "$0: make #3 failed\n";
27da23d5 885
886 }
887 elsif ( $Clean || $DistClean ) {
888 if ( $ext eq "ext\\Errno" ) {
889 unlink( "Errno.pm", "Makefile" );
890 }
891 else {
892 if ( -f "Makefile" ) {
893 if ($Clean) {
c1c0c258 894 system_echo("make clean") == 0 or die "$0: make clean failed\n";
27da23d5 895 }
896 elsif ($DistClean) {
c1c0c258 897 system_echo("make distclean") == 0
27da23d5 898 or die "$0: make distclean failed\n";
899 }
900 }
1215b447 901 if ( $ext eq "ext\\Compress\\Zlib" ) {
902 my @bak;
903 find( sub { push @bak, $File::Find::name if /\.bak$/ }, "." );
904 unlink(@bak) if @bak;
905 my @src;
906 find( sub { push @src, $_ if -f $_ }, "zlib-src" );
907 unlink(@src) if @src;
908 unlink("constants.xs");
909 }
27da23d5 910 if ( $ext eq "ext\\Devel\\PPPort" ) {
911 unlink("ppport.h");
912 }
913 }
1215b447 914 my @D = glob("../BMARM/*.def ../BWINS/*.def");
915 unlink(@D) if @D;
27da23d5 916 my @B = glob("ext/BWINS ext/BMARM ext/*/BWINS ext/*/BMARM Makefile");
917 rmdir(@B) if @B;
918 }
919
c1c0c258 920 update_dir($BUILDROOT);
27da23d5 921
922} # for my $ext
923
924exit(0);
925