This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perldelta for 8348ac19a3c3
[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
5909b2ae 9unshift @INC, dirname $0 || '.';
e81465be 10do "sanity.pl" or die $@;
27da23d5
JH
11
12my $CoreBuild = -d "ext" && -f "perl.h" && -d "symbian" && -f "perl.c";
13
25ca88e0
JH
14my $SymbianVersion;
15
16if (exists $ENV{EPOCROOT}) {
17 if ($ENV{EPOCROOT} =~ m!\\Symbian\\UIQ_21\\$!i) {
18 $SymbianVersion = '7.0s'; # TODO: other UIQ versions
19 } elsif ($ENV{EPOCROOT} =~ m!\\Symbian\\(.+?)\\!i) {
20 $SymbianVersion = $1;
21 }
22}
23
24$SymbianVersion = $ENV{XSBUILD_SYMBIAN_VERSION}
25 if exists $ENV{XSBUILD_SYMBIAN_VERSION};
26
27da23d5
JH
27my $PerlVersion = $ENV{XSBUILD_PERL_VERSION};
28my $CSuffix = '.c';
29my $CPlusPlus;
30my $Config;
31my $Build;
32my $Clean;
33my $DistClean;
34my $Sis;
35
36sub usage {
37 die <<__EOF__;
38$0: Usage: $0 [--symbian=version] [--perl=version]
d0d72822
JH
39 [--extversion=x.y]
40 [--csuffix=csuffix] [--cplusplus|--cpp]
41 [--win=win] [--arm=arm]
27da23d5
JH
42 [--config|--build|--clean|--distclean|--sis] ext
43__EOF__
44}
45
46my $CWD;
47my $SDK;
48my $VERSION;
49my $R_V_SV;
50my $PERLSDK;
c8f896e5
JH
51my $WIN = 'wins';
52my $ARM = 'thumb';
c1c0c258 53my $BUILDROOT = getcwd();
27da23d5
JH
54
55if ( !defined $PerlVersion && $0 =~ m:\\symbian\\perl\\(.+)\\bin\\xsbuild.pl:i )
56{
57 $PerlVersion = $1;
58}
59
60if ( !defined $SymbianVersion) {
25ca88e0 61 ($SymbianVersion) = ($ENV{PATH} =~ m!\\Symbian\\(.+?)\\!i);
27da23d5
JH
62}
63
ed76c0e4
JH
64my ($SYMBIAN_ROOT, $SYMBIAN_VERSION, $SDK_NAME, $SDK_VARIANT, $SDK_VERSION);
65
27da23d5 66if ($CoreBuild) {
e81465be
NC
67 do "sanity.pl" or die $@;
68 my %VERSION = %{ do "version.pl" or die $@ };
ed76c0e4 69 ($SYMBIAN_ROOT, $SYMBIAN_VERSION, $SDK_NAME, $SDK_VARIANT, $SDK_VERSION) =
e81465be 70 @{ do "sdk.pl" or die $@ };
27da23d5
JH
71 $VERSION = "$VERSION{REVISION}$VERSION{VERSION}$VERSION{SUBVERSION}";
72 $R_V_SV = "$VERSION{REVISION}.$VERSION{VERSION}.$VERSION{SUBVERSION}";
e81465be 73 $BUILDROOT = do "cwd.pl" or die $@;
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
53d44271
JH
104#die "$0: Symbian version '$SymbianVersion' not found\n"
105# unless -d "\\Symbian\\$SymbianVersion";
27da23d5
JH
106
107die "$0: Perl version undefined\n" unless defined $PerlVersion;
108
53d44271
JH
109$PERLSDK = "$SYMBIAN_ROOT\\Perl\\$PerlVersion";
110
27da23d5 111die "$0: Perl version '$PerlVersion' not found\n"
53d44271 112 if !$CoreBuild && !-d $PERLSDK;
27da23d5
JH
113
114print "Configuring with Symbian $SymbianVersion and Perl $PerlVersion...\n";
115
27da23d5
JH
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";
1ae6ead9 140 open( BLD_INF, '>', 'bld.inf' ) or die "$0: bld.inf: $!\n";
27da23d5
JH
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;
d1144667 166 $ENV{PERL_CORE} = 1 if $CoreBuild;
1215b447 167 system_echo("perl -I$BUILDROOT\\lib -I$BUILDROOT\\xlib\\symbian -I$BUILDROOT\\t\\lib $PL") == 0
27da23d5 168 or warn "$0: $PL failed.\n";
27da23d5
JH
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 ) = @_;
1ae6ead9 191 if ( -r $mmp && open( MMP, '<', $mmp ) ) {
27da23d5
JH
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
JH
210 my ( $ext, $base, $userinclude, @src ) = @_;
211
212 my $extdash = $ext; $extdash =~ s!\\!-!g;
27da23d5
JH
213
214 print "\t$base.mmp\n";
5c271e25 215 $CONF{TARGET} = "perl$VERSION-$extdash.dll";
27da23d5
JH
216 $CONF{TARGETPATH} = "\\System\\Libs\\Perl\\$R_V_SV";
217 $CONF{SOURCE} = [@src];
c1c0c258
JH
218 $CONF{SOURCEPATH} = [ $CWD, $BUILDROOT ];
219 $CONF{USERINCLUDE} = [ $CWD, $BUILDROOT ];
27da23d5 220 $CONF{SYSTEMINCLUDE} = ["$PERLSDK\\include"] unless $CoreBuild;
25ca88e0 221 $CONF{SYSTEMINCLUDE} = [ $BUILDROOT, "$BUILDROOT\\symbian" ] if $CoreBuild;
27da23d5
JH
222 $CONF{LIBRARY} = [];
223 $CONF{MACRO} = [];
224 read_mmp( \%CONF, "_init.mmp" );
225 read_mmp( \%CONF, "$base.mmp" );
226
0added8b
JH
227 if ($base eq 'Zlib') {
228 push @{$CONF{USERINCLUDE}}, "$CWD\\zlib-src";
229 }
230
27da23d5
JH
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
JH
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
25ca88e0
JH
252 if ($SDK_VARIANT eq 'S60') {
253 push @{ $CONF{MACRO} }, '__SERIES60__'
254 unless grep { $_ eq '__SERIES60__' } @{ $CONF{MACRO} };
255 }
256 if ($SDK_VARIANT eq 'S80') {
257 push @{ $CONF{MACRO} }, '__SERIES80__'
258 unless grep { $_ eq '__SERIES80__' } @{ $CONF{MACRO} };
259 }
53d44271
JH
260 if ($SDK_VARIANT eq 'S90') {
261 push @{ $CONF{MACRO} }, '__SERIES90__'
262 unless grep { $_ eq '__SERIES90__' } @{ $CONF{MACRO} };
263 }
25ca88e0
JH
264 if ($SDK_VARIANT eq 'UIQ') {
265 push @{ $CONF{MACRO} }, '__UIQ__'
266 unless grep { $_ eq '__UIQ__' } @{ $CONF{MACRO} };
267 }
268
27da23d5
JH
269 for my $u (qw(SOURCE SOURCEPATH SYSTEMINCLUDE USERINCLUDE LIBRARY MACRO)) {
270 $CONF{$u} = uniquefy_filenames( $CONF{$u} );
271 }
1ae6ead9 272 open( BASE_MMP, '>', "$base.mmp" ) or die "$0: $base.mmp: $!\n";
27da23d5
JH
273
274 print BASE_MMP <<__EOF__;
275TARGET $CONF{TARGET}
276TARGETTYPE dll
277TARGETPATH $CONF{TARGETPATH}
278SOURCE @{$CONF{SOURCE}}
279$SRCDBG
280__EOF__
281 for my $u (qw(SOURCEPATH SYSTEMINCLUDE USERINCLUDE)) {
282 for my $v ( @{ $CONF{$u} } ) {
283 print BASE_MMP "$u\t$v\n";
284 }
285 }
286 # OPTION does not work in MMPs for pre-2.0 SDKs?
287 print BASE_MMP <<__EOF__;
288LIBRARY @{$CONF{LIBRARY}}
289MACRO @{$CONF{MACRO}}
25ca88e0
JH
290// OPTION MSVC /P // Uncomment for creating .i (cpp'ed .cpp)
291// OPTION GCC -E // Uncomment for creating .i (cpp'ed .cpp)
27da23d5 292__EOF__
25ca88e0
JH
293# if (-f "$base.rss") {
294# print BASE_MMP "RESOURCE\t$base.rss\n";
295# }
27da23d5
JH
296 close(BASE_MMP);
297
298}
299
300sub write_makefile {
301 my ( $base, $build ) = @_;
302
303 print "\tMakefile\n";
304
ed76c0e4 305 my $windef1 = "$SYMBIAN_ROOT\\Epoc32\\Build$CWD\\$base\\$WIN\\$base.def";
27da23d5 306 my $windef2 = "..\\BWINS\\${base}u.def";
ed76c0e4 307 my $armdef1 = "$SYMBIAN_ROOT\\Epoc32\\Build$CWD\\$base\\$ARM\\$base.def";
27da23d5
JH
308 my $armdef2 = "..\\BMARM\\${base}u.def";
309
25ca88e0 310 my $wrap = $SYMBIAN_ROOT && defined $SDK_VARIANT eq 'S60' && $SDK_VERSION eq '1.2' && $SYMBIAN_ROOT !~ /_CW$/;
27da23d5
JH
311 my $ABLD = $wrap ? 'perl b.pl' : 'abld';
312
1ae6ead9 313 open( MAKEFILE, '>', 'Makefile' ) or die "$0: Makefile: $!\n";
27da23d5
JH
314 print MAKEFILE <<__EOF__;
315WIN = $WIN
316ARM = $ARM
317ABLD = $ABLD
318
319all: build freeze
320
321sis: build_arm freeze_arm
322
323build: abld.bat build_win build_arm
324
325abld.bat:
326 bldmake bldfiles
327
328build_win: abld.bat
329 bldmake bldfiles
330 \$(ABLD) build \$(WIN) udeb
331
332build_arm: abld.bat
333 bldmake bldfiles
334 \$(ABLD) build \$(ARM) $UARM
335
336win: build_win freeze_win
337
338arm: build_arm freeze_arm
339
340freeze: freeze_win freeze_arm
341
342freeze_win:
343 bldmake bldfiles
344 \$(ABLD) freeze \$(WIN) $base
345
346freeze_arm:
347 bldmake bldfiles
348 \$(ABLD) freeze \$(ARM) $base
349
350defrost: defrost_win defrost_arm
351
352defrost_win:
353 -del /f $windef1
354 -del /f $windef2
355
356defrost_arm:
357 -del /f $armdef1
358 -del /f $armdef2
359
360clean: clean_win clean_arm
361
362clean_win:
363 \$(ABLD) clean \$(WIN)
364
365clean_arm:
366 \$(ABLD) clean \$(ARM)
367
368realclean: clean realclean_win realclean_arm
369 -del /f _init.c b.pl
370 -del /f $base.c $base.mmp
371
372realclean_win:
373 \$(ABLD) reallyclean \$(WIN)
374
375realclean_arm:
376 \$(ABLD) reallyclean \$(ARM)
377
378distclean: defrost realclean
379 -rmdir ..\\BWINS ..\\BMARM
380 -del /f const-c.inc const-xs.inc
381 -del /f Makefile abld.bat bld.inf
382__EOF__
383 close(MAKEFILE);
384 if ($wrap) {
1ae6ead9 385 if(open(B, '>', 'b.pl')) {
27da23d5
JH
386 print B <<'__EOF__';
387# abld.pl wrapper.
388
389# nmake doesn't like MFLAGS and MAKEFLAGS being set to -w and w.
390delete $ENV{MFLAGS};
391delete $ENV{MAKEFLAGS};
392
393print "abld @ARGV\n";
c1c0c258 394system_echo("abld @ARGV");
27da23d5
JH
395__EOF__
396 close(B);
397 } else {
398 warn "$0: failed to create b.pl: $!\n";
399 }
400 }
401}
402
403sub update_dir {
404 print "[chdir from ", getcwd(), " to ";
405 chdir(shift) or return;
406 update_cwd();
407 print getcwd(), "]\n";
408}
409
d1144667
JH
410sub patch_config {
411 # Problem: the Config.pm we have in $BUILDROOT\\lib carries the
412 # version number of the Perl we are building, while the Perl
413 # we are running might have some other version. Solution:
414 # temporarily replace the Config.pm with a patched version.
415 #
416 # Reverse patch will be done with this special script
417 my $config_restore_script = "$BUILDROOT\\lib\\symbian_config_restore.pl";
418 # make sure the patch script was not left from previous run
419 unlink $config_restore_script;
420 return unless $CoreBuild;
421 my $V = sprintf "%vd", $^V;
422 # create reverse patch script
1ae6ead9 423 if (open(RSCRIPT, '>', $config_restore_script)) {
d1144667
JH
424 print RSCRIPT <<__EOF__;
425#!perl -pi.bak
426s:\\Q$V:$R_V_SV:
427__EOF__
428 close RSCRIPT;
429 } else {
430 die "$0: Cannot create $config_restore_script: $!";
431 }
432 # patch the config
433 unlink("$BUILDROOT\\lib\\Config.pm.bak");
434 print "(patching $BUILDROOT\\lib\\Config.pm)\n";
435 system_echo("perl -pi.bak -e \"s:\\Q$R_V_SV:$V:\" $BUILDROOT\\lib\\Config.pm");
436}
437
438sub restore_config {
439 my $config_restore_script = "$BUILDROOT\\lib\\symbian_config_restore.pl";
440 # this function should always return True
441 # because it's commonly used in error handling blocks as
442 # &restore_config and die
443 return 1 unless -f $config_restore_script;
444 unlink("$BUILDROOT\\lib\\Config.pm.bak");
445 print "(restoring $BUILDROOT\\lib\\Config.pm)\n";
446 system_echo("perl -pi.bak $config_restore_script $BUILDROOT\\lib\\Config.pm");
447 unlink "$BUILDROOT\\lib\\Config.pm.bak", $config_restore_script;
448 # above command should always return 2 already,
449 # but i want to be absolutely sure that return value is True
450 return 1;
451}
452
27da23d5
JH
453sub xsconfig {
454 my ( $ext, $dir ) = @_;
c8f896e5 455 print "Configuring for $ext, directory '$dir'...\n";
c1c0c258 456 my $extu = $CoreBuild ? "$BUILDROOT\\lib\\ExtUtils" : "$PERLSDK\\lib\\ExtUtils";
27da23d5 457 update_dir($dir) or die "$0: chdir '$dir': $!\n";
d1144667
JH
458 &patch_config;
459
27da23d5
JH
460 my $build = dirname($ext);
461 my $base = basename($ext);
462 my $basexs = "$base.xs";
463 my $basepm = "$base.pm";
464 my $basec = "$base$CSuffix";
465 my $extdir = ".";
466 if ( $dir =~ m:^ext\\(.+): ) {
467 $extdir = $1;
468 }
469 elsif ( $dir ne "." ) {
470 $extdir = $dir;
471 }
472 my $extdirdir = dirname($extdir);
473 my $targetroot = "\\System\\Libs\\Perl\\$R_V_SV";
474 write_bld_inf($base) if -f $basexs;
475
476 my %src;
477 $src{$basec}++;
478
479 $extdirdir = $extdirdir eq "." ? "" : "$extdirdir\\";
480
5c271e25
JH
481 my $extdash = $ext; $extdash =~ s!\\!-!g;
482
27da23d5 483 my %lst;
5c271e25 484 $lst{"$UREL\\perl$VERSION-$extdash.dll"} =
27da23d5
JH
485 "$targetroot\\$ARM-symbian\\$base.dll"
486 if -f $basexs;
487 $lst{"$dir\\$base.pm"} = "$targetroot\\$extdirdir$base.pm"
488 if -f $basepm && $base ne 'XSLoader';
489
490 my %incdir;
491 my $ran_PL;
492 if ( -d 'lib' ) {
493 use File::Find;
494 my @found;
495 find( sub { push @found, $File::Find::name if -f $_ }, 'lib' );
496 for my $found (@found) {
5c271e25 497 next if $found =~ /\.bak$/i; # Zlib
27da23d5
JH
498 my ($short) = ( $found =~ m/^lib.(.+)/ );
499 $short =~ s!/!\\!g;
500 $found =~ s!/!\\!g;
501 $lst{"$dir\\$found"} = "$targetroot\\$short";
502 }
503 }
504 if ( my @pm = glob("*.pm */*.pm") ) {
505 for my $pm (@pm) {
506 next if $pm =~ m:^t/:;
507 $pm =~ s:/:\\:g;
508 $lst{"$dir\\$pm"} = "$targetroot\\$extdirdir$pm";
509 }
510 }
511 if ( my @c = glob("*.c *.cpp */*.c */*.cpp") ) {
5909b2ae 512 map { s:^zlib-src/:: } @c if $ext eq 'ext\Compress\Raw\Zlib';
27da23d5
JH
513 for my $c (@c) {
514 $c =~ s:/:\\:g;
515 $src{$c}++;
516 }
517 }
518 if ( my @h = glob("*.h */*.h") ) {
5909b2ae 519 map { s:^zlib-src/:: } @h if $ext eq 'ext\Compress\Raw\Zlib';
27da23d5
JH
520 for my $h (@h) {
521 $h =~ s:/:\\:g;
522 $h = dirname($h);
523 $incdir{"$dir\\$h"}++ unless $h eq ".";
524 }
525 }
526 if ( exists $EXTCFG{$ext} ) {
527 for my $cfg ( @{ $EXTCFG{$ext} } ) {
528 if ( $cfg =~ /^([-+])?(.+\.(c|cpp|h))$/ ) {
529 my $o = defined $1 ? $1 : '+';
530 my $f = $2;
531 $f =~ s:/:\\:g;
532 for my $f ( glob($f) ) {
533 if ( $o eq '+' ) {
534 warn "$0: no source file $dir\\$f\n" unless -f $f;
535 $src{$f}++ unless $cfg =~ /\.h$/;
536 if ( $f =~ m:^(.+)\\[^\\]+$: ) {
537 $incdir{$1}++;
538 }
539 }
540 elsif ( $o eq '-' ) {
541 delete $src{$f};
542 }
543 }
544 }
545 if ( $cfg =~ /^([-+])?(.+\.(pm|pl|inc))$/ ) {
546 my $o = defined $1 ? $1 : '+';
547 my $f = $2;
548 $f =~ s:/:\\:g;
549 for my $f ( glob($f) ) {
550 if ( $o eq '+' ) {
551 warn "$0: no Perl file $dir\\$f\n" unless -f $f;
552 $lst{"$dir\\$f"} = "$targetroot\\$extdir\\$f";
553 }
554 elsif ( $o eq '-' ) {
555 delete $lst{"$dir\\$f"};
556 }
557 }
558 }
559 if ( $cfg eq 'CONST' && !$ran_PL++ ) {
560 run_PL( "Makefile.PL", $dir, "const-xs.inc" );
561 }
562 }
563 }
564 unless ( $ran_PL++ ) {
565 run_PL( "Makefile.PL", $dir ) if -f "Makefile.PL";
566 }
567 if ( $dir eq "ext\\Errno" ) {
568 run_PL( "Errno_pm.PL", $dir, "Errno.pm" );
569 $lst{"$dir\\Errno.pm"} = "$targetroot\\Errno.pm";
570 }
571 elsif ( $dir eq "ext\\Devel\\PPPort" ) {
572 run_PL( "ppport_h.PL", $dir, "ppport.h" );
573 }
574 elsif ( $dir eq "ext\\DynaLoader" ) {
575 run_PL( "XSLoader_pm.PL", $dir, "XSLoader.pm" );
576 $lst{"ext\\DynaLoader\\XSLoader.pm"} = "$targetroot\\XSLoader.pm";
577 }
578 elsif ( $dir eq "ext\\Encode" ) {
579 system_echo("perl bin\\enc2xs -Q -O -o def_t.c -f def_t.fnm") == 0
d1144667 580 or &restore_config and die "$0: running enc2xs failed: $!\n";
27da23d5
JH
581 }
582
583 my @lst = sort keys %lst;
584
585 read_mmp( \%CONF, "_init.mmp" );
586 read_mmp( \%CONF, "$base.mmp" );
587
588 if ( -f $basexs ) {
589 my %MM; # MakeMaker results
590 my @MM = qw(VERSION XS_VERSION);
591 if ( -f "Makefile" ) {
592 print "\tReading MakeMaker Makefile...\n";
1ae6ead9 593 if ( open( MAKEFILE, '<', 'Makefile' ) ) {
27da23d5
JH
594 while (<MAKEFILE>) {
595 for my $m (@MM) {
596 if (m!^$m = (.+)!) {
597 $MM{$m} = $1;
598 print "\t$m = $1\n";
599 }
600 }
601 }
602 close(MAKEFILE);
603 }
604 else {
605 warn "$0: Makefile: $!";
606 }
607 print "\tDeleting MakeMaker Makefile.\n";
608 unlink("Makefile");
609 }
610
611 unlink($basec);
612 print "\t$basec\n";
613 if ( defined $CONF{EXTVERSION} ) {
614 my $EXTVERSION = $CONF{EXTVERSION};
615 print "\tUsing $EXTVERSION for version...\n";
616 $MM{VERSION} = $MM{XS_VERSION} = $EXTVERSION;
617 }
d1144667 618 (&restore_config and die "$0: VERSION or XS_VERSION undefined\n")
27da23d5 619 unless defined $MM{VERSION} && defined $MM{XS_VERSION};
1ae6ead9 620 if ( open( BASE_C, '>', $basec ) ) {
27da23d5
JH
621 print BASE_C <<__EOF__;
622#ifndef VERSION
623#define VERSION "$MM{VERSION}"
624#endif
625#ifndef XS_VERSION
626#define XS_VERSION "$MM{XS_VERSION}"
627#endif
628__EOF__
629 close(BASE_C);
630 }
631 else {
632 warn "$0: $basec: $!";
633 }
634 unless (
c1c0c258
JH
635 system_echo(
636"perl -I$BUILDROOT\\lib -I$PERLSDK\\lib $extu\\xsubpp -csuffix .cpp -typemap $extu\\typemap -noprototypes $basexs >> $basec"
27da23d5
JH
637 ) == 0
638 && -s $basec
639 )
640 {
d1144667 641 &restore_config;
27da23d5
JH
642 die "$0: perl xsubpp failed: $!\n";
643 }
644
645 print "\t_init.c\n";
1ae6ead9 646 open( _INIT_C, '>', '_init.c' )
d1144667 647 or &restore_config and die "$!: _init.c: $!\n";
27da23d5
JH
648 print _INIT_C <<__EOF__;
649 #include "EXTERN.h"
650 #include "perl.h"
651 EXPORT_C void _init(void *handle) {
652 }
653__EOF__
654 close(_INIT_C);
655
656 my @src = ( "_init.c", sort keys %src );
657
658 if ( $base eq "Encode" ) { # Currently unused.
659 for my $submf ( glob("*/Makefile") ) {
660 my $d = dirname($submf);
661 print "Configuring Encode::$d...\n";
1ae6ead9 662 if ( open( SUBMF, '<', $submf ) ) {
27da23d5
JH
663 if ( update_dir($d) ) {
664 my @subsrc;
665 while (<SUBMF>) {
666 next if 1 .. /postamble/;
667 if (m!^(\w+_t)\.c : !) {
c1c0c258 668 system_echo(
27da23d5
JH
669 "perl ..\\bin\\enc2xs -Q -o $1.c -f $1.fnm")
670 == 0
671 or warn "$0: enc2xs: $!\n";
672 push @subsrc, "$1.c";
673 }
674 }
675 close(SUBMF);
676 unlink($submf);
677 my $subbase = $d;
678 $subbase =~ s!/!::!g;
5c271e25 679 write_mmp( $ext, $subbase, ["..\\Encode"], "$subbase.c",
27da23d5
JH
680 @subsrc );
681 write_makefile( $subbase, $build );
682 write_bld_inf($subbase);
683
684 unless (
c1c0c258
JH
685 system_echo(
686"perl -I$BUILDROOT\\lib ..\\$extu\\xsubpp -csuffix .cpp -typemap ..\\$extu\\typemap -noprototypes $subbase.xs > $subbase.c"
27da23d5
JH
687 ) == 0
688 && -s "$subbase.c"
689 )
690 {
d1144667 691 &restore_config;
27da23d5
JH
692 die "$0: perl xsubpp failed: $!\n";
693 }
694 update_dir("..");
695 }
696 else {
697 warn "$0: chdir $d: $!\n";
698 }
699 }
700 else {
701 warn "$0: $submf: $!";
702 }
703 }
704 print "Configuring Encode...\n";
705 }
706
5c271e25 707 write_mmp( $ext, $base, [ keys %incdir ], @src );
27da23d5
JH
708 write_makefile( $base, $build );
709 }
d1144667
JH
710 &restore_config;
711
27da23d5
JH
712 my $lstname = $ext;
713 $lstname =~ s:^ext\\::;
714 $lstname =~ s:\\:-:g;
715 print "\t$lstname.lst\n";
716 my $lstout =
c1c0c258 717 $CoreBuild ? "$BUILDROOT/symbian/$lstname.lst" : "$BUILDROOT/$lstname.lst";
1ae6ead9 718 if ( open( my $lst, '>', $lstout ) ) {
27da23d5
JH
719 for my $f (@lst) { print $lst qq["$f"-"!:$lst{$f}"\n] }
720 close($lst);
721 }
722 else {
723 die "$0: $lstout: $!\n";
724 }
c1c0c258 725 update_dir($BUILDROOT);
27da23d5
JH
726}
727
728sub update_cwd {
729 $CWD = getcwd();
53d44271 730 $CWD =~ s!^[A-Z]:!!i;
27da23d5
JH
731 $CWD =~ s!/!\\!g;
732}
733
da933031
JH
734if (grep /^(Compress::Raw::Zlib|Cwd|Data::Dumper|Digest::SHA|Sys::Syslog|Time::HiRes)$/, @ARGV) {
735 &patch_config;
736 system_echo("perl -I$BUILDROOT\\lib -I$PERLSDK\\lib $BUILDROOT\\mkppport");
737 &restore_config;
738}
739
27da23d5
JH
740for my $ext (@ARGV) {
741
742 $ext =~ s!::!\\!g;
d0d72822 743 my $extdash = $ext =~ /ext\\/ ? $ext : "ext\\$ext"; $extdash =~ s!\\!-!g;
27da23d5
JH
744 $ext =~ s!/!\\!g;
745
746 my $cfg;
747
748 $cfg = $2 if $ext =~ s/(.+?),(.+)/$1/;
749
750 my $dir;
751
752 unless ( -e $ext ) {
753 if ( $ext =~ /\.xs$/ && !-f $ext ) {
754 if ( -f "ext\\$ext" ) {
755 $ext = "ext\\$ext";
756 $dir = dirname($ext);
757 }
758 }
759 elsif ( !-d $ext ) {
760 if ( -d "ext\\$ext" ) {
761 $ext = "ext\\$ext";
762 $dir = $ext;
763 }
764 }
765 $dir = "." unless defined $dir;
766 }
767 else {
768 if ( $ext =~ /\.xs$/ && -f $ext ) {
769 $ext = dirname($ext);
770 $dir = $ext;
771 }
772 elsif ( -d $ext ) {
773 $dir = $ext;
774 }
775 }
776
777 if ( $ext eq "XSLoader" ) {
778 $ext = "ext\\XSLoader";
779 }
780 if ( $ext eq "ext\\XSLoader" ) {
781 $dir = "ext\\DynaLoader";
782 }
783
784 $EXTCFG{$ext} = [ split( /,/, $cfg ) ] if defined $cfg;
785
786 die "$0: no lib\\Config.pm\n"
787 if $CoreBuild && $Build && !-f "lib\\Config.pm";
788
789 if ($CoreBuild) {
1ae6ead9 790 open( my $cfg, '<', 'symbian/install.cfg' )
27da23d5
JH
791 or die "$0: symbian/install.cfg: $!\n";
792 my $extdir = $dir;
793 $extdir =~ s:^ext\\::;
794 while (<$cfg>) {
795 next unless /^ext\s+(.+)/;
796 chomp;
797 my $ext = $1;
798 my @ext = split( ' ', $ext );
799 $EXTCFG{"ext\\$ext[0]"} = [@ext];
800 }
801 close($cfg);
802 }
803
804 if ( $Config || $Build ) {
805 xsconfig( $ext, $dir ) or die "$0: xsconfig '$ext' failed\n";
806 next if $Config;
807 }
808
1215b447
JH
809 if ($dir eq ".") {
810 warn "$0: No directory for $ext, skipping...\n";
811 next;
812 }
813
27da23d5
JH
814 my $chdir = $ext eq "ext\\XSLoader" ? "ext\\DynaLoader" : $dir;
815 die "$0: no directory '$chdir'\n" unless -d $chdir;
816 update_dir($chdir) or die "$0: chdir '$chdir' failed: $!\n";
817
818 my %CONF;
819
820 my @ext = split( /\\/, $ext );
821 my $base = $ext[-1];
822
823 if ( $Clean || $DistClean ) {
824 print "Cleaning $ext...\n";
825 unlink("bld.inf");
826 unlink("$base.mmp");
827 unlink("_init.c");
828 unlink("const-c.inc");
829 unlink("const-xs.inc");
830 rmdir("..\\bmarm");
831 }
832
833 if ( $Build && $ext ne "ext\\XSLoader" && $ext ne "ext\\Errno" ) {
834
835 # We compile the extension three (3) times.
836 # (1) Only the _init.c to get _init() as the ordinal 1 function in the DLL.
837 # (2) With the rest and the _init.c to get ordinals for the rest.
838 # (3) With an updated _init.c that carries the symbols from step (2).
839
c1c0c258 840 system_echo("make clean");
c8f896e5 841 system_echo("make defrost") == 0 or warn "$0: make defrost failed\n";
27da23d5
JH
842
843 my @TARGET;
844
845 push @TARGET, 'sis' if $Sis;
846
847 # Compile #1.
848 # Hide all but the _init.c.
849 print "\n*** $ext - Compile 1 of 3.\n\n";
c1c0c258 850 print "(patching $base.mmp)\n";
27da23d5
JH
851 system(
852"perl -pi.bak -e \"s:^SOURCE\\s+_init.c:SOURCE\\t_init.c // :\" $base.mmp"
853 );
c1c0c258
JH
854 system_echo("bldmake bldfiles");
855 system_echo("make @TARGET") == 0 or die "$0: make #1 failed\n";
27da23d5
JH
856
857 # Compile #2.
858 # Reveal the rest again.
859 print "\n*** $ext - Compile 2 of 3.\n\n";
c1c0c258 860 print "(patching $base.mmp)\n";
27da23d5
JH
861 system(
862"perl -pi.bak -e \"s:^SOURCE\\t_init.c // :SOURCE\\t_init.c :\" $base.mmp"
863 );
c1c0c258 864 system_echo("make @TARGET") == 0 or die "$0: make #2 failed\n";
27da23d5
JH
865 unlink("$base.mmp.bak");
866
1ae6ead9 867 open( _INIT_C, '>', '_init.c' ) or die "$0: _init.c: $!\n";
27da23d5
JH
868 print _INIT_C <<'__EOF__';
869#include "EXTERN.h"
870#include "perl.h"
871
872/* This is a different but matching definition from in dl_symbian.xs. */
873typedef struct {
874 void* handle;
875 int error;
876 HV* symbols;
877} PerlSymbianLibHandle;
878
879EXPORT_C void _init(void* handle) {
880__EOF__
881
882 my %symbol;
883 my $def;
884 my $basef;
ed76c0e4 885 for my $f ("$SYMBIAN_ROOT\\Epoc32\\Build$CWD\\$base\\WINS\\perl$VERSION-$extdash.def",
5c271e25 886 "..\\BMARM\\perl$VERSION-${extdash}u.def") {
27da23d5 887 print "\t($f - ";
1ae6ead9 888 if ( open( $def, '<', $f ) ) {
27da23d5
JH
889 print "OK)\n";
890 $basef = $f;
891 last;
892 } else {
893 print "no)\n";
894 }
895 }
896 unless (defined $basef) {
897 die "$0: failed to find .def for $base\n";
898 }
899 while (<$def>) {
900 next while 1 .. /^EXPORTS/;
901 if (/^\s*(\w+) \@ (\d+) /) {
902 $symbol{$1} = $2;
903 }
904 }
905 close($def);
906
907 my @symbol = sort keys %symbol;
908 if (@symbol) {
909 print _INIT_C <<'__EOF__';
910 dTHX;
911 PerlSymbianLibHandle* h = (PerlSymbianLibHandle*)handle;
912 if (!h->symbols)
913 h->symbols = newHV();
914 if (h->symbols) {
915__EOF__
916 for my $sym (@symbol) {
917 my $len = length($sym);
918 print _INIT_C <<__EOF__;
919 hv_store(h->symbols, "$sym", $len, newSViv($symbol{$sym}), 0);
920__EOF__
921 }
922 }
923 else {
924 die "$0: $basef: no exports found\n";
925 }
926
927 print _INIT_C <<'__EOF__';
928 }
929}
930__EOF__
931 close(_INIT_C);
932
933 # Compile #3. This is for real.
934 print "\n*** $ext - Compile 3 of 3.\n\n";
c1c0c258 935 system_echo("make @TARGET") == 0 or die "$0: make #3 failed\n";
27da23d5
JH
936
937 }
938 elsif ( $Clean || $DistClean ) {
939 if ( $ext eq "ext\\Errno" ) {
940 unlink( "Errno.pm", "Makefile" );
941 }
942 else {
943 if ( -f "Makefile" ) {
944 if ($Clean) {
c1c0c258 945 system_echo("make clean") == 0 or die "$0: make clean failed\n";
27da23d5
JH
946 }
947 elsif ($DistClean) {
c1c0c258 948 system_echo("make distclean") == 0
27da23d5
JH
949 or die "$0: make distclean failed\n";
950 }
951 }
53d44271 952 if ( $ext eq "ext\\Compress\\Raw\\Zlib" ) {
1215b447
JH
953 my @bak;
954 find( sub { push @bak, $File::Find::name if /\.bak$/ }, "." );
955 unlink(@bak) if @bak;
956 my @src;
957 find( sub { push @src, $_ if -f $_ }, "zlib-src" );
958 unlink(@src) if @src;
959 unlink("constants.xs");
960 }
27da23d5
JH
961 if ( $ext eq "ext\\Devel\\PPPort" ) {
962 unlink("ppport.h");
963 }
964 }
1215b447
JH
965 my @D = glob("../BMARM/*.def ../BWINS/*.def");
966 unlink(@D) if @D;
27da23d5
JH
967 my @B = glob("ext/BWINS ext/BMARM ext/*/BWINS ext/*/BMARM Makefile");
968 rmdir(@B) if @B;
969 }
970
c1c0c258 971 update_dir($BUILDROOT);
27da23d5
JH
972
973} # for my $ext
974
975exit(0);
976