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