diff -r 000000000000 -r 83f4b4db085c sbsv1_os/e32toolp/platform/cl_bpabi.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbsv1_os/e32toolp/platform/cl_bpabi.pm Tue Feb 02 01:39:43 2010 +0200 @@ -0,0 +1,2885 @@ +# 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: +# + +# This package contains routines to handle Base Platform ABI (BPABI) Platforms. +package Cl_bpabi; + +my @commonOptions; +my @thumbOptions; +my @armOptions; +my @kernelOptions; +my @invariantOptions; +my @linkerOptions; +my @archiverOptions; +my @debugFormat; +my $ArmIncDir; +my @ArmLibList; + +my %configVariables; + +#Check if Function call Logger is enabled +my $Function_Call_Logger=&main::IsFunctionCallLogging(); + +# Get the information regarding supporting Compiler Wrapper Option +my $IsCompilerWrapperOption=&main::CompilerWrapperOption(); +my $IsProxyWrapperOption=&main::ProxyWrapperOption(); + +# takes an 'expression' to evaluate with $_ bound to each of the +# remaining args +sub PrintList +{ + my $expr = shift @_; + foreach (@_) { + my $str = eval($expr); + &main::Output($str); + } +} + +sub DepLinkList +{ + my $expr = shift @_; + my @arr; + foreach (@_) { + my $str = eval($expr); + push @arr, $str; + } + return @arr; +} + +require Exporter; +@ISA=qw(Exporter); +@EXPORT=qw( + PMHelp_Mmp + PMPlatProcessMmp + PMStartBldList + PMBld + PMStartSrcList + PMBitMapBld + PMResrcBld + PMStartSrc + PMAifBld + PMSrcDepend + PMSrcBldDepend + PMEndSrcBld + PMEndSrc + PMEndSrcList + PMPrefixFile + PMToolChainIncDir + PMSupportsFeatureVariants +); + +use Cwd; + +# Armutl package does various ancillary things for armedg modules +use Armutl; +use BPABIutl; +use E32Plat; +use RVCT_plat2set; +use gcce_plat2set; + +# This is the RVCT Version information required by Armutl package +my $RVCTMajorVersion; +my $RVCTMinorVersion; +my $RVCTVersion; + +my $GCCEMajorVersion; +my $GCCEMinorVersion; +my $GCCEVersion; + +# The name of the build platform, e.g. ARMV6. +my $PlatName = main::Plat(); + +# The name of the root platform. This is useful if the plaform is derived using a +# BSF file. If the current platform is not derived, $RootName will be the same as +# $PlatName. +my $RootName = E32Plat::Plat_Root($PlatName); + + +# cl_generic package contains generic routines to handle bits of makefiles which are +# common to all of the platforms. Currently it deals with AIF, MBM amd RSC files. +use cl_generic; + +# E32env package contains information for makmake and associated e32tools perl programs +# within the Epoc32 Environment +use E32env; + +# Genutl package contains utility subroutines for MAKMAKE and associated scripts +use Genutl; + +# Modload package is the runtime module-loading routine for loading e32tools modules into +# 'main' module +use Modload; + +use constant NOCOMPRESSIONMETHOD => 0; +use constant INFLATECOMPRESSIONMETHOD => 1; +use constant BYTEPAIRCOMPRESSIONMETHOD => 2; + +use constant NOTPAGED => 0; +use constant UNPAGED => 1; +use constant PAGED => 2; + +use constant NON_DEBUGGABLE => 0; +use constant DEBUGGABLE => 1; +use constant DEBUGGABLE_UDEBONLY => 2; + +my %plat = &main::PlatRec(); +my $CustomizedARMV5Plat = 0; + +if (($plat{'CUSTOMIZES'}) && (($plat{'ROOTPLATNAME'} eq "ARMV5") || ($plat{'ROOTPLATNAME'} eq "ARMV5_ABIV2"))) { +# The following flag is set to handle the exceptions related to ARMV5 toolchain. + $CustomizedARMV5Plat = 1; +} + +#this fucntion will be used for cw_ide platform to update the PlatName and reinitialize the hashtable +sub getVariableForNewPlat +{ + $PlatName = main::Plat(); + undef(%configVariables); +} +sub PMHelp_Mmp { + +# Help Text for ARM Platform, lists out the MMP keywords used incase of ARM Compiler + if($PlatName eq "ARMV5" || $PlatName eq "ARMV5_ABIV2" || $CustomizedARMV5Plat) + { + return &Armutl_Help_Mmp; + } + else + { + return ""; + } +} + +my $ToolChainIncDir; +my @ToolChainLibList; +my $ArmRT = 0; +my %AsmFiles = (); +my %AsmDirs = (); +my $NamedSymLkup = 0; +my $InterWorking = ''; + +sub PMPlatProcessMmp (@) { + &InitToolChain(@_); + $ToolChainIncDir = &GetToolChainIncDir; + &main::SetStdIncPaths($ToolChainIncDir); + @ToolChainLibList = &GetLibList; +# Variable to check if the target forms part of the run time libraries, if it is so +# shouldn't be linked against itself or other runtime libs + $ArmRT = &IsTargetRT; + my @AsmFileList = &GetToolChainAsmFileList; + foreach (@AsmFileList) { $AsmFiles{ucfirst lc $_} = 1; } +} + +my $preinclude; + +my $Makecmd; + +sub PMStartBldList($) { + ($Makecmd) = @_; + my $ABI=&main::ABI; + my $BaseTrg=&main::BaseTrg; + my $BasicTrgType=&main::BasicTrgType; + my @BldList=&main::BldList; + my @ChopSysIncPaths=&main::Path_Chop(&main::SysIncPaths); + my @ChopUserIncPaths=&main::Path_Chop(&main::UserIncPaths); + my $DefFile=&main::DefFile; + my $EPOCPath=&main::EPOCPath; + my $LinkAs=&main::LinkAs; + my $LibPath=&main::LibPath.'LIB\\'; + my @MacroList=&main::MacroList(); + push @MacroList, "__SUPPORT_CPP_EXCEPTIONS__"; + push @MacroList, "__SYMBIAN_STDCPP_SUPPORT__" if ( StdCppTarget() ); + + my $Plat=&main::Plat; + my $Trg=&main::Trg; + my $TrgType=&main::TrgType; + + # This horrible change (presumably to allow GCCE to work with edll.lib etc. + # produced by RVCT breaks SMP (and also breaks any optimized platform + # builds such as ARMV6, and also Thumb2 builds). + # Work round for now by conditioning the horrible change on the absence of + # SMP in the platform definition. + my %PlatHash = &main::PlatRec(); + unless ($PlatHash{SMP}) { + my $myStatLinkPath; + $myStatLinkPath = "$E32env::Data{LinkPath}"; + $myStatLinkPath .= "ARMV5"; + &main::SetStatLinkPath($myStatLinkPath); + } + + my $VariantFile=&ChangeSlash(&main::VariantFile); + + my @UidList=&main::UidList; + my $SystemTrg = &main::SystemTrg; + my $ExportLibrary=&main::ExportLibrary; + my $NoExportLibrary=&main::NoExportLibrary; + # N.B. should get better way to detect kernel probably!! + $SystemTrg = 1 if ($ExportLibrary =~ /EKERN/i); + + # N.B. should get better way to detect this + $SystemTrg = 1 if ($Trg =~ /KSRT/i); + + my %Version = &main::Version(); + my $ExtraExportLibrary; + my $PrimaryExportLibrary = $ExportLibrary; + unless ($Version{explicit}) { + $ExtraExportLibrary = $ExportLibrary; + $ExtraExportLibrary =~ s/\{(\d|a|b|c|d|e|f){8}\}//i; + $PrimaryExportLibrary = $ExtraExportLibrary; + } + +# set up LinkAs + $UidList[2]=~/^0x(.*)$/o; + if ($1 ne '00000000') { # have to make sure than series of noughts in brackets doesn't appear in name for null uids + $LinkAs=join '', &main::Path_Split('Base',$LinkAs),"[$1]",&main::Path_Split('Ext',$LinkAs); + } + + # Required for .lib generation + $InterWorking = ($ABI eq 'ARMV4') ? "" : "--inter"; + + # need to add config file for makmake invocation + my $config_file = BPABIutl_Config_Path($PlatName); + + &main::Output("\n", "include $config_file\n", "\n"); + &Generic_Header(0,$Makecmd, 1); # define standard things using absolute paths and request that a make function + # is provided to provide optional conversion of absolute paths to Unix slashes + +# modified start: makefile improvement + &main::Output( + "CHECKVMAP : CHECKVMAPUDEB CHECKVMAPUREL", + "\n" + ); +# modified end: makefile improvement + if ($Makecmd eq "nmake") { + &main::Output( + "\n", + "PATH=",&main::Path_Drive,$EPOCPath,"gcc\$(PBUILDPID)\\bin;\$(PATH)\n", + "\n" + ); + } + else { + &main::Output( + "\n", + "# must set both PATH and Path to make it work correctly\n", + "Path:=",&main::Path_Drive,$EPOCPath,"gcc\$(PBUILDPID)\\bin;\$(Path)\n", + "PATH:=\$(Path)\n", + "\n" + ); + } + + if ($BasicTrgType=~/^(DLL|EXE)/o) + { + + my $OtherLinkerOpts; + my $toolchain = getConfigVariable('COMPILER_PLAT'); + + # In case of GCCE releases, '--map' option was supported only from build 3.4.3 Q1C release + # Hence this is a special case, where GCCE platform is checked to ensure that the --map option + # is accepted in the correct relase. Even if the option is provided in the config file, it will be + # ignored for versions before 3.4.3 Q1C 2005 release. + + # Check to be included in the Makefile, so that the map filename is provided as input only + # when the MAP option is supplied + + &main::Output("ifdef LINKER_SYMBOLS_MAP_OPTION\n"); + foreach (@BldList) + { + &main::Output("\t$_"."_MAP_FILE=\"\$(EPOCTRG$_)\\".&main::Trg($_).".map\"\n"); + } + &main::Output("else\n"); + foreach (@BldList) + { + &main::Output("\t$_"."_MAP_FILE=\n"); + } + &main::Output("endif\n"); + + # In some compiler toolchains, the start address may be required to be provided using the appropriate option. + # Incase if the option is provided by the toolchain, then pass we need to pass in the start address. + &main::Output( + "\nifdef CODE_SEGMENT_START\n", + "\tCODE_SEGMENT_START += 0x8000 \n", + "endif\n", + ); + + + # In some compiler toolchain, the symboled archives may have to be listed + &main::Output( + "ifdef START_GROUP_SYMBOL\n", + "\tEEXE_OBJECT=\$(START_GROUP_SYMBOL)UC_EXE_.o\$(END_GROUP_SYMBOL)\n", + "\tEDLL_OBJECT=\$(START_GROUP_SYMBOL)UC_DLL_.o\$(END_GROUP_SYMBOL)\n", + "\tDENTRY_OBJECT=\$(START_GROUP_SYMBOL)D_ENTRY_.o\$(END_GROUP_SYMBOL)\n", + "\tLENTRY_OBJECT=\$(START_GROUP_SYMBOL)L_ENTRY_.o\$(END_GROUP_SYMBOL)\n", + "\tXENTRY_OBJECT=\$(START_GROUP_SYMBOL)X_ENTRY_.o\$(END_GROUP_SYMBOL)\n", + "\tVENTRY_OBJECT=\$(START_GROUP_SYMBOL)V_ENTRY_.o\$(END_GROUP_SYMBOL)\n", + "\tKENTRY_OBJECT=\$(START_GROUP_SYMBOL)K_ENTRY_.o\$(END_GROUP_SYMBOL)\n", + "endif\n\n" + ); + + # put the extra linker options from MMP file into the linker flags + $OtherLinkerOpts=&main::LinkerOption($toolchain); + + if($OtherLinkerOpts) { + &main::Output( + "\n# ADDITIONAL LINKER OPTIONS\n", + "ifdef SYMBIAN_UREL_LINK_FLAGS\n", + "\tSYMBIAN_UREL_LINK_FLAGS += $OtherLinkerOpts \n", + "else\n", + "\tSYMBIAN_UREL_LINK_FLAGS = $OtherLinkerOpts \n", + "endif\n", + "ifdef SYMBIAN_UDEB_LINK_FLAGS\n", + "\tSYMBIAN_UDEB_LINK_FLAGS += $OtherLinkerOpts \n", + "else\n", + "\tSYMBIAN_UDEB_LINK_FLAGS = $OtherLinkerOpts \n", + "endif\n\n" + ); + } + } + + &main::Output( + "INCDIR =" + ); + + PrintList("\" \\\$(INCLUDE_OPTION) \$_\"", @ChopUserIncPaths); + PrintList("\" \\\$(INCLUDE_OPTION) \$_\"", @ChopSysIncPaths); + + $ToolchainIncDir = &GetToolChainIncDir; + + if($ToolchainIncDir ne '') + { + &main::Output( + " \$(INCLUDE_OPTION) ","\"$ToolchainIncDir\""); + } + + &main::Output( + "\n", + "\n" + ); + + #Function call logger takes -I as include option + my $FCLogger_inc_option = getConfigVariable('FC_LOGGER_INCLUDE_OPTION'); + if ($Function_Call_Logger) { + &main::Output( + "INCDIR_FCLOGGER =" + ); + PrintList("\" $FCLogger_inc_option \$_\"", @ChopUserIncPaths); + PrintList("\" $FCLogger_inc_option \$_\"", @ChopSysIncPaths); + $ToolchainIncDir = &GetToolChainIncDir; + if($ToolchainIncDir ne '') { + &main::Output( + " $FCLogger_inc_option \"$ToolchainIncDir\"" + ); + } + &main::Output( + "\n", + "\n" + ); + } + + # Set control warnings and errors options for building Standard C++ application + if( StdCppTarget() ) { + &main::Output("CC_WARNINGS_CONTROL_OPTION=\$(CC_STDCPP_WARNINGS_CONTROL_OPTION)","\n"); + &main::Output("CC_ERRORS_CONTROL_OPTION=\$(CC_STDCPP_ERRORS_CONTROL_OPTION)","\n"); + &main::Output("\n", "\n"); + } + + Read_BSF_Options() if ($plat{'CUSTOMIZES'}); + + my $kernelOption=0; + my $buildAsArmOption=0; + my $thumbOption=0; + + if (SysTrg()) + { + $kernelOption=1; + } + elsif (main::BuildAsARM() or ($ABI eq 'ARMV4')) + { + $buildAsArmOption=1; + } + else + { + $thumbOption=1; + } + + my $OtherOpts = undef; + + my $toolchain = getConfigVariable('COMPILER_PLAT'); + + $OtherOpts = &main::CompilerOption($toolchain); + + + if($kernelOption==1) + { + if(@kernelOptions) { +# Kernel options as read from BSF file (KERNEL_OPTIONS keyword) + Set_BSF_Options('KERNEL_OPTIONS',\@kernelOptions); + } + $OtherOpts .= " \$(KERNEL_OPTIONS) "; + } + elsif($buildAsArmOption==1) + { + if(@armOptions) { +# Arm options as read from BSF file (ARM_OPTIONS keyword) + Set_BSF_Options('ARM_OPTIONS',\@armOptions); + } + $OtherOpts .= " \$(ARM_OPTIONS) "; + } + elsif($thumbOption==1) + { + if(@thumbOptions) { +# Thumb options as read from BSF file (THUMB_OPTIONS keyword) + Set_BSF_Options('THUMB_OPTIONS',\@thumbOptions); + } + $OtherOpts .= " \$(THUMB_OPTIONS) "; + } + + if($thumbOption==1 || $buildAsArmOption==1 || $kernelOption ==1 ) + { + if (&main::ARMFPU && (&main::ARMFPU =~ /^VFPV2$/i)) + { + $OtherOpts .= " \$(VFP2MODE_OPTION) "; + } + else + { + $OtherOpts .= " \$(SOFTVFPMODE_OPTION) "; + } + } + + if ($thumbOption==1) + { + $OtherOpts .= " \$(COMPILER_THUMB_DEFINES) "; + } + + $OtherOpts .= " \$(COMPILER_INTERWORK_DEFINES) "; + + # Options to export symbols by default, for OE + if($TrgType=~/^STDDLL$/o || $TrgType=~/^STDEXE$/o || $TrgType=~/^STDLIB$/o) { + $OtherOpts .= " \$(OE_OPTIONS) "; + } + + if($OtherOpts) + { + &main::Output( + "OTHEROPTIONS=$OtherOpts", + "\n", + "CCFLAGS += \$(OTHEROPTIONS)", + "\n" + ); + } + + if(@invariantOptions) { +# Invariant options as read from BSF file (INVARIANT_OPTIONS keyword) + Set_BSF_Options('INVARIANT_OPTIONS',\@invariantOptions); + } + + if(@commonOptions) { +# Common options as read from BSF file (COMMON_OPTIONS keyword) + Set_BSF_Options('COMMON_OPTIONS',\@commonOptions); + } + + if(@linkerOptions) { +# Linker options as read from BSF file (LD_OPTIONS keyword) + Set_BSF_Options('LD_OPTIONS',\@linkerOptions); + } + + if ($BasicTrgType=~/^LIB$/o) { + if(@archiverOptions) { +# Archiver options as read from BSF file (AR_OPTIONS keyword) + Set_BSF_Options('AR_OPTIONS',\@archiverOptions); + } + } + + if(@debugFormat) { + Set_BSF_Options('DEBUG_FORMAT',\@debugFormat); + } + + &main::Output( + "CCDEFS = \$(COMPILER_DEFINES) " + ); + + PrintList("\" -D\$_\"", @MacroList); + + &main::Output( + " \$(PLATFORM_DEFINES) " + ); + + &main::Output( + + ); + + if($kernelOption==1) + { + &main::Output( + "-D__KERNEL_MODE__ " + ); + } + + if($VariantFile){ + #Function Call Logger + if ($Function_Call_Logger) { + #FC Logger accepts product include file without path + my $file=&main::Path_Split('File', &main::VariantFile); + &main::Output( + " -D\"__PRODUCT_INCLUDE__=\\\"${file}\\\"\"" + ); + } + else { + &main::Output( + " -D__PRODUCT_INCLUDE__=\\\"${VariantFile}\\\"" + ); + } + } + + &main::Output( + " \$(USERDEFS)\n", + "\n" + ); + + if ( $RootName =~ /^ARMV5$/ ) { + # Now we know that the platform is either ARMV5 or a platform derived from + # ARMV5 (BSF). + + # See if an environment variable overrides the default DWARF version for + # this platform. + + my $env_dwarf_key = "ABLD_${PlatName}_DWARF"; + my $env_dwarf_val = $ENV{$env_dwarf_key}; + + if ($env_dwarf_val) { + main::FatalError("The value of $env_dwarf_key is invalid.") unless ($env_dwarf_val =~ /^[23]$/); + main::FatalError("We don't support DWARF-2 on ARMV7.") if ($PlatName =~ /^ARMV7/ && $env_dwarf_val == 2); + + &main::Output( "DEBUG_FORMAT=\$(DEBUG_FORMAT_DWARF$env_dwarf_val)\n\n"); + } + } + + + foreach (@BldList) { + &main::Output( + "CC$_ = ", $IsProxyWrapperOption ? "$ENV{ABLD_COMPWRAP} ":"", "\$(CC) " + ); + + # SYMBIAN_UDEB/UREL_CCFLAGS don't have the optimisation levels. + if(&main::DebugSwitchUsed() ){ + if(&main::SymbolicDebugEnabled() ) { + &main::Output( + " \$(SYMBIAN_UDEB_CCFLAGS) " + ); + } + else { + &main::Output( + " \$(SYMBIAN_UREL_CCFLAGS) " + ); + } + } + elsif (/DEB$/o) { + &main::Output( + " \$(SYMBIAN_UDEB_CCFLAGS) " + ); + } + else { + &main::Output( + " \$(SYMBIAN_UREL_CCFLAGS) " + ); + + } + #Set the optimisation levels depending on whether it is a UREL or a UDEB build + if (/DEB$/o) { + &main::Output( + " \$(DEBUG_OPTIMISATION) " + ); + } + else { + &main::Output( + " \$(REL_OPTIMISATION) " + ); + } + + &main::Output( + "\$(RUNTIME_SYMBOL_VISIBILITY_OPTION) " + ); + + if($kernelOption == 0) + { + &main::Output( + "\$(EXCEPTIONS) " + ); + } + &main::Output( + '$(CCFLAGS) ' + ); + + my @ml = &main::MacroList($_); + PrintList("\" -D\$_\"", @ml); + + &main::Output( + " \$(CCDEFS)\n" + ); + my @mmpReplaceOptions = &main::ReplaceOptions($toolchain); + + if (@mmpReplaceOptions) + { + my $OptionPrefix = getConfigVariable('OPTION_PREFIX'); + my $Pattern; + + # Set the value of '$Pattern' which is required to segregate one option from another based on the option prefix. + if($OptionPrefix) + { + $Pattern = $OptionPrefix.'\S+\s*(?!'.$OptionPrefix.')\S*'; + } + else + { + # If option prefix is not set in the configuration make file, then set default + # option prefix as '-' or '--'. + $Pattern = '-{1,2}\S+\s*(?!-)\S*'; + } + + foreach my $options (@mmpReplaceOptions) + { + my @opts = $options =~ /$Pattern/g; + my $count = 0; + + while ($count <= $#opts) + { + my $opt; + my $rep; + if ($opts[$count] =~ /^(\S+)\s+(\S+)$/) + { + $opt = $1; + $rep = $2; + &main::Output( + "CC$_ := \$(subst $opt ,@@,\$(CC$_))\n", + "CC$_ := \$(CC$_:@@%=$opt $rep)", + "\n" + ); + $count++; + } + else + { + $opt = $opts[$count]; + $rep = $opts[$count+1]; + + # Substitute '=' with '%' which is a wild card character in makefile. + $opt =~ s/=/%/; + + &main::Output( + "CC$_ := \$(CC$_:$opt=$rep)", + "\n" + ); + $count+=2; + } + } + } + } + &main::Output( + "\n" + ); + } + + &main::Output( + "\n" + ); + + #Function call logger + if ($Function_Call_Logger) { + #Send all the debug macros to logger + foreach (@BldList) { + &main::Output + ( + "FCLOGGER$_ = ", + $EPOCPath, + "tools\\fc_logger\\edgcpfe" + ); + + my @ml = &main::MacroList($_); + PrintList("\" -D\$_\"", @ml); + if ($thumbOption==1) { + &main::Output( + " \$(COMPILER_THUMB_DEFINES)" + ); + } + &main::Output(" \$(COMPILER_INTERWORK_DEFINES)", + " \$(CCDEFS)", + " \$(FC_LOGGER_DEFINES)", + " \$(FC_LOGGER_OPTION)"); + &main::Output( + "\n", + "\n" + ); + } + } + + foreach (@BldList) { + &main::Output( + "$_ :" + ); + + if ($BasicTrgType !~ /IMPLIB/io) { + &main::Output ( + " \\\n\t", + &Generic_Quote("\$(EPOCTRG$_)\\".&main::Trg($_)) + ); + } + +# lib has to come after the main target so that a .DEF file will be generated if the project is not frozen + if ($DefFile and not &main::ExportUnfrozen) { + &main::Output( + " \\\n", + "\tLIBRARY\n" + ); + } + &main::Output( + "\n", + "\n" + ); + } + + # Resource building is done entirely via cl_generic.pm + PrintList("\"\nRESOURCE\$_ : MAKEWORK\$_\"", @BldList); + &main::Output( + "\n", + "\n", + ); + + &main::Output( + "LIBRARY : MAKEWORKLIBRARY" + ); + if ($BasicTrgType=~/^LIB$/o) { +# code to ensure that the static libraries for all builds are built at the library stage + PrintList("\" \$_\"", @BldList); + } + elsif ($DefFile and !$NoExportLibrary) { + unless (&main::ExportUnfrozen) { + if (-e $DefFile) { # effectively "if project frozen ..." + if ($PlatName =~ /^ARMV5$/) { + &main::Output( + " ", &Generic_Quote("\$(EPOCLIB)\\LIB\\$PrimaryExportLibrary.dso"), + " ", &Generic_Quote("\$(EPOCLIB)\\LIB\\$PrimaryExportLibrary.lib"), "\n" + ); + } + else { + &main::Output( + " ", &Generic_Quote("\$(EPOCLIB)\\LIB\\$PrimaryExportLibrary.dso"), "\n" + ); + } + } + else { + &main::Output( + "\n", + "\t\@echo WARNING: Not attempting to create any import libraries.\n", + "\t\@echo When exports are frozen in \"$DefFile\", regenerate Makefile.\n" + ); + } + } else { + &main::Output( + "\n", + "\t\@echo Not attempting to create \"\$(EPOCLIB)\\LIB\\$PrimaryExportLibrary.dso\"\n", + "\t\@echo from frozen .DEF file, since EXPORTUNFROZEN specified.\n" + ); + } + + my $theDefFile = $DefFile; + $theDefFile = "\$(EPOCBLD)\\$BaseTrg.def" unless (-e $DefFile); + &main::Output( + "\n", + "\n", + "# REAL TARGET - LIBRARY (.dso) \n", + "\n", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExportLibrary.dso"), " : ", + &Generic_Quote($DefFile), "\n", + "\tperl -S prepdef.pl ", &Generic_Quote($DefFile), " \"\$(EPOCBLD)\\$ExportLibrary.prep.def\"\n", + "\telf2e32 --definput=\"\$(EPOCBLD)\\$ExportLibrary.prep.def\" --dso=", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExportLibrary.dso"), + " --linkas=$LinkAs\n", + "\n" + ); + if ($ExtraExportLibrary) { + &main::Output( + "\n", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExtraExportLibrary.dso"), " : ", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExportLibrary.dso"), "\n", + "\tcopy \"\$<\" \"\$@\"\n" + ); + } + + # Generate .lib files which will be used for ARMV5_ABIV1 platform (ABIV1 mode toolchain) + # Only for ARMV5 platform + if ($PlatName =~ /^ARMV5$/) + { + &main::Output( + "\n", + "\n", + "# REAL TARGET - LIBRARY (.lib) \n", + "\n", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExportLibrary.lib"), " : ", + &Generic_Quote($DefFile), "\n", + "\tperl -S prepdef.pl ", &Generic_Quote($DefFile), " \"\$(EPOCBLD)\\$ExportLibrary.prep.def\"\n", + "\tdef2dll.bat --path=\$(EPOCLIB)\\LIB \\\n\t\t--bldpath=\$(EPOCBLD) \\\n\t\t--import=$ExportLibrary \\\n", + "\t\t--deffile=\"\$(EPOCBLD)\\$ExportLibrary.prep.def\" \\\n\t\t--linkAs=$LinkAs \\\n\t\t$InterWorking\n", + "\n", + ); + if ($ExtraExportLibrary) { + &main::Output( + "\n", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExtraExportLibrary.lib"), " : ", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$ExportLibrary.lib"), "\n", + "\tcopy \"\$<\" \"\$@\"\n" + ); + } + } + } + + my $freezeDir = &main::Path_Split('Path', $DefFile); + chop($freezeDir); + + # dummy rule for def files to cope with filename case differences + unless (&main::ExportUnfrozen) { + if (-e $DefFile) { # effectively "if project frozen ..." + &main::Output( + "\n", + "\n", + &Generic_Quote($DefFile), " : ", "\n", + "\t\@rem Do nothing\n", + ); + } + } + + &main::Output( + "\n", + "\n", + &Generic_Quote($freezeDir), " : ", "\n", + "\tperl -S emkdir.pl \$\@\n", + ); + + &main::Output( + "\n", + "\n", + "FREEZE : ", + &Generic_Quote($freezeDir), "\n", + ); + if ($DefFile and $BasicTrgType!~/^IMPLIB$/io) { +# call perl on the script here so make will die if there are errors +# - this doesn't happen if calling perl in a batch file + &main::Output( "\tperl -S efreeze.pl \$(EFREEZE_ALLOW_REMOVE) \"$DefFile\" \"\$(EPOCBLD)\\$ExportLibrary.def\" \n" ); + } + else { + &main::Output( "\tperl -e \"print \\\"warning: freeze could not be supported or \\ + you need to declare an explicitly specified def file using the keyword \\ + DEFFILE in the MMP file!\\n\\\"\""); + } + &main::Output( + "\n", + "CLEANLIBRARY :\n" + ); + if ($DefFile and !$NoExportLibrary) { + &main::Output( + "\t-\$(ERASE) \"\$(EPOCLIB)\\LIB\\$ExportLibrary.dso\"\n" + ); + if ($ExtraExportLibrary) { + &main::Output( + "\t-\$(ERASE) \"\$(EPOCLIB)\\LIB\\$ExtraExportLibrary.dso\"\n" + ); + } + } + &main::Output( + "\n", + "\n" + ); + &Generic_MakeWorkDir('MAKEWORKLIBRARY',"${LibPath}"); + + &Generic_Releaseables; +} + + +sub PMBld { + + my $ABI=&main::ABI; + my @ASSPLibList=&main::ASSPLibList; + my @SrcList=&main::SrcList; + my $FeatureVariantBaseTrg=&main::FeatureVariantBaseTrg; + my $Bld=&main::Bld; + my $ChopBldPath=&main::Path_Chop(&main::BldPath); + my $DefFile=&main::DefFile; + my $EPOCIncPath=&main::EPOCIncPath; + my $FirstLib=&main::FirstLib; + my $BasicTrgType=&main::BasicTrgType; + my @LibList; + my @RTLibList = &GetRTLibList(); + my $SystemTrg = &main::SystemTrg; + my $LibPath= &main::LibPath; + my $LinkAs=&main::LinkAs; + my $ExportLibrary=&main::ExportLibrary; + my $NoExportLibrary=&main::NoExportLibrary; + # N.B. should get better way to detect kernel probably!! + $SystemTrg = 1 if ($ExportLibrary =~ /EKERN/i); + my $ChopRelPath=&main::Path_Chop(&main::RelPath); + my $RelPath=&main::RelPath; + my @StatLibList=&main::StatLibList; + my $StatLinkPath=&main::StatLinkPath; + my $Trg=&main::Trg; + my $TrgType=&main::TrgType; + my @UidList=&main::UidList; + my %Version = &main::Version(); + my $ExtraExportLibrary; + unless ($Version{explicit}) { + $ExtraExportLibrary = $ExportLibrary; + $ExtraExportLibrary =~ s/\{(\d|a|b|c|d|e|f){8}\}//i; + } + my $objectFiles; + + if ($Bld =~ /DEB/) { + @LibList = &main::DebugLibList; + } else { + @LibList = &main::LibList; + } + +# set up $LinkAs + $UidList[2]=~/^0x(.*)$/o; + if ($1 ne '00000000') { # have to make sure than series of noughts in brackets doesn't appear in name for null uids + $LinkAs=join '', &main::Path_Split('Base',$LinkAs),"[$1]",&main::Path_Split('Ext',$LinkAs); + } + + + # REAL TARGETS + #------------- + &main::Output( + "# REAL TARGET - BUILD VARIANT $Bld\n", + "\n" + ); + +# releasables + my @releaseables; + + push @releaseables, "$RelPath$Trg" if ($BasicTrgType!~/^IMPLIB$/io); + if ($BasicTrgType=~/^(DLL|EXE)$/o) { + push @releaseables, "$RelPath$Trg.map"; + } + if (-e $DefFile and !$NoExportLibrary) { # effectively "if project frozen ..." + push @releaseables, "$LibPath$ExportLibrary.dso"; + push @releaseables, "$LibPath$ExtraExportLibrary.dso" if ($ExtraExportLibrary); + if ($PlatName =~ /^ARMV5$/) { + push @releaseables, "$LibPath$ExportLibrary.lib"; + push @releaseables, "$LibPath$ExtraExportLibrary.lib" if ($ExtraExportLibrary); + } + } + + push @releaseables, &main::FeatureVariantVMapFile() if &main::FeatureVariantVMapFile(); + + &main::Output( + "WHAT$Bld : WHATGENERIC\n", + "\n", + "CLEAN$Bld : CLEANBUILD$Bld CLEANRELEASE$Bld\n", + "\n", + "CLEANBUILD$Bld : \n", + "\t\@perl -S ermdir.pl \"\$(EPOCBLD$Bld)\"\n", + "\n", + "CLEANRELEASE$Bld : CLEANGENERIC\n", + "\n" + ); + + &Generic_WhatTargets($Bld, "WHAT$Bld", @releaseables); + my @cleantargets = (@releaseables, "$RelPath$ExtraExportLibrary.sym"); + + if (-e $DefFile and !$NoExportLibrary) { # effectively "if project frozen ..." + &Generic_CleanTargets($Bld, "CLEANRELEASE$Bld", @cleantargets); + } + else { + push @cleantargets, "$LibPath$ExportLibrary.dso"; + push @cleantargets, "$LibPath$ExtraExportLibrary.dso" if ($ExtraExportLibrary); + if ($PlatName =~ /^ARMV5$/) { + push @cleantargets, "$LibPath$ExportLibrary.lib"; + push @cleantargets, "$LibPath$ExtraExportLibrary.lib" if ($ExtraExportLibrary); + } + &Generic_CleanTargets($Bld, "CLEANRELEASE$Bld", @cleantargets); + } + + &Generic_MakeWorkDir("MAKEWORK$Bld",$ChopBldPath); + &Generic_MakeWorkDir("MAKEWORK$Bld",$ChopRelPath); + + return if ($BasicTrgType=~/^IMPLIB$/io); + + &main::Output( + "LISTING$Bld : MAKEWORK$Bld" + ); + foreach (@SrcList) { + my $BaseSrc = &main::Path_Split('Base', $_); + my $Ext = &main::Path_Split('Ext', $_); + if ($Ext =~ /cia/i && ($PlatName ne "GCCE")) { + $BaseSrc = "$BaseSrc\_"; + } + &main::Output( + " \\\n\tLISTING$Bld$BaseSrc" + ); + } + &main::Output( + "\n", + "\n" + ); + #Compiler wrapper support starts + if($IsCompilerWrapperOption) + { + my $Platcmpwrap=&main::Plat; + + &main::Output( + "COMPWRAP$Bld : OUTPUT_NAME = ", + "$Platcmpwrap\_$Bld", + "\n" + ); + + &main::Output( + "COMPWRAP$Bld : MAKEWORK$Bld" + ); + + foreach (@SrcList) { + my $BaseSrc = &main::Path_Split('Base', $_); + &main::Output( + " \\\n\tCOMPWRAP$Bld$BaseSrc" + ); + } + + &main::Output( + "\n", + "\n" + ); + } + #--Compiler wrapper support ends + + # Flag that tells us wheter to run checklib.exe on user-added static libraries. + my $run_checklib = 0; + + if (@StatLibList && $BasicTrgType =~ /^(EXE|DLL)$/o && !$SystemTrg && main::StdCppSupport()) { + # There are user-added static libraries. They should be checked for + # consistent use of operator new. + $run_checklib = 1; + + #Create a make variable for the libraries. + main::Output("\nUSER_ADDED_ARCHIVES_$Bld="); + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\"\\\$\(EPOCSTATLINK$Bld\)\\\\\$_\"\)", @StatLibList); + main::Output("\n\n"); + } + + &main::Output( + "LIBS$Bld=" + ); + + my @depLibs; + if ($BasicTrgType=~/^DLL$/o) { # Add the DLL stub library + &main::Output( + " \\\n\t", + &Generic_Quote("\$(EPOCSTATLINK$Bld)\\EDLLSTUB.lib") + ); + push @depLibs, &Generic_Quote("\$(EPOCSTATLINK$Bld)\\EDLLSTUB.lib"); + } + + my $StaticRTLib = ""; + + + if ($SystemTrg) { + $StaticRTLib = "ksrt"; + } + else { + $StaticRTLib = "usrt"; + } + + if ($RVCTVersion) { + $StaticRTLib .= $RVCTVersion; + } + elsif ($GCCEVersion) { + if ($GCCEMajorVersion < 4) { + $StaticRTLib .= "2_2"; + } + else { + $StaticRTLib .= "3_1"; + } + } + else { + $StaticRTLib .= "2_2"; + } + + &main::Output(" \\\n\$(EPOCSTATLINK$Bld)\\$StaticRTLib\.lib"); + + &main::Output(" \\\n\t",getConfigVariable('VIA_FILE_PREFIX')); + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\"\\\$\(EPOCBSFSTATLINK$Bld\)\\\\\$_\"\)", @StatLibList); + &main::Output(" \\\n\t",getConfigVariable('VIA_FILE_SUFFIX')); + + @depLibs = (@depLibs, DepLinkList("\&Generic_Quote\(\"\\\$\(EPOCBSFSTATLINK$Bld\)\\\\\$_\"\)", @StatLibList)); + + + my @ImportLibList = ImportLibraryList(@LibList); + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\"\\\$\(EPOCLIB\)\\\\LIB\\\\\$_\"\)", @ImportLibList); + @depLibs = (@depLibs, DepLinkList("\&Generic_Quote\(\"\\\$\(EPOCLIB\)\\\\LIB\\\\\$_\"\)", @ImportLibList)); + + if ($TrgType=~/^STDEXE$/o || $TrgType=~/^STDDLL$/o) { + $NamedSymLkup = 1; + my @OEImportLibraryList = &GetOEImportLibList(); + @OEImportLibraryList = ImportLibraryList(@OEImportLibraryList); + if(not (grep /^libc.dso$/i, @LibList)) { + push @OEImportLibraryList, "libc.dso"; + } + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\"\\\$\(EPOCLIB\)\\\\LIB\\\\\$_\"\)", @OEImportLibraryList); + @depLibs = (@depLibs, DepLinkList("\&Generic_Quote\(\"\\\$\(EPOCLIB\)\\\\LIB\\\\\$_\"\)", @OEImportLibraryList)); + } + + unless ($ArmRT || ($BasicTrgType=~/^LIB$/o)) { + my $TargLib = "$ExportLibrary.dso"; + $TargLib =~ s/\{(\d|a|b|c|d|e|f){8}\}//i; + unless ($SystemTrg) { + foreach (@RTLibList) { + # Ignore the empty file name Modified by Kun Xu for DEF126030 on 06/08/2008 + if(!$_) + { + next; + } + &main::Output( + " \\\n\t", + &Generic_Quote("\$(EPOCLIB)\\LIB\\$_") + ) unless ($_ =~ /$TargLib/i); + push @depLibs, &Generic_Quote("\$(EPOCLIB)\\LIB\\$_") unless ($_ =~ /$TargLib/i); + } + } + } + #OE Glue Code + if ($TrgType=~/^STDEXE$/o) { + my @OELibList = &GetOELibList(); + foreach (@OELibList) { + &main::Output( + " \\\n\t", + &Generic_Quote("\$(EPOCSTATLINK$Bld)\\$_"), + ); + push @depLibs, &Generic_Quote("\$(EPOCSTATLINK$Bld)\\$_"); + } + } + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\"\$_\"\)", @ToolChainLibList); + + &main::Output( + "\n", + "\n" + ); + + main::Output( + "LIBS$Bld" . "DEPS=" + ); + + my @tmp; + for my $lib (@depLibs) + { + $lib =~ s/\(.*\.o\)//; + $lib =~ s/\\$//; + push @tmp, $lib unless ($lib =~ /-\(/ || $lib =~ /-\)/); + } + + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\"\$_\"\)", @tmp); + + &main::Output( + "\n", + "\n" + ); + + &main::Output( + "VTBLEXPORTS$Bld=" + ); + my $vtobj = quotemeta("(VtblExports.o)"); + &main::Output( + "\n", + "\n" + ); + + &main::Output( + "OBJECTS$Bld=" + ); + foreach (@SrcList) { + my $BaseSrc = &main::Path_Split('Base', $_); + my $Ext = &main::Path_Split('Ext', $_); + if ($Ext =~ /cia/i && ($PlatName ne "GCCE")) { + $BaseSrc = "$BaseSrc\_"; + } + + &main::Output( + " \\\n\t", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.o") + ); + + $objectFiles .= &main::BldPath.$BaseSrc.".o "; + } + &main::Output( + "\n", + "\n" + ); + + # IsCustomDllUseCase() subroutine is called to check if the given executable + # is a custom dll or not. + my $IsCustomDll = IsCustomDllUseCase(); + + if ($IsCustomDll) + { + # Generate ".bin" file(assembly listing file) only if frozen deffile is present and EXPORTUNFROZEN is not specified + # in the Mmp file. + if((-e $DefFile) && (!&main::ExportUnfrozen)) + { + &main::Output( + "EXPFILE$Bld = \$(EPOCBLD$Bld)\\$ExportLibrary.bin \n", + "\n" + ); + } + else + { + &main::Output( + "EXPFILE$Bld = \n", + "\n" + ); + } + } + + # Create "via" file containing all object files in order to reduce + # command line lengths in pertinent calls + my $objectsViaFile = &main::CommandFile(); + my $viaoption = getConfigVariable('COMMANDFILE_OPTION'); + + if ($BasicTrgType=~/^LIB$/o && StdCppTarget() ) { + + # Add the magic object that identifies the library as a STDLIB. + $objectFiles .= "$ENV{EPOCROOT}epoc32/tools/tag/tag_elf"; + } + + $objectFiles =~ s/\\/\//g ; + + &main::CreateExtraFile($objectsViaFile, $objectFiles); + + &main::Output( + &Generic_Quote("\$(EPOCTRG$Bld)\\$Trg"), + " : \$(OBJECTS$Bld) \$(LIBS". $Bld . "DEPS)" + ); + + if (-e $DefFile) { # effectively "if project frozen ..." + &main::Output( + " ", &Generic_Quote($DefFile) + ); + } + + if($IsCustomDll eq 1) + { + &main::Output( " \$(EXPFILE$Bld) " ); + } + + &main::Output("\n"); + + +# get rid of any -symbols produced .map file + if ($BasicTrgType=~/^(DLL|EXE)/o) { + &main::Output( + "\t-\$(ERASE) \"\$(EPOCTRG$Bld)\\$Trg.map\" \n" + ); + } + + my $AbsentSubst = ''; + if ($BasicTrgType=~/^(DLL|EXE)/o) { + + if ($run_checklib) { + my $checklib = "checklib"; + + if ( StdCppTarget() ) { + $checklib .= " stdc++ --elf"; + } + else { + $checklib .= " symc++ --elf"; + } + + &main::Output( "\t$checklib ","\$(USER_ADDED_ARCHIVES_$Bld)\n" ); + } + + my $WrapLD = $IsProxyWrapperOption ? "$ENV{ABLD_COMPWRAP} " : ""; + if ($Bld =~ /DEB/) + { + if($PlatName ne "GCCE"){ + # if the compiler is RVCT then append SYMBIAN_UDEB_LINK_FLAGS to option string + # in order to override the default ones. + &main::Output( + "\t", $WrapLD, "\$(LD) ","\$(STATIC_LIBS) ", "\$(SHARED_OBJECT_OPTION) ", + "\$(CODE_SEGMENT_START) ", "\$(DATA_SEGMENT_START) 0x400000 ", "\$(SYMVER_OPTION) ", "\$(SYMBIAN_UDEB_LINK_FLAGS) ", "\$(SO_NAME_OPTION) ","$LinkAs" + ); + } else { + &main::Output( + "\t", $WrapLD, "\$(LD) ","\$(STATIC_LIBS) ","\$(SYMBIAN_UDEB_LINK_FLAGS) ", "\$(SHARED_OBJECT_OPTION) ", + "\$(CODE_SEGMENT_START) ", "\$(DATA_SEGMENT_START) 0x400000 ", "\$(SYMVER_OPTION) ","\$(SO_NAME_OPTION) ","$LinkAs" + ); + } + } + else + { + if($PlatName ne "GCCE"){ + # if the compiler is RVCT then append SYMBIAN_UREL_LINK_FLAGS to option string + # in order to override the default ones. + &main::Output( + "\t", $WrapLD, "\$(LD) ","\$(STATIC_LIBS) ","\$(SHARED_OBJECT_OPTION) ", + "\$(CODE_SEGMENT_START) ", "\$(DATA_SEGMENT_START) 0x400000 ", "\$(SYMVER_OPTION) ", "\$(SYMBIAN_UREL_LINK_FLAGS) ", "\$(SO_NAME_OPTION) ", "$LinkAs" + ); + } else { + &main::Output( + "\t", $WrapLD, "\$(LD) ","\$(STATIC_LIBS) ","\$(SYMBIAN_UREL_LINK_FLAGS) ","\$(SHARED_OBJECT_OPTION) ", + "\$(CODE_SEGMENT_START) ", "\$(DATA_SEGMENT_START) 0x400000 ", "\$(SYMVER_OPTION) ","\$(SO_NAME_OPTION) ","$LinkAs" + ); + } + } + + if(&main::DebugSwitchUsed()){ + if(&main::SymbolicDebugEnabled() ) { + &main::Output( + " \$(LINKER_DEBUG_OPTION) " + ); + } + else { + &main::Output( + " \$(LINKER_NODEBUG_OPTION) " + ); + } + } + elsif($Bld =~/DEB/){ + &main::Output( + " \$(LINKER_DEBUG_OPTION) " + ); + } + else { + &main::Output( + " \$(LINKER_NODEBUG_OPTION) " + ); + } + + my $EntrySymbol; + if ($BasicTrgType=~/^DLL$/o) { + $EntrySymbol = '_E32Dll'; + } + elsif ($BasicTrgType=~/^EXE$/o) { + $EntrySymbol = '_E32Startup'; + } + if ($EntrySymbol) { + $AbsentSubst = " --absent $EntrySymbol"; + } + + if (($BasicTrgType=~/^DLL$/o) || ($BasicTrgType=~/^EXE$/o)) { + &main::Output( + " \$(LINKER_ENTRY_OPTION)", + " $EntrySymbol " + ); + my $undefined_option = getConfigVariable('UNDEFINED_SYMBOL_REF_OPTION'); + if ($undefined_option) + { + &main::Output( + " \$(UNDEFINED_SYMBOL_REF_OPTION)", + " $EntrySymbol " + ); + } + } + + if ($BasicTrgType=~/^DLL$/o) { + # get the right object file for the entry point + my $ObjFile="\$(EDLL_OBJECT)"; + if ($FirstLib =~ /EDEV/i) { + $ObjFile="\$(DENTRY_OBJECT)"; + } + if ($FirstLib =~ /EKLL/i) { + $ObjFile="\$(LENTRY_OBJECT)"; + } + if ($FirstLib =~ /EEXT/i) { + $ObjFile="\$(XENTRY_OBJECT)"; + } + if ($FirstLib =~ /EVAR/i) { + $ObjFile="\$(VENTRY_OBJECT)"; + } + + &main::Output( + " \$(EPOCSTATLINK$Bld)\\$FirstLib", "$ObjFile", + " \$(EPOCSTATLINK$Bld)\\$FirstLib", " \\", "\n" + ); + } elsif ($BasicTrgType=~/^EXE$/o || $TrgType=~/^EXEXP$/o) { + # get the right object file for the entry point + my $ObjFile="\$(EEXE_OBJECT)"; + if ($FirstLib =~ /KC_EXE/i) { + $ObjFile="\$(KENTRY_OBJECT)"; + } + + &main::Output( + " \$(EPOCSTATLINK$Bld)\\$FirstLib", "$ObjFile", + " \$(EPOCSTATLINK$Bld)\\$FirstLib", " \\", "\n" + ); + } + + &main::Output( + "\t\t\$(LINKER_OUTPUT_OPTION) \"\$(EPOCBLD$Bld)\\$Trg\" \\\n", +# "\t\t\$(OBJECTS$Bld) \\\n" + ); + + &main::Output( + "\t\t\$(LINKER_SYMBOLS_MAP_OPTION) ", + "\$(","$Bld","_MAP_FILE) \\\n" + ); + + # Pass in the command file if the command file option is passed in + if($viaoption) { + #'@' is for GCCE whos version is not 3.4.3 + if($viaoption eq '@'){ + main::Output( + "\t\t$viaoption$objectsViaFile \\\n" + ); + } + #'-via' is for RVCT + else{ + main::Output( + "\t\t$viaoption $objectsViaFile \\\n" + ); + } + } + else { + &main::Output( + "\t\t\$(OBJECTS$Bld) \\\n" + ); + } + + if($IsCustomDll eq 1) { + &main::Output( "\t\t\$(EXPFILE$Bld) \\\n" ); + } + + &main::Output( + "\t\t\$(LIBS$Bld) \\\n", + "\t\t\$(VTBLEXPORTS$Bld) \$(USERLDFLAGS) \n" + ); + + if(&main::DebugSwitchUsed() ){ + if(&main::SymbolicDebugEnabled() ) { + &main::Output( + "\tcopy \"\$(EPOCBLD$Bld)\\$Trg\" \"\$(EPOCTRG$Bld)\\$FeatureVariantBaseTrg.sym\"\n" + ); + } + } + elsif ($Bld=~/^U?DEB$/o) { + &main::Output( + "\tcopy \"\$(EPOCBLD$Bld)\\$Trg\" \"\$(EPOCTRG$Bld)\\$FeatureVariantBaseTrg.sym\"\n" + ); + } + if (-e $DefFile) { + &main::Output( + "\tcopy ", &Generic_Quote(("\"$DefFile\"")), " \"\$(EPOCBLD)\\$ExportLibrary.prep.def\"\n", + ); + } + + &main::Output( + "\telf2e32 --sid=", &main::SecureId(), " " + ); + + if (&main::IsDebuggable eq DEBUGGABLE) { + &main::Output( + ' --debuggable ' + ); + } + + if (&main::IsDebuggable eq DEBUGGABLE_UDEBONLY) { + if ($Bld=~/^UDEB$/o) { + &main::Output( + ' --debuggable ' + ); + } + } + + # Do not export Arm Static Library Symbols + if (&Armutl_ArmLibList) { + &main::Output( + ' --excludeunwantedexports' + ); + } + + if ($IsCustomDll eq 1) { + &main::Output( + ' --customdlltarget' + ); + } + if (keys(%Version)) { + &main::Output( + ' --version=', &Genutl_VersionToUserString(%Version) + ); + } + # exexps are allowed data, but they look like dlls to elftran.... + if (&main::AllowDllData || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) { + &main::Output( + ' --dlldata' + ); + } + if (&main::DataLinkAddress) { + &main::Output( + ' --datalinkaddress=',&main::DataLinkAddress + ); + } + if (&main::FixedProcess) { + &main::Output( + ' --fixedaddress' + ); + } + if (&main::HeapSize) { + my %HeapSize=&main::HeapSize; + &main::Output( + ' --heap=',$HeapSize{Min},',',$HeapSize{Max} + ); + } + if (&main::ProcessPriority) { + &main::Output( + ' --priority=',&main::ProcessPriority + ); + } + if (&main::StackSize) { + &main::Output( + ' --stack=',&main::StackSize + ); + } + &main::Output( + "\\\n\t\t" + ); + + my $i=1; + foreach (@UidList) { + &main::Output( + " --uid$i=$_" + ); + $i++; + } + if(&main::VendorId) { + &main::Output( + ' --vid=',&main::VendorId + ); + } + &main::Output( + "\\\n\t\t" + ); + + &main::Output( + ' --capability=',&main::Capability + ); + + my $vfpv2_support = getConfigVariable('VFP2MODE_OPTION'); + if ($vfpv2_support && &main::ARMFPU && (&main::ARMFPU =~ /^VFPV2$/i)) + { + &main::Output( + ' --fpu=vfpv2' + ); + } + else + { + &main::Output( + ' --fpu=softvfp' + ); + } + + if (&main::SmpSafe) + { + &main::Output( + ' --smpsafe' + ); + } + + + if(($BasicTrgType=~/^DLL/ && $TrgType!~/^DLL/ ) || $TrgType=~/^EXEXP/ || $TrgType=~/^STDEXE/){ + &main::Output( + ' --targettype=',$TrgType + ); + } + else{ + &main::Output( + ' --targettype=',$BasicTrgType + ); + } + + &main::Output( + ' --output=',"\"\$\@\"" + ); + if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) { + if (-e $DefFile) { + &main::Output( + ' --definput=',"\"\$(EPOCBLD)\\$ExportLibrary.prep.def\"" + ); + } + # Non-callable exports will be ignored if the MMP file does not contain the DEFFILE keyword or contains the NOEXPORTLIBRARY keyword + if (!($DefFile) || $NoExportLibrary) { + &main::Output( " --ignorenoncallable" ); + } + &main::Output( + ' --dso=', + &Generic_Quote("\$(EPOCBLD$Bld)\\$ExportLibrary.dso") + ); + &main::Output( + ' --defoutput=', + &Generic_Quote("\$(EPOCBLD$Bld)\\$ExportLibrary.def") + ); + if(&main::ExportUnfrozen) { + &main::Output( ' --unfrozen '); + } + } + #the input elf file - as the last arg + &main::Output( + " --elfinput=","\"\$(EPOCBLD$Bld)\\$Trg\"", + " --linkas=$LinkAs" + ); + if (&main::CompressTarget) + { + &main::Output( + " --uncompressed" + ); + } + else + { + if(&main::CompressTargetMode == NOCOMPRESSIONMETHOD) + { + # Do nothing + } + elsif(&main::CompressTargetMode == INFLATECOMPRESSIONMETHOD) + { + &main::Output( + " --compressionmethod inflate" + ); + } + elsif(&main::CompressTargetMode == BYTEPAIRCOMPRESSIONMETHOD) + { + &main::Output( + " --compressionmethod bytepair" + ); + } + + } + + if($NamedSymLkup){ + &main::Output(" --namedlookup" + ); + } + + &main::Output( + " --libpath=", "\"\$(EPOCLIB)\\LIB\"" + ); + + if($BasicTrgType=~/^DLL/ && $TrgType!~/^DLL/){ + my $Export; + my $Ordinal=1; + foreach $Export (&main::Exports) { + if($Ordinal == 1) { + &main::Output(" --sysdef="); + } + &main::Output( + "$Export,$Ordinal; " + ); + $Ordinal++; + } + } + + if (&main::CodePagingTargetMode == UNPAGED) { + &main::Output( + ' --codepaging=unpaged' + ); + } + elsif (&main::CodePagingTargetMode == PAGED) { + &main::Output( + ' --codepaging=paged' + ); + } + + if (&main::DataPagingTargetMode == UNPAGED) { + &main::Output( + ' --datapaging=unpaged' + ); + } + elsif (&main::DataPagingTargetMode == PAGED) { + &main::Output( + ' --datapaging=paged' + ); + } + + &main::Output( + "\n" + ); + + } + elsif ($BasicTrgType=~/^LIB$/o) { + &main::Output( + "\t\$(AR) ", + " \$(ARCHIVER_CREATE_OPTION) ", + " \$(EPOCBSFSTATLINK$Bld)\\$Trg \\\n" + ); + # Pass in the command file if the command file option is passed in + if($viaoption) { + #'@' is for GCCE whos version is not 3.4.3 + if($viaoption eq '@'){ + &main::Output( + "\t\t$viaoption$objectsViaFile\n" + ); + } + #'-via' is for RVCT + else{ + &main::Output( + "\t\t$viaoption $objectsViaFile\n" + ); + } + } + else { + &main::Output( + "\t\t\$(OBJECTS$Bld) \n" + ); + } + # Pass the archiver options which can be customized form BSF file + &main::Output( + "\t\t\$(AR_OPTIONS) \n" + ); + } + + &main::Output( + "\n" + ); + + if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $TrgType=~/^EXEDLL$/o) { + &main::Output( + "\tcopy ", " \"\$(EPOCBLD$Bld)\\$ExportLibrary.def\" ", "\"\$(EPOCBLD)\\$ExportLibrary.def\"\n" + ); + if (&main::ExportUnfrozen) { + if ($PlatName =~ /^ARMV5$/) + { + &main::Output( + "\tdef2dll.bat --path=\$(EPOCBLD$Bld) \\\n\t\t--bldpath=\$(EPOCBLD$Bld) \\\n\t\t--export=$ExportLibrary \\\n\t\t--import=$ExportLibrary \\\n", + "\t\t--deffile=\$(EPOCBLD)\\$ExportLibrary.def \\\n\t\t--linkAs=$LinkAs \\\n\t\t$InterWorking \\\n\t\t--absent=undef \n" + ); + &main::Output( + "\n", + "\tcopy ", " \"\$(EPOCBLD$Bld)\\$ExportLibrary.lib\" ", + "\"\$(EPOCLIB)\\LIB\\$ExportLibrary.lib\"", + "\n" + ); + if ($ExtraExportLibrary) { + &main::Output( + "\n", + "\tcopy ", " \"\$(EPOCLIB)\\LIB\\$ExportLibrary.lib\" ", + "\"\$(EPOCLIB)\\LIB\\$ExtraExportLibrary.lib\"", + "\n" + ); + } + } + + &main::Output( + "\n", + "\tcopy ", " \"\$(EPOCBLD$Bld)\\$ExportLibrary.dso\" ", + "\"\$(EPOCLIB)\\LIB\\$ExportLibrary.dso\"", + "\n" + ); + + &main::Output( + "\n", + "\tcopy ", " \"\$(EPOCBLD$Bld)\\$ExportLibrary.dso\" ", + "\"\$(EPOCLIB)\\LIB\\$ExtraExportLibrary.dso\"", + "\n" + ) if ($ExtraExportLibrary); + + } + } + + if($IsCustomDll eq 1) + { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$ExportLibrary.bin"), ": $DefFile\n"); + + my $theDefFile = "\$(EPOCBLD)\\$ExportLibrary.def"; + $theDefFile = $DefFile if (-e $DefFile && !&main::ExportUnfrozen); + my $theAssembler = " \$(ASM) "; + &main::Output( + "\telf2e32 \\\n\t\t--definput=$theDefFile \\\n\t\t--dump=a \\\n\t\t--output=\$(EPOCBLD$Bld)\\$ExportLibrary.s \n", + "\t$theAssembler \$(AAPCS_OPTION) \\\n\t\t \$(ASM_OUTPUT_OPTION) \$(EPOCBLD$Bld)\\$ExportLibrary.bin \$(EPOCBLD$Bld)\\$ExportLibrary.s\n\n" + ); + &main::Output( + "\t-\$(ERASE) \"\$(EPOCBLD$Bld)\\$ExportLibrary.s\"\n\n" + ); + } + + &main::Output( "\n" ); +} + +# Set to 1 if multifile compilation wanted +my $domultifile = 0; + +sub DoMultiFile () { + return $ENV{RVCTMultiFile} if (defined $ENV{RVCTMultiFile}); + return $domultifile; +} + +my %CompilationGroups = (); + +sub InitMultiFileCompilation() { +# Do preparatory work for multifile compilation + my $SourceStructRef=&main::SourceStructRef; + +# We sort the source files by path and extension. These form natural groups to compile together. + my %PathToSourceMap = (); + foreach my $SourceRef (@$SourceStructRef) { + my $SrcFile = $$SourceRef{CurFile}; + my $Ext = &main::Path_Split('Ext', $SrcFile); + push @{$PathToSourceMap{$$SourceRef{SrcPath}}{$Ext}}, $SrcFile; + } + +# Now we split each group into sets of 10. + foreach my $SrcPath (keys %PathToSourceMap) { + foreach my $Ext (keys %{$PathToSourceMap{$SrcPath}}) { + my @FileList; + my @ObjectList; + my @SourceList; + my $NumToGo = 10; + foreach my $File (@{$PathToSourceMap{$SrcPath}{$Ext}}) { + my $base = &main::Path_Split('Base', $File); + my $cia = ($Ext =~ /cia/i); + $base .= "_" if $cia && ($PlatName ne "GCCE"); + push @FileList, $File; + push @ObjectList, "$base.o"; +# this gives us our source files xxx + push @SourceList, ($cia && ($PlatName ne "GCCE")) ? "$base.cpp" : "$SrcPath$base$Ext"; + $NumToGo--; + unless ($NumToGo) { +# Use the last file as the key. This means e.g that all the dependency +# info will have been generated for the earlier files in the list + push @{$CompilationGroups{$FileList[$#FileList]}{Sources}}, @SourceList; + push @{$CompilationGroups{$FileList[$#FileList]}{Objects}}, @ObjectList; + $NumToGo = 10; + undef @FileList; + undef @ObjectList; + undef @SourceList; + } + } + push @{$CompilationGroups{$FileList[$#FileList]}{Sources}}, @SourceList; + push @{$CompilationGroups{$FileList[$#FileList]}{Objects}}, @ObjectList; + } + } + +# debug print out + if (0) { + foreach my $keyfile (keys %CompilationGroups) { + print "$keyfile :\n"; + foreach my $class (keys %{$CompilationGroups{$keyfile}}) { + print "\t$class:\n\t\t"; + print join " ", @{$CompilationGroups{$keyfile}{$class}}, "\n"; + } + } + } + +} + +sub PMStartSrcList { + + &main::Output( + "# SOURCES\n", + "\n" + ); + + InitMultiFileCompilation() if DoMultiFile(); + +} + +sub PMBitMapBld { + + &Generic_BitMapBld; + +} + +sub PMResrcBld { + + &Generic_ResrcBld; + +} + +sub PMAifBld { + &Generic_AifBld; +} + + +sub PMStartSrc { + my $Src=&main::Src; + + &main::Output( + "# Source $Src\n", + "\n" + ); +} + +sub PMSrcDepend { + my @DepList=&main::DepList; + return if (@DepList == 0); + + my @BldList=&main::BldList; + my $BaseSrc=&main::BaseSrc; + my $ExtSrc=&main::ExtSrc; + + my $BaseObj=$BaseSrc; + my $cia = 0; + if ($ExtSrc =~ /cia/i ) { + $cia = 1; + $BaseObj .= '_' if ($PlatName ne "GCCE"); + } + + foreach my $Bld (@BldList) { + my $tranasm = getConfigVariable('TRANASM'); + if ($tranasm) + { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.pre"), " ", + ) if $cia && ($PlatName ne "GCCE"); + } + + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseObj.cpp"), " ", + ) if $cia && ($PlatName ne "GCCE"); + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), " ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseObj.o"), " \\\n", + ); + } + &main::Output( + ":" + ); + + my $prefix_file=getConfigVariable('PREFIXFILE'); + + my @tempdeplist = &main::DepList; + + my $totalcount = $#tempdeplist; + my $count = 0; + while( $totalcount >= $count ) + { + my $dependencyfile = shift(@tempdeplist); + if($dependencyfile eq $prefix_file ) + { + $DepList[$count]="\$(PREFIXFILE)"; + } + $count += 1; + } + + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\$_\)", @DepList); + &main::Output( + "\n", + "\n" + ); +} + +sub PMSrcBldDepend { + my @DepList=&main::DepList; + return if (@DepList == 0); + + my $Bld=&main::Bld; + my $BaseSrc=&main::BaseSrc; + my $ExtSrc=&main::ExtSrc; + + my $BaseObj=$BaseSrc; + my $cia = 0; + if ($ExtSrc =~ /cia/i ) { + $cia = 1; + $BaseObj .= '_' if ($PlatName ne "GCCE"); + } + + my $tranasm = getConfigVariable('TRANASM'); + if ($tranasm) + { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.pre"), " ", + ) if $cia && ($PlatName ne "GCCE"); + } + + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseObj.cpp"), " ", + ) if $cia && ($PlatName ne "GCCE"); + + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), " ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseObj.o"), " :", + ); + + my $prefix_file=getConfigVariable('PREFIXFILE'); + + my @tempdeplist = &main::DepList; + + my $totalcount = $#tempdeplist; + my $count = 0; + while( $totalcount >= $count ) + { + my $dependencyfile = shift(@tempdeplist); + if($dependencyfile eq $prefix_file ) + { + $DepList[$count]="\$(PREFIXFILE)"; + } + $count += 1; + } + + PrintList("\' \\\n\t\'\.\&Generic_Quote\(\$_\)", @DepList); + &main::Output( + "\n", + "\n" + ); +} + +sub quoted_path +{ + my $curdrive=""; + my ($arg) = @_; + return "\"$arg\"" if ($arg !~ /^\\[^\\]/); # not an absolute path + + $curdrive=$1 if (cwd =~ /^(.:)/); + return "\"$curdrive$arg\""; +} + +sub PMPrefixFile +{ +# Prefix Header File passed to the preprocessor + + my $prefix_file=getConfigVariable('PREFIXFILE'); + return quoted_path($prefix_file) if defined $prefix_file; +} + +sub PMToolChainIncDir + { + # Extra system include directories dictated by the toolchain + return $ToolChainIncDir; + } + +sub PMEndSrcBld { +# Generate multifile compilation stuff if needed. + if (DoMultiFile()) { + MultiFileEndSrcBld(); + return; + } + + my $ABI=&main::ABI; + my $Plat=&main::Plat; + my $BaseSrc=&main::BaseSrc; + my $Bld=&main::Bld; + my $Src=lc &main::Src; + my $SrcPath=&main::SrcPath; + my $BaseTrg=&main::BaseTrg; + my $BldPath = &main::BldPath; + my $Ext = &main::Path_Split('Ext', $Src); + $Src = ucfirst $Src if ($Ext !~ /\.(cpp|c)$/); + my $LangOptions = &SelectLangOptions($Ext); + # support for auto 'translated' ASM + my $AsmFilep = $AsmFiles{$Src}; + + $preinclude = &GetToolChainPreInclude(); + + #Function call logger takes -I as include option + my $FCLogger_inc_option = getConfigVariable('FC_LOGGER_INCLUDE_OPTION'); + my $logger_preinclude = getConfigVariable('PREINCLUDE_OPTION_FCLOGGER'); + my $Dictionary_File_Name = getConfigVariable('FC_LOGGER_DICTIONARY_FILE_NAME'); + my $Generated_C_File_Name = getConfigVariable('FC_LOGGER_GENERATED_C_FILE_NAME'); + + my $ChopSrcPath=&main::Path_Chop($SrcPath); + my $lfboption = LinkerFeedBackOption(); + my $LstExt ; + if($Plat =~ /^(ARMV[6-9])/i){ + $LstExt = $1 ; + } + else{ + $LstExt = $ABI; + } + if ($AsmFilep || ($Ext =~ /cia/i && ($PlatName ne "GCCE"))) { + &main::Output( +# compile the translated, preprocessed source + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.o"), " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), "\n", + "\t\@echo $Src\n", + "\t\$(CC$Bld) $lfboption $LangOptions ", "\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ \$(EPOCBLD$Bld)\\$BaseSrc\_.cpp)\n", + "\n" + ); +# rule to translate the preprocessed source + my $tranasm = getConfigVariable('TRANASM'); + if ($tranasm) + { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.pre"), "\n", + + "\t\$(TRANASM) \$(TRANASM_FLAGS) \$(TRANASM_OUTPUT_OPTION)\$\@ \$(TRANASM_INPUT_OPTION)\$(EPOCBLD$Bld)\\$BaseSrc.pre\n", + "\n" + ); +# rule to preprocess the source + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.pre"), " : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\$(CC$Bld) \$(PREPROCESSOR_OPTION) $preinclude $LangOptions ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) $ChopSrcPath\\$Src \$(OUTPUT_OPTION) \$\@) \n", +# generate an assembly listing target too + "LISTING$Bld$BaseSrc\_ : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), "\n", + "\t", &Generic_CopyAction("$SrcPath$BaseSrc\_.$LstExt.lst"), + "\n", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), "\n", + "\t\$(CC$Bld) $LangOptions ", "\$(ASSEMBLER_LISTING_OPTION) ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ \$(EPOCBLD$Bld)\\$BaseSrc\_.cpp)\n", + "\n" + ); + } + else + { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), " : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\$(CC$Bld) \$(PREPROCESSOR_OPTION) $preinclude $LangOptions ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) $ChopSrcPath\\$Src \$(OUTPUT_OPTION) \$\@) \n", +# generate an assembly listing target too + "LISTING$Bld$BaseSrc\_ : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), "\n", + "\t", &Generic_CopyAction("$SrcPath$BaseSrc\_.$LstExt.lst"), + "\n", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), "\n", + "\t\$(CC$Bld) $LangOptions ", "\$(ASSEMBLER_LISTING_OPTION) ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ \$(EPOCBLD$Bld)\\$BaseSrc\_.cpp)\n", + "\n" + ); + } + } + else { + #If Function call logging is enabled, add call to function call logger + if ($Function_Call_Logger) { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.o"), + " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.int.cpp"), + "\n", + "\t\@echo $BaseSrc.int.cpp\n", + "\t\$(CC$Bld) $lfboption$LangOptions ", + " \$(INCLUDE_OPTION) ", + "\$(call absolutePaths, $ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ \$(EPOCBLD$Bld)\\$BaseSrc.int.cpp)\n", + "\n", +# generate an assembly listing target too + "LISTING$Bld$BaseSrc : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), + "\n", + "\t", + &Generic_CopyAction("$SrcPath$BaseSrc.$LstExt.lst"), + "\n", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), + " : ", + &Generic_Quote("$SrcPath$Src"), + "\n", + "\t\$(CC$Bld) $LangOptions ", + "\$(ASSEMBLER_LISTING_OPTION) ", + "\$(INCLUDE_OPTION)", + " \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ $ChopSrcPath\\$Src) \n", + "\n" + ); + + #Call to Function Call Logger + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.int.cpp"), + " : ", + &Generic_Quote("$SrcPath\\$Src"), + "\n", + "\t\@echo $BaseSrc.int.cpp\n", + "\t\$(FCLOGGER$Bld) $lfboption \\\n" , + "\t$FCLogger_inc_option $ChopSrcPath \\\n", + "\t$logger_preinclude \\\n ", + "\t\$(INCDIR_FCLOGGER) \\\n" , + "\t$Dictionary_File_Name $BldPath$BaseTrg.txt \\\n" , + "\t$Generated_C_File_Name \$\@ $ChopSrcPath\\$Src \n", + "\n\n" + ); + } + else { + &main::Output( + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.o"), " : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\@echo $Src\n", + "\t\$(CC$Bld) $lfboption $LangOptions ", "\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ $ChopSrcPath\\$Src)\n", + "\n", +# generate an assembly listing target too + "LISTING$Bld$BaseSrc : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), "\n", + "\t", &Generic_CopyAction("$SrcPath$BaseSrc.$LstExt.lst"), + "\n", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), " : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\$(CC$Bld) $LangOptions ","\$(ASSEMBLER_LISTING_OPTION) ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ $ChopSrcPath\\$Src) \n", + "\n" + ); + # Compiler wrapper support starts... + if($IsCompilerWrapperOption) + { + &main::Output( + "COMPWRAP$Bld$BaseSrc : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\@echo Analysing $Src\n", + "\t\$(COMPWRAP) \$(CC$Bld) $lfboption $LangOptions ", "\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR) \$(OUTPUT_OPTION) \$\@ $ChopSrcPath\\$Src)\n", + "\n" + ); + } + # Compiler wrapper support ends... + } + } +} + +my $MFVarN = 0; +sub MultiFileEndSrcBld { + my $ABI=&main::ABI; + my $BaseSrc=&main::BaseSrc; + my $Bld=&main::Bld; + my $KeyFile = &main::Src; + my $Src=ucfirst lc $KeyFile; + my $SrcPath=&main::SrcPath; + my $Ext = &main::Path_Split('Ext', $Src); + my $LangOptions = &SelectLangOptions($Ext); + # support for auto 'translated' ASM + my $AsmFilep = $AsmFiles{$Src}; + + my $ChopSrcPath=&main::Path_Chop($SrcPath); + my $lfboption = LinkerFeedBackOption(); + + if ($AsmFilep || ($Ext =~ /cia/i && ($PlatName ne "GCCE"))) { + if ($CompilationGroups{$KeyFile}) { +# compile the translated, preprocessed source + &main::Output( "OBJECTS$MFVarN = "); + foreach my $obj (@{$CompilationGroups{$KeyFile}{Objects}}) { + &main::Output( &Generic_Quote("\\\n\t\$(EPOCBLD$Bld)\\$obj"), " "); + } + &main::Output( "\n\n"); + &main::Output( "SOURCES$MFVarN = "); + foreach my $src (@{$CompilationGroups{$KeyFile}{Sources}}) { + &main::Output( &Generic_Quote("\\\n\t\$(EPOCBLD$Bld)\\$src", " ")); + } + &main::Output( "\n\n"); + &main::Output( "\$(OBJECTS$MFVarN) : \$(SOURCES$MFVarN) \n"); + + &main::Output( + "\t\@echo Compiling \$(SOURCES$MFVarN)\n", + "\t\$(CC$Bld) ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR)) $lfboption\\\n", + "\t\t$LangOptions \$(OUTPUT_OPTION) \$\@ --multifile \$(SOURCES$MFVarN)" + ); + &main::Output( "\n\n"); + $MFVarN++; + } + &main::Output( +# rule to translate the preprocessed source + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.pre"), "\n", + "\ttranasm -n -s -o=\$\@ \$(EPOCBLD$Bld)\\$BaseSrc.pre\n", + "\n", +# rule to preprocess the source + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.pre"), " : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\$(CC$Bld) \$(PREPROCESSOR_OPTION) $preinclude $LangOptions ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR)) $ChopSrcPath\\$Src \$(OUTPUT_OPTION) \$\@ \n", +# generate an assembly listing target too + "LISTING$Bld$BaseSrc\_ : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), "\n", + "\t", &Generic_CopyAction("$SrcPath$BaseSrc\_.$LstExt.lst"), + "\n", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), " : ", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.cpp"), "\n", + "\t\$(CC$Bld) $LangOptions ", "\$(ASSEMBLER_LISTING_OPTION) ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR)) \$(OUTPUT_OPTION) \$\@ \$(EPOCBLD$Bld)\\$BaseSrc\_.cpp\n", + "\n" + ); + } else { + + if ($CompilationGroups{$KeyFile}) { +# compile the source + &main::Output( "OBJECTS$MFVarN = "); + foreach my $obj (@{$CompilationGroups{$KeyFile}{Objects}}) { + &main::Output( &Generic_Quote("\\\n\t\$(EPOCBLD$Bld)\\$obj"), " "); + } + &main::Output( "\n\n"); + &main::Output( "SOURCES$MFVarN = "); + foreach my $src (@{$CompilationGroups{$KeyFile}{Sources}}) { + &main::Output( &Generic_Quote("\\\n\t$src"), " "); + } + &main::Output( "\n\n"); + &main::Output( "\$(OBJECTS$MFVarN) : \$(SOURCES$MFVarN) \n"); + + &main::Output( + "\t\@echo Compiling \$(SOURCES$MFVarN)\n", + "\t\$(CC$Bld) ", "\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR)) $lfboption\\\n", + "\t\t$LangOptions \$(OUTPUT_OPTION) \$\@ --multifile \$(SOURCES$MFVarN)" + ); + &main::Output( "\n\n"); + $MFVarN++; + } +# generate an assembly listing target too + &main::Output( + "LISTING$Bld$BaseSrc : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), "\n", + "\t", &Generic_CopyAction("$SrcPath$BaseSrc.$LstExt.lst"), + "\n", + &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), " : ", + &Generic_Quote("$SrcPath$Src"), "\n", + "\t\$(CC$Bld) $LangOptions ","\$(ASSEMBLER_LISTING_OPTION) ","\$(INCLUDE_OPTION)"," \$(call absolutePaths,$ChopSrcPath \$(INCDIR)) \$(OUTPUT_OPTION) \$\@ $ChopSrcPath\\$Src \n", + "\n" + ); + } +} + + +sub PMEndSrc { + + &main::Output( + "\n", + "\n" + ); +} + +sub PMEndSrcList { + + # Deal with accumulated MAKEDIRS etc. + + &Generic_End; +# modified start: makefile improvement + &checkVMAPFiles; +# modified end: makefile improvement +} + +sub ImportLibraryList { + my $dso; + my $base; + my @ImportLibList; + foreach $dso (@_) { + $base = &main::Path_Split('Base', $dso); + $dso = $base.".dso"; + push @ImportLibList, $dso; + } + return @ImportLibList; +} + +sub ChangeSlash($) { + my $abspath = $_[0]; + $abspath =~ s/\\/\//g ; + return $abspath; +} + +# System libraries such as the standard C++ libraries or floating point libraries or any other +# static libraries are made into DLLs by linking its export table against them. Such DLLs that are +# created from a static library is known as a Custom DLL. The ARM libraries can be supplied using +# the ARMLIBS mmp keyword A DLL is considered to be a customdll based on the presence of ARMLIBS +# keyword and also the presence of DEFFILE keyword. + +sub IsCustomDllUseCase() +{ + # To check if ARMLIBS keyword is passed in the MMP file. + # Armutl_ArmLibList() gets the list of static arm libraries, if used by an executable. + my $armliblist = &Armutl_ArmLibList; + + # To check if DEFFILE keyword is used in the MMP file to supply the def file. + my $deffile = &main::DefFile; + + if ($armliblist && $deffile) + { + return 1; + } + return 0; + +} + +sub GetToolChainPreInclude { + my $preinclude_file = getConfigVariable('PREINCLUDE_OPTION'); + + $preinclude_file =~ s/\\/\//g; + return "$preinclude_file"; +} + +sub SelectLangOptions { + my ($Ext) = @_; + $preinclude = &GetToolChainPreInclude; + if ($Ext=~/^.cpp$/ || ($Ext=~/^.cia$/ && ($PlatName eq "GCCE"))) { + #Function Call Logger + return " \$(CPP_LANG_OPTION) " if ($Function_Call_Logger); + return " \$(CPP_LANG_OPTION) $preinclude "; + } + if ($Ext=~/^.cia$/) { + return " \$(CIA_LANG_OPTION) "; + } + if ($Ext=~/^.c$/) { + my $CompilerOption = &main::CompilerOption("ARMCC"); + if($CompilerOption =~ /--cpp/){ + #Function Call Logger + return " \$(CPP_LANG_OPTION) " if ($Function_Call_Logger); + return " \$(CPP_LANG_OPTION) $preinclude "; + } + else { + #Function Call Logger + return " \$(C_LANG_OPTION) " if ($Function_Call_Logger); + return " \$(C_LANG_OPTION) $preinclude "; + } + } + # To support .cc, .cxx, .c++ file extensions for Open Environment + elsif ($Ext=~/^(.cc|.cxx|.c\+\+)$/) { + #Function Call Logger + return " \$(CPP_LANG_OPTION) " if ($Function_Call_Logger); + return " \$(CPP_LANG_OPTION) $preinclude "; + } + return ''; +} + +sub IsMapOptAvail() { + open PIPE, "arm-none-symbianelf-g++ -v 2>&1 | "; + while(){ + + if($_ =~ /gcc version (.*) \(release\).*/i) + { + if($1 lt "3.4.3") + { + return 0; + } + elsif($_ =~ /gcc version (.*) \(release\) \(CodeSourcery ARM (.*) (\d*)\)/i) + { + if($1 eq "3.4.3" && uc $2 ne "Q1B" && $3 ge 2005) + { + return 1; + } + elsif($1 gt "3.4.3") + { + return 1; + } + else + { + return 0; + } + } + + } + + } + close PIPE; +} + +sub StdCppTarget() { + + # STDCPP is supported + return 0 if (! main::StdCppSupport()); + + if ( main::NoStdCpp() ) { #MMP keyword NOSTDCPP set + return 0; + } + + if ( main::StdCpp() ) { # MMP keyword STDCPP set. + return 1; + } + else { + return ( main::TrgType() =~ /^(STDEXE|STDDLL|STDLIB)$/io ); + } +} + +sub GetRTLibList() { + + my $newlib = main::NewLib(); # Could have been set in the MMP file. + + unless ($newlib) { + if ( StdCppTarget() ) { + $newlib = getConfigVariable('OE_NEW_LIB'); + } + else { + $newlib = getConfigVariable('SYM_NEW_LIB'); + } + } + + my @RtLib; + my $list = "$newlib " . getConfigVariable('RUNTIME_LIBS_LIST') ; + if (length($list) >0) + { + @RtLib = split(/\s+/, $list); + } + return @RtLib; +} + +sub GetOELibList() { + my @OELib; + my $list; + if (&main::IsWideCharMain()) { + $list = getConfigVariable('OE_EXE_LIBS_WCHAR'); + } + else { + $list = getConfigVariable('OE_EXE_LIBS'); + } + + if (length($list) >0) + { + @OELib = split(/\s+/, $list); + } + return @OELib; +} + +sub GetOEImportLibList() { + my @OEImportLib; + my $list; + $list = getConfigVariable('OE_IMPORT_LIBS'); + + if (length($list) >0) + { + @OEImportLib = split(/\s+/, $list); + } + return @OEImportLib; +} + +sub InitToolChain(@) { + + if($PlatName eq "ARMV5" || $PlatName eq "ARMV5_ABIV2" || $CustomizedARMV5Plat) + { + my $RVCTBuildNumber; + + ($RVCTMajorVersion, $RVCTMinorVersion, $RVCTBuildNumber) = RVCT_plat2set::get_version_list($PlatName); + + $RVCTVersion = "${RVCTMajorVersion}_${RVCTMinorVersion}"; + + my $aRVCTVersion = "${RVCTMajorVersion}.${RVCTMinorVersion}"; + if (($aRVCTVersion == 2.2) && ($RVCTBuildNumber < 559)) + { + warn "WARNING: When building using ABIV2 mode toolchain Compiler RVCT2.2 Build 559 or later is required.\n"; + } + &Armutl_DoMmp(@_); + } + elsif ($RootName eq "GCCE") + { + ($GCCEMajorVersion, $GCCEMinorVersion) = gcce_plat2set::get_version_list($Platname); + + $GCCEVersion = "${GCCEMajorVersion}_${GCCEMinorVersion}"; + } + +} + +my %BSF_keywords = ( + COMMON_OPTIONS => 1, + THUMB_OPTIONS => 1, + ARM_OPTIONS => 1, + KERNEL_OPTIONS => 1, + INVARIANT_OPTIONS => 1, + LD_OPTIONS => 1, + AR_OPTIONS => 1, + DEBUG_FORMAT => 1 + ); + + +sub Read_BSF_Options() { + my %plat = (main::PlatRec()); + my @Customization_Data = split(/\n/,$plat{'CUSTOMIZATION_DATA'}); + foreach my $option (@Customization_Data) { + next if ($option =~ /^$/); + warn "Unrecognized BSF syntax: $option.\n" + unless ($option =~ /\s*(\S+)\s+(.+)$/); + my $key = uc $1; + my $val = $2; + warn "Unrecognized BSF keyword: $key.\n" + unless ($BSF_keywords{$key}); + if ($key =~ /COMMON_OPTIONS/) { + push @commonOptions, $val; + next; + } + if ($key =~ /THUMB_OPTIONS/) { + push @thumbOptions, $val; + next; + } + if ($key =~ /ARM_OPTIONS/) { + push @armOptions, $val; + next; + } + if ($key =~ /KERNEL_OPTIONS/) { + push @kernelOptions, $val; + next; + } + if ($key =~ /INVARIANT_OPTIONS/) { + push @invariantOptions, $val; + next; + } + if ($key =~ /LD_OPTIONS/) { + push @linkerOptions, $val; + next; + } + if ($key =~ /AR_OPTIONS/) { + push @archiverOptions, $val; + next; + } + if ($key =~ /DEBUG_FORMAT/) { + push @debugFormat, $val; + next; + } + + } +} + +# Set the options passed from BSF file +# @param OptionName - BSF Keyword using which the options would be overridden in the BSF file +# @param Options - List of options read from the BSF keyword +sub Set_BSF_Options($$) +{ + my ($OptionName,$Options) = @_; + my @Fragments=(); + foreach my $val (@{$Options}) + { + # Check if the value of BSF option is to be set or added/removed. + if($val =~ /\+\[.*\]\+|\-\[.*\]\-/) + { + if (@Fragments = Split_BSF_Options($val,'RemoveOptions')) + { + foreach my $Opt (@Fragments) + { + # Remove trailing white spaces + $Opt =~ s/\s+$//; + # Substitute '=' with '%' which is a wild card character in makefile. + # This is required for cases where option to be removed contains '=' (e.g.'-march=armv5t'). + # When such options are to be removed, "$(INVARIANT_OPTIONS:-march=armv5t=)" is written in the makefile. + # However, because of the occurence of '=', pattern match fails in the makefile and such options are not removed. + # To resolve this, '=' is replaced with '%' in the makefile so that the substitution pattern looks like + # "$(INVARIANT_OPTIONS:-march%armv5t=)" in makefile (e.g."$(INVARIANT_OPTIONS:-march%armv5t=)"). + $Opt =~ s/=/%/; + &main::Output( + "$OptionName := \$($OptionName:$Opt=)", + "\n" + ); + } + @Fragments=(); + } + if (@Fragments = Split_BSF_Options($val,'AddOptions')) + { + &main::Output( + "$OptionName += @Fragments ", + "\n" + ); + @Fragments=(); + } + + # Warn if options are not present in the form '+[...]+' or '-[...]-' + $val =~ s/\+\[.*?\]\+|\-\[.*?\]\-//g; + if($val !~ /^\s*$/) + { + print "Warning: Ignoring option(s) \"$val\" for $OptionName as option(s) should be in the form '+[...]+' or '-[...]-.\n"; + } + } + else + { + &main::Output( + "$OptionName = $val ", + "\n" + ); + } + } + &main::Output( + "\n" + ); +} + +# Split BSF options to find options which are to be added/removed +# @param String - List of options present in form '+[...]+' or '-[....]-' +# @param $Task - Variable to decide whether to return options to be addded or options to be removed +sub Split_BSF_Options($$) +{ + my ($String,$Task) = @_; + my @Result = (); + my @Fragments = (); + my $Pattern = ''; + # Get the toolchain specific option prefix to segregate the options. + my $OptionPrefix = getConfigVariable('OPTION_PREFIX'); + + if ($Task eq 'AddOptions') + { + # Get the options which are to be added (present in the form '+[...]+') + @Fragments = $String =~ /\+\[(.*?)\]\+/g; + } + elsif ($Task eq 'RemoveOptions') + { + # Get the options which are to be removed (present in the form '-[...]-') + @Fragments = $String =~ /\-\[(.*?)\]\-/g; + } + + # Set the value of '$Pattern' which is required to segregate one option from another based on the option prefix. + if($OptionPrefix) + { + $Pattern = $OptionPrefix.'\S+\s*(?!'.$OptionPrefix.')\S*'; + } + else + { + # If option prefix is not set in the configuration make file, then set default + # option prefix as '-' or '--'. + $Pattern = '-{1,2}\S+\s*(?!-)\S*'; + } + + foreach my $Val (@Fragments) + { + my @Opt = $Val =~ /$Pattern/g; + push @Result,@Opt; + } + return @Result; +} + +sub SysTrg () { + return 1 if &main::SystemTrg; + my $ExportLibrary=&main::ExportLibrary; + return 1 if ($ExportLibrary =~ /EKERN/i); + my $Trg=&main::Trg; + return 1 if ($Trg =~ /KSRT/i); + return 0; +} + +sub GetLibList() { + my @LibList; + my @StaticLibList; + my $list = getConfigVariable('STATIC_LIBS_LIST') ; + + if (length($list) >0) + { + @StaticLibList = split(/\s+/, $list); + } + if($PlatName eq "ARMV5" || $PlatName eq "ARMV5_ABIV2" || $CustomizedARMV5Plat) { + @LibList=&Armutl_ArmLibList; + if(@LibList==0) { + my $LibDir = Armutl_ArmLibDir(); + # convert '/' to '\' if there are some '/' + $LibDir =~ s#/#\\#g; + if (@StaticLibList) { + foreach my $lib (@StaticLibList) { + push @LibList, ("$LibDir\\$lib"); + } + } + } + } + else + { + @LibList = ('$(STATIC_LIBS_LIST)'); + } + return @LibList; +} + +sub GetToolChainAsmFileList() { + my @FileList; + @FileList=&Armutl_AsmFileList; + if(@FileList) + { + return @FileList; + } + return; +} + +sub IsTargetRT() { + my $RTtarget=&Armutl_ArmRT; + if($RTtarget) + { + return $RTtarget; + } + return; +} + +sub GetToolChainIncDir { + if($PlatName eq "ARMV5" || $PlatName eq "ARMV5_ABIV2" || $CustomizedARMV5Plat) + { + #the ToolChainIncDir's value depends on the key word ARMINC in mmp file + return &Armutl_ArmIncDir; + } + else + { + my $compiler_inc_path = getConfigVariable('COMPILER_INCLUDE_PATH'); + $compiler_inc_path =~ s/^\s+//g; + return ($compiler_inc_path); + } +} + +my $useLinkerFeedBack = 0; + +sub LinkerFeedBackFile() { + return unless $useLinkerFeedBack; + my $Trg = &main::Trg; + return "$Trg.lfb"; +} + +sub LinkerFeedBackOption() { + return "" unless $useLinkerFeedBack; + my $BasicTrgType=&main::BasicTrgType; + return "" unless ($BasicTrgType=~/^(DLL|EXE)/o); + my $file = LinkerFeedBackFile(); + return "/$(FEEDBACK_FILE_OPTION) $file "; + +} + +sub getConfigVariable +{ + my ($variable) = @_; + initialiseConfigVariables(); + return $configVariables{$variable}; +} + +sub initialiseConfigVariables() +{ + if (!keys(%configVariables)) + { + %configVariables = BPABIutl_Get_Config_Variables($PlatName); + + if (!keys(%configVariables)) + { + # no variables were extracted from configuration file. + &main::FatalError("Cannot extract configuration variables for $PlatName"); + } + } +} + +sub PMSupportsFeatureVariants +{ + return 1; +} +# modified start: makefile improvement +sub checkVMAPFiles +{ + my %srcSet = %{&main::getSrcSet}; + my %featureVariantInfo = &main::FeatureVariantInfo(); + my $vmapfile = &main::Trg.".".$featureVariantInfo{NAME}.".vmap"; + my $mmpFile = &main::MmpFile; + if ( $vmapfile ){ + &main::Output( + "\n", + "\n", + "# Rules to check out the VMAP files", + "\n", + "\n", + ); + &main::Output( + "CHECKVMAPUREL : ", + "\$(EPOCTRG)\\urel\\", + $vmapfile, + " \n", + "\$(EPOCTRG)\\urel\\", + $vmapfile, + " : \\\n", + "\t", + $mmpFile, + ); + foreach my $srcfile (sort keys(%srcSet)) + { + &main::Output( + " \\\n \t", + $srcfile, + ); + } + &main::Output( + "\n", + "\t-\$(ERASE) \$(EPOCTRG)\\urel\\", + $vmapfile, + "\n", + "\n", + ); + &main::Output( + "CHECKVMAPUDEB : ", + "\$(EPOCTRG)\\udeb\\", + $vmapfile, + " \n", + "\$(EPOCTRG)\\udeb\\", + $vmapfile, + " : \\\n", + "\t", + $mmpFile, + ); + foreach my $srcfile (sort keys(%srcSet)) + { + &main::Output( + " \\\n \t", + $srcfile, + ); + } + &main::Output( + "\n", + "\t-\$(ERASE) \$(EPOCTRG)\\udeb\\", + $vmapfile, + "\n", + "\n", + ); + } +} +# modified by SV end: makefile improvement +# modified end: makefile improvement + + +1;