ROM Tools 13.1.0.1
Bug468 initialized static data built into a static library does not get initialized correctly
# 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\"");
}