First public contribution.
1 # Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
3 # This component and the accompanying materials are made available
4 # under the terms of the License "Eclipse Public License v1.0"
5 # which accompanies this distribution, and is available
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 # Initial Contributors:
9 # Nokia Corporation - initial contribution.
14 # \f32test\loader\dlltree.pl
15 # Generate header and build files for one or more trees
16 # of DLLs and EXEs according to a description file.
22 my $dllbasename='dllt';
24 my $exebasename='exet';
30 my $source0ext='.cpp';
31 my $source1ext='.cia';
32 my $xippath="sys\\bin\\";
33 my $nonxippath="sys\\bin\\";
35 my $hostpath="\\Epoc32\\Release\\##MAIN##\\##BUILD##\\";
38 my $flag_value_fixed=2;
39 my $flag_value_data=4;
41 my $flag_value_dll_in_cycle=16;
42 my $flag_value_data_in_tree=32;
43 my $flag_value_xip_data_in_tree=64;
44 my $flag_value_exports=128;
45 my $flag_value_pagedcode=256;
46 my $flag_value_unpagedcode=512;
47 my $flag_value_idrive=1024;
48 my $flag_value_vdrive=2048;
49 my $flag_value_bytepair=4096;
50 my $flag_value_uncompressed=8192;
51 my $flag_value_targetonly=16384;
52 my $flag_value_pageddata=32768;
53 my $flag_value_unpageddata=65536;
55 my $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst;
56 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
57 my $copy_end=$year+1900;
59 my $argc=scalar(@ARGV);
60 ($argc==1 or $argc==2 or $argc==3) or die "Usage: perl dlltree.pl <filename> <dir> [-allowbad]\n";
62 open IN, $infile or die "Cannot open input file $infile\n";
71 unless (-d $destdir) {
72 mkdir $destdir, 0777 or die "Can't create directory $destdir\n";
74 chdir $destdir or die "Can't chdir to directory $destdir\n";
78 if ($ARGV[2] eq '-allowbad') {
85 if ($destpath=~/^\w\:(.*)/) {
88 unless ($destpath=~/^(.*?)\\$/) {
102 next if (/^\s*$/ or /^\s*\#/);
104 if (/^\!TESTCASES/) {
109 my $modname=shift @moddesc;
110 if (grep {lc($$_{name}) eq lc($modname)} @modules) {
111 die "Duplicate module specification at line $line\n";
114 $module{name}=$modname;
115 $module{num}=$modnum;
117 $module{nclients}=0; # number of modules which import from this one
118 while (scalar(@moddesc)) {
119 my $att=shift @moddesc;
122 } elsif ($att=~/^X$/i) {
124 } elsif ($att=~/^F$/i) {
126 } elsif ($att=~/^D$/i) {
128 } elsif ($att=~/^P$/i) {
129 $module{pagedcode}=1;
130 } elsif ($att=~/^PD$/i) {
131 $module{pageddata}=1;
132 } elsif ($att=~/^B$/i) {
134 } elsif ($att=~/^U$/i) {
135 $module{uncompressed}=1;
136 } elsif ($att=~/^I$/i) {
138 } elsif ($att=~/^V$/i) {
140 } elsif ($att=~/^N$/i) {
141 $module{unpagedcode}=1;
142 } elsif ($att=~/^T$/i) {
143 $module{targetonly}=1;
144 } elsif ($att=~/^R(.*?)$/i) {
147 if ($attp=~/^\,(.*?)$/) {
148 $module{attpname}=$1;
149 } elsif (!($attp=~/^\s*$/)) {
150 die "Garbage following R attribute at line $line\n";
154 if ($module{fixed} && !$module{exe}) {
155 die "Can't have FIXED without EXE at line $line\n";
157 if ($module{pagedcode} && $module{xip}) {
158 die "Can't have PAGEDCODE with XIP at line $line\n";
161 # makmake won't support paged binaries which aren't bytepair or uncompressed.
162 # However, P can be specified without them in dlltree.txt. This program generates
163 # an MMP file with neither flag. The flag is added when the files are copied to
164 # internal media by T_LDRTST. (It would be pointless to copy the files to removable
165 # media and then edit them because removable media doesn't support paging.)
167 my $bothCodePageFlags = $module{pagedcode} && $module{unpagedcode};
168 if ($bothCodePageFlags && !$module{idrive}) {
169 die "Can't have PAGEDCODE and UNPAGEDCODE without INTERNAL DRIVE at line $line\n";
171 if ($module{unpagedcode} && $module{xip}) {
172 die "Can't have UNPAGEDCODE with XIP at line $line\n";
174 if ($module{pageddata} && !$module{exe}) {
175 die "Can't have PAGEDDATA without EXE at line $line\n";
177 if ($module{idrive} && $module{xip}) {
178 die "Can't have INTERNAL DRIVE with XIP at line $line\n";
180 if ($module{vdrive} && $module{xip}) {
181 die "Can't have REMOVABLE DRIVE with XIP at line $line\n";
183 if ($module{idrive} && $module{vdrive}) {
184 die "Can't have INTERNAL DRIVE with REMOVABLE DRIVE at line $line\n";
186 if ($module{bytepair} && $module{uncompressed}) {
187 die "Can't have BYTEPAIR with UNCOMPRESSED at line $line\n";
190 if ($module{attpname}) {
191 warn "Attach process with EXE ignored at line $line\n";
192 delete $module{attpname};
194 $module{basefilename}=$exebasename.$modnum;
195 $module{filename}=$module{basefilename}.$exeext;
196 $module{source0}=$exebasename.$source0ext;
198 $module{trgtype}='exexp';
199 $module{lib}=$module{basefilename}.$libext;
201 $module{basefilename}=$dllbasename.$modnum;
202 $module{filename}=$module{basefilename}.$dllext;
203 $module{source0}=$dllbasename.$source0ext;
204 $module{source1}=$dllbasename.$source1ext;
205 $module{trgtype}='dll';
206 $module{lib}=$module{basefilename}.$libext;
208 $module{depnames}=\@moddesc; # dependency names are left over
211 push @modules, \%module;
213 } elsif ($state<=2) {
216 die "Syntax error at line $line\n" unless (/^(\w+)\:/);
227 my @modlist=split(/\s+/, $concat);
228 my $tcname=shift @modlist;
229 $tcname=~/^(.*?)\:$/ or die "???\n";
233 $tc{mod_names}=\@modlist;
234 push @testcases, \%tc;
237 foreach $modref (@modules) {
238 my $moddepref=$$modref{depnames};
240 foreach (@$moddepref) {
242 my @match=grep {lc($$_{name}) eq $depname} @modules;
243 if (scalar(@match)==0) {
244 die "Unknown dependent module $depname at line $$modref{line}\n";
246 my $depref=$match[0];
247 if ($$modref{xip} and !$$depref{xip}) {
248 die "Illegal dependency: $$modref{name} (XIP) on $$depref{name} (non-XIP)\n";
250 push @deps, $$depref{num};
251 ++$$depref{nclients};
253 $$modref{deps}=\@deps;
254 my $attpname=$$modref{attpname};
256 my @match=grep {lc($$_{name}) eq lc($attpname)} @modules;
257 if (scalar(@match)==0) {
258 die "Unknown attach process $attpname at line $$modref{line}\n";
260 my $attpref=$match[0];
261 if (!$$attpref{exe}) {
262 die "Specified attach process is not EXE at line $$modref{line}\n";
263 } elsif (!$$attpref{xip}) {
264 die "Specified attach process is not XIP at line $$modref{line}\n";
266 $$modref{attp}=$attpref;
269 foreach $tcref (@testcases) {
270 my $modlistref=$$tcref{mod_names};
272 foreach $modname (@$modlistref) {
273 next if ($modname=~/^\s*$/);
274 my @match=grep {lc($$_{name}) eq lc($modname)} @modules;
275 if (scalar(@match)==0) {
276 die "Unknown module $modname in test case $$tcref{name}\n";
278 push @modnums, $match[0]->{num};
280 $$tcref{modules}=\@modnums;
281 $$tcref{count}=scalar(@modnums);
284 foreach $modref (@modules) {
285 if ($$modref{nclients}==0 and $$modref{exe}) {
286 # EXE with no exports
288 $$modref{trgtype}='exe';
291 my $modnum=$$modref{num};
293 calc_tc(\@tcdeps, \@modules, $modref, $next_mark);
294 $$modref{tcdeps}=\@tcdeps;
295 if (grep {$_==$modnum} @tcdeps) {
298 my @exes=grep {$modules[$_]->{exe}} @tcdeps;
299 my $nexes=scalar(@exes);
303 die "Module $$modref{name} links to more than one EXE\n";
304 } elsif ($nexes==1) {
305 my $exeref=$modules[$exes[0]];
306 $$modref{linkexe}=$exeref;
308 if ($$exeref{num}!=$modnum) {
309 die "EXE $modref{name} links to another EXE\n";
312 if ($$modref{attp} and $$exeref{num}!=$modref->{attp}->{num}) {
313 die "DLL $$modref{name} ($modnum) incompatible attach process\n";
315 if (!$$modref{attp}) {
316 $$modref{attp}=$exeref;
322 foreach $depnum (@tcdeps) {
323 my $depref=$modules[$depnum];
324 my $depattpref=$depref->{attp};
325 if ($depattpref and $depattpref->{num}!=$modnum) {
326 die "DEP DLL $$depref{name} ($$depref{num}) incompatible attach process\n";
328 # if (!$depattpref) {
329 # $$depref{attp}=$modref;
334 foreach $modref (@modules) {
336 my $tcdepref=$$modref{tcdeps};
337 push @total_deps, @$tcdepref;
338 my $linkexe=$$modref{linkexe};
340 my $exetcdepref=$$linkexe{tcdeps};
341 push @total_deps, @$exetcdepref;
343 push @total_deps, $$modref{num};
344 my $data=scalar(grep {$modules[$_]->{data}} @total_deps);
346 $$modref{dataintree}=1;
348 my $xipdata=scalar(grep {$modules[$_]->{data} and $modules[$_]->{xip}} @total_deps);
350 $$modref{xipdataintree}=1;
354 #foreach $modref (@modules) {
355 # print "Module $$modref{num}:\n";
356 # print "\tName: $$modref{name}\n";
357 # print "\tFilename: $$modref{filename}\n";
358 # my $depref=$$modref{deps};
359 # my $ndeps=scalar(@$depref);
360 # print "\t#Deps: $ndeps\n";
361 # print "\tDeps: ",join(',',@$depref),"\n";
365 my $bldname='dlltree.inf';
366 push @bldinf, "// $destpath$bldname\n";
367 push @bldinf, "//\n";
368 push @bldinf, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n";
369 push @bldinf, "//\n";
371 push @bldinf, "PRJ_PLATFORMS\n";
372 push @bldinf, "BASEUSERDEFAULT\n";
374 push @bldinf, "PRJ_TESTMMPFILES\n";
378 my $dlltreename='dlltree.h';
379 push @dlltree, "// $destpath$dlltreename\n";
380 push @dlltree, "//\n";
381 push @dlltree, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n";
382 push @dlltree, "//\n";
384 push @dlltree, "#ifndef __DLLTREE_H__\n";
385 push @dlltree, "#define __DLLTREE_H__\n";
386 push @dlltree, "#include <e32std.h>\n";
388 push @dlltree, "class MDllList;\n";
391 my $ibyname='ldrtest.iby';
394 foreach $modref (@modules) {
396 my $num=$$modref{num};
397 my $mmpname=$$modref{basefilename}.$mmpext;
398 my $defname=$$modref{basefilename}.$defext;
399 my $depsref=$$modref{deps};
400 my $ndeps=scalar(@$depsref);
401 push @mmp, "// $destpath$mmpname\n";
403 push @mmp, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n";
405 push @mmp, "// Generated from $$modref{name}\n";
407 push @mmp, "macro __DLLNUM$num\n";
408 push @mmp, "target $$modref{filename}\n";
409 push @mmp, "targettype $$modref{trgtype}\n";
410 push @mmp, "sourcepath .\n";
411 push @mmp, "source $$modref{source0} $$modref{source1}\n";
412 push @mmp, "library euser.lib efsrv.lib\n";
413 push @mmp, "Capability NONE\n";
414 foreach (@$depsref) {
415 my $depref=$modules[$_];
416 push @mmp, "library $$depref{lib}\n";
418 if ($$modref{exports}) {
419 push @mmp, "deffile ./$defname\n";
420 push @mmp, "nostrictdef\n";
422 push @mmp, "OS_LAYER_SYSTEMINCLUDE_SYMBIAN \n";
423 push @mmp, "systeminclude ../../../e32test/mmu \n";
424 push @mmp, "userinclude . \n";
425 if ($$modref{fixed}) {
426 push @mmp, "epocfixedprocess\n";
429 # if both paged flags are set or the compression is not pageable then print neither.
430 # T_LDRTST will add the required flags when it copies the file to internal media.
432 my $bothCodePageFlags = $$modref{pagedcode} && $$modref{unpagedcode};
433 my $pageableCompression = $$modref{bytepair} || $$modref{uncompressed};
434 if (!$bothCodePageFlags && $pageableCompression) {
435 push @mmp, "pagedcode\n" if $$modref{pagedcode};
436 push @mmp, "unpagedcode\n" if $$modref{unpagedcode};
440 # make exes unpageddata by default
441 if (!$$modref{pageddata}) {
442 $$modref{unpageddata}=1;
444 if ($$modref{pageddata}) {
445 push @mmp, "pageddata\n";
447 if ($$modref{unpageddata}) {
448 push @mmp, "unpageddata\n";
452 if ($$modref{bytepair}) {
453 push @mmp, "bytepaircompresstarget\n";
456 if ($$modref{uncompressed}) {
457 push @mmp, "nocompresstarget\n";
460 if ($$modref{data} && !$$modref{exe}) {
461 push @mmp, "epocallowdlldata\n";
463 push @mmp, sprintf("uid 0x00000000 0x%08x\n", $num+256);
464 push @mmp, "SMPSAFE\n";
467 if ($$modref{exports}) {
469 push @def, "EXPORTS\n";
471 push @def, "\tRegisterConstructorCall @ 1 NONAME\n";
472 push @def, "\tRegisterInitCall @ 2 NONAME\n";
473 push @def, "\tRegisterDestructorCall @ 3 NONAME\n";
475 push @def, "\tInit$num @ 1 NONAME\n";
476 push @def, "\tChkC$num @ 2 NONAME\n";
477 push @def, "\tBlkI$num @ 3 NONAME\n";
478 push @def, "\tGetGeneration @ 4 NONAME\n";
479 push @def, "\tRBlkI$num @ 5 NONAME\n";
480 push @def, "\tSetCloseLib @ 6 NONAME\n";
485 push @bldinf, "$$modref{basefilename}\t\tsupport\n";
488 push @dlltree, "#if defined(__DLLNUM$num)\n";
490 push @dlltree, "#elif defined(__DLLNUM$num)\n";
492 push @dlltree, "#define DLLNUM $num\n";
494 push @dlltree, "#define EXENUM $num\n";
495 push @dlltree, "_LIT(KServerName, \"$$modref{name}\");\n";
497 push @dlltree, "#define INITFUNC Init$num\n";
498 push @dlltree, "#define CHKCFUNC ChkC$num\n";
499 push @dlltree, "#define BLKIFUNC BlkI$num\n";
500 push @dlltree, "#define RBLKIFUNC RBlkI$num\n";
501 push @dlltree, "#define CHKDEPS(r) (\\\n";
502 foreach (@$depsref) {
503 my $depref=$modules[$_];
504 unless ($$depref{exe}) {
506 push @dlltree, "\t((r)=$func())!=0 ||\\\n";
509 push @dlltree, "\t((r)=0)!=0 )\n";
510 push @dlltree, "#define INITDEPS(r,l) (\\\n";
511 foreach (@$depsref) {
512 my $depref=$modules[$_];
513 unless ($$depref{exe}) {
515 push @dlltree, "\t((r)=$func(l))!=0 ||\\\n";
518 push @dlltree, "\t((r)=0)!=0 )\n";
520 push @dlltree, "#define RBLKIFUNC_DEPS(i,g) {\\\n";
521 foreach (@$depsref) {
522 my $depref=$modules[$_];
527 push @dlltree, "\t(i)=$func(i,g);\\\n";
530 push @dlltree, "\t}\n";
532 push @dlltree, "#define __DLL_LINK_TO_EXE\n";
534 if ($$modref{cycle}) {
535 push @dlltree, "#define __DLL_IN_CYCLE\n";
537 if ($$modref{data}) {
538 push @dlltree, "#define __MODULE_HAS_DATA\n";
540 if ($$modref{exports}) {
541 push @dlltree, "#define __MODULE_EXPORT\t\tEXPORT_C\n";
542 push @dlltree, "#define __MODULE_IMPORT\t\tIMPORT_C\n";
544 push @dlltree, "#define __MODULE_EXPORT\n";
545 push @dlltree, "#define __MODULE_IMPORT\n";
547 foreach (@$depsref) {
548 my $depref=$modules[$_];
551 push @dlltree, "extern \"C\" IMPORT_C TInt Init$_(MDllList&);\n";
552 push @dlltree, "extern \"C\" IMPORT_C TInt ChkC$_();\n";
553 push @dlltree, "extern \"C\" IMPORT_C TInt RBlkI$_(TInt, TInt);\n";
556 my $hostfullpathname=$hostpath.$$modref{filename};
558 my $epocfullpathname=$xippath.$$modref{filename};
560 if ($$modref{attp}) {
561 $flags='process '.$modref->{attp}->{filename};
563 push @iby, "file=$hostfullpathname\t\t$epocfullpathname\t\t$flags\n";
565 my $epocfullpathname=$nonxippath.$$modref{filename};
566 push @iby, "data=$hostfullpathname\t\t$epocfullpathname\n";
570 #push @dlltree, "#else\n";
571 #push @dlltree, "#error No __DLLNUM macro defined\n";
572 push @dlltree, "#endif\n";
575 my $module_count=scalar(@modules);
576 push @dlltree, "const TInt KNumModules=$module_count;\n";
578 push @dlltree, "#ifdef __INCLUDE_DEPENDENCY_GRAPH\n";
579 push @dlltree, "static const TText* const ModuleName[KNumModules] =\n";
580 push @dlltree, "\t\{\n";
581 foreach $modref (@modules) {
582 my $string="\t(const TText*)L\"$$modref{name}\"";
583 unless ($$modref{num}==$module_count-1) {
586 push @dlltree, $string;
587 my $pad=41-length($string);
589 push @dlltree, "\t"x$pad, "\/*", $$modref{num}, "*\/\n";
591 push @dlltree, "\t\};\n";
593 push @dlltree, "#define MODULE_NAME(n) TPtrC(ModuleName[n])\n";
595 push @dlltree, "static const TText* const ModuleFileName[KNumModules] =\n";
596 push @dlltree, "\t\{\n";
597 foreach $modref (@modules) {
598 if ($$modref{idrive} || $$modref{vdrive}) {
599 my $fn = $$modref{filename};
600 my $used_nxip_path = "?:\\$nonxippath$fn";
601 $used_nxip_path =~ s/\\/\\\\/g; # double backslashes
602 substr($used_nxip_path,0,1) = $$modref{idrive} ? "0" : "1";
603 push @dlltree, "\t(const TText*)L\"$used_nxip_path\"";
605 push @dlltree, "\t(const TText*)L\"$$modref{filename}\"";
607 if ($$modref{num}==$module_count-1) {
610 push @dlltree, ",\n";
613 push @dlltree, "\t\};\n";
615 push @dlltree, "#define MODULE_FILENAME(n) TPtrC(ModuleFileName[n])\n";
617 foreach $modref (@modules) {
618 my $modnum=$$modref{num};
619 my $tcdepsref=$$modref{tcdeps};
620 my $numdeps=scalar(@$tcdepsref);
621 push @dlltree, "static const TInt Module$modnum","Deps[] =\n";
622 push @dlltree, "\t\{$numdeps";
624 push @dlltree, ",", join(',',@$tcdepsref)
626 push @dlltree, "\};\n";
628 push @dlltree, "static const TInt* const ModuleDependencies[KNumModules] =\n";
629 push @dlltree, "\t\{\n";
630 foreach $modref (@modules) {
631 my $modnum=$$modref{num};
632 push @dlltree, "\tModule$modnum","Deps";
633 if ($$modref{num}==$module_count-1) {
636 push @dlltree, ",\n";
639 push @dlltree, "\t\};\n";
641 push @dlltree, sprintf "const TInt KModuleFlagExe=0x%04x;\n", $flag_value_exe;
642 push @dlltree, sprintf "const TInt KModuleFlagFixed=0x%04x;\n", $flag_value_fixed;
643 push @dlltree, sprintf "const TInt KModuleFlagData=0x%04x;\n", $flag_value_data;
644 #push @dlltree, "#ifdef __EPOC32__\n";
645 push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", $flag_value_xip;
646 push @dlltree, sprintf "const TInt KModuleFlagPagedCode=0x%04x;\n", $flag_value_pagedcode;
647 push @dlltree, sprintf "const TInt KModuleFlagUnpagedCode=0x%04x;\n", $flag_value_unpagedcode;
648 push @dlltree, sprintf "const TInt KModuleFlagIDrive=0x%04x;\n", $flag_value_idrive;
649 push @dlltree, sprintf "const TInt KModuleFlagVDrive=0x%04x;\n", $flag_value_vdrive;
650 push @dlltree, sprintf "const TInt KModuleFlagBytePair=0x%04x;\n", $flag_value_bytepair;
651 push @dlltree, sprintf "const TInt KModuleFlagUncompressed=0x%04x;\n", $flag_value_uncompressed;
652 #push @dlltree, "#else\n";
653 #push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", 0; # no XIPs on emulator
654 #push @dlltree, "#endif\n";
655 push @dlltree, sprintf "const TInt KModuleFlagDllInCycle=0x%04x;\n", $flag_value_dll_in_cycle;
656 push @dlltree, sprintf "const TInt KModuleFlagDataInTree=0x%04x;\n", $flag_value_data_in_tree;
657 #push @dlltree, "#ifdef __EPOC32__\n";
658 push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", $flag_value_xip_data_in_tree;
659 #push @dlltree, "#else\n";
660 #push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", 0;
661 #push @dlltree, "#endif\n";
662 push @dlltree, sprintf "const TInt KModuleFlagExports=0x%04x;\n", $flag_value_exports;
663 push @dlltree, sprintf "const TInt KModuleFlagTargetOnly=0x%04x;\n", $flag_value_targetonly;
664 push @dlltree, sprintf "const TInt KModuleFlagPagedData=0x%04x;\n", $flag_value_pageddata;
665 push @dlltree, sprintf "const TInt KModuleFlagUnpagedData=0x%04x;\n", $flag_value_unpageddata;
666 push @dlltree, "static const TInt ModuleFlags[KNumModules] =\n";
667 push @dlltree, "\t\{\n";
668 foreach $modref (@modules) {
672 push @flagNames, "KModuleFlagExe" if ($$modref{exe});
673 push @flagNames, "KModuleFlagFixed" if ($$modref{fixed});
674 push @flagNames, "KModuleFlagData" if ($$modref{data});
675 push @flagNames, "KModuleFlagXIP" if ($$modref{xip});
676 push @flagNames, "KModuleFlagPagedCode" if ($$modref{pagedcode});
677 push @flagNames, "KModuleFlagUnpagedCode" if ($$modref{unpagedcode});
678 push @flagNames, "KModuleFlagPagedData" if ($$modref{pageddata});
679 push @flagNames, "KModuleFlagUnpagedData" if (!$$modref{pageddata});
680 push @flagNames, "KModuleFlagIDrive" if ($$modref{idrive});
681 push @flagNames, "KModuleFlagVDrive" if ($$modref{vdrive});
682 push @flagNames, "KModuleFlagBytePair" if ($$modref{bytepair});
683 push @flagNames, "KModuleFlagDllInCycle" if ($$modref{cycle});
684 push @flagNames, "KModuleFlagDataInTree" if ($$modref{dataintree});
685 push @flagNames, "KModuleFlagXIPDataInTree" if ($$modref{xipdataintree});
686 push @flagNames, "KModuleFlagExports" if ($$modref{exports});
687 push @flagNames, "KModuleFlagUncompressed" if ($$modref{uncompressed});
688 push @flagNames, "KModuleFlagTargetOnly" if ($$modref{targetonly});
690 @flagNames = qw(0) if (scalar(@flagNames) == 0);
691 my $flagString = "/\* " . $$modref{num} . " \*/\t" . join(' | ', @flagNames);
692 unless ($$modref{num}==$module_count-1) {
695 push @dlltree, $flagString . "\n";
697 push @dlltree, "\t\};\n";
699 foreach $modref (@modules) {
700 my $modnum=$$modref{num};
703 calc_rblki(\@rblki, \@modules, $modref, $next_mark);
704 my $rblki_count=scalar(@rblki);
709 push @dlltree, "static const TInt Module$modnum","RBlkIParams[2] = \{ $rblki_count, $rblki_sum \};\n";
712 push @dlltree, "static const TInt* const ModuleRBlkIParams[KNumModules] =\n";
713 push @dlltree, "\t\{\n";
714 foreach $modref (@modules) {
715 my $modnum=$$modref{num};
716 push @dlltree, "\tModule$modnum","RBlkIParams";
717 if ($$modref{num}==$module_count-1) {
720 push @dlltree, ",\n";
723 push @dlltree, "\t\};\n";
725 foreach $modref (@modules) {
726 my $modnum=$$modref{num};
727 my $mod_attp=$modnum;
728 my $mod_linkp=$modnum;
729 unless ($$modref{exe}) {
730 $mod_attp = ($$modref{attp}) ? ($modref->{attp}->{num}) : -1;
731 $mod_linkp = ($$modref{linkexe}) ? ($modref->{linkexe}->{num}) : -1;
733 push @dlltree, "static const TInt Module$modnum","ExeInfo[2] = \{ $mod_attp, $mod_linkp \};\n";
736 push @dlltree, "static const TInt* const ModuleExeInfo[KNumModules] =\n";
737 push @dlltree, "\t\{\n";
738 foreach $modref (@modules) {
739 my $modnum=$$modref{num};
740 push @dlltree, "\tModule$modnum","ExeInfo";
741 if ($$modref{num}==$module_count-1) {
744 push @dlltree, ",\n";
747 push @dlltree, "\t\};\n";
749 foreach $tcref (@testcases) {
751 my $modlistref=$$tcref{modules};
752 my $count=$$tcref{count};
753 my $arraysize=$count+1;
754 push @dlltree, "static const TInt TC_$$tcref{name}\[$arraysize\]=\n\t\{\n";
756 push @dlltree, "\t$count\n";
758 push @dlltree, "\t$count\,\n";
760 foreach (@$modlistref) {
763 push @dlltree, "\t$_\n";
765 push @dlltree, "\t$_\,\n";
768 push @dlltree, "\t\};\n";
771 push @dlltree, "#endif\n";
773 push @dlltree, "#endif\n";
775 foreach $modref (@modules) {
776 my $mmpname=$$modref{basefilename}.$mmpext;
777 my $mmpref=$$modref{mmp};
778 open OUT, ">$mmpname" or die "Could not open $mmpname for output\n";
781 if ($$modref{exports}) {
782 my $defname=$$modref{basefilename}.$defext;
783 my $defref=$$modref{def};
784 open OUT, ">$defname" or die "Could not open $defname for output\n";
790 push @bldinf, "t_ldrtst\n";
792 open OUT, ">$bldname" or die "Could not open $bldname for output\n";
795 open OUT, ">$dlltreename" or die "Could not open $dlltreename for output\n";
798 my $testbatch = "$ENV{EPOCROOT}epoc32\\build";
799 $destpath =~ s/\//\\/go;
800 $testbatch.="\\" unless ($destpath =~ /^\\/);
801 $testbatch.=$destpath;
802 $testbatch.="##MAIN##.auto.bat";
804 push @iby, "data=$testbatch\t\ttest\\loader.auto.bat\n";
806 open OUT, ">$ibyname" or die "Could not open $ibyname for output\n";
811 # Accumulate list of dependency numbers
812 # 1st arg = \output list
813 # 2nd arg = \module list
814 # 3rd arg = \module to start from
815 # 4th arg = mark value to use
818 my ($out, $mods, $modref, $mark)=@_;
819 my $depsref=$$modref{deps};
820 foreach $dep (@$depsref) {
821 my $depref=$$mods[$dep];
822 if ($$depref{mark} != $mark) {
823 $$depref{mark}=$mark;
824 unless ($$depref{exe}) {
825 calc_tc($out, $mods, $depref, $mark);
833 # Accumulate RBlkI parameters
834 # 1st arg = \output list
835 # 2nd arg = \module list
836 # 3rd arg = \module to start from
837 # 4th arg = mark value to use
839 sub calc_rblki($$$$) {
840 my ($out, $mods, $modref, $mark)=@_;
841 if ($$modref{mark} != $mark) {
842 $$modref{mark}=$mark;
843 if (!$$modref{exe} and $$modref{data}) {
844 push @$out, $$modref{num};
845 my $depsref=$$modref{deps};
846 foreach $dep (@$depsref) {
847 calc_rblki($out, $mods, $$mods[$dep], $mark);