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