sbsv1/abld/platform/cl_codewarrior.pm
author Mike Kinghan <mikek@symbian.org>
Thu, 25 Nov 2010 13:59:07 +0000
changeset 40 68f68128601f
permissions -rw-r--r--
1) Add the sbsv1 components from sftools/dev/build to make the linux_build package independent of the obsolete buildtools package. 2) Enhance romnibus.pl so that it generate the symbol file for the built rom when invoked by Raptor 3) Make the maksym.pl tool portable for Linux as well as Windows. 4) Remove the of armasm2as.pl from the e32tools component in favour of the copy now exported from sbsv1/e32util.

# Copyright (c) 2001-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:
#


package Cl_codewarrior;

# declare variables global for module
my @Win32LibList=();
my $Win32StdHeaders;
my $BaseAddressFlag;
my $Win32Resrc;

my $MWCC;
my $MWLD;
my $MWIncludePath;
my $MWIncludeVar;
my $CWVersion;
my $CWVersionReadable;
my $CWBuildNum;
my $CWRuntimeLibs="";

require Exporter;
@ISA=qw(Exporter);
@EXPORT=qw(
	PMHelp_Mmp

	PMCheckPlatformL

	PMPlatProcessMmp

	PMPlatCheckSource
	
	PMStartBldList
		PMBld
	PMStartSrcList
		PMBitMapBld
		PMResrcBld
		PMAifBld
		PMStartSrc
		PMSrcDepend
			PMSrcBldDepend
			PMEndSrcBld
		PMEndSrc
	PMEndSrcList
);

use Winutl;
use cl_generic;
use E32Variant;

my $NamedSymLkup = 0;

my $stdcpp_tag_file = 'tag_coff';
my $stdcpp_tag_path = '$(EPOCROOT)epoc32\tools\tag';

sub RoundUp1k($) {
	# Accept C hexadecimal number (0xNNN).  Convert argument to Kb
	# rounded up to the next 1kb boundary.
	use integer;
	return (hex($_[0]) + 1023) / 1024;
}


sub PMHelp_Mmp {
	&Winutl_Help_Mmp;
}

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 PMCheckPlatformL {

	my $IsProxyWrapperOption=&main::ProxyWrapperOption();

	# check version of CodeWarrior for Symbian OS
	
	if (defined($ENV{MWCSym2Includes})) {
		$MWCC = "mwccsym2.exe";
		$MWLD = "mwldsym2.exe";
	}
	if (!defined($MWCC) && defined($ENV{MWSym2Libraries})) {
		$MWCC = "mwccsym2.exe";
		$MWLD = "mwldsym2.exe";
	}
	if (!defined($MWCC) && defined($ENV{CWFolder})) {
		$MWCC = "mwcc.exe";
		$MWLD = "mwld.exe";
	}
	if (!defined($MWCC)) {
		die "ERROR: Unable to identify a valid CodeWarrior for Symbian OS installation\n";
	}

	# determine default include path
	
	$MWIncludeVar = 'MWCIncludes';	# default, even if it doesn't exist
	$MWIncludePath = '';			# default is empty
	
	foreach my $var ('MWCSym2Includes','MWCWinx86Includes','MWCIncludes') {
		if (defined($ENV{$var})) {
			$MWIncludePath = $ENV{$var};
			$MWIncludeVar = $var;
			last;
		}
	}

	open PIPE, "$MWCC |", or &main::FatalError( "Failed to find version information for $MWCC \n");
	while (<PIPE>) {
		if($_ =~ /Version\s+(\d+)\.(\d+)\.(\d+)\s+build\s+(\d+)/) {
			my $MajorVer = $1;
			my $MinorVer = $2;
			my $PatchNum = $3;
			
			$CWBuildNum = $4;

            $CWVersionReadable = "$1.$2.$3 build $4";

#			The CW compiler documentation says that the compiler version is a 2-byte value as
#			0xMnpp (the corresponding CW's pre-defined macro is __MWERKS__), where,
#				M is the major version number (which means it is accomodated in the first 4 bits, 
#				n is the minor version number (which means it is accomodated in the next 4 bits, 
#				pp is the patch number (which means it is accomodated in the next 8 bits.
#			Here, an integer is formed from these 3 values to uniquely identify the compiler version.
			$CWVersion = ($MajorVer << 12) + ($MinorVer << 8) + $PatchNum;
			last;
		}
	}
	close PIPE;
	
	if ($IsProxyWrapperOption){
		$MWCC = "$ENV{ABLD_COMPWRAP} " . $MWCC;
		$MWLD = "$ENV{ABLD_COMPWRAP} " . $MWLD;
	}
}

sub PMPlatProcessMmp (@) {
	&Winutl_DoMmp(\@_, $MWIncludePath);
	$BaseAddressFlag=&Winutl_BaseAddress;
	if ($BaseAddressFlag ne "") {
		$BaseAddressFlag=" -imagebase \"$BaseAddressFlag\"";
	}
	@Win32LibList=&Winutl_Win32LibList;
	$Win32Resrc=&Winutl_Win32Resrc;
	$Win32StdHeaders=&Winutl_Win32StdHeaders;
}

sub PMPlatCheckSource () {
	&Winutl_CheckSourceMMPMetaData ();
}

sub PMStartBldList($) {
	my ($makecmd) = @_;
	my $AifStructRef=&main::AifStructRef;
	my $BaseTrg=&main::BaseTrg;
	my $BitMapStructRef=&main::BitMapStructRef;
	my @BldList=&main::BldList;
	my @ChopSysIncPaths=&main::Path_Chop(&main::SysIncPaths);
	my @ChopUserIncPaths=&main::Path_Chop(&main::UserIncPaths);
	my $ExportLibrary=&main::ExportLibrary;
	my $NoExportLibrary=&main::NoExportLibrary;
	my $DefFile=&main::DefFile;
	my $BasicTrgType=&main::BasicTrgType;
	my $LibPath=&main::LibPath;
	my @MacroList=&main::MacroList();
	push @MacroList, "__SUPPORT_CPP_EXCEPTIONS__";

	push @MacroList, "__SYMBIAN_STDCPP_SUPPORT__" if StdCppTarget();
	
    my $VariantFile=&main::VariantFile();
	my $ResourceStructRef=&main::ResourceStructRef;
	my $Plat=&main::Plat;
	my $Trg=&main::Trg;
	my $TrgType=&main::TrgType;
	my $WarningLevel=&main::CompilerOption("CW");
	my $LinkAs=&main::LinkAs;

	Generic_Header(0,$makecmd);	# define standard things using absolute paths

	my $TrgDir="";
	my $AifTrgDir="";
	if (&Generic_Definition("TRGDIR") ne "") {
		$TrgDir="\$(TRGDIR)\\";
		$AifTrgDir=$TrgDir;
	}

# Handle migration of binaries to secure location

	&Winutl_AdjustTargetPath(\$TrgDir);
	
# Change - mwwinrc.exe uses MWWinx86Includes or MWCIncludes, but some installations
# fail to install either. Set MWCIncludes from the chosen variable as part
# of the Makefile.
	if (!defined($ENV{MWCIncludes}) && $MWIncludeVar ne 'MWCIncludes') {
		&main::Output(
			"\n",
			"MWCIncludes:=\$($MWIncludeVar)\n",
			"export MWCIncludes\n",
			"\n"
		);
	}
	if( ($CWVersion == 0x3205 && $CWBuildNum == 465)){
		if($TrgType =~ /^(STDDLL|STDEXE|STDLIB)$/o) {
		&main::Output(
				"\n",
				"MWSym2LibraryFiles:=msl_all_mse_symbian_d.lib;gdi32.lib;user32.lib;kernel32.lib;\n",
				"export MWSym2LibraryFiles\n",
				"\n"
			);
		}
		else {
			&main::Output(
				"\n",
				"MWSym2LibraryFiles:=msl_all_static_mse_symbian_d.lib;gdi32.lib;user32.lib;kernel32.lib;\n",
				"export MWSym2LibraryFiles\n",
				"\n"
			);
		}
	}
		
	if($WarningLevel =~ /\-cwd\s\s*include/){	
		&main::Output(
			"# EPOC DEFINITIONS\n",
			"\n",
			"INCDIR  = -cwd include -i-"
		);
	}
	else {
		&main::Output(
			"# EPOC DEFINITIONS\n",
			"\n",
			"INCDIR  = -cwd source -i-"
		);
	}
	foreach (@ChopUserIncPaths,@ChopSysIncPaths) {
		&main::Output(
			" \\\n -i \"$_\""
		);
	}
	use Pathutl;
	if($VariantFile){
	    my $variantFilePath = Path_Split('Path',$VariantFile);
	    $VariantFile  = Path_Split('FILE',$VariantFile);
	    # workaround for codewarrior defect:
	    # codewarrior at the moment doesn't accept an absolute path with the
	    # the -include option unless it contains a drive letter, this is solved
	    # by including the directory and the file separately
	    &main::Output("\\\n -i \"$variantFilePath \" -include \"$VariantFile\"");
	}
	&main::Output(
		"\n",
		"\n"
	);

	&main::Output(
		"CWFLAGS ="		
	);

	# 'wchar_t' should be treated as default datatype for OE targets because when wchar_t option is turned off, 
	# using 'wchar_t' defaults to the unsigned short int and wrong functionality. 
	if ( $TrgType =~ /^(STDEXE|STDDLL|STDLIB)$/io || StdCppTarget() ) 
	{
		&main::Output(
			" -wchar_t on"
		);	
	}
	else 
	{
		&main::Output(
			" -wchar_t off"
		);
	}

	&main::Output(		
		" -align 4",		# long alignment
		" -warnings on",	# selection of warnings
		" -w nohidevirtual",	# turn off "hides inherited virtual function" warning
		   ",nounusedexpr",	# turn off "expression has no side effect" warning
		" -msgstyle gcc",	# use GCC-style message format
		# " -strict on",		# strict ANSI/ISO C++ checking
		" -enum int",		# use int for enumeration types
		" -str pool",		# pool strings into a single data object
		" -exc ms",			# SEH C++ exception implementation
		" -trigraphs on",		# Enable recognition of C-style trigraphs, e.g. '??/' -> '\'
		" $WarningLevel"		
	
	);

	if ($Win32StdHeaders or &main::Plat eq 'TOOLS') {
		&main::Output(
			" -stdinc"		# insist because mwccsym2 has -nostdinc as the default(?)
		);
	}
	else {
		&main::Output(
			" -nostdinc"	# insist because mwcc has -stdinc as the default.
		);
	}
	&main::Output(
		"\n",
		"\n"
	);

	&main::Output(
		"CWDEFS  = "
	);
	foreach(@MacroList) {
		&main::Output(
			" -d \"$_\""
		);
	}
	&main::Output(
		" \$(USERDEFS)\n",
		"\n"
	);

	foreach (@BldList) {
		&main::Output(
			"CW$_ = $MWCC"
		);
		if (/DEB$/o) {
			&main::Output(
				' -g -O0'   # debug information, no optimisation
			);
#			euser change to apply inlining on the _NAKED functions

#			stdexe/stddll change so that the inline functions dont 
#			get exported (in debug build) causing a different export list for debug and release builds
			if ($BaseTrg!~/^EUSER$/oi && $TrgType !~ /^(STDEXE|STDDLL)$/io) {
				&main::Output(
					' -inline off'
				);
			}	
		}
		elsif (/REL$/o) {
			&main::Output(
				' -O4,s'	# highest level of optimisation, optimise for space
			);
		}

		if( ($CWVersion == 0x3205 && $CWBuildNum >= 465) || $CWVersion > 0x3205){
			if ($TrgType =~ /^(STDEXE|STDDLL|STDLIB)$/io) {
				&main::Output(
					' -runtime dllmulti'
				);
			}
			else {
				&main::Output(
					' -runtime staticmulti'
				);
			}
		}

		&main::Output(
			' $(CWFLAGS)'
		);
		foreach (&main::MacroList($_)) {
			&main::Output(
				" -d $_"
			);
		}
		&main::Output(
			" \$(CWDEFS) \$(INCDIR)\n"
		);
	}
	&main::Output(
		"\n",
		"\n"
	);
	
	foreach (@BldList) {
		&main::Output(
			"$_ :"
		);

		if ($BasicTrgType !~ /IMPLIB/io) {
			&main::Output (
				" \\\n",
				"\t", &Generic_Quote("\$(EPOCTRG$_)\\$TrgDir$Trg")
			);
			if (&Winutl_CopyForStaticLinkage) {
				&main::Output(
					" \\\n",
					"\t", &Generic_Quote("\$(EPOCTRG$_)\\$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"
		);
	}

	foreach (@BldList) {
		my $makework="MAKEWORK$_";
		&main::Output(
			"\n",
			"RESOURCE$_ : $makework"
		);

		my $BitMapRef;
		foreach $BitMapRef (@$BitMapStructRef) {
			my $file="\$(EPOCTRG$_)\\$$BitMapRef{TrgPath}$$BitMapRef{Trg}";
			&Generic_MakeWorkFile($makework,$file);
			&main::Output(
				" \\\n",
				"\t", &Generic_Quote($file)
			);
		}
		undef $BitMapRef;

		my $ResourceRef;
		foreach $ResourceRef (@$ResourceStructRef) {
			if(! defined $$ResourceRef{Hdronly}) {
				my $file="\$(EPOCTRG$_)\\$$ResourceRef{Trg}";
				&Generic_MakeWorkFile($makework,$file);
				&main::Output(	# must come before main target because source for target will depend on the
				" \\\n",		# *.rsg file in $EPOCIncPath
				"\t", &Generic_Quote("$file")
				);
			}
		}
		undef $ResourceRef;

		my $AifRef;
		foreach $AifRef (@$AifStructRef) {
			my $file="\$(EPOCTRG$_)\\$AifTrgDir$$AifRef{Trg}";
			&Generic_MakeWorkFile($makework,$file);
			&main::Output(
				" \\\n",
				"\t", &Generic_Quote($file)
			);
		}
		undef $AifRef;

		&main::Output(
			"\n"
		);
	}
	&main::Output(
		"\n",
		"\n",
	);

	&main::Output(
		"\n",
		"# REAL TARGET - LIBRARY\n",
		"\n",
		"LIBRARY : MAKEWORKLIBRARY"
	);
	if ($BasicTrgType=~/^LIB$/o) {
#		code to ensure that the static libraries for all builds are built at the library stage
		foreach (@BldList) {
			&main::Output(
				" $_"
			);
		}
	}
	elsif ($DefFile and !$NoExportLibrary) {
		unless (&main::ExportUnfrozen) {
			if (-e $DefFile) { # effectively "if project frozen ..."
				my $LibLinkAs = ($BasicTrgType=~/^IMPLIB$/io) ? $LinkAs : $Trg;
				&main::Output(
					" ", &Generic_Quote("\$(EPOCLIB)\\UDEB\\$ExportLibrary.lib"), "\n",
					"\n",
					&Generic_Quote("\$(EPOCLIB)\\UDEB\\$ExportLibrary.lib"), " : ",
					&Generic_Quote($DefFile), "\n",
					"\tperl -S prepdef.pl ",&Generic_Quote($DefFile)," \"\$(EPOCBLD)\\$ExportLibrary.prep.def\"\n",
					"\t$MWLD \"\$(EPOCBLD)\\$ExportLibrary.prep.def\" -importlib -o \$\@",
					" -addcommand \"out:$LibLinkAs\" -warnings off",
					"\n"
				);
			} else {
				&main::Output(
					"\n",
					"\t\@echo WARNING: Not attempting to create \"\$(EPOCLIB)\\UDEB\\$ExportLibrary.lib\".\n",
					"\t\@echo When exports are frozen in \"$DefFile\", regenerate Makefile.\n"
				);
			}
		} else {
			&main::Output(
				"\n",
				"\t\@echo Not attempting to create \"\$(EPOCLIB)\\UDEB\\$ExportLibrary.lib\"\n",
				"\t\@echo from frozen .DEF file, since EXPORTUNFROZEN specified.\n"
			);
		}
	}
	&main::Output(
		"\n",
		"\n",
		"FREEZE :\n"
	);
	if ($DefFile and $BasicTrgType!~/^IMPLIB$/io) {
		&main::Output(
#			call perl on the script here so nmake will die if there are errors - this doesn't happen if calling perl in a batch file
			"\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)\\UDEB\\$ExportLibrary.lib\"\n"
		);
	}
	&main::Output(
		"\n"
	);
	&Generic_MakeWorkDir('MAKEWORKLIBRARY',"${LibPath}UDEB");

	&Generic_Releaseables;
}

my $uidfile;
sub PMBld {

	my $AifStructRef=&main::AifStructRef;
	my @SrcList=&main::SrcList;
	my $BaseTrg=&main::BaseTrg;
	my $BitMapStructRef=&main::BitMapStructRef;
	my $Bld=&main::Bld;
	my $ChopBldPath=&main::Path_Chop(&main::BldPath);
	my $ExportLibrary=&main::ExportLibrary;
	my $NoExportLibrary=&main::NoExportLibrary;
	my $DefFile=&main::DefFile;
	my $EPOCIncPath=&main::EPOCIncPath;
	my $BasicTrgType=&main::BasicTrgType;
	my @LibList;
	my $RelPath=&main::RelPath;
	my $ResourceStructRef=&main::ResourceStructRef;
	my @StatLibList=&main::StatLibList;
	my $Trg=&main::Trg;
	my $TrgPath=&main::TrgPath;
	my $TrgType=&main::TrgType;
	# Get the information regarding supporting Compiler Wrapper Option
	my $IsCompilerWrapperOption=&main::CompilerWrapperOption();

	$NamedSymLkup = 1 if($TrgType =~ /^(STDDLL|STDEXE)$/o);

	$uidfile = "$BaseTrg.UID";

	if ($Bld =~ /DEB/) {
		@LibList=&main::DebugLibList;
	} else {
		@LibList=&main::LibList;
	}

	# OE Glue Code
	my @oe_exe_libs=("libcrt0.lib");
	my @oe_exe_libs_wchar=("libwcrt0.lib");

	# OE Import Libraries
	my @oe_import_libs=("euser.lib"); 
 	if(not (grep /^libc.lib$/i, @LibList)){
 			push @oe_import_libs, "libc.lib";
 	}	   	
	   	
   # Handle migration of binaries to secure location

	my $BLDTRGPATH = "";
	my $AIFBLDTRGPATH = "";
	if ($TrgPath) {
		$BLDTRGPATH = "\$(TRGDIR)\\";	    # handles TARGETPATH
		$AIFBLDTRGPATH = $BLDTRGPATH;
		&Winutl_AdjustTargetPath(\$BLDTRGPATH);
	}
	$BLDTRGPATH = "\$(EPOCTRG$Bld)\\".$BLDTRGPATH;
	$AIFBLDTRGPATH = "\$(EPOCTRG$Bld)\\".$AIFBLDTRGPATH;

	# REAL TARGETS
	#-------------
	&main::Output(
		"# REAL TARGET - BUILD VARIANT $Bld\n",
		"\n"
	);

#	releasables
	my @releaseables;
	
	unless (&main::Plat() eq 'TOOLS') {
		if ($TrgType !~ /^IMPLIB$/io) {
			if ($TrgType !~ /^NONE/io) {
				push @releaseables, "$BLDTRGPATH$Trg";
				if ($Bld=~/REL$/o && $BasicTrgType!~/^LIB$/o) {
					push @releaseables,"$BLDTRGPATH$Trg.map";
				}
				if (&Winutl_CopyForStaticLinkage) {
					push @releaseables, "\$(EPOCTRG$Bld)\\$Trg";
				}
			}
			my $BitMapRef;
			foreach $BitMapRef (@$BitMapStructRef) {
				push @releaseables, "\$(EPOCTRG$Bld)\\$$BitMapRef{TrgPath}$$BitMapRef{Trg}";
			}
			my $ResourceRef;
			foreach $ResourceRef (@$ResourceStructRef) {
				if(! defined $$ResourceRef{Hdronly}) {
					push @releaseables,"\$(EPOCTRG$Bld)\\$$ResourceRef{Trg}";
				}
			}
			my $AifRef;
			foreach $AifRef (@$AifStructRef) {
				push @releaseables, "$AIFBLDTRGPATH$$AifRef{Trg}";
			}
		}
		if (-e $DefFile and !$NoExportLibrary) { # effectively "if project frozen ..."
			push @releaseables, "\$(EPOCLIB$Bld)\\$ExportLibrary.lib";
		}
		if ($Bld=~/DEB$/o) {
			# debugging support files?
		}
	}
	else {
		if ($BasicTrgType !~ /^IMPLIB$/io) {
			my $toolspath=&main::EPOCToolsPath();
			push @releaseables, "$toolspath$Trg";
		}
	}


	my $firstlib = "";
	my $newlib = "";

	if ( $BasicTrgType =~ /^(EXE|DLL)$/o && main::Plat() ne 'TOOLS' ) {

		$firstlib = main::FirstLib();

		unless ( StdCppTarget() || ! main::StdCppSupport()) {

			$newlib = main::NewLib(); # Check if has been set in the MMP file.

			unless ($newlib) {
				if ( main::SystemTrg() ) {

					$newlib = 'scppnwdl_kern.lib';
				}
				else {
					$newlib = 'scppnwdl.lib';
				}
			}
		}
	}


	&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_WhatCleanTargets($Bld, "WHAT$Bld", "CLEANRELEASE$Bld", @releaseables);

	my $adjustedTargetPath=$TrgPath;
	&Winutl_AdjustTargetPath(\$adjustedTargetPath);
	&Generic_MakeWorkDir("MAKEWORK$Bld", &main::BldPath);
	&Generic_MakeWorkDir("MAKEWORK$Bld", "$RelPath$adjustedTargetPath");

	&main::Output(
		"\n",
		"\n"
	);

	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', $_);
		$BaseSrc.='_' if (lc($Ext) eq '.cia');
		$BaseSrc =~ s/\.UID/_UID_/i if ($BaseSrc eq $uidfile);
		
   		&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', $_);
			my $Ext = &main::Path_Split('Ext', $_);
			$BaseSrc.='_' if (lc($Ext) eq '.cia');
			$BaseSrc =~ s/\.UID/_UID_/i if ($BaseSrc eq $uidfile);
			
			&main::Output(
				" \\\n\tCOMPWRAP$Bld$BaseSrc"
			);
		}

		&main::Output(
			"\n",
			"\n"
		);
	}
	#--Compiler wrapper support ends

	# Flag that tells whether to run checklib.exe on static libraries.
	my $run_checklib = 0;

	if (@StatLibList && $BasicTrgType =~ /^(EXE|DLL)$/o && !main::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=");
		for (@StatLibList) {
			&main::Output(
				" \\\n\t", &Generic_Quote("\$(EPOCSTATLINK$Bld)\\$_")
			);
		}

		main::Output("\n\n");
	}

	&main::Output(
		"LIBS$Bld="
	);
	foreach (@StatLibList) {
		&main::Output(
			" \\\n\t", &Generic_Quote("\$(EPOCSTATLINK$Bld)\\$_")
		);
	}
	
	#OE Glue Code
	if ($TrgType=~/^STDEXE$/o) {
		if (&main::IsWideCharMain()) {
			foreach (@oe_exe_libs_wchar) {
				&main::Output(
					" \\\n\t", &Generic_Quote("\$(EPOCSTATLINK$Bld)\\$_")
				);
			}
		}
		else {
			foreach (@oe_exe_libs) {
				&main::Output(
					" \\\n\t", &Generic_Quote("\$(EPOCSTATLINK$Bld)\\$_")
				);
			}
		}
	}

	foreach (@LibList) {
		&main::Output(
			" \\\n\t", &Generic_Quote("\$(EPOCLINK$Bld)\\$_")
		);
	}

	#OE Import Libraries
	if ($TrgType =~ /^STDEXE$/o || $TrgType =~ /^STDDLL$/o) {
		foreach (@oe_import_libs) {
		&main::Output(
			" \\\n\t", &Generic_Quote("\$(EPOCLINK$Bld)\\$_")
		);
		}
	}

	&main::Output(
		"\n",
		"\n"
	);

	&main::Output(
		"LINK_OBJS$Bld="
	);
	my $have_uidfile = 0;
	foreach (@SrcList) {
		my $BaseSrc = &main::Path_Split('Base', $_);
		my $Ext = &main::Path_Split('Ext', $_);
		if ($BaseSrc eq $uidfile) {
			$have_uidfile = 1;
			next;
		}
		$BaseSrc.='_' if (lc($Ext) eq '.cia');
   		&main::Output(
			" \\\n",
			"\t", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.o")
   		);
   	}

	my $add_stdcpp_tag = 0;

	if ($BasicTrgType=~/^LIB$/o && StdCppTarget() ) {
		$add_stdcpp_tag = 1;
	}

	if ($add_stdcpp_tag) {
		&main::Output(
			" \\\n",
			"\t", &Generic_Quote("$stdcpp_tag_path\\$stdcpp_tag_file")
		);
	}
	if ($Win32Resrc) {
		my $resbase=&main::Path_Split('Base',$Win32Resrc);
		&main::Output(
			" \\\n",
			"\t", &Generic_Quote("\$(EPOCBLD$Bld)\\$resbase.res")
		);
	}
	if ($have_uidfile) {
		# ensure that the uid file is at the end of the list, as it's implicit in
		# CodeWarrior IDE projects.
		&main::Output(
			" \\\n",
			"\t", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseTrg"."_UID_.o")
		);
	}
	&main::Output(
		"\n",
		"\n"
	);

	&main::OutFormat(
		"COMMON_LINK_FLAGS$Bld=",
		' -msgstyle gcc',
		' -stdlib'		# use default runtime library for compiler help functions
	);
	if ($MWLD =~ /mwcc.exe/) {
		&main::OutFormat(
			' -warnings on'	# on by default in mwccsym2.exe
		);
	}

	main::OutFormat(" \"\$(EPOCSTATLINK$Bld)\\$firstlib\" ") if $firstlib;
	main::OutFormat(" \"\$(EPOCSTATLINK$Bld)\\$newlib\" ")   if $newlib;

	foreach my $lib (@Win32LibList) {
		 my $win32lib = $lib;    # take a copy, to avoid updating contents of Win32LibList!
		$win32lib = "-l$win32lib" unless ($win32lib =~ /\\/);
		&main::OutFormat(
			" ",lc $win32lib
		);
	}
	if ($BasicTrgType=~/^DLL$/o) {
		&main::OutFormat(
			"$BaseAddressFlag",
			' -main __Win32DllMain@12',
			' -shared'
		);
	}
	elsif ($TrgType=~/^EXEXP$/o) {
		&main::OutFormat(
			"$BaseAddressFlag",
			' -noentry',
			' -shared'
		);
	}
	elsif ($BasicTrgType=~/^EXE$/o) {
		unless (&main::Plat eq 'TOOLS') {
			&main::OutFormat(
				' -m "?_E32Bootstrap@@YGXXZ"'
			);
		}
	}
	if (&main::Plat=~/^(WINC|TOOLS)$/o && $BasicTrgType=~/^EXE$/o) {
		&main::OutFormat(
			' -subsystem console'
		);
	}
	else {
		&main::OutFormat(
			' -subsystem windows'
		);
	}
	if (&main::HeapSize) {
		my %HeapSize=&main::HeapSize;
		&main::OutFormat(
			' -heapreserve=',RoundUp1k($HeapSize{Max}),' -heapcommit=',RoundUp1k($HeapSize{Min})
		);
	}
	if ($BasicTrgType=~/^(DLL|EXE)$/o) {
		if ($Bld=~/DEB$/o) {
			&main::OutFormat(
				' -g'
			);
		}
	}
	&main::Output(
		"\n",
		"\n"
	);

	if($TrgType =~/^(STDEXE|STDDLL|STDLIB)$/o) {
		if(! (( $CWVersion == 0x3205 && $CWBuildNum >= 465 ) || $CWVersion > 0x3205 ) ) {
			&main::FatalError("TargetType $TrgType requires CodeWarrior version `3.2.5 build 465' or later but you have $CWVersionReadable.");
		}
	}

	my $EntrySymbol='';
	if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o || $NamedSymLkup) {
		my $Include="";
		if ($BasicTrgType=~/^DLL$/o) {
			$Include="-m __E32Dll";
			$EntrySymbol='__E32Dll';
		}
		else {
			$Include="-m __E32Startup";
			$EntrySymbol='__E32Startup';
		}
		&main::Output(
			"STAGE1_LINK_FLAGS$Bld= \$(COMMON_LINK_FLAGS$Bld) \$(LIBS$Bld) \\\n\t",
			" -o \"\$(EPOCBLD$Bld)\\$Trg\"");
		
		if ($NamedSymLkup) {
			&main::Output(
			" -export all",
			" -map \"\$(EPOCBLD$Bld)\\$Trg.map\""
			);
		}
		else {
			&main::Output(' -export dllexport');
		}

		if($CWRuntimeLibs ne "") {
			&main::Output(
				" -l$CWRuntimeLibs "
			);
		}
		if($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o) {
			&main::Output(
				" $Include",
				' -nocompactimportlib', 
				" -implib \"\$(EPOCBLD$Bld)\\$ExportLibrary.lib\"",
				" -addcommand \"out:$Trg\" -warnings off",
				"\n",
			);
		}
		else{
#		Dont generate import libs for an Exe
			&main::Output(
				" $Include",
				" -addcommand \"out:$Trg\" -warnings off",
				"\n",
			);
		}
	}
	my $AbsentSubst = '';
	if ($EntrySymbol) {
		$AbsentSubst = " -absent $EntrySymbol";
	}

	&main::Output(
		"LINK_FLAGS$Bld= \$(COMMON_LINK_FLAGS$Bld) \$(LIBS$Bld) \\\n\t",
		" -o \"$BLDTRGPATH$Trg\" ", &main::LinkerOption("CW") 
	);
	if($CWRuntimeLibs ne "") {
			&main::Output(
				" -l$CWRuntimeLibs "
			);
	}
	if ($Bld=~/REL$/o && $BasicTrgType!~/^LIB$/o) {
		# Generate map file for release build executables
		&main::Output(
			" -map \"$BLDTRGPATH$Trg.map\"", 
		);
	}
	if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o) {
		&main::Output(
			" -f \"\$(EPOCBLD)\\$ExportLibrary.def\"",	# use generated .DEF file
		);
		if (&main::ExportUnfrozen) {
			&main::Output(
				" -implib \"\$(EPOCLIB)\\UDEB\\$ExportLibrary.lib\"",
				" -addcommand \"out:$Trg\" -warnings off"
			);
		}
		else {
			&main::Output(
				' -noimplib'
			);
		}
	}
	else {
		&main::Output(
			' -noimplib'
		);
	}
	&main::Output(
		"\n",
		"\n"
	);

	&main::Output(
		&Generic_Quote("$BLDTRGPATH$Trg"), " : \$(LINK_OBJS$Bld) "
	);
	if (-e $DefFile) { # effectively "if project frozen ..."
		&main::Output(
			&Generic_Quote($DefFile)
		);
	}

	main::Output(" ", Generic_Quote("\$(EPOCSTATLINK$Bld)\\$firstlib") ) if $firstlib;
	main::Output(" ", Generic_Quote("\$(EPOCSTATLINK$Bld)\\$newlib") )   if $newlib;

	&main::Output(
		" \$(LIBS$Bld)\n"
	);

	my $checklib = "checklib";

	if ( StdCppTarget() ) {
		$checklib .= " stdc++ --coff";
	}
	else {
		$checklib .= " symc++ --coff";
	}

	&main::Output( "\t$checklib ","\$(USER_ADDED_ARCHIVES_$Bld)\n" ) if ($run_checklib);
#	Link by name first time round for dlls
	if ($BasicTrgType=~/^DLL$/o || $TrgType=~/^EXEXP$/o) {
		&main::Output(
			"\t$MWLD \$(STAGE1_LINK_FLAGS$Bld) -l \$(EPOCBLD$Bld) -search \$(notdir \$(LINK_OBJS$Bld))\n",
		);
		if(!$NamedSymLkup){
#		Dont delete the binary as we need to extract symbol/dependency info
			&main::Output(
			"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$Trg\"\n",
			);
		}

#		Generate an export info file
		my $show_options = "names,verbose";
		$show_options = "names,unmangled,verbose" if ($MWLD =~ /mwldsym2.exe/);
		&main::Output(
			"\t$MWLD -S -show only,$show_options -o \"\$(EPOCBLD$Bld)\\$ExportLibrary.inf\" \"\$(EPOCBLD$Bld)\\$ExportLibrary.lib\"\n"
		);

#		call makedef to reorder the export information
		&main::Output(
#			call perl on the script here so nmake will die if there are errors - this doesn't happen if calling perl in a batch file
			"\tperl -S makedef.pl $AbsentSubst -Inffile \"\$(EPOCBLD$Bld)\\$ExportLibrary.inf\""
		);
		if (SysTrg()) {
    			&main::Output( "\t\t-SystemTargetType \\\n" );
	    	}		
		if (-e $DefFile) { # effectively "if project frozen ..."
			&main::Output(
				" -Frzfile \"$DefFile\""
			);
		}
		my $Export;
		my $Ordinal=1;
		foreach $Export (&main::Exports) {
#				replace "$" with "$$" so that NMAKE doesn't think there's a macro in the function name
			$Export=~s-\$-\$\$-go;
			&main::Output(
				" -$Ordinal $Export"
			);
			$Ordinal++;
		}
		&main::Output(" -sym_name_lkup") if($NamedSymLkup);

		&main::Output(" -export_entrypoint_E32Dll") if ($TrgType =~ /^STDDLL$/i);  # Workaround: To export entry point _E32DLL for target type STDDLL

		&main::Output(
			" \"\$(EPOCBLD)\\$ExportLibrary.def\" \n",
			"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$ExportLibrary.inf\"\n",
			"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$ExportLibrary.lib\"\n"
		);
	}
	elsif($NamedSymLkup) {
#	2-stage linking required for all those targets that enable symbol lookup
		&main::Output( "\t$checklib ","\$(USER_ADDED_ARCHIVES_$Bld)\n" ) if ($run_checklib);
		&main::Output(
			"\t$MWLD \$(STAGE1_LINK_FLAGS$Bld) -l \$(EPOCBLD$Bld) -search \$(notdir \$(LINK_OBJS$Bld))\n",
		);
	}
	my $gen_src_file = "";
	if($NamedSymLkup){
#		pick the symbols and the dependencies.
		&main::Output(
			"\t$MWLD -S -show only,names,verbose -o \"\$(EPOCBLD$Bld)\\$ExportLibrary.sym\" \"\$(EPOCBLD$Bld)\\$Trg\"\n",
		);

#		Generate the source file with symbol and dependency information in the named data segment.
		$gen_src_file = "${BaseTrg}_SYM_";
		
		if($BasicTrgType=~/^EXE$/o){
#		For an EXE, generate the symbols as well as the dependencies
			&main::Output(
				"\tperl -S sym_lkup_util.pl -o \"\$(EPOCBLD$Bld)\\$gen_src_file.cpp\" -sym \"\$(EPOCBLD$Bld)\\$ExportLibrary.sym\" -map \"\$(EPOCBLD$Bld)\\$Trg.map\"\n"
			);
		}
		else {
#		For DLLs, generate only the dependencies.
			&main::Output(
				"\tperl -S sym_lkup_util.pl -o \"\$(EPOCBLD$Bld)\\$gen_src_file.cpp\" -sym \"\$(EPOCBLD$Bld)\\$ExportLibrary.sym\" --ignore_export_dir\n"
			);
		}
		main::Output(
			"\t\$(CW$Bld) -c \"\$(EPOCBLD$Bld)\\$gen_src_file.cpp\" -o \"\$(EPOCBLD$Bld)\\$gen_src_file.o\"\n",
		);
	}

#	Perform the final link step
	&main::Output(
		"\t$MWLD "
	);
	if ($BasicTrgType=~/^LIB$/o) {
		&main::Output(
			"-library "
		);

		&main::Output( "-l $stdcpp_tag_path ") if ($add_stdcpp_tag);
	}
	
	if($NamedSymLkup){
#	Final linking and cleanup
		main::Output(
		"\$(LINK_FLAGS$Bld) -l \$(EPOCBLD$Bld) -search \$(notdir \$(LINK_OBJS$Bld))",
		" \"\$(EPOCBLD$Bld)\\$gen_src_file.o\"\n",
		"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$gen_src_file.cpp\"\n",
		"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$gen_src_file.o\"\n",
		"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$ExportLibrary.sym\"\n",
		"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$Trg.map\"\n",
		"\t\$(ERASE) \"\$(EPOCBLD$Bld)\\$Trg\"\n",
		);
	}
	else {
		&main::Output(
			"\$(LINK_FLAGS$Bld) -l \$(EPOCBLD$Bld) -search \$(notdir \$(LINK_OBJS$Bld))\n",
		);
	}
	
	
	if (&main::Plat eq 'TOOLS') {
		&main::Output(
			"\tcopy \"BLDTRGPATH$Trg\" \"",&main::EPOCToolsPath,"$Trg\"\n"
		);
	}
	if (&Winutl_CopyForStaticLinkage) {
		&Generic_MakeWorkDir("MAKEWORK$Bld", "\$(EPOCTRG$Bld)");
		&main::Output(
			"\n",
			&Generic_Quote("\$(EPOCTRG$Bld)\\$Trg"), " : ", 
			&Generic_Quote("$BLDTRGPATH$Trg"), "\n",
			"\t", &Generic_CopyAction(),
		);
	}

	&main::Output(
		"\n",
		"\n"
	);
}

sub PMStartSrcList {

	&main::Output(
		"# SOURCES\n",
		"\n"
	);
}

sub PMBitMapBld {

	&Generic_BitMapBld;

	# Need to copy generic resource into emulated Z drive

	my $BitMapRef=&main::BitMapRef;

	my $ChopTrgPath="";
	if ($$BitMapRef{TrgPath}) {
		$ChopTrgPath.="\\$$BitMapRef{TrgPath}";
		chop $ChopTrgPath;
	}

	my @BldList=&main::BldList;
	my $Bld;
	foreach $Bld (@BldList) {
		my $path="\$(EPOCTRG$Bld)$ChopTrgPath";
		&main::Output(
			&Generic_Quote("$path\\$$BitMapRef{Trg}"), " : ", 
			&Generic_Quote("$$BitMapRef{GenericTrg}"), "\n",
			"\t", &Generic_CopyAction(),
			"\n"
		);
	}
}

sub PMResrcBld {

	&Generic_ResrcBld;

	# Need to copy generic resource into emulated Z drive

	my $ResourceRef=&main::ResourceRef;
	my @BldList=&main::BldList;

	foreach my $Bld (@BldList) 
	{
		if(! defined $$ResourceRef{Hdronly})
		{
			&main::Output(
				&Generic_Quote("\$(EPOCTRG$Bld)\\$$ResourceRef{Trg}"), " : ", 
				&Generic_Quote("$$ResourceRef{GenericTrg}"), "\n",
				"\t", &Generic_CopyAction(),
				"\n"
			);
		}
	}
}

sub PMAifBld {

	&Generic_AifBld;

	# Need to copy generic resource into emulated Z drive

	my $AifRef=&main::AifRef;
	my $TrgDir="";
	if (&Generic_Definition("TRGDIR") ne "") {
		$TrgDir="\\\$(TRGDIR)";
	}

	my @BldList=&main::BldList;
	my $Bld;
	foreach $Bld (@BldList) {
		my $path="\$(EPOCTRG$Bld)$TrgDir";
		&main::Output(
			&Generic_Quote("$path\\$$AifRef{Trg}"), " : ",
			&Generic_Quote("$$AifRef{GenericTrg}"), "\n",
			"\t", &Generic_CopyAction(),
			"\n"
		);
	}
}


sub PMStartSrc {
	my $Src=&main::Src;

	&main::Output(
		"# Source $Src\n",
		"\n"
	);
}

sub PMSrcDepend {
	my @BldList=&main::BldList;	
	my @DepList=&main::DepList;
	my $BaseSrc=&main::BaseSrc;
	$BaseSrc =~ s/\.UID/_UID_/i if ($BaseSrc eq $uidfile);

	return if (@DepList == 0);

	foreach (@BldList) {
		&main::Output(
			&Generic_Quote("\$(EPOCBLD$_)\\$BaseSrc.o"), " \\\n",
		);
	}
	&main::Output(
		":"
	);
	foreach (@DepList) {
		&main::Output(
		" \\\n\t", &Generic_Quote($_)
		);
	}
	&main::Output(
		"\n",
		"\n"
	);
}

sub PMSrcBldDepend {
	my $Bld=&main::Bld;
	my @DepList=&main::DepList;
	my $BaseSrc=&main::BaseSrc;
	$BaseSrc =~ s/\.UID/_UID_/i if ($BaseSrc eq $uidfile);

	return if (@DepList == 0);

	&main::Output(
		&Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.o"), " :",
	);
	foreach (@DepList) {
		&main::Output(
			" \\\n\t", &Generic_Quote($_)
		);
	}
	&main::Output(
		"\n",
		"\n"
	);
}

sub PMEndSrcBld {
	my $BaseSrc=&main::BaseSrc;
	$BaseSrc =~ s/\.UID/_UID_/i if ($BaseSrc eq $uidfile);
	my $Bld=&main::Bld;
	my $Plat=&main::Plat;
	my $Src=&main::Src;
	my $SrcPath=&main::SrcPath;
	my $Ext=&main::ExtSrc;
	my $Cia = (lc($Ext) eq '.cia') ? 1 : 0;
	my $TrgType=&main::TrgType;
	# Get the information regarding supporting Compiler Wrapper Option
	my $IsCompilerWrapperOption=&main::CompilerWrapperOption();

	if ($Cia) {
		&main::Output(
			&Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.o"), " : ",
			&Generic_Quote("$SrcPath$Src"), "\n",
			"\techo $Src\n",
			"\t\$(CW$Bld) -lang c++ -o \"\$\@\" -c \"$SrcPath$Src\"\n",
			"\n",
#			assembler listing target - uses implicit rule to do disassembly
			"LISTING$Bld$BaseSrc\_ : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc\_.lis"), "\n",
			"\t", &Generic_CopyAction("$SrcPath$BaseSrc\_.$Plat.lst"),
			"\n"
		);
	} else {
		&main::Output(
			&Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.o"), " : ",
			&Generic_Quote("$SrcPath$Src"), "\n",
			"\techo $Src\n",
			"\t\$(CW$Bld) -o \"\$\@\" -c \"$SrcPath$Src\" "
		);
		# When building for OE target type and source file is of C++ type, 
 		# then pass macro "__wchar_t_defined" to indicate that datatype "wchar_t" is enabled.
 		if ( StdCppTarget() || $TrgType =~ /^(STDEXE|STDDLL|STDLIB)$/io ) 
 		{			
 			if (lc($Ext) =~ /^(.cpp|.cc|.cxx|.c\+\+)$/)
 			{
 				&main::Output(
 					" -d \"__wchar_t_defined\" "					
 				);			
 			}
 		}
 		&main::Output(
   			"\n",
 			"\n"
 		);
		&main::Output(
#			assembler listing target - uses implicit rule to do disassembly
			"LISTING$Bld$BaseSrc : ", &Generic_Quote("\$(EPOCBLD$Bld)\\$BaseSrc.lis"), "\n",
			"\t", &Generic_CopyAction("$SrcPath$BaseSrc.$Plat.lst"),
			"\n"
		);

		# Output files if Compiler Wrapper Option is specified
		if($IsCompilerWrapperOption)
		{
			my $Platcmpwrap=&main::Plat;
			&main::Output(
				"COMPWRAP$Bld$BaseSrc : ",
				&Generic_Quote("$SrcPath$Src"), "\n",
				"\techo Analysing $Src\n",
				"\t\$(COMPWRAP) \$(CW$Bld) -o \"\$\@\" -c \"$SrcPath$Src\" ",
				"\n\n"
			);

		}
	}
}

sub PMEndSrc {

	&main::Output(
		"\n",
		"\n"
	);
}

sub PMEndSrcList {

	my $show_options = "source";
	$show_options = "source,unmangled,comments" if ($MWLD =~ /mwldsym2.exe/);
	
	&main::Output(
		"\n",
		"# Implicit rule for generating .lis files\n",
		"\n",
		".SUFFIXES : .lis .o\n",
		"\n",
		".o.lis:\n",
		"\t$MWLD -S -show $show_options \$< -o \$\@\n",
		"\n",
		"\n"
	);

	if ($Win32Resrc) {
		my @BldList=&main::BldList;
		my @DepList=&main::Deps_GenDependsL($Win32Resrc);

		&main::Output(
			"# Win32 Resource $Win32Resrc\n",
			"\n",
			"DEPEND="
		);
		foreach (@DepList) {
			&main::Output(
				" \\\n\t", &Generic_Quote($_)
			);
		}
		&main::Output(
			"\n",
			"\n"
		);
	
		my $Bld;
		my $resbase=&main::Path_Split('Base',$Win32Resrc);
		my $respath=&main::Path_Chop(&main::Path_Split('Path',$Win32Resrc));
		foreach $Bld (@BldList) {
			&main::Output(
				&Generic_Quote("\$(EPOCBLD$Bld)\\$resbase.res"), " : ",
				&Generic_Quote($Win32Resrc), " \$(DEPEND)\n",
				"\tmwwinrc -o \$\@ \"$Win32Resrc\"\n",
				"\n"
			);
		}
		&main::Output(
			"\n",
			"\n"
		);
	}

	# Deal with accumulated MAKEDIRS etc.

	&Generic_End;
}

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 );
	}
}


1;