--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv1/abld/bldmake/bldmake.pl Fri Jun 25 17:29:25 2010 +0800
@@ -0,0 +1,2325 @@
+# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# all variables called *Path* are set up to end with a backslash
+# all variables called *Path or *File are stored as absolute (file)paths within makmake
+# all variables called UpPath* are stored as relative paths within makmake
+#
+#
+
+
+use FindBin; # for FindBin::Bin
+use Getopt::Long;
+
+my $PerlLibPath; # fully qualified pathname of the directory containing our Perl modules
+
+BEGIN {
+# check user has a version of perl that will cope
+ require 5.005_03;
+# establish the path to the Perl libraries: currently the same directory as this script
+ $PerlLibPath = $FindBin::Bin; # X:/epoc32/tools
+ $PerlLibPath =~ s/\//\\/g; # X:\epoc32\tools
+ $PerlLibPath .= "\\";
+}
+sub ExportDirs ($);
+
+use lib $PerlLibPath;
+use E32env;
+use E32Plat;
+use Modload;
+use Output;
+use Pathutl;
+use E32Variant;
+use RVCT_plat2set;
+use BPABIutl;
+use wrappermakefile;
+use CheckSource;
+use File::Path; # for rmtree
+use featurevariantparser;
+
+my $BldInfName = 'BLD.INF';
+my %Options;
+my %KeepGoing;
+my @DefaultPlats=('WINSCW', 'GCCXML', 'EDG', 'X86GCC');
+my @BaseUserDefaultPlats=('ARM4', 'ARM4T', 'WINSCW', 'GCCXML', 'EDG', 'X86GCC');
+my @OptionalPlats=('VS6', 'VS2003');
+my @PlatsReq;
+
+my %CheckSourceEXPORTSMetaData;
+my %CheckSourceEXPORTSIncludes;
+my %CheckSourceMMPFILESMetaData;
+my %CheckSourceEXTENSIONSMetaData;
+my %CheckSourceBldInfIncludes;
+
+for ('ARMV4', 'ARMV5')
+{
+ push @BaseUserDefaultPlats, $_ if RVCT_plat2set::compiler_exists($_);
+}
+
+# Add ARMV5_ABIV1 platform if ENABLE_ABIV2_MODE is set in variant.cfg
+my $variantABIV2Keyword = &Variant_GetMacro();
+# Add ARMV5_ABIV1 platform only after determining the presence of RVCT compiler.
+if ($variantABIV2Keyword && RVCT_plat2set::compiler_exists('ARMV5_ABIV1') ) {
+ push @OptionalPlats, 'ARMV5_ABIV1';
+}
+
+# bldmake -k shouldn't die if Extension Makefile is missing
+our $IgnoreMissingExtensionMakefile = 0;
+
+# Add the BPABI Platforms to be added
+my @BPABIPlats = &BPABIutl_Plat_List;
+foreach my $BPABIPlat (@BPABIPlats)
+{
+ # BPABI platform related with ARMV5(eg.ARMV5_ABIV2) is added to the platform list after
+ # determining the presence of RVCT compiler
+ if(($BPABIPlat =~/^ARMV5/i))
+ {
+ if(!($BPABIPlat =~/^ARMV5$/i) && RVCT_plat2set::compiler_exists('ARMV5'))
+ {
+ push @OptionalPlats, $BPABIPlat;
+ }
+ }
+ # All other BPABI platforms(eg. gcce) are added to the platform list.
+ else
+ {
+ push @OptionalPlats, $BPABIPlat;
+ }
+}
+
+if ( RVCT_plat2set::compiler_exists('ARMV5') ) {
+ #determine the presence of ARVCT compiler
+ push @DefaultPlats, 'ARMV5';
+}
+
+# Need to add WINS and X86 if MSDEV compiler is present
+# Use MSDevDir to determine the presence of the compiler
+push @BaseUserDefaultPlats, 'WINS', 'X86' if (exists($ENV{'MSDevDir'}));
+
+my @BaseDefaultPlats = @BaseUserDefaultPlats;
+push @BaseDefaultPlats, 'X86SMP' if (grep /^X86$/, @BaseUserDefaultPlats);
+push @BaseDefaultPlats, 'ARM4SMP' if (grep /^ARM4$/, @BaseUserDefaultPlats);
+push @BaseDefaultPlats, 'ARMV4SMP' if (grep /^ARMV4$/, @BaseUserDefaultPlats);
+push @BaseDefaultPlats, 'ARMV5SMP' if (grep /^ARMV5$/, @BaseUserDefaultPlats);
+push @BaseDefaultPlats, 'X86GMP' if (grep /^X86GCC$/, @BaseUserDefaultPlats);
+
+my $variantMacroHRHFile = Variant_GetMacroHRHFile();
+sub ExportDirs ($);
+
+# THE MAIN PROGRAM SECTION
+##########################
+
+# Load default feature variant info - for the hrh file
+my %DefaultFeatureVariant = featurevariantparser->GetVariant('DEFAULT') if (featurevariantparser->DefaultExists());
+my @FeatureVariants = featurevariantparser->GetBuildableFeatureVariants();
+
+{
+ Load_SetModulePath($PerlLibPath);
+ Plat_Init($PerlLibPath);
+
+ {
+ my @PlatList = &Plat_List();
+
+ if (RVCT_plat2set::compiler_exists('ARMV6')){
+ foreach my $ARMV6Target ("ARMV6", "ARMV6_ABIV1", "ARMV6_ABIV2"){
+ if (grep /^$ARMV6Target$/, @PlatList) {
+ push @BaseUserDefaultPlats, "$ARMV6Target" if (!grep /^$ARMV6Target$/, @BaseUserDefaultPlats);
+ push @BaseDefaultPlats, "$ARMV6Target" if (!grep /^$ARMV6Target$/, @BaseDefaultPlats);
+ }
+ }
+ }
+
+ if (RVCT_plat2set::compiler_exists('ARMV7')){
+ my $rvct_ver = RVCT_plat2set::get_version_string('ARMV7');
+ if ((defined $rvct_ver) and ($rvct_ver ge "3.1.674")) {
+ if (grep /^ARMV7$/, @PlatList ) {
+ push @DefaultPlats, 'ARMV7' if (!grep /^ARMV7$/, @DefaultPlats);
+ push @BaseUserDefaultPlats, "ARMV7" if (!grep /^ARMV7$/, @BaseUserDefaultPlats);
+ push @BaseDefaultPlats, "ARMV7" if (!grep /^ARMV7$/, @BaseDefaultPlats);
+ }
+ }
+ }
+ }
+
+# process the commmand-line
+ unless (GetOptions(\%Options, 'v', "k|keepgoing", "notest", "file|f=s")) {
+ exit 1;
+ }
+ unless (@ARGV>=1) {
+ &Usage();
+ }
+ my $Command=uc shift @ARGV;
+ unless ($Command=~/^(BLDFILES|CLEAN|INF|PLAT)$/o) {
+ &Usage();
+ }
+ my $CLPlat=uc shift @ARGV;
+
+ unless ($CLPlat) {
+ $CLPlat='ALL';
+ }
+
+ if ($Command eq 'INF') {
+ &ShowBldInfSyntax();
+ exit;
+ }
+
+ if ($Command eq 'PLAT') {
+ my @PlatList = ($CLPlat);
+ my $PlatName;
+ # Variable introduced to check if the bldmake plat command is called, To be
+ # passed as an argument in Plat_GetL function call.
+ my $platcommand=1;
+ if ($CLPlat eq "ALL") {
+ @PlatList = &Plat_List();
+ print(
+ "Supported Platforms:\n",
+ " @PlatList\n\n"
+ );
+ }
+ print(
+ "Macros defined for BLD.INF preprocessing of MMPFILE sections:\n"
+ );
+ foreach $PlatName (@PlatList) {
+ my %Plat;
+ eval { &Plat_GetL($PlatName, \%Plat,{},$platcommand); };
+ die $@ if $@;
+ print(
+ "\nPlatform $PlatName:\n",
+ " @{$Plat{MmpMacros}}\n"
+ );
+ }
+ exit;
+ }
+ if ($Options{file}) {
+ $BldInfName = $Options{file};
+ }
+
+# check that the BLD.INF file exists
+# maybe BLDMAKE should allow a path to be specified leading to the BLD.INF file
+ my $BldInfPath=&Path_WorkPath;
+ unless (-e "${BldInfPath}$BldInfName") {
+ &FatalError("Can't find \"${BldInfPath}$BldInfName\"");
+ }
+
+ if (!-d $E32env::Data{EPOCPath}){
+ &FatalError("Directory \"$E32env::Data{EPOCPath}\" does not exist");
+ }
+
+# decide the output directory
+ my $OutDir=&Path_Chop($E32env::Data{BldPath}).$BldInfPath;
+
+# Work out the path for the IBY files
+ my $RomDir=&Path_Chop($E32env::Data{RomPath}).$BldInfPath;
+
+# Work out the name for the BLD.INF module
+ my @Dirs=&Path_Dirs($BldInfPath);
+ my $Module = pop @Dirs;
+ if (lc($Module) eq 'group') {
+ $Module = pop @Dirs;
+ }
+
+ if ($Command eq 'CLEAN') {
+ unlink "${BldInfPath}ABLD.BAT";
+ $OutDir=~m-(.*)\\-o;
+ if (-d $1) { # remove backslash for test because some old versions of perl can't cope
+ opendir DIR, $1;
+ my @Files=grep s/^([^\.].*)$/$OutDir$1/, readdir DIR;
+ closedir DIR;
+ unlink @Files;
+ }
+ rmtree <$OutDir\\wrappermakefiles>;
+# modified start: makefile improvement
+ rmtree <$OutDir\\FeatureVariantInfo>;
+# modified end: makefile improvement
+ exit;
+ }
+
+# parse BLD.INF - to get the platforms and the export files
+ eval { &Load_ModuleL('PREPFILE'); };
+ &FatalError($@) if $@;
+
+ my @RealPlats=();
+ my @Exports=();
+ my @TestExports=();
+ if ($Options{v}) {
+ print "Reading \"${BldInfPath}$BldInfName\" for platforms and exports\n";
+ }
+ &ParseBldInf(\@RealPlats, \@Exports, \@TestExports, $BldInfPath,
+ $E32env::Data{EPOCIncPath}, $E32env::Data{EPOCPath}, $E32env::Data{EPOCDataPath});
+
+# Add Customizations
+ my @additions;
+ foreach my $plat (@RealPlats) {
+ my @customizations = Plat_Customizations($plat);
+ foreach my $custom (@customizations) {
+ push @additions, $custom
+ unless grep /$custom/, @additions;
+ }
+ }
+ unless ($CLPlat eq 'ALL') {
+ push @RealPlats, @additions;
+ }
+
+ # Force GCCXML support for anything that compiles as ARMV5
+ if ( (grep /^ARMV5$/, @RealPlats) and not (grep /^GCCXML$/,@RealPlats) )
+ {
+ push @RealPlats, 'GCCXML';
+ }
+
+ # Force EDG support for anything that compiles as ARMV5
+ if ( (grep /^ARMV5$/, @RealPlats) and not (grep /^EDG$/,@RealPlats) )
+ {
+ push @RealPlats, 'EDG';
+ }
+
+if (0) {
+# Add ARMV5 to the platforms if ARM4 is defined
+ if (grep /^ARM4$/, @RealPlats) {
+ unless ( (grep /^ARMV4$/, @RealPlats) or (grep /^ARMV5$/, @RealPlats) ){
+ push @RealPlats, 'ARMV5';
+ push @RealPlats, 'ARMV4';
+ }
+ }
+}
+
+# get any IDE platforms required into a new platforms list, and
+# Create a hash to contain the 'real' names of the platforms, i.e. WINS rather than VC6
+ my @Plats=@RealPlats;
+ my %Real;
+ foreach (@RealPlats) { # change to get VC6 batch files
+ $Real{$_}=$_;
+ my $AssocIDE;
+ my @AssocIDEs;
+
+# Get the IDEs associated with a real platform. A real plat like,
+# WINSCW may have multiple associated IDEs like VC6 .NET2003 or CW IDE.
+ &Plat_AssocIDE($_, \@AssocIDEs);
+ next unless @AssocIDEs;
+
+ push @Plats, @AssocIDEs;
+ foreach $AssocIDE (@AssocIDEs)
+ {
+ $Real{$AssocIDE}=$Real{$_};
+ }
+
+ }
+ if ($Options{v}) {
+ print "Platforms: \"@Plats\"\n";
+ }
+
+# check that the platform specified on the command-line is acceptable
+# and sort out a list of platforms to process
+ my @DoRealPlats=@RealPlats;
+ my @DoPlats=@Plats;
+
+ unless (@Plats) {
+# include the optional platform list if no platform is specified
+ my $OptionalPlat;
+ foreach $OptionalPlat (@OptionalPlats) {
+ unless (grep /^$OptionalPlat$/i, @DoPlats) {
+ push @DoPlats, $OptionalPlat;
+ }
+ }
+ }
+
+ unless ($CLPlat eq 'ALL') {
+ unless (grep /^$CLPlat$/, @Plats) {
+ &FatalError("Platform $CLPlat not supported by \"${BldInfPath}$BldInfName\"\n");
+ }
+ @DoPlats=($CLPlat);
+ @DoRealPlats=$Real{$CLPlat};
+ }
+
+# sort out the export directories we might need to make
+ my @ExportDirs=ExportDirs(\@Exports);
+ my @TestExportDirs=ExportDirs(\@TestExports);
+
+# parse the BLD.INF file again for each platform supported by the project
+# storing the information in a big data structure
+ my %AllPlatData;
+ my %AllPlatTestData;
+ my $Plat;
+
+ if ($Options{v} and $CLPlat ne 'ALL'){
+ print "Reading \"${BldInfPath}$BldInfName\" for $CLPlat \n";
+ }
+
+ foreach $Plat (@RealPlats) {
+ if ($Options{v}) {
+ if ($CLPlat eq 'ALL') {
+ print "Reading \"${BldInfPath}$BldInfName\" for $Plat\n";
+ }
+ }
+ my (@PlatData, @PlatTestData);
+ if ($CLPlat eq 'ALL') {
+ &ParseBldInfPlat(\@PlatData, \@PlatTestData, $Plat, $BldInfPath, ($DefaultFeatureVariant{VALID} && &Plat_SupportsFeatureVariants($Plat) ? \%DefaultFeatureVariant : undef));
+ }
+ else {
+ &ParseBldInfPlat(\@PlatData, \@PlatTestData, $CLPlat, $BldInfPath, ($DefaultFeatureVariant{VALID} && &Plat_SupportsFeatureVariants($CLPlat) ? \%DefaultFeatureVariant : undef));
+ }
+ $AllPlatData{$Plat}=\@PlatData;
+ $AllPlatTestData{$Plat}=\@PlatTestData;
+ }
+ undef $Plat;
+
+ undef $CLPlat;
+ if ($Command eq 'BLDFILES') {
+
+# create the perl file, PLATFORM.PM, listing the platforms
+ if ($Options{v}) {
+ print "Creating \"${OutDir}PLATFORM.PM\"\n";
+ }
+ &CreatePlatformPm($OutDir, \@Plats, \@RealPlats, \%Real, \%AllPlatData, \%AllPlatTestData);
+
+# create the .BAT files required to call ABLD.PL
+ if ($Options{v}) {
+ print "Creating \"${BldInfPath}ABLD.BAT\"\n";
+ }
+ &CreatePerlBat($BldInfPath);
+
+# create the makefile for exporting files
+ if ($Options{v}) {
+ print "Creating \"${OutDir}EXPORT.MAKE\"\n";
+ }
+ &CreateExportMak("${OutDir}EXPORT.MAKE", \@Exports, \@ExportDirs);
+
+# create the makefile for exporting test files
+ if ($Options{v}) {
+ print "Creating \"${OutDir}EXPORTTEST.MAKE\"\n";
+ }
+ &CreateExportMak("${OutDir}EXPORTTEST.MAKE", \@TestExports, \@TestExportDirs);
+
+# modified start: makefile improvement
+ #create the feature variant infor file
+ foreach my $copyofPlat (@DoPlats)
+ {
+ my $realplat = $Real{$copyofPlat};
+ if(&Plat_SupportsFeatureVariants($copyofPlat))
+ {
+ my $variant_info = &Path_Chop($E32env::Data{BldPath}).$BldInfPath."\\FeatureVariantInfo\\".$realplat."\\";
+ eval { &Path_MakePathL($variant_info); };
+ die $@ if $@;
+ if ($Options{v}) {
+ print "Creating: \"$variant_info\"\n";
+ }
+ foreach my $featureVariant (@FeatureVariants)
+ {
+ my $variant_file = $variant_info."$realplat.$featureVariant.info";
+# modified by SV start: makefile improvement
+ my $refdata = $AllPlatData{$realplat};
+ my $testrefdata = $AllPlatTestData{$realplat};
+ if ( @$refdata ) {
+ foreach my $RefPro (@$refdata)
+ {
+ $variant_file = $variant_info."$realplat.$featureVariant.$$RefPro{Base}.info";
+ my $ref_basedir = $variant_file;
+ $ref_basedir=~s/(.*[\\\/]).*/$1/;
+ if ( ! -d $ref_basedir ){
+ eval { &Path_MakePathL($ref_basedir); };
+ die $@ if $@;
+ }
+ open VARIANTINFOR,">$variant_file" or die "ERROR: Can't open or create file \"$variant_file\"\n";
+ print VARIANTINFOR "VARIANT_PLAT_NAME_$$RefPro{Base}:=default \n";
+ close VARIANTINFOR or die "ERROR: Can't close file \"$variant_file\"\n";
+ }
+ }
+ else {
+ open VARIANTINFOR,">$variant_file" or die "ERROR: Can't open or create file \"$variant_file\"\n";
+ print VARIANTINFOR "VARIANT_PLAT_NAME:=$featureVariant \n";
+ close VARIANTINFOR or die "ERROR: Can't close file \"$variant_file\"\n";
+ print "file \"$variant_file\"\n"
+ }
+ if ($testrefdata){
+ foreach my $RefPro (@$testrefdata)
+ {
+ $variant_file = $variant_info."$realplat.$featureVariant.$$RefPro{Base}.info";
+ my $ref_basedir = $variant_file;
+ $ref_basedir=~s/(.*[\\\/]).*/$1/;
+ if ( ! -d $ref_basedir ){
+ eval { &Path_MakePathL($ref_basedir); };
+ die $@ if $@;
+ }
+ open VARIANTINFOR,">$variant_file" or die "ERROR: Can't open or create file \"$variant_file\"\n";
+ print VARIANTINFOR "VARIANT_PLAT_NAME_$$RefPro{Base}:=default \n";
+ close VARIANTINFOR or die "ERROR: Can't close file \"$variant_file\"\n";
+ }
+
+ }
+# modified by SV end: makefile improvement
+ # Close and cleanup
+ if ($Options{v}) {
+ print "Variant info file has been successfully created\n";
+ }
+ }
+ }
+ }
+# modified end: makefile improvement
+# create the platform meta-makefiles
+ foreach my $copyofPlat (@DoPlats) { # Do not use $_ here !!
+ if ($Options{v}) {
+ print "Creating \"$OutDir$copyofPlat.MAKE\"\n";
+ }
+ my $realplat = $Real{$copyofPlat};
+ &CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatData{$realplat}, $copyofPlat, $realplat, $RomDir, $Module, $BldInfPath, \@Exports, '');
+
+ if (&Plat_SupportsFeatureVariants($copyofPlat))
+ {
+ foreach my $featureVariant (@FeatureVariants)
+ {
+ print "Creating \"$OutDir$copyofPlat.$featureVariant.MAKE\"\n" if ($Options{v});
+ &CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatData{$realplat}, $copyofPlat, $realplat, $RomDir, $Module, $BldInfPath, \@Exports, '', ".$featureVariant");
+ }
+ }
+ }
+ foreach (@DoPlats) {
+ if ($Options{v}) {
+ print "Creating \"$OutDir${_}TEST.MAKE\"\n";
+ }
+ &CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatTestData{$Real{$_}}, $_, $Real{$_}, $RomDir, $Module, $BldInfPath, \@TestExports, 'TEST');
+
+ if (&Plat_SupportsFeatureVariants($_))
+ {
+ foreach my $featureVariant (@FeatureVariants)
+ {
+ print "Creating \"$OutDir${_}.".$featureVariant."TEST.MAKE\"\n" if ($Options{v});
+ &CreatePlatMak($OutDir, $E32env::Data{BldPath}, $AllPlatTestData{$Real{$_}}, $_, $Real{$_}, $RomDir, $Module, $BldInfPath, \@TestExports, 'TEST', ".$featureVariant");
+ }
+ }
+ }
+
+# create the platform test batch files
+ foreach (@DoRealPlats) {
+ if ($Options{v}) {
+ print "Creating test batch files in \"$OutDir\" for $_\n";
+ }
+ &CreatePlatBatches($OutDir, $AllPlatTestData{$_}, $_);
+ }
+
+# modified by SV start: makefile improvement
+# create all sub directories
+ foreach my $refplat (@DoRealPlats) {
+ my $tmp = $AllPlatData{$refplat};
+ foreach my $dref (@$tmp){
+ my $builddir = $OutDir . $$dref{Base} ."\\" . $refplat . "\\";
+ if (!-d $builddir){
+ if ($Options{v}) {
+ print "Creating directory \"$builddir\" \n";
+ }
+ eval { &Path_MakePathL($builddir); };
+ &FatalError($@) if $@;
+ }
+ }
+ }
+# modified by SV end: makefile improvement
+
+# report any near-fatal errors
+ if (scalar keys %KeepGoing) {
+ print STDERR
+ "\n${BldInfPath}$BldInfName WARNING(S):\n",
+ sort keys %KeepGoing
+ ;
+ }
+
+ exit;
+ }
+}
+
+
+################ END OF MAIN PROGRAM SECTION #################
+#------------------------------------------------------------#
+##############################################################
+
+
+# SUBROUTINE SECTION
+####################
+
+sub Usage () {
+
+ eval { &Load_ModuleL('E32TPVER'); };
+ &FatalError($@) if $@;
+
+ print
+ "\n",
+ "BLDMAKE - Project building Utility (Build ",&E32tpver,")\n",
+ "\n",
+ "BLDMAKE {options} [<command>] [<platform>]\n",
+ "\n",
+ "<command>: (case insensitive)\n",
+ " BLDFILES - create build batch files\n",
+ " CLEAN - remove all files bldmake creates\n",
+ " INF - display basic BLD.INF syntax\n",
+ " PLAT - display platform macros\n",
+ "\n",
+ "<platform>: (case insensitive)\n",
+ " if not specified, defaults to \"ALL\"\n",
+ "\n",
+ "Options: (case insensitive)\n",
+ " -v -> verbose mode\n",
+ " -k -> keep going even if files are missing\n"
+ ;
+ exit 1;
+}
+
+sub ShowBldInfSyntax () {
+
+ print <<ENDHERE1;
+
+BLD.INF - Syntax
+
+/* Use C++ comments if required */
+// (Curly braces denote optional arguments)
+
+PRJ_PLATFORMS
+{DEFAULT} {-<platform> ...} {<list of platforms>}
+// list platforms your project supports here if not default
+ENDHERE1
+
+ print "// default = ".join(" ",@DefaultPlats)."\n";
+
+ print <<ENDHERE;
+
+PRJ_EXPORTS
+[<source path>\<source file>] {<destination>}
+// list each file exported from source on a separate line
+// {<destination>} defaults to \\EPOC32\\Include\\<source file>
+
+PRJ_TESTEXPORTS
+[<source path>\<source file>] {<destination>}
+// list each file exported from source on a separate line
+// {<destination>} defaults to BLD.INF dir
+
+PRJ_MMPFILES
+[<mmp path>\<mmp file>] {<qualifiers>}
+{MAKEFILE|NMAKEFILE} [<path>\<makefile>] {build_as_arm}
+// <qualifiers> are tidy, ignore, build_as_arm
+
+#if defined(<platform>)
+// .MMP statements restricted to <platform>
+#endif
+
+PRJ_TESTMMPFILES
+[<mmp path>\<mmp file>] {<qualifiers>}
+{MAKEFILE|NMAKEFILE} [<path>\<makefile>] {<qualifiers>}
+// <qualifiers> are {tidy} {ignore} {manual} {support} {build_as_arm}
+
+#if defined(<platform>)
+// .MMP statements restricted to <platform>
+#endif
+
+ENDHERE
+
+}
+
+sub WarnOrDie ($$) {
+ my ($dieref, $message) = @_;
+ if ($Options{k}) {
+ $KeepGoing{$message} = 1;
+ } else {
+ push @{$dieref}, $message;
+ }
+}
+
+sub ExtensionMakefileMissing($)
+{
+ $IgnoreMissingExtensionMakefile = @_;
+}
+
+sub ParseBldInf ($$$$$) {
+ my ($PlatsRef, $ExportsRef, $TestExportsRef, $BldInfPath, $EPOCIncPath, $EPOCPath, $EPOCDataPath)=@_;
+
+ my @Prj2D;
+ eval { &Prepfile_ProcessL(\@Prj2D, "${BldInfPath}$BldInfName",$variantMacroHRHFile); };
+ &FatalError($@) if $@;
+
+ my @SupportedPlats=&Plat_List();
+
+ my @Plats;
+ my %RemovePlats;
+
+ my $DefaultPlatsUsed=0;
+ my %PlatformCheck;
+
+ my %ExportCheck;
+ my $Section=0;
+ our @PrjFileDie;
+ my $Line;
+ my $CurFile="${BldInfPath}$BldInfName";
+ LINE: foreach $Line (@Prj2D) {
+ my $LineNum=shift @$Line;
+ $_=shift @$Line;
+ if ($LineNum eq '#') {
+ $CurFile=$_;
+ next LINE;
+ }
+
+ $CurFile = &Path_Norm ($CurFile);
+
+ if (/^PRJ_(\w*)$/io) {
+ $Section=uc $1;
+ if ($Section=~/^(PLATFORMS|EXPORTS|TESTEXPORTS|MMPFILES|TESTMMPFILES|EXTENSIONS|TESTEXTENSIONS)$/o) {
+ if (@$Line) {
+ push @PrjFileDie, "$CurFile($LineNum) : Can't specify anything on the same line as a section header\n";
+ }
+ next LINE;
+ }
+ push @PrjFileDie, "$CurFile($LineNum) : Unknown section header - $_\n";
+ $Section=0;
+ next LINE;
+ }
+ if ($Section eq 'PLATFORMS') {
+# platforms are gathered up into a big list that contains no duplicates. "DEFAULT" is
+# expanded to the list of default platforms. Platforms specified with a "-" prefix
+# are scheduled for removal from the list. After processing platforms specified
+# with the "-" prefix are removed from the list.
+
+ unshift @$Line, $_;
+ my $Candidate;
+ CANDLOOP: foreach $Candidate (@$Line) {
+ $Candidate=uc $Candidate;
+# ignore old WINC target
+ if ($Candidate eq 'WINC') {
+ next CANDLOOP;
+ }
+# expand DEFAULT
+ if ($Candidate eq 'DEFAULT') {
+ $DefaultPlatsUsed=1;
+ my $Default;
+ foreach $Default (@DefaultPlats) {
+ unless ($PlatformCheck{$Default}) {
+ push @Plats, $Default;
+ $PlatformCheck{$Default}="$CurFile: $LineNum";
+ }
+ }
+ next CANDLOOP;
+ }
+# expand BASEDEFAULT
+ if ($Candidate eq 'BASEDEFAULT') {
+ $DefaultPlatsUsed=1;
+ my $Default;
+ foreach $Default (@BaseDefaultPlats) {
+ unless ($PlatformCheck{$Default}) {
+ push @Plats, $Default;
+ $PlatformCheck{$Default}="$CurFile: $LineNum";
+ }
+ }
+ next CANDLOOP;
+ }
+# expand BASEUSERDEFAULT
+ if ($Candidate eq 'BASEUSERDEFAULT') {
+ $DefaultPlatsUsed=1;
+ my $Default;
+ foreach $Default (@BaseUserDefaultPlats) {
+ unless ($PlatformCheck{$Default}) {
+ push @Plats, $Default;
+ $PlatformCheck{$Default}="$CurFile: $LineNum";
+ }
+ }
+ next CANDLOOP;
+ }
+# check for removals
+ if ($Candidate=~/^-(.*)$/o) {
+ $Candidate=$1;
+# check default is specified
+ unless ($DefaultPlatsUsed) {
+ push @PrjFileDie, "$CurFile($LineNum) : \"DEFAULT\" must be specified before platform to be removed\n";
+ next CANDLOOP;
+ }
+ $RemovePlats{$Candidate}=1;
+ next CANDLOOP;
+ }
+# If tools platform is specified in bld.inf file then component is built for cwtools as well
+ if ($Candidate =~ /^tools/i)
+ {
+ push @Plats, 'CWTOOLS';
+ }
+# check platform is supported
+ unless (grep /^$Candidate$/, @SupportedPlats) {
+ WarnOrDie(\@PrjFileDie, "$CurFile($LineNum) : Unsupported platform $Candidate specified\n");
+ next CANDLOOP;
+ }
+# check platform is not an IDE
+ if ($Candidate=~/^VC/o) {
+ push @PrjFileDie, "$CurFile($LineNum) : No need to specify platform $Candidate here\n";
+ next CANDLOOP;
+ }
+# add the platform
+ unless ($PlatformCheck{$Candidate}) {
+ push @Plats, $Candidate;
+ my $SubPlat = sprintf("%sEDG", $Candidate);
+ push @Plats, $SubPlat
+ if (grep /^$SubPlat$/, @SupportedPlats);
+ $PlatformCheck{$Candidate}="$CurFile: $LineNum";
+ }
+ }
+ next LINE;
+ }
+
+ # Skip PRJ_TESTEXPORT section if -notest flag
+ next LINE if ($Options{notest} && ($Section=~/^(TESTEXPORTS)$/o));
+
+ if ($Section=~/^(EXPORTS|TESTEXPORTS)$/o) {
+
+# make path absolute - assume relative to group directory
+ my $Type = 'file';
+ if (/^\:(\w+)/) {
+ # Export an archive
+ $Type = lc $1;
+ unless ($Type eq 'zip') {
+ push @PrjFileDie, "$CurFile($LineNum) : Unknown archive type - $Type\n";
+ next LINE;
+ }
+ $_ = shift @$Line;
+ }
+
+ my $loggedSourceExport = $_;
+ $_ = &Path_Norm ($_);
+
+ my $Source=&Path_MakeAbs($CurFile, $_);
+ my $Releasable='';
+ my $emReleasable='';
+ my $unzip_option ='';
+ if (@$Line) {
+# get the destination file if it's specified
+ $Releasable=shift @$Line;
+ CheckSource_MetaData(%CheckSourceEXPORTSMetaData, $CurFile, "PRJ_".$Section, $Releasable, $LineNum);
+ $Releasable = &Path_Norm ($Releasable);
+ $emReleasable=ucfirst $Releasable;
+ if ($emReleasable=~/^([A-Z]):(\\.*)$/) {
+ $emReleasable=~s/://;
+ $Releasable=$EPOCDataPath.$emReleasable;
+ }
+ }
+
+ my $sourceExportTypeSuffix = "";
+ $sourceExportTypeSuffix .= " (NO DESTINATION)" if (!$Releasable && $Section =~ /^EXPORTS$/);
+ CheckSource_MetaData(%CheckSourceEXPORTSMetaData, $CurFile, "PRJ_".$Section.$sourceExportTypeSuffix, $loggedSourceExport, $LineNum, $CheckSource_PhysicalCheck);
+
+ if (@$Line) {
+ $unzip_option = shift @$Line;
+ unless ($unzip_option=~ /overwrite/i) {
+ push @PrjFileDie, "$CurFile($LineNum) : Too many arguments in exports section line\n";
+ next LINE;
+ }
+ }
+ unless ($Type eq 'zip' or &Path_Split('File', $Releasable)) {
+# use the source filename if no filename is specified in the destination
+# no filename for archives
+ $Releasable.=&Path_Split('File', $Source);
+ }
+ my $defpath;
+ if ($Type eq 'zip') {
+# archives relative to EPOCROOT
+ $defpath = $ENV{EPOCROOT};
+ }
+ elsif (($Section =~ /EXPORTS$/) && ($Releasable =~ s/^\|[\/|\\]?//)) {
+# '|' prefix forces "relative to bld.inf file" in PRJ_[TEST]EXPORTS destinations
+ $defpath = $CurFile;
+ }
+ elsif ($Section eq 'EXPORTS') {
+# assume the destination is relative to $EPOCIncPath
+ $defpath = $EPOCIncPath;
+ }
+ else {
+ $defpath = $CurFile;
+ }
+ $Releasable=&Path_MakeEAbs($EPOCPath, $defpath, $Releasable);
+
+# sanity checks!
+ if ($Type eq 'file' && $ExportCheck{uc $Releasable}) {
+ push @PrjFileDie, "$CurFile($LineNum) : Duplicate export $Releasable (from line $ExportCheck{uc $Releasable})\n";
+ next LINE;
+ }
+ $ExportCheck{uc $Releasable}="$CurFile: $LineNum";
+ if (! -e $Source) {
+ WarnOrDie(\@PrjFileDie, "$CurFile($LineNum) : Exported source file $Source not found\n");
+ }
+ elsif ($Type ne 'zip' && -d $Releasable) {
+ push @PrjFileDie, "$CurFile($LineNum) : Export target $Releasable must be a file.\n";
+ }
+ else {
+ if ($Section eq 'EXPORTS') {
+ push @$ExportsRef, {
+ 'Source'=>$Source,
+ 'Releasable'=>$Releasable,
+ 'emReleasable'=>$emReleasable,
+ 'Type'=>$Type,
+ 'UnzipOption'=>$unzip_option
+ };
+ }
+ else {
+ push @$TestExportsRef, {
+ 'Source'=>$Source,
+ 'Releasable'=>$Releasable,
+ 'emReleasable'=>$emReleasable,
+ 'Type'=>$Type,
+ 'UnzipOption'=>$unzip_option
+ };
+ }
+ }
+ next LINE;
+ }
+ }
+ if (@PrjFileDie) {
+ print STDERR
+ "\n${BldInfPath}$BldInfName FATAL ERROR(S):\n",
+ @PrjFileDie
+ ;
+ exit 1;
+ }
+
+# set the list of platforms to the default if there aren't any platforms specified,
+# else add platforms to the global list unless they're scheduled for removal,
+ unless (@Plats) {
+ @$PlatsRef=@DefaultPlats;
+ # Include the list of BPABI Platforms in a default build.
+ my $OptionalPlat;
+ foreach $OptionalPlat (@OptionalPlats) {
+ # VS6 and VS2003 are not real platforms and hence are not included in a default build
+ unless ( $OptionalPlat eq 'VS6' || $OptionalPlat eq 'VS2003') {
+ if (not grep /^$OptionalPlat$/i, @$PlatsRef) {
+ push @$PlatsRef, $OptionalPlat;
+ }
+ }
+ }
+ }
+ else {
+ my $Plat;
+ foreach $Plat (@Plats) {
+ unless ($RemovePlats{$Plat}) {
+ push @$PlatsRef, $Plat;
+ }
+ }
+ push @PlatsReq , @$PlatsRef;
+ }
+}
+
+sub ExportDirs ($) {
+ my ($ExportsRef)=@_;
+
+ my %ExportDirHash;
+ foreach (@$ExportsRef) {
+ my $dir = ($$_{Type} eq 'zip') ? $$_{Releasable} : &Path_Split('Path',$$_{Releasable});
+ if ($dir) {
+ $dir=&Path_Chop($dir);
+ $ExportDirHash{uc $dir}=$dir;
+ }
+ }
+ my @ExportDirs;
+ foreach (keys %ExportDirHash) {
+ push @ExportDirs, $ExportDirHash{$_};
+ }
+ @ExportDirs;
+}
+
+
+sub ParseBldInfPlat ($$$$) {
+ my ($DataRef, $TestDataRef, $Plat, $BldInfPath, $FeatureVar)=@_;
+
+# get the platform .MMP macros
+ my %Plat;
+ eval { &Plat_GetL($Plat,\%Plat); };
+ &FatalError($@) if $@;
+
+# get the raw data from the BLD.INF file
+ my @Prj2D;
+ eval { &Prepfile_ProcessL(\@Prj2D, "${BldInfPath}$BldInfName", ($FeatureVar ? $FeatureVar->{VARIANT_HRH} : $variantMacroHRHFile), @{$Plat{MmpMacros}}); };
+ &FatalError($@) if $@;
+
+ my %dummy;
+ my @userIncludes = ('.');
+ my @systemIncludes = ();
+ $CheckSourceBldInfIncludes{$Plat} = CheckSource_Includes("${BldInfPath}$BldInfName", %dummy, $variantMacroHRHFile, @{$Plat{MmpMacros}}, @userIncludes, @systemIncludes, $CheckSource_NoUserSystemDistinction);
+
+# process the raw data
+ my $IsExtensionBlock =0;
+ my (@ExtensionBlockData, $ErrorString);
+ my %Check;
+ my $Section=0;
+ my @PrjFileDie;
+ my $Line;
+ my $CurFile="${BldInfPath}$BldInfName";
+ LINE: foreach $Line (@Prj2D) {
+
+ my %Data;
+ my %Temp;
+
+ my $LineNum=shift @$Line;
+ if ($LineNum eq '#') {
+ $CurFile=shift @$Line;
+ next LINE;
+ }
+
+ $CurFile = &Path_Norm ($CurFile);
+
+# upper-case all the data here, but record original source case
+# in a hash so that it can be recalled for CheckSource purposes
+
+ my %originalSourceCase;
+ foreach (@$Line) {
+ $originalSourceCase{uc $_} = $_; # needed for extension template makefile MACROs
+ $_=uc $_;
+ }
+
+ $_=shift @$Line;
+
+# check for section headers - don't test for the right ones here
+# because we do that in the first parse function
+
+ if (/^PRJ_(\w*)$/o) {
+ $Section=$1;
+ next LINE;
+ }
+
+# Skip section if PRJ_TESTMMPFILES and -notest option
+ next LINE if ($Options{notest} && ($Section=~/^(TESTMMPFILES)$/o));
+
+# check for EXTENSION sections
+ if ($Section=~/^(EXTENSIONS|TESTEXTENSIONS)$/o) {
+
+# We have an extension block
+ if (/^start(\w*)$/io) {
+ if ($IsExtensionBlock) {
+ &FatalError("$CurFile($LineNum) : Cannot embed Extension Template 'start' sections\n");
+ }
+ $IsExtensionBlock =1;
+ $ErrorString = "$CurFile($LineNum)";
+ foreach (@$Line)
+ {
+ if (/^EXTENSION$/)
+ {
+ my $extensionTemplate = @$Line[scalar(@$Line)-1];
+ CheckSource_MetaData(%CheckSourceEXTENSIONSMetaData, $CurFile, "PRJ_".$Section, $originalSourceCase{$extensionTemplate}.".mk", $LineNum, $CheckSource_PhysicalCheck) if ($extensionTemplate);
+ }
+ }
+
+ push @ExtensionBlockData, $Line;
+ next LINE;
+ }
+
+ if (($IsExtensionBlock) & (! (/^end(\w*)$/io))) {
+ if (($_ ne "TOOL") & ($_ ne "OPTION") & ($_ ne "TARGET") & ($_ ne "SOURCES") & ($_ ne "DEPENDENCIES")) {
+ &FatalError("$CurFile($LineNum) : Unrecognised keyword: $_. Is there an 'end' corresponding to the 'start' for the Extension Template?\n");
+ }
+ if ($_ ne "OPTION") {
+ unshift(@$Line, $_);
+ }
+# Need to revert MACROs back to their original case
+ foreach (@$Line) {
+ $_=$originalSourceCase{$_};
+ }
+ push @ExtensionBlockData, $Line;
+ next LINE;
+ }
+
+ if (/^end(\w*)$/io) {
+ if (! $IsExtensionBlock) {
+ &FatalError("$CurFile($LineNum) : No 'start' corresponding to this 'end' in Extension Template section\n");
+ }
+ $IsExtensionBlock =0;
+ my $OutDir=Path_Chop($E32env::Data{BldPath}).$BldInfPath;
+# Generate wrapper makefile for this platform.
+ eval { &Load_ModuleL('WrapperMakefile'); };
+ &FatalError($@) if $@;
+ $OutDir=~ s/\\/\//g; # convert to unix slashes for wrappermakefile.pm
+ %Data = GenerateWrapper($Plat, $OutDir, $ErrorString, \@PrjFileDie, @ExtensionBlockData);
+ if (!$IgnoreMissingExtensionMakefile)
+ {
+ $Data{ExtensionRoot}=&Path_Split('Path', $CurFile);
+ $Data{Path}=~ s/\//\\/g; # convert unix slashes back to win32
+ $Data{Base}=~ s/\//\\/g;
+ }
+ @ExtensionBlockData = (); # clear array
+ }
+ }
+
+# check for MMP sections and get the .MMP file details
+ if ($Section=~/^(MMPFILES|TESTMMPFILES)$/o) {
+ $Data{Ext}='.MMP';
+# check for MAKEFILE statements for custom building
+ my $SubSection = "MMP";
+ if (/^MAKEFILE$/o) {
+ $SubSection = $_;
+ $Data{Makefile}=2; # treat MAKEFILE=>NMAKEFILE =1;
+ $_=shift @$Line;
+ $Data{Ext}=&Path_Split('Ext', $_);
+ }
+ if (/^NMAKEFILE$/o) {
+ $SubSection = $_;
+ $Data{Makefile}=2;
+ $_=shift @$Line;
+ $Data{Ext}=&Path_Split('Ext', $_);
+ }
+ if (/^GNUMAKEFILE$/o) {
+ $SubSection = $_;
+ $Data{Makefile}=1;
+ $_=shift @$Line;
+ $Data{Ext}=&Path_Split('Ext', $_);
+ }
+ CheckSource_MetaData(%CheckSourceMMPFILESMetaData, $CurFile, "PRJ_$Section $SubSection", $originalSourceCase{$_}, $LineNum, $CheckSource_PhysicalCheck);
+ $_ = &Path_Norm ($_);
+
+# path considered relative to the current file
+ $Data{Path}=&Path_Split('Path', &Path_MakeAbs($CurFile, $_));
+
+# this function doesn't care whether the .MMPs are listed with their extensions or not
+ $Data{Base}=&Path_Split('Base', $_);
+ my $MmpFile= $Data{Path}.$Data{Base};
+
+# check the file isn't already specified
+ if ($Check{$MmpFile}) {
+ push @PrjFileDie, "$CurFile($LineNum) : duplicate $Data{Base} (from line $Check{$MmpFile})\n";
+ next;
+ }
+ $Check{$MmpFile}="$CurFile: $LineNum";
+
+# check the file exists
+ unless (-e "$Data{Path}$Data{Base}$Data{Ext}") {
+ WarnOrDie(\@PrjFileDie, "$CurFile($LineNum) : $Data{Path}$Data{Base}$Data{Ext} does not exist\n");
+ next LINE;
+ }
+
+
+# process the file's attributes
+ if ($Section eq 'MMPFILES') {
+ foreach (@$Line) {
+ if (/^TIDY$/o) {
+ $Data{Tidy}=1;
+ next;
+ }
+ if (/^IGNORE$/o) {
+ next LINE;
+ }
+ if (/^BUILD_AS_ARM$/o) {
+ $Data{BuildAsARM}="-arm";
+ next;
+ }
+
+ push @PrjFileDie, "$CurFile($LineNum) : Don't understand .MMP file argument \"$_\"\n";
+ }
+ }
+
+# process the test .MMP file's attributes
+ elsif ($Section eq 'TESTMMPFILES') {
+ foreach (@$Line) {
+ if (/^TIDY$/o) {
+ $Data{Tidy}=1;
+ next;
+ }
+ if (/^IGNORE$/o) {
+ next LINE;
+ }
+ if (/^BUILD_AS_ARM$/o) {
+ $Data{BuildAsARM}="-arm";
+ next;
+ }
+ if (/^MANUAL$/o) {
+ $Data{Manual}=1;
+ next;
+ }
+ if (/^SUPPORT$/o) {
+ $Data{Support}=1;
+ next;
+ }
+ push @PrjFileDie, "$CurFile($LineNum) : Don't understand test .MMP file argument \"$_\"\n";
+ }
+ }
+ }
+
+# store the data
+ if (($Section eq 'MMPFILES') or ($Section eq 'EXTENSIONS')) {
+ if ($IgnoreMissingExtensionMakefile and $Section eq 'EXTENSIONS')
+ {
+ # More than more ext makefile can be missing so reset indicator
+ $IgnoreMissingExtensionMakefile = 0;
+ }
+ else
+ {
+ push @$DataRef, \%Data;
+ }
+ next LINE;
+ }
+ if (($Section eq 'TESTMMPFILES') or ($Section eq 'TESTEXTENSIONS')) {
+ if ($IgnoreMissingExtensionMakefile and $Section eq 'TESTEXTENSIONS')
+ {
+ # More than more ext makefile can be missing so reset indicator
+ $IgnoreMissingExtensionMakefile = 0;
+ }
+ else
+ {
+ push @$TestDataRef, \%Data;
+ }
+ next LINE;
+ }
+
+ }
+# line loop end
+
+# exit if there are errors
+ if (@PrjFileDie) {
+ print STDERR
+ "\n\"${BldInfPath}$BldInfName\" FATAL ERROR(S):\n",
+ @PrjFileDie
+ ;
+ exit 1;
+ }
+}
+
+
+sub FatalError (@) {
+
+ print STDERR "BLDMAKE ERROR: @_\n";
+ exit 1;
+}
+
+sub CreatePlatformPm ($$$$$$) {
+ my ($BatchPath, $PlatsRef, $RealPlatsRef, $RealHRef, $AllPlatDataHRef, $AllPlatTestDataHRef)=@_;
+
+
+# exclude GCCXML, EDG and CWTOOLS from list of RealPlats
+ my @RealPlats;
+ foreach my $Plat (@$RealPlatsRef){
+ unless (($Plat =~ /^gccxml/i) or ($Plat =~ /^edg/i) or ($Plat =~ /^cwtools/i) or ($Plat =~ /^x86gcc/i) or ($Plat =~ /^x86gmp/i)) {
+# exclude BPABI targets from list of RealPlats provided they are not specified in the platform list
+ if (grep /^$Plat$/i, @OptionalPlats) {
+ if (grep /^$Plat$/, @PlatsReq) {
+ push @RealPlats, $Plat;
+ }
+ next;
+ }
+ push @RealPlats, $Plat;
+ }
+ }
+
+
+ &Output(
+ "# Bldmake-generated perl file - PLATFORM.PM\n",
+ "\n",
+ "# use a perl integrity checker\n",
+ "use strict;\n",
+ "\n",
+ "package Platform;\n",
+ "\n",
+ "use vars qw(\@Plats \@RealPlats %Programs %TestPrograms %FeatureVariantSupportingPlats);\n",
+ "\n",
+ "\@Plats=(\'",join('\',\'',@$PlatsRef),"\');\n",
+ "\n",
+ "\@RealPlats=(\'", join('\',\'',@RealPlats),"\');\n",
+ "\n",
+ "%Programs=(\n"
+ );
+ my %All; # all programs for all platforms
+ my $TmpStr;
+ my $Plat;
+ foreach $Plat (@$PlatsRef) {
+ $TmpStr=" \'$Plat\'=>[";
+ if (@{${$AllPlatDataHRef}{$$RealHRef{$Plat}}}) {
+ my $ProgRef;
+ foreach $ProgRef (@{${$AllPlatDataHRef}{$$RealHRef{$Plat}}}) {
+ $TmpStr.="'$$ProgRef{Base}',";
+ $All{$$ProgRef{Base}}=1;
+ }
+ chop $TmpStr;
+ }
+ &Output(
+ "$TmpStr],\n"
+ );
+ }
+ $TmpStr=" ALL=>[";
+ if (keys %All) {
+ my $Prog;
+ foreach $Prog (keys %All) {
+ $TmpStr.="'$Prog',";
+ }
+ chop $TmpStr;
+ }
+ &Output(
+ "$TmpStr]\n",
+ ");\n",
+ "\n",
+ "%TestPrograms=(\n"
+ );
+ %All=();
+ foreach $Plat (@$PlatsRef) {
+ $TmpStr=" \'$Plat\'=>[";
+ if (@{${$AllPlatTestDataHRef}{$$RealHRef{$Plat}}}) {
+ my $ProgRef;
+ foreach $ProgRef (@{${$AllPlatTestDataHRef}{$$RealHRef{$Plat}}}) {
+ $TmpStr.="'$$ProgRef{Base}',";
+ $All{$$ProgRef{Base}}=1;
+ }
+ chop $TmpStr;
+ }
+ &Output("$TmpStr],\n");
+ }
+ $TmpStr=" ALL=>[";
+ if (keys %All) {
+ my $Prog;
+ foreach $Prog (keys %All) {
+ $TmpStr.="'$Prog',";
+ }
+ chop $TmpStr;
+ }
+ &Output(
+ "$TmpStr]\n",
+ ");\n",
+ "\n"
+ );
+
+ &Output(
+ "\n",
+ "%FeatureVariantSupportingPlats=("
+ );
+
+ $TmpStr = "";
+ foreach $Plat (@$PlatsRef)
+ {
+ $TmpStr .= "\n\t$Plat=>1," if (&Plat_SupportsFeatureVariants($Plat));
+ }
+
+ chop $TmpStr;
+
+ &Output(
+ "$TmpStr\n",
+ ");\n",
+ "\n",
+ "1;\n"
+ );
+
+# write the PLATFORM.PM file
+ &WriteOutFileL($BatchPath."PLATFORM.PM");
+}
+
+sub CreatePerlBat ($) {
+ my ($BldInfPath)=@_;
+
+# create ABLD.BAT, which will call ABLD.PL
+# NB. must quote $BldInfPath because it may contain spaces, but we know it definitely
+# ends with \ so we need to generate "\foo\bar\\" to avoid quoting the close double quote
+ &Output(
+ "\@ECHO OFF\n",
+ "\n",
+ "REM Bldmake-generated batch file - ABLD.BAT\n",
+ "REM ** DO NOT EDIT **",
+ "\n",
+ "\n",
+ "perl -S ABLD.PL \"${BldInfPath}\\\" %1 %2 %3 %4 %5 %6 %7 %8 %9\n",
+ "if errorlevel==1 goto CheckPerl\n",
+ "goto End\n",
+ "\n",
+ ":CheckPerl\n",
+ "perl -v >NUL\n",
+ "if errorlevel==1 echo Is Perl, version 5.003_07 or later, installed?\n",
+ "goto End\n",
+ "\n",
+ ":End\n"
+ );
+
+# check that the .BAT file does not already exist and is read-only
+ if ((-e "${BldInfPath}ABLD.BAT") && !(-w "${BldInfPath}ABLD.BAT")) {
+ warn "BLDMAKE WARNING: read-only ABLD.BAT will be overwritten\n";
+ chmod 0222, "${BldInfPath}ABLD.BAT";
+ }
+
+# create the .BAT file in the group directory
+ &WriteOutFileL($BldInfPath."ABLD.BAT",1);
+
+}
+
+sub GetArchiveExportList($) {
+ my ($ExportRef) = @_;
+ my $Type = $ExportRef->{Type};
+ my $Src = $ExportRef->{Source};
+ my $Dest = $ExportRef->{Releasable};
+ $Dest = '' if (!defined($Dest));
+ my @list = ();
+ if ($Type eq 'zip') {
+ unless (open PIPE, "unzip -l $Src | ") {
+ warn "Can't unzip $Src\n";
+ }
+ while (<PIPE>) {
+ if (/^\s*\d+\s+\S+\s+\S+\s+(.*?)\s*$/) {
+# ignore empty lines and anything that finishes with /
+ unless(($1=~/\/\s*$/) || ($1=~/^$/)) {
+
+ my $member = $1;
+ $member =~ s/\$/\$\$/g;
+ if (!$Dest){
+ push @list, "$ENV{EPOCROOT}$member";
+ }
+ else{
+ push @list, "$Dest\\$member";
+ }
+ }
+ }
+ }
+ close PIPE;
+ }
+ return @list;
+}
+
+sub CreateExportMak ($$$) {
+ my ($Makefile, $ExportsRef, $ExpDirsRef)=@_;
+
+# create EXPORT.MAKE
+
+ my $erasedefn = "\@erase";
+ $erasedefn = "\@erase 2>>nul" if ($ENV{OS} eq "Windows_NT");
+ &Output(
+ "ERASE = $erasedefn\n",
+ "\n",
+ "\n",
+ "EXPORT : EXPORTDIRS"
+ );
+ my $ref;
+ if (@$ExportsRef) {
+ foreach $ref (@$ExportsRef) {
+ if ($$ref{Type} eq 'zip') {
+ my @list = &GetArchiveExportList($ref);
+ foreach (@list) {
+ my $dst=$_;
+ &Output(
+ " \\\n",
+ "\t$dst"
+ );
+ }
+ } else {
+ my $name=&Path_Quote($$ref{Releasable});
+ &Output(
+ " \\\n",
+ "\t$name"
+ );
+ }
+ }
+ }
+ else {
+ &Output(
+ " \n",
+ "\t\@echo Nothing to do\n"
+ );
+ }
+ &Output(
+ "\n",
+ "\n",
+ "\n",
+ "EXPORTDIRS :"
+ );
+ my $dir;
+ foreach $dir (@$ExpDirsRef) {
+ $dir=&Path_Quote($dir);
+ &Output(
+ " $dir"
+ );
+ }
+ &Output(
+ "\n",
+ "\n"
+ );
+ foreach $dir (@$ExpDirsRef) {
+ &Output(
+ "$dir :\n",
+ "\t\@perl -S emkdir.pl \"\$\@\"\n",
+ "\n"
+ );
+ }
+ &Output(
+ "\n",
+ "\n"
+ );
+ foreach $ref (@$ExportsRef) {
+ my $unzipoption = $$ref{UnzipOption};
+ CheckSource_ExportedIncludes($$ref{Source}, $$ref{Releasable}, %CheckSourceEXPORTSIncludes);
+
+ if ($$ref{Type} eq 'zip') {
+ my $src = &Path_Quote($$ref{Source});
+ my $destdir = &Path_Quote($$ref{Releasable});
+ $destdir=$ENV{EPOCROOT} if (!defined($destdir) or ($destdir eq ''));
+ my @list = &GetArchiveExportList($ref);
+ foreach (@list) {
+ my $dst=$_;
+ &Output(
+ "$dst : $src\n",
+ );
+ }
+ if ($unzipoption =~ /overwrite/i){
+ &Output(
+ "\t- unzip -o $src -d \"$destdir\"\n",
+ );
+ }
+ else{
+ &Output(
+ "\t- unzip -u -o $src -d \"$destdir\"\n",
+ );
+ }
+ } else {
+ my $dst=&Path_Quote($$ref{Releasable});
+ my $src=&Path_Quote($$ref{Source});
+ &Output(
+ "$dst : $src\n",
+ "\tcopy \"\$?\" \"\$\@\"\n",
+ "\n"
+ );
+ }
+ }
+ &Output(
+ "\n",
+ "\n"
+ );
+ if (@$ExportsRef) {
+ &Output(
+ "CLEANEXPORT :\n"
+ );
+ foreach $ref (@$ExportsRef) {
+ if ($$ref{Type} eq 'zip') {
+ my @list = &GetArchiveExportList($ref);
+ foreach (@list) {
+ my $dst=$_;
+ $dst =~ s/\//\\/go;
+ &Output(
+ "\t-\$(ERASE) \"$dst\"\n"
+ );
+ }
+ } else {
+ my $dst = $$ref{Releasable};
+ $dst =~ s/\//\\/go;
+ &Output(
+ "\t-\$(ERASE) \"$dst\"\n"
+ );
+ }
+ }
+ &Output(
+ "\n",
+ "WHAT :\n"
+ );
+ foreach $ref (@$ExportsRef) {
+ if ($$ref{Type} eq 'zip') {
+ my @list = &GetArchiveExportList($ref);
+ foreach (@list) {
+ my $dst=$_;
+ $dst =~ s/\//\\/go;
+ &Output(
+ "\t\@echo \"$dst\"\n"
+ );
+ }
+ } else {
+ my $dst = $$ref{Releasable};
+ $dst =~ s/\//\\/go;
+ &Output(
+ "\t\@echo \"$dst\"\n"
+ );
+ }
+ }
+ }
+ else {
+ &Output(
+ "CLEANEXPORT :\n",
+ "\t\@echo Nothing to do\n",
+ "WHAT :\n",
+ "\t\@rem do nothing\n"
+ );
+ }
+
+ &Output(
+ "\nCHECKSOURCE :\n"
+ );
+
+ &Output (CheckSource_MakefileOutput(%CheckSourceEXPORTSMetaData));
+ &Output (CheckSource_MakefileOutput(%CheckSourceEXPORTSIncludes));
+
+ &Output("\n");
+
+# write EXPORT.MAKE
+ &WriteOutFileL($Makefile);
+}
+
+sub CreatePlatExports ($$) {
+ my ($RealPlat,$Exports)=@_;
+ my $Ref;
+ &Output(
+ "\n# Rules which handle the case when \$(CFG) is not defined\n\n" ,
+ "EXPORT: \tEXPORTUREL EXPORTUDEB\n",
+ "EXPORTCLEAN: \tEXPORTCLEANUREL EXPORTCLEANUDEB\n",
+ "EXPORTWHAT: \tEXPORTWHATUREL EXPORTWHATUDEB\n",
+
+ "\n# definitions \n",
+ "DATAx = $ENV{EPOCROOT}epoc32\\data\n",
+ "EMULx = $ENV{EPOCROOT}epoc32\\$RealPlat\n",
+ "URELx = $ENV{EPOCROOT}epoc32\\release\\$RealPlat\\urel\n",
+ "UDEBx = $ENV{EPOCROOT}epoc32\\release\\$RealPlat\\udeb\n",
+ "\n"
+ );
+
+ &Output(
+ "# Exports to emulated drive A: to Y \n\n",
+ "EXPORTGENERIC : EXPORTDIRSGENERIC",
+ );
+
+ my @dirs;
+ my @expgen;
+ my %dirsg;
+ foreach $Ref (@$Exports) {
+ if ($$Ref{emReleasable}=~/^([A-Y])(\\.*)$/){
+ my $exp="\\$$Ref{emReleasable}";
+ if ($$Ref{Type} eq 'zip') {
+ my @list = &GetArchiveExportList($Ref);
+ foreach (@list) {
+ my $dst=&Path_Quote($_);
+ if ($dst=~/([^\\]*)$/o){
+ $dst=$1;
+ }
+ my $zipdest=$dst;
+ $zipdest =~ s/\//\\/g;
+ push @expgen, "$exp\\$zipdest";
+ my $zippath= &Path_Chop(&Path_Split('Path', $zipdest));
+ if(!$zippath){
+ $dirsg{$exp}=$exp;
+ }
+ else{
+ $dirsg{"$exp\\$zippath"}="$exp\\$zippath";
+ }
+ &Output(" \\\n","\t\$(EMULx)$exp\\$zipdest");
+ }
+ }
+ else {
+ my $dir = &Path_Chop(&Path_Split('Path', $exp));
+ push @expgen, $exp;
+ $dirsg{$dir}=$dir;
+ &Output(" \\\n", "\t\$(EMULx)$exp ");
+ }
+ }
+ }
+ &Output("\n\nEXPORTDIRSGENERIC : ");
+ foreach (keys %dirsg){
+ push @dirs, "\$(EMULx)$dirsg{$_}";
+ &Output(" \\\n", "\t\$(EMULx)$_");
+ }
+ &Output("\n\n");
+ foreach (@expgen){
+ &Output(
+ "\$(EMULx)$_ : \t\$(DATAx)$_ \n",
+ "\tcopy \"\$?\" \"\$@\" \n"
+ );
+ }
+ &Output("\nEXPORTCLEANGENERIC :\n");
+ foreach (@expgen){
+ &Output("\t-@\$(ERASE) \$(EMULx)$_ \n");
+ }
+ &Output("\nEXPORTWHATGENERIC :\n");
+ foreach (@expgen){
+ &Output("\t\@echo \$(EMULx)$_ \n");
+ }
+
+ &Output(
+ "\n\n# Exports to emulated drive Z: - UREL version \n\n",
+ "EXPORTUREL : EXPORTDIRSUREL",
+ );
+
+ my @expurel;
+ my %dirsurel;
+ foreach $Ref (@$Exports) {
+ if ($$Ref{emReleasable}=~/^(Z)(\\.*)$/){
+ my $exp="\\$$Ref{emReleasable}";
+ if ($$Ref{Type} eq 'zip') {
+ my @list = &GetArchiveExportList($Ref);
+ foreach (@list) {
+ my $dst=&Path_Quote($_);
+ if ($dst=~/([^\\]*)$/o){
+ $dst=$1;
+ }
+ my $zipdest=$dst;
+ $zipdest=~ s/\//\\/g;
+ push @expurel, "$exp\\$zipdest";
+ my $zippath= &Path_Chop(&Path_Split('Path', $zipdest));
+ if(!$zippath){
+ $dirsurel{$exp}=$exp;
+ }
+ else{
+ $dirsurel{"$exp\\$zippath"}="$exp\\$zippath";
+ }
+ &Output(" \\\n","\t\$(URELx)$exp\\$zipdest");
+ }
+ }
+ else {
+ my $dir = &Path_Chop(&Path_Split('Path', $exp));
+ push @expurel, $exp;
+ $dirsurel{$dir}=$dir;
+ &Output(" \\\n", "\t\$(URELx)$exp ");
+ }
+ }
+ }
+ &Output("\n\nEXPORTDIRSUREL : ");
+ foreach (keys %dirsurel){
+ push @dirs, "\$(URELx)$dirsurel{$_}";
+ &Output(" \\\n", "\t\$(URELx)$_ ");
+ }
+ &Output("\n\n");
+ foreach (@expurel){
+ &Output(
+ "\$(URELx)$_ : \t\$(DATAx)$_ \n",
+ "\tcopy \"\$?\" \"\$@\" \n"
+ );
+ }
+ &Output("\nEXPORTCLEANUREL :\n");
+ foreach (@expurel){
+ &Output("\t-@\$(ERASE) \$(URELx)$_ \n");
+ }
+ &Output("\nEXPORTWHATUREL :\n");
+ foreach (@expurel){
+ &Output( "\t\@echo \$(URELx)$_ \n");
+ }
+
+ &Output(
+ "\n\n# Exports to emulated drive Z: - UDEB version \n\n",
+ "EXPORTUDEB : EXPORTDIRSUDEB",
+ );
+
+ my %dirsudeb=%dirsurel;
+ my @expudeb=@expurel;
+ foreach (@expudeb){
+ &Output(" \\\n", "\t\$(UDEBx)$_ ");
+ }
+ &Output("\n\nEXPORTDIRSUDEB : ");
+ foreach(keys %dirsudeb){
+ push @dirs, "\$(UDEBx)$dirsudeb{$_}";
+ &Output(" \\\n", "\t\$(UDEBx)$_ ");
+
+ }
+ &Output("\n\n");
+ foreach (@expudeb){
+ &Output(
+ "\$(UDEBx)$_ : \t\$(DATAx)$_ \n",
+ "\tcopy \"\$?\" \"\$@\" \n"
+ );
+ }
+ &Output("\nEXPORTCLEANUDEB :\n");
+ foreach (@expudeb){
+ &Output("\t-@\$(ERASE) \$(UDEBx)$_ \n");
+ }
+ &Output("\nEXPORTWHATUDEB :\n");
+ foreach (@expudeb){
+ &Output("\t\@echo \$(UDEBx)$_ \n");
+ }
+
+ &Output("\n# Directories \n\n");
+ &Output(join (" \\\n", @dirs)." :")
+ &Output("\n\t\@perl -S emkdir.pl \$@\n\n");
+
+}
+
+sub CreatePlatMak ($$$$$$$$$;$) {
+ my ($BatchPath, $E32MakePath, $DataRef, $Plat, $RealPlat, $RomDir, $Module, $BldInfPath, $Exports, $Test, $FeatureVariant)=@_;
+ $FeatureVariant = "" if (!$FeatureVariant);
+
+ unless ($Test) {
+ $Test='';
+ }
+ else {
+ $Test='TEST';
+ }
+
+ my $Ref;
+ my $eDrive=0;
+ if ($RealPlat =~ /^WINS/) {
+ foreach $Ref (@$Exports) {
+ if ($$Ref{emReleasable}=~/^([A-Z])(\\.*)$/) {
+ $eDrive=1;
+ last;
+ }
+ }
+ }
+
+
+ my $OutRomFile="$RomDir$RealPlat$Test.IBY";
+ my $GCCDir="gcc\$(PBUILDPID)\\bin";
+
+ my $erasedefn = "\@erase";
+ $erasedefn = "\@erase 2>>nul" if ($ENV{OS} eq "Windows_NT");
+
+# Get the root platform name to support hierarchy of customizations
+ my $root = Plat_Root($Plat);
+
+ my $config_file = "";
+
+ if (grep /^$root$/i, @BPABIPlats) {
+ $config_file = BPABIutl_Config_Path($root);
+ }
+
+ my $rvct_path = "";
+
+ if ( $config_file ) {
+
+ if ($root =~ /^ARMV\d/) {
+
+ unless ( RVCT_plat2set::compiler_exists($Plat) )
+ {
+ FatalError("Can't find any RVCT installation.");
+ }
+
+ my $rvct_ver = RVCT_plat2set::get_version_string($Plat);
+
+ if ($Plat =~ "^ARMV5" && $rvct_ver lt "2.2.559")
+ {
+ warn "BLDMAKE WARNING: ARMV5 requires at least RVCT 2.2.559.";
+ OutText();
+ return;
+ }
+
+ if ($Plat =~ "^ARMV6" && $rvct_ver lt "2.2.559")
+ {
+ warn "BLDMAKE WARNING: ARMV6 requires at least RVCT 2.2.559.";
+ OutText();
+ return;
+ }
+
+ if ($Plat =~ "^ARMV7" && $rvct_ver lt "3.1.674")
+ {
+ warn "BLDMAKE WARNING: ARMV7 requires at least RVCT 3.1.674.";
+ OutText();
+ return;
+ }
+
+ my $rvct_bin_name = RVCT_plat2set::get_bin_name($Plat);
+ my $rvct_bin_path = RVCT_plat2set::get_bin_path($Plat);
+ my $rvct_inc_name = RVCT_plat2set::get_inc_name($Plat);
+ my $rvct_inc_path = RVCT_plat2set::get_inc_path($Plat);
+ my $rvct_lib_name = RVCT_plat2set::get_lib_name($Plat);
+ my $rvct_lib_path = RVCT_plat2set::get_lib_path($Plat);
+
+ main::Output("export $rvct_bin_name:=$rvct_bin_path\n");
+ main::Output("export $rvct_inc_name:=$rvct_inc_path\n");
+ main::Output("export $rvct_lib_name:=$rvct_lib_path\n");
+
+ my ($rvct_M, $rvct_m, $rvct_b) = RVCT_plat2set::get_version_list($Plat);
+
+ Output( "\n" );
+ Output( "export RVCT_VER_MAJOR:=$rvct_M\n" );
+ Output( "export RVCT_VER_MINOR:=$rvct_m\n" );
+ Output( "export RVCT_VER_BUILD:=$rvct_b\n" );
+
+ $rvct_path = "\$($rvct_bin_name);"; # Example: '$(RVCT22BIN);'.
+ }
+
+ &Output(
+ "\n",
+ "export PLAT:=${Plat}\n\n",
+ "include $config_file\n\n"
+ );
+ }
+# modified start: makefile improvement
+ unless($FeatureVariant eq "")
+ {
+# modified by SV start: makefile improvement
+ foreach $Ref (@$DataRef) {
+ &Output(
+ "include $BatchPath"."FeatureVariantInfo\\".uc($Plat)."\\"."$Plat$FeatureVariant.$$Ref{Base}.info\n\n",
+ );
+ }
+# modified by SV end: makefile improvement
+ }
+# modified end: makefile improvement
+ # Don't hardcode the rvct path if rvct auto switch feature is not enabled.
+ if ($ENV{ABLD_PLAT_INI})
+ {
+ &Output(
+ 'export Path:=',&main::Path_Drive,$E32env::Data{EPOCPath},$GCCDir,";", $rvct_path,"\$(Path)\n",
+ "export PATH:=\$(Path)\n"
+ );
+ }
+ else
+ {
+ &Output(
+ 'export Path:=',&main::Path_Drive,$E32env::Data{EPOCPath},$GCCDir,";", "\$(Path)\n",
+ "export PATH:=\$(Path)\n"
+ );
+ }
+
+ &Output(
+ "\n",
+ "# prevent MAKEFLAGS variable from upsetting calls to NMAKE\n",
+ "unexport MAKEFLAGS\n",
+ "\n",
+ "ERASE = $erasedefn\n",
+ "\n",
+ "\n",
+ "ifdef EFREEZE_ALLOW_REMOVE\n",
+ "REMOVEMACRO := EFREEZE_ALLOW_REMOVE=-remove\n",
+ "endif\n",
+ "\n",
+ "\n"
+ );
+
+ if ($eDrive) {
+ # Generate exports into emulated drives
+ &CreatePlatExports($RealPlat,$Exports);
+ }
+ my $Command;
+ foreach $Command (qw(CLEAN CLEANMAKEFILE CLEANALL FINAL FREEZE LIBRARY MAKEFILE RESOURCE SAVESPACE TARGET LISTING WHATMAKEFILE)) {
+ &Output(
+ "$Command :"
+ );
+
+ if ($eDrive and $Command eq 'CLEAN'){
+ &Output(" EXPORTCLEANGENERIC EXPORTCLEAN\$(CFG) ");
+ foreach $Ref (@$DataRef) {
+ &Output(" $Command$$Ref{Base}");
+ }
+ }
+ elsif ($eDrive and $Command eq 'RESOURCE'){
+ &Output(" EXPORTGENERIC EXPORT\$(CFG) ");
+ foreach $Ref (@$DataRef) {
+ &Output(" $Command$$Ref{Base}");
+ }
+
+ foreach $Ref (@$DataRef) {
+ &Output("\n\nRESOURCE$$Ref{Base} : EXPORTGENERIC EXPORT\$(CFG)");
+ }
+ }
+ else {
+ if(@$DataRef){
+ foreach $Ref (@$DataRef) {
+ &Output(" $Command$$Ref{Base}");
+ }
+ }
+ else {
+ &Output("\n","\t\@echo Nothing to do\n");
+ }
+ }
+ &Output("\n","\n");
+ }
+
+ &Output(
+ "WHAT :"
+ );
+ if($eDrive){
+ &Output(" EXPORTWHATGENERIC EXPORTWHAT\$(CFG) ");
+ }
+ my $whatcount=0;
+ foreach $Ref (@$DataRef) {
+ unless ($$Ref{Tidy}) {
+ $whatcount++;
+ &Output(
+ " WHAT$$Ref{Base}"
+ );
+ }
+ }
+ if ($whatcount==0 and !$eDrive) {
+ &Output(
+ "\n",
+ "\t\@rem do nothing\n"
+ );
+ }
+
+ &Output(
+ "\n",
+ "\n",
+ "CHECKSOURCE :"
+ );
+ my $CheckSource=' CHECKSOURCE_GENERIC';
+ foreach $Ref (@$DataRef) {
+ $CheckSource.=" CHECKSOURCE$$Ref{Base}" if ($$Ref{Ext} eq ".MMP");
+ }
+ &Output(
+ "$CheckSource\n"
+ );
+
+ &Output(
+ "\n",
+ "CHECKSOURCE_GENERIC :\n"
+ );
+
+ if ($CheckSourceBldInfIncludes{$Plat})
+ {
+ my %dummy;
+ $dummy{$CheckSourceBldInfIncludes{$Plat}} = 1;
+ &Output (CheckSource_MakefileOutput(%dummy));
+ }
+
+ &Output (CheckSource_MakefileOutput(%CheckSourceMMPFILESMetaData));
+ &Output (CheckSource_MakefileOutput(%CheckSourceEXTENSIONSMetaData));
+
+ &Output(
+ "\n",
+ "\n",
+ "TIDY :"
+ );
+ my $Tidy='';
+ foreach $Ref (@$DataRef) {
+ if ($$Ref{Tidy}) {
+ $Tidy.=" TIDY$$Ref{Base}";
+ }
+ }
+ if ($Tidy) {
+ &Output(
+ "$Tidy\n"
+ );
+ }
+ else {
+ &Output(
+ "\n",
+ "\t\@echo Nothing to do\n"
+ );
+ }
+ &Output(
+ "\n",
+ "\n"
+ );
+# change for non-EPOC platforms
+ if ($RealPlat=~/^(WINS|WINSCW|WINC|TOOLS|TOOLS2)$/o) {
+ &Output(
+ "ROMFILE :\n"
+ );
+ }
+ else {
+ &Output(
+ 'ROMFILE : STARTROMFILE'
+ );
+ foreach $Ref (@$DataRef) {
+ &Output(
+ " ROMFILE$$Ref{Base}"
+ );
+ }
+ &Output(
+ "\n",
+ "\n",
+ "STARTROMFILE :\n",
+ "\t\@perl -S emkdir.pl \"", &Path_Chop($RomDir), "\"\n",
+ "\t\@echo // $OutRomFile > $OutRomFile\n",
+ "\t\@echo // >> $OutRomFile\n"
+ );
+ if ($Test) {
+ my ($Auto, $Manual);
+ foreach $Ref (@$DataRef) {
+ ++$Auto unless ($$Ref{Manual} or $$Ref{Support});
+ ++$Manual if ($$Ref{Manual});
+ }
+ if ($Auto) {
+ my $IbyTextFrom="data=$BatchPath$Plat.AUTO.BAT";
+ my $IbyTextTo="Test\\$Module.AUTO.BAT";
+ my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1;
+ &Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, $IbyTextTo, ">> $OutRomFile\n");
+ }
+ if ($Manual) {
+ my $IbyTextFrom="data=$BatchPath$Plat.MANUAL.BAT";
+ my $IbyTextTo="Test\\$Module.MANUAL.BAT";
+ my $Spaces= 60>length($IbyTextFrom) ? 60-length($IbyTextFrom) : 1;
+ &Output("\t\@echo ", $IbyTextFrom, ' 'x$Spaces, $IbyTextTo, ">> $OutRomFile\n");
+ }
+ }
+ }
+ &Output(
+ "\n",
+ "\n"
+ );
+ my $CallNmake='nmake -nologo -x - $(VERBOSE) $(KEEPGOING)';
+ my $CallGNUmake='$(MAKE) $(VERBOSE) $(KEEPGOING)';
+
+ my %PlatHash;
+ &Plat_GetL($RealPlat, \%PlatHash);
+ my $CallMake=$CallNmake;
+ if ($PlatHash{MakeCmd} eq "make") {
+ $CallMake="$CallGNUmake -r";
+ }
+ &Plat_GetL($Plat, \%PlatHash);
+
+ foreach $Ref (@$DataRef) {
+
+# standard commands
+ unless ($$Ref{Makefile}) {
+ my $MakefilePath=join('', &Path_Chop($E32MakePath), $BldInfPath, $$Ref{Base}, "\\", $RealPlat, "\\");
+# modified start: makefile improvement
+ my $RealMakefile;
+ if($FeatureVariant eq "")
+ {
+ $RealMakefile="-f \"$MakefilePath$$Ref{Base}.$RealPlat$FeatureVariant\"";
+ }
+ else{
+ $RealMakefile="-f \"$MakefilePath$$Ref{Base}.$RealPlat.\$(VARIANT_PLAT_NAME_$$Ref{Base})\"";
+ }
+# modified end: makefile improvement
+ my $MakefileBase="$MakefilePath$$Ref{Base}";
+
+ if($Plat eq 'VS6' || $Plat eq 'VS2003')
+ {
+ $CallMake .= "-f ";
+ $RealMakefile = "$MakefileBase$PlatHash{Ext}";
+ }
+ &Output(
+ "MAKEFILE$$Ref{Base}_FILES= \\\n",
+ "\t\"$MakefileBase$PlatHash{Ext}$FeatureVariant\"",
+ );
+# changes for WINS/WINSCW/WINC and VC6
+ if ($Plat =~ /^VC6/) {
+ &Output(
+ " \\\n\t\"$MakefileBase.DSW\"",
+ " \\\n\t\"$MakefileBase.SUP.MAKE\""
+ );
+ }
+ if ($Plat eq 'CW_IDE') {
+ &Output(
+ " \\\n\t\"$MakefileBase.pref\"" # Defect: actually uses $BaseTrg, not mmp file name
+ );
+ }
+ if ($RealPlat=~/^(WINS|WINSCW|WINC)$/o) {
+ &Output(
+ " \\\n\t\"$MakefileBase.UID.CPP\"" # Defect: actually uses $BaseTrg, not mmp file name
+ );
+ }
+
+ my $bld_flags="";
+ $bld_flags="\$(ABLD_FLAGS)" if (($Plat =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats) || (Plat_Root($Plat) =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats));
+
+
+ my $build_as_arm_arg="";
+ $build_as_arm_arg = $$Ref{BuildAsARM} if ($$Ref{BuildAsARM});
+
+ # Compiler Wrapper option Support
+ # Generate the flag to keep the Compiler Wrapper option information
+ my $cmp_wrap_flag="";
+ if (($Plat =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats) || ($Plat=~/^WINSCW$/) || (Plat_Root($Plat) =~ /^ARMV5(_ABIV1)?$/ || grep /$Plat/i, @BPABIPlats))
+ {
+ # for armv5 , armv5_abiv1, winscw and all bpabi plaforms
+ $cmp_wrap_flag="\$(ABLD_COMPWRAP_FLAG)" ;
+ }
+
+ &Output(
+ "\n",
+ "\n",
+ "MAKEFILE$$Ref{Base} :\n",
+ "\tperl -S makmake.pl \$(NO_DEPENDENCIES) -D $$Ref{Path}$$Ref{Base} $Plat$FeatureVariant $build_as_arm_arg $bld_flags $cmp_wrap_flag\n",
+
+ "\n",
+ "CLEANMAKEFILE$$Ref{Base} :\n",
+ "\t-\$(ERASE) \$(MAKEFILE$$Ref{Base}_FILES)\n",
+ "\n",
+ "WHATMAKEFILE$$Ref{Base} :\n",
+ "\t\@echo \$(MAKEFILE$$Ref{Base}_FILES)\n",
+ "\n",
+ "TARGET$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile \$(CFG)\n",
+ "\n",
+ "SAVESPACE$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile \$(CFG) CLEANBUILD\$(CFG)\n",
+ "\n",
+ "LISTING$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile MAKEWORK\$(CFG) LISTING\$(CFG)\$(SOURCE)\n",
+ "\n",
+ "FINAL$$Ref{Base} :\n",
+ "\t\@rem do nothing\n",
+ "\n",
+ );
+ foreach $Command (qw(CLEANALL)) {
+ &Output(
+ "CLEANALL$$Ref{Base} :\n",
+ "\tperl -S ermdir.pl $MakefilePath\n",
+ "\n",
+ );
+ }
+ foreach $Command (qw(CLEAN RESOURCE)) {
+ &Output(
+ "$Command$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile $Command\$(CFG)\n",
+ "\n"
+ );
+ }
+ foreach $Command (qw(LIBRARY)) {
+ &Output(
+ "$Command$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile $Command\n",
+ "\n"
+ );
+ }
+ foreach $Command (qw(FREEZE)) {
+ &Output(
+ "$Command$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile $Command \$(REMOVEMACRO)\n",
+ "\n"
+ );
+ }
+ unless ($$Ref{Tidy}) {
+ &Output(
+ "WHAT$$Ref{Base} :\n",
+ "\t\@$CallMake -s $RealMakefile WHAT\$(CFG)\n",
+ "\n"
+ );
+ }
+ else {
+ &Output(
+ "TIDY$$Ref{Base} :\n",
+ "\t$CallMake $RealMakefile CLEANRELEASE CLEANLIBRARY\n",
+ "\n"
+ );
+ }
+
+ &Output(
+ "CHECKSOURCE$$Ref{Base} :\n",
+ "\t\@$CallMake -s $RealMakefile CHECKSOURCE\n",
+ "\t\@$CallMake -s $RealMakefile CHECKSOURCE\$(CFG)\n",
+ "\n"
+ );
+ &Output(
+ "ROMFILE$$Ref{Base} :\n",
+ "\t\@$CallMake $RealMakefile ROMFILE >> $OutRomFile\n",
+ "\n",
+ "\n"
+ );
+ }
+
+# calls to custom makefiles
+ else {
+ my $ChopRefPath=&Path_Chop($$Ref{Path});
+ my $ChopBldInfPath=&Path_Chop($BldInfPath);
+ my $MakefileCall;
+ if ($$Ref{Makefile}==2) {
+ $MakefileCall="cd $ChopRefPath;$CallNmake";
+ } else {
+ $MakefileCall="$CallGNUmake -C $ChopRefPath";
+ }
+ $MakefileCall.=" -f \"$$Ref{Base}$$Ref{Ext}\" TO_ROOT=";
+ $MakefileCall.=&Path_Chop(&Path_UpToRoot($$Ref{Path}));
+ $MakefileCall.=" EPOCBLD=";
+ $MakefileCall.=join('', &Path_Chop(&Path_UpToRoot($$Ref{Path})), &Path_Chop($E32MakePath), $BldInfPath, $$Ref{Base}, "\\", $RealPlat);
+ $MakefileCall.=" TO_BLDINF=";
+ $MakefileCall.=join('', &Path_Chop(&Path_UpToRoot($$Ref{Path})), $ChopBldInfPath);
+ if ($$Ref{ExtensionRoot}) {
+ $MakefileCall.=" EXTENSION_ROOT=".&Path_Chop($$Ref{ExtensionRoot});
+ }
+ if ($$Ref{BuildAsARM}) {
+ $MakefileCall.=" BUILD_AS_ARM=1";
+ }
+ &Output(
+# should change to MAKEFILE
+ "MAKEFILE$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$Plat MAKMAKE\n",
+ "\n",
+# should call in custom makefiles maybe
+ "CLEANMAKEFILE$$Ref{Base} :\n",
+ "# $MakefileCall PLATFORM=$Plat CLEANMAKEFILE\n",
+ "\n",
+ "WHATMAKEFILE$$Ref{Base} :\n",
+ "# \@$MakefileCall -s PLATFORM=$Plat WHATMAKEFILE\n",
+ "\n",
+# should change to TARGET
+ "TARGET$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) BLD\n",
+ "\n",
+# should ignore this target and just call the TARGET target instead?
+ "SAVESPACE$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) SAVESPACE\n",
+ "\n",
+ "LISTING$$Ref{Base} :\n",
+ "\n",
+ "\n",
+# should change to LIBRARY
+ "LIBRARY$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat LIB\n",
+ "\n",
+ "FREEZE$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat FREEZE \$(REMOVEMACRO)\n",
+ "\n",
+ );
+
+ foreach $Command (qw(CLEANALL)) {
+ &Output(
+ "$Command$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) CLEAN\n",
+ "\n"
+ );
+ }
+
+ foreach $Command (qw(CLEAN RESOURCE FINAL)) {
+ &Output(
+ "$Command$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat CFG=\$(CFG) $Command\n",
+ "\n"
+ );
+ }
+ unless ($$Ref{Tidy}) {
+# should change to WHAT
+ &Output(
+ "WHAT$$Ref{Base} :\n",
+ "\t\@$MakefileCall -s PLATFORM=$RealPlat CFG=\$(CFG) RELEASABLES\n",
+ "\n"
+ );
+ }
+ else {
+ &Output(
+ "TIDY$$Ref{Base} :\n",
+ "\t$MakefileCall PLATFORM=$RealPlat TIDY\n",
+# should change to CLEANLIBRARY
+ "\t$MakefileCall CLEANLIB\n",
+ "\n"
+ );
+ }
+ &Output(
+ "ROMFILE$$Ref{Base} :\n",
+ "\t\@$MakefileCall PLATFORM=$RealPlat ROMFILE >> $OutRomFile\n",
+ "\n",
+ "\n"
+ );
+ }
+
+ }
+
+ &WriteOutFileL("$BatchPath$Plat$FeatureVariant$Test.MAKE");
+}
+
+sub CreatePlatBatches ($$$) {
+ my ($OutDir, $DataRef, $Plat)=@_;
+
+# create the test batch files
+# this function won't work properly if the target basename is different from the .MMP basename
+# so perhaps it should call makmake on the .mmp file to check
+
+ my $AutoText;
+ my $ManualText;
+
+ my $Ref;
+ foreach $Ref (@$DataRef) {
+ if ($$Ref{Manual}) {
+ $ManualText.="$$Ref{Base}\n";
+ next;
+ }
+ if ($$Ref{Ext} eq ".MK") {
+ next;
+ }
+ if ($$Ref{Support}) {
+ next;
+ }
+ else {
+ $AutoText.="$$Ref{Base}\n";
+ }
+ }
+
+ if ($AutoText) {
+ &Output($AutoText);
+ &WriteOutFileL("$OutDir$Plat.AUTO.BAT");
+ }
+
+ if ($ManualText) {
+ &Output($ManualText);
+ &WriteOutFileL("$OutDir$Plat.MANUAL.BAT");
+ }
+}
+
+sub WriteOutFileL ($$) { # takes batch file and boolean read-only flag
+ my ($BATFILE, $ReadOnly)=@_;
+
+ $BATFILE=~ s/\//\\/g; # convert unix slashes from wrappermakefile.pm
+
+ eval { &Path_MakePathL($BATFILE); };
+ &FatalError($@) if $@;
+
+ open BATFILE,">$BATFILE" or &FatalError("Can't open or create Batch File \"$BATFILE\"");
+ print BATFILE &OutText or &FatalError("Can't write output to Batch File \"$BATFILE\"");
+ close BATFILE or &FatalError("Can't close Batch File \"$BATFILE\"");
+}
+
+