[GCCE] We need a way for the HAL config extension to parameterise the HAL config file (.hcf) that will be used, depending upon
the toolchain we are building with. E.g. if we are building BeagleBoard with RVCT we can configure hardware floating point
because we have ARM's vfp math libraries; if we are building it with GCC, we lack this library support.
# 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 strict;
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 -w -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 -w -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 -w -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 -w -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 -w -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 -w -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\"");
}