Commit | Line | Data |
27da23d5 |
1 | #!/usr/bin/perl -w |
2 | |
3 | use strict; |
4 | |
5 | use Getopt::Long; |
6 | use File::Basename; |
7 | use Cwd; |
8 | |
5909b2ae |
9 | unshift @INC, dirname $0 || '.'; |
e81465be |
10 | do "sanity.pl" or die $@; |
27da23d5 |
11 | |
12 | my $CoreBuild = -d "ext" && -f "perl.h" && -d "symbian" && -f "perl.c"; |
13 | |
25ca88e0 |
14 | my $SymbianVersion; |
15 | |
16 | if (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 |
27 | my $PerlVersion = $ENV{XSBUILD_PERL_VERSION}; |
28 | my $CSuffix = '.c'; |
29 | my $CPlusPlus; |
30 | my $Config; |
31 | my $Build; |
32 | my $Clean; |
33 | my $DistClean; |
34 | my $Sis; |
35 | |
36 | sub usage { |
37 | die <<__EOF__; |
38 | $0: Usage: $0 [--symbian=version] [--perl=version] |
d0d72822 |
39 | [--extversion=x.y] |
40 | [--csuffix=csuffix] [--cplusplus|--cpp] |
41 | [--win=win] [--arm=arm] |
27da23d5 |
42 | [--config|--build|--clean|--distclean|--sis] ext |
43 | __EOF__ |
44 | } |
45 | |
46 | my $CWD; |
47 | my $SDK; |
48 | my $VERSION; |
49 | my $R_V_SV; |
50 | my $PERLSDK; |
c8f896e5 |
51 | my $WIN = 'wins'; |
52 | my $ARM = 'thumb'; |
c1c0c258 |
53 | my $BUILDROOT = getcwd(); |
27da23d5 |
54 | |
55 | if ( !defined $PerlVersion && $0 =~ m:\\symbian\\perl\\(.+)\\bin\\xsbuild.pl:i ) |
56 | { |
57 | $PerlVersion = $1; |
58 | } |
59 | |
60 | if ( !defined $SymbianVersion) { |
25ca88e0 |
61 | ($SymbianVersion) = ($ENV{PATH} =~ m!\\Symbian\\(.+?)\\!i); |
27da23d5 |
62 | } |
63 | |
ed76c0e4 |
64 | my ($SYMBIAN_ROOT, $SYMBIAN_VERSION, $SDK_NAME, $SDK_VARIANT, $SDK_VERSION); |
65 | |
27da23d5 |
66 | if ($CoreBuild) { |
e81465be |
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 |
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 |
75 | } |
76 | |
d0d72822 |
77 | my %CONF; |
78 | |
27da23d5 |
79 | usage() |
80 | unless GetOptions( |
d0d72822 |
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 |
93 | ); |
94 | |
95 | usage() unless @ARGV; |
96 | |
97 | $CSuffix = '.cpp' if $CPlusPlus; |
98 | $Build = !( $Config || $Clean || $DistClean ) || $Sis unless defined $Build; |
99 | |
100 | die "$0: Symbian version undefined\n" unless defined $SymbianVersion; |
101 | |
102 | $SymbianVersion =~ s:/:\\:g; |
103 | |
53d44271 |
104 | #die "$0: Symbian version '$SymbianVersion' not found\n" |
105 | # unless -d "\\Symbian\\$SymbianVersion"; |
27da23d5 |
106 | |
107 | die "$0: Perl version undefined\n" unless defined $PerlVersion; |
108 | |
53d44271 |
109 | $PERLSDK = "$SYMBIAN_ROOT\\Perl\\$PerlVersion"; |
110 | |
27da23d5 |
111 | die "$0: Perl version '$PerlVersion' not found\n" |
53d44271 |
112 | if !$CoreBuild && !-d $PERLSDK; |
27da23d5 |
113 | |
114 | print "Configuring with Symbian $SymbianVersion and Perl $PerlVersion...\n"; |
115 | |
27da23d5 |
116 | $R_V_SV = $PerlVersion; |
117 | |
c8f896e5 |
118 | $VERSION = $PerlVersion unless defined $VERSION; |
119 | |
120 | $VERSION =~ tr/.//d if defined $VERSION; |
27da23d5 |
121 | |
ed76c0e4 |
122 | $ENV{SDK} = $SYMBIAN_ROOT; # For the Errno extension |
123 | $ENV{CROSS} = 1; # For the Encode extension (unbuilt now) |
27da23d5 |
124 | |
c8f896e5 |
125 | my $UARM = 'urel'; |
ed76c0e4 |
126 | my $UREL = "$SYMBIAN_ROOT\\epoc32\\release\\-ARM-\\$UARM"; |
c8f896e5 |
127 | my $SRCDBG; |
128 | if (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 |
135 | my %EXTCFG; |
136 | |
137 | sub 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__; |
142 | PRJ_MMPFILES |
143 | $base.mmp |
144 | PRJ_PLATFORMS |
145 | $WIN $ARM |
146 | __EOF__ |
147 | close(BLD_INF); |
148 | } |
149 | |
150 | sub system_echo { |
151 | my $cmd = shift; |
152 | print "xsbuild: ", $cmd, "\n"; |
153 | return system($cmd); |
154 | } |
155 | |
156 | sub 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 |
169 | if ( defined $file ) { -s $file or die "$0: No $file created.\n" } |
170 | } |
171 | |
172 | sub read_old_multi { |
173 | my ( $conf, $k ) = @_; |
174 | push @{ $conf->{$k} }, split( ' ', $1 ) if /^$k\s(.+)$/; |
175 | } |
176 | |
177 | sub 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 | |
189 | sub 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 | |
209 | sub 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; |
25ca88e0 |
221 | $CONF{SYSTEMINCLUDE} = [ $BUILDROOT, "$BUILDROOT\\symbian" ] 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 | |
25ca88e0 |
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 |
260 | if ($SDK_VARIANT eq 'S90') { |
261 | push @{ $CONF{MACRO} }, '__SERIES90__' |
262 | unless grep { $_ eq '__SERIES90__' } @{ $CONF{MACRO} }; |
263 | } |
25ca88e0 |
264 | if ($SDK_VARIANT eq 'UIQ') { |
265 | push @{ $CONF{MACRO} }, '__UIQ__' |
266 | unless grep { $_ eq '__UIQ__' } @{ $CONF{MACRO} }; |
267 | } |
268 | |
27da23d5 |
269 | for my $u (qw(SOURCE SOURCEPATH SYSTEMINCLUDE USERINCLUDE LIBRARY MACRO)) { |
270 | $CONF{$u} = uniquefy_filenames( $CONF{$u} ); |
271 | } |
272 | open( BASE_MMP, ">$base.mmp" ) or die "$0: $base.mmp: $!\n"; |
273 | |
274 | print BASE_MMP <<__EOF__; |
275 | TARGET $CONF{TARGET} |
276 | TARGETTYPE dll |
277 | TARGETPATH $CONF{TARGETPATH} |
278 | SOURCE @{$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__; |
288 | LIBRARY @{$CONF{LIBRARY}} |
289 | MACRO @{$CONF{MACRO}} |
25ca88e0 |
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 |
293 | # if (-f "$base.rss") { |
294 | # print BASE_MMP "RESOURCE\t$base.rss\n"; |
295 | # } |
27da23d5 |
296 | close(BASE_MMP); |
297 | |
298 | } |
299 | |
300 | sub 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 |
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 |
311 | my $ABLD = $wrap ? 'perl b.pl' : 'abld'; |
312 | |
313 | open( MAKEFILE, ">Makefile" ) or die "$0: Makefile: $!\n"; |
314 | print MAKEFILE <<__EOF__; |
315 | WIN = $WIN |
316 | ARM = $ARM |
317 | ABLD = $ABLD |
318 | |
319 | all: build freeze |
320 | |
321 | sis: build_arm freeze_arm |
322 | |
323 | build: abld.bat build_win build_arm |
324 | |
325 | abld.bat: |
326 | bldmake bldfiles |
327 | |
328 | build_win: abld.bat |
329 | bldmake bldfiles |
330 | \$(ABLD) build \$(WIN) udeb |
331 | |
332 | build_arm: abld.bat |
333 | bldmake bldfiles |
334 | \$(ABLD) build \$(ARM) $UARM |
335 | |
336 | win: build_win freeze_win |
337 | |
338 | arm: build_arm freeze_arm |
339 | |
340 | freeze: freeze_win freeze_arm |
341 | |
342 | freeze_win: |
343 | bldmake bldfiles |
344 | \$(ABLD) freeze \$(WIN) $base |
345 | |
346 | freeze_arm: |
347 | bldmake bldfiles |
348 | \$(ABLD) freeze \$(ARM) $base |
349 | |
350 | defrost: defrost_win defrost_arm |
351 | |
352 | defrost_win: |
353 | -del /f $windef1 |
354 | -del /f $windef2 |
355 | |
356 | defrost_arm: |
357 | -del /f $armdef1 |
358 | -del /f $armdef2 |
359 | |
360 | clean: clean_win clean_arm |
361 | |
362 | clean_win: |
363 | \$(ABLD) clean \$(WIN) |
364 | |
365 | clean_arm: |
366 | \$(ABLD) clean \$(ARM) |
367 | |
368 | realclean: clean realclean_win realclean_arm |
369 | -del /f _init.c b.pl |
370 | -del /f $base.c $base.mmp |
371 | |
372 | realclean_win: |
373 | \$(ABLD) reallyclean \$(WIN) |
374 | |
375 | realclean_arm: |
376 | \$(ABLD) reallyclean \$(ARM) |
377 | |
378 | distclean: 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) { |
385 | if(open(B,">b.pl")) { |
386 | print B <<'__EOF__'; |
387 | # abld.pl wrapper. |
388 | |
389 | # nmake doesn't like MFLAGS and MAKEFLAGS being set to -w and w. |
390 | delete $ENV{MFLAGS}; |
391 | delete $ENV{MAKEFLAGS}; |
392 | |
393 | print "abld @ARGV\n"; |
c1c0c258 |
394 | system_echo("abld @ARGV"); |
27da23d5 |
395 | __EOF__ |
396 | close(B); |
397 | } else { |
398 | warn "$0: failed to create b.pl: $!\n"; |
399 | } |
400 | } |
401 | } |
402 | |
403 | sub update_dir { |
404 | print "[chdir from ", getcwd(), " to "; |
405 | chdir(shift) or return; |
406 | update_cwd(); |
407 | print getcwd(), "]\n"; |
408 | } |
409 | |
d1144667 |
410 | sub 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 |
423 | if (open(RSCRIPT, ">$config_restore_script")) { |
424 | print RSCRIPT <<__EOF__; |
425 | #!perl -pi.bak |
426 | s:\\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 | |
438 | sub 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 |
453 | sub 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 |
458 | &patch_config; |
459 | |
27da23d5 |
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 |
481 | my $extdash = $ext; $extdash =~ s!\\!-!g; |
482 | |
27da23d5 |
483 | my %lst; |
5c271e25 |
484 | $lst{"$UREL\\perl$VERSION-$extdash.dll"} = |
27da23d5 |
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 |
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 |
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 |
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 |
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"; |
593 | if ( open( MAKEFILE, "Makefile" ) ) { |
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}; |
620 | if ( open( BASE_C, ">$basec" ) ) { |
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 |
635 | system_echo( |
636 | "perl -I$BUILDROOT\\lib -I$PERLSDK\\lib $extu\\xsubpp -csuffix .cpp -typemap $extu\\typemap -noprototypes $basexs >> $basec" |
27da23d5 |
637 | ) == 0 |
638 | && -s $basec |
639 | ) |
640 | { |
d1144667 |
641 | &restore_config; |
27da23d5 |
642 | die "$0: perl xsubpp failed: $!\n"; |
643 | } |
644 | |
645 | print "\t_init.c\n"; |
d1144667 |
646 | open( _INIT_C, ">_init.c" ) |
647 | or &restore_config and die "$!: _init.c: $!\n"; |
27da23d5 |
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"; |
662 | if ( open( SUBMF, $submf ) ) { |
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 |
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 |
680 | @subsrc ); |
681 | write_makefile( $subbase, $build ); |
682 | write_bld_inf($subbase); |
683 | |
684 | unless ( |
c1c0c258 |
685 | system_echo( |
686 | "perl -I$BUILDROOT\\lib ..\\$extu\\xsubpp -csuffix .cpp -typemap ..\\$extu\\typemap -noprototypes $subbase.xs > $subbase.c" |
27da23d5 |
687 | ) == 0 |
688 | && -s "$subbase.c" |
689 | ) |
690 | { |
d1144667 |
691 | &restore_config; |
27da23d5 |
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 |
708 | write_makefile( $base, $build ); |
709 | } |
d1144667 |
710 | &restore_config; |
711 | |
27da23d5 |
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"; |
27da23d5 |
718 | if ( open( my $lst, ">$lstout" ) ) { |
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 |
726 | } |
727 | |
728 | sub update_cwd { |
729 | $CWD = getcwd(); |
53d44271 |
730 | $CWD =~ s!^[A-Z]:!!i; |
27da23d5 |
731 | $CWD =~ s!/!\\!g; |
732 | } |
733 | |
da933031 |
734 | if (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 |
740 | for my $ext (@ARGV) { |
741 | |
742 | $ext =~ s!::!\\!g; |
d0d72822 |
743 | my $extdash = $ext =~ /ext\\/ ? $ext : "ext\\$ext"; $extdash =~ s!\\!-!g; |
27da23d5 |
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) { |
790 | open( my $cfg, "symbian/install.cfg" ) |
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 |
809 | if ($dir eq ".") { |
810 | warn "$0: No directory for $ext, skipping...\n"; |
811 | next; |
812 | } |
813 | |
27da23d5 |
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 |
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 |
851 | system( |
852 | "perl -pi.bak -e \"s:^SOURCE\\s+_init.c:SOURCE\\t_init.c // :\" $base.mmp" |
853 | ); |
c1c0c258 |
854 | system_echo("bldmake bldfiles"); |
855 | system_echo("make @TARGET") == 0 or die "$0: make #1 failed\n"; |
27da23d5 |
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 |
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 |
865 | unlink("$base.mmp.bak"); |
866 | |
867 | open( _INIT_C, ">_init.c" ) or die "$0: _init.c: $!\n"; |
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. */ |
873 | typedef struct { |
874 | void* handle; |
875 | int error; |
876 | HV* symbols; |
877 | } PerlSymbianLibHandle; |
878 | |
879 | EXPORT_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 - "; |
888 | if ( open( $def, $f ) ) { |
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 |
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 |
946 | } |
947 | elsif ($DistClean) { |
c1c0c258 |
948 | system_echo("make distclean") == 0 |
27da23d5 |
949 | or die "$0: make distclean failed\n"; |
950 | } |
951 | } |
53d44271 |
952 | if ( $ext eq "ext\\Compress\\Raw\\Zlib" ) { |
1215b447 |
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 |
961 | if ( $ext eq "ext\\Devel\\PPPort" ) { |
962 | unlink("ppport.h"); |
963 | } |
964 | } |
1215b447 |
965 | my @D = glob("../BMARM/*.def ../BWINS/*.def"); |
966 | unlink(@D) if @D; |
27da23d5 |
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 |
972 | |
973 | } # for my $ext |
974 | |
975 | exit(0); |
976 | |