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