sbsv2/raptor/lib/flm/e32abiv2.flm
author timothy.murphy@nokia.com
Fri, 30 Apr 2010 16:07:17 +0100
branchfix
changeset 511 7581d432643a
parent 483 941b2742ee49
child 516 cd8318d5fb3a
permissions -rw-r--r--
fix: support new trace compiler features for preventing clashes. Automatically turn on OST_TRACE_COMPILER_IN_USE macro. Look for trace header in systemincludes. Make directories in makefile parse to prevent clashes during build. Correct path for autogen headers. Correct case issue with autogen headers on Linux.

# Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "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:
# ARMv5 EXE/DLL ABIv2 Function Like Makefile (FLM)
# Knows how to build all possible ABIV2 executables for ARM
#
#

# Feature/Binary Variation
#
# FEATUREVARIANTNAME != "" implies a product build configuration
# FEATUREVARIANT == 1 implies a .mmp defined feature variant binary
#
# By default:
#   Build all binaries in non-product builds *and*
#   Only build feature variant binaries in product builds.
#
#   test FEATUREVARIANTNAME=="" or FEATUREVARIANT==1
#
# If FEATUREVARIANTSAFE is set:
#   Only build feature invariant binaries in non-product builds *and*
#   Only build feature variant binaries in product builds.
#
#   test (FEATUREVARIANTNAME=="" and FEATUREVARIANT=="") or
#        (FEATUREVARIANTNAME!="" and FEATUREVARIANT==1)
#

DOBUILD:=
ifeq ($(FEATUREVARIANTSAFE),)
  DOBUILD:=$(if $(or $(call equal,$(FEATUREVARIANTNAME),),\
                     $(call equal,$(FEATUREVARIANT),1)),1)
else
  DOBUILD:=$(if $(or $(and $(call equal,$(FEATUREVARIANTNAME),),\
                           $(call equal,$(FEATUREVARIANT),)),\
                     $(and $(call not,$(call equal,$(FEATUREVARIANTNAME),)),\
                           $(call equal,$(FEATUREVARIANT),1))),1)
endif

ifeq ($(DOBUILD),1)

$(if $(FLMDEBUG),$(info <debug><flm name='e32abiv2' target='$(TARGET)' type='$(TARGETTYPE)' outputpath='$(OUTPUTPATH)' metasource='$(METASOURCE)' postlinkfiletype='$(POSTLINKFILETYPE)' /></debug>))

# Strip switch-type parameters
#
POSTLINKTARGETTYPE:=$(strip $(POSTLINKTARGETTYPE))
UID1:=$(strip $(UID1))
UID2:=$(strip $(UID2))
UID3:=$(strip $(UID3))
SID:=$(strip $(SECUREID))
VENDORID:=$(strip $(VENDORID))
AUTOEXPORTS:=$(strip $(AUTOEXPORTS))
DEFFILE:=$(strip $(DEFFILE))
IMPORTLIBRARYREQUIRED:=$(strip $(IMPORTLIBRARYREQUIRED))
EPOCALLOWDLLDATA:=$(strip $(EPOCALLOWDLLDATA))
PAGED:=$(strip $(PAGED))

# the output directories
VARIANTPLATFORM:=$(VARIANTPLATFORM)$(FEATUREVARIANTNAME)
RELEASABLEPATH:=$(RELEASEPATH)/$(VARIANTPLATFORM)/$(VARIANTTYPE)
INTERMEDIATEPATH:=$(OUTPUTPATH)/$(VARIANTPLATFORM)/$(VARIANTTYPE)
INTERMEDIATE_PLATFORM_PATH:=$(OUTPUTPATH)/$(VARIANTPLATFORM)
TRACE_MARKER_PATH:=$(OUTPUTPATH)
IMPORTLIBPATH:=$(RUNTIME_LIBS_PATH)

# LOCALLY USED VARIABLES
CLEANTARGETS:=
WHATRELEASE:=

# Work out which new/delete library to use for binaries.
CHECKLIB_TYPE:=symc++
STDCPPTAGFILE:=
ifeq ($(NOSTDCPP),1)
  ifeq ($(STDCPP),1)
    $(info <warning>STDCPP and NOSTDCPP both specified in $(PROJECT_META)</warning>)
  else
    ifeq ($(HAS_DEDICATED_OP_NEWDEL_LIB),1)
      DEFAULT_NEWLIB:=$(DEFAULT_SYMBIAN_NEWLIB)
    endif
  endif
else
  ifeq ($(STDCPP),1)
    CDEFS:=$(CDEFS) __SYMBIAN_STDCPP_SUPPORT__
    ifneq ($(SUPPORTS_STDCPP_NEWLIB),)
      ifeq ($(HAS_DEDICATED_OP_NEWDEL_LIB),1)
        DEFAULT_NEWLIB:=$(DEFAULT_STDCPP_NEWLIB)
      endif
      CHECKLIB_TYPE:=stdc++
      STDCPPTAGFILE:=$(EPOCROOT)/epoc32/tools/tag/tag_elf
    endif
  endif
endif

# If NEWLIB is specified in the MMP file, it overrides all the past stuff.
ifeq ($(NEWLIB),)
  NEWLIB:=$(DEFAULT_NEWLIB)
endif


##########################################################################
## OUTPUTS - externally relevant targets that this FLM generates


ifeq ($(EXPORTLIBRARY),)
  EXPORTLIBRARY:=$(TARGET)
endif

# This will insert the file version between the name and the extension.
# If there is more than one dot in generated filename the inserted position will be
# BEFORE the last but two dot. E.g name1.name2.name3.dll to name1.name2{version}.name3.dll
LIBEXT:=$(lastword $(subst .,$(CHAR_SPACE) ,$(EXPORTLIBRARY)))
LIBBASE:=$(patsubst %.$(LIBEXT),%,$(EXPORTLIBRARY))
ifneq ($(findstring .,$(EXPORTLIBRARY)),)
  # Please note $(EXPORTLIBRARY) doesn't include target type.
  VER_E32IMPORTLIBBASE:=$(IMPORTLIBPATH)/$(LIBBASE){$(VERSIONHEX)}.$(LIBEXT)
else
  VER_E32IMPORTLIBBASE:=$(IMPORTLIBPATH)/$(EXPORTLIBRARY){$(VERSIONHEX)}
endif

# Postlinkable targets need to be linked and elf2e32'd
ifneq ($(DOPOSTLINK),)
    E32TARGET:=$(RELEASABLEPATH)/$(TARGET)$(if $(EXPLICITVERSION),{$(VERSIONHEX)},).$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(POSTLINKFILETYPE))
    LINK_TARGET:=$(RELEASABLEPATH)/$(TARGET)$(if $(EXPLICITVERSION),{$(VERSIONHEX)},).$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(POSTLINKFILETYPE)).sym
    MAPFILE:=$(RELEASABLEPATH)/$(TARGET).$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(POSTLINKFILETYPE)).map
else
  E32TARGET:=
  LINK_TARGET:=
  MAPFILE:=
endif

# libs and klibs, on the other hand need to be archived
ifneq ($(call isoneof,$(TARGETTYPE),lib klib stdlib),)
  ARTARGET:=$(RELEASABLEPATH)/$(TARGET).lib
  # We need libs and klibs before we can link stuff with them:
  LIBRARY:: $(ARTARGET)
else
  ARTARGET:=
endif


ifneq ($(IMPORTLIBRARYREQUIRED),) # no dso files for plugins, animation dlls etc
  # make sure we don't build import libraries more than once for UDEB and UREL
  # Without this, wierd target-specific variable problems happen with LIBRARY in particular

  TMP_IMPORTLIBTARGET_ROOT:=$(IMPORTLIBPATH)/$(EXPORTLIBRARY)

  # ABIv2 .dso
  IMPORTLIBTARGET_DSO:=
  IMPORTLIBTARGETVERSIONED_DSO:=

  BUILDMARKER_IMPORTLIBTARGET_DSO:=TARGET_$(subst :,,$(VER_E32IMPORTLIBBASE)).dso
  WHATRELEASE:=$(WHATRELEASE) $(if $(EXPLICITVERSION),,$(TMP_IMPORTLIBTARGET_ROOT).dso)
  WHATRELEASE:=$(WHATRELEASE) $(VER_E32IMPORTLIBBASE).dso
  ifeq ($($(BUILDMARKER_IMPORTLIBTARGET_DSO)),)
    IMPORTLIBTARGET_DSO:=$(TMP_IMPORTLIBTARGET_ROOT).dso
    IMPORTLIBTARGETVERSIONED_DSO:=$(VER_E32IMPORTLIBBASE).dso
  endif

  # ABIv1 .lib (for specific builds, toolchains and host OS platforms only)
  IMPORTLIBTARGET_LIB:=
  IMPORTLIBTARGETVERSIONED_LIB:=
  BUILDMARKER_IMPORTLIBTARGET_LIB:=TARGET_$(subst :,,$(VER_E32IMPORTLIBBASE)).lib
  # Only for builds that require and support them, and only on windows
  ifeq ($(OSTYPE),cygwin)
  ifeq ($(GENERATE_ABIV1_IMPLIBS),1)
    WHATRELEASE:=$(WHATRELEASE) $(if $(EXPLICITVERSION),,$(TMP_IMPORTLIBTARGET_ROOT).lib)
    WHATRELEASE:=$(WHATRELEASE) $(VER_E32IMPORTLIBBASE).lib
    ifeq ($($(BUILDMARKER_IMPORTLIBTARGET_LIB)),)
      IMPORTLIBTARGET_LIB:=$(TMP_IMPORTLIBTARGET_ROOT).lib
      IMPORTLIBTARGETVERSIONED_LIB:=$(VER_E32IMPORTLIBBASE).lib
    endif
  endif
  endif
endif

# Try to make sure that we get the right linkas name
# If linkas is specified then split it up and
# put the hex version number in the right place
ifeq ($(LINKAS),)
  LINKASNAME=$(TARGET)
  LINKASTYPE=$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(POSTLINKFILETYPE))
else
  SPLIT_LINKAS=$(subst ., ,$(LINKAS))
  LINKASNAME=$(word 1,$(SPLIT_LINKAS))
  LINKASTYPE=$(word 2,$(SPLIT_LINKAS))
endif

# ignore UID3 if it is zero
ifeq ($(UID3),00000000)
  LINKASVERSIONED=$(LINKASNAME){$(VERSIONHEX)}.$(LINKASTYPE)
else
  LINKASVERSIONED=$(LINKASNAME){$(VERSIONHEX)}$(if $(UID3),[$(UID3)],).$(LINKASTYPE)
endif

##########################################################################
## TARGET GROUPS ##
RELEASABLES:=$(strip $(E32TARGET) $(ARTARGET) $(LINK_TARGET) $(MAPFILE))
# More targets to be added later
TARGETS:=$(strip $(E32TARGET) $(IMPORTLIBTARGET) $(LINK_TARGET) $(ARTARGET))

CREATABLEPATHS:=$(OUTPUTPATH)
CREATABLEPATHS:=$(CREATABLEPATHS) $(INTERMEDIATE_PLATFORM_PATH)
CREATABLEPATHS:=$(CREATABLEPATHS) $(INTERMEDIATEPATH)
CREATABLEPATHS:=$(CREATABLEPATHS) $(RELEASABLEPATH)
CREATABLEPATHS:=$(CREATABLEPATHS) $(RUNTIME_LIBS_PATH)
CREATABLEPATHS:=$(CREATABLEPATHS) $(IMPORTLIBPATH)
WHATRELEASE:=$(WHATRELEASE) $(RELEASABLES)



## HIGH LEVEL Targets ##
.PHONY:: $(ALLTARGET)

## GLOBAL TARGETS ############################################################
$(ALLTARGET):: $(RELEASABLES)
TARGET:: $(RELEASABLES)

## Internal targets ##

# Determine the name of the generated DSO file ###############################
# This is to generate the dso with the Some{Versionhex}.file.dso
# It reproduces what appears to be a problem in the current build system
# that affects messageintercept{000a0000}.esockdebug.dso whose
# filename differs from it's "linkas" name.
E32VAR:=$(subst .,$(CHAR_SPACE) ,$(TARGET))
E32SOME:=$(word 1,$(E32VAR))
E32VAR2:=$(patsubst $(E32SOME).%,%,$(TARGET))

# Separate '_SH' variables created for output into bash - Preserves '{' and '}'

ifneq ($(findstring .,$(TARGET)),)
	DSODEFFILENAMEBASE:=$(E32SOME){$(VERSIONHEX)}.$(E32VAR2)
else
	DSODEFFILENAMEBASE:=$(TARGET){$(VERSIONHEX)}
endif
GENERATED_DSO:=$(call dblquote,$(INTERMEDIATEPATH)/$(DSODEFFILENAMEBASE).dso)
GENERATED_DEFFILE:=$(INTERMEDIATEPATH)/$(DSODEFFILENAMEBASE).def

## IMPORT LIBRARY  ###########################################################

# Static libraries will be postlinked when they are used so don't try to postlink them

ifneq ($(IMPORTLIBRARYREQUIRED),)
ifneq ($(or $(DEFFILE),$(EXPORTUNFROZEN)),)
# Both ABIv2 .dso and ABIv1 .lib import library generation require a processed .def file,
# unless EXPORTUNFROZEN is being used
PREPPEDDEFFILE:=
ifneq ($(DEFFILE),)
  ifeq ($(EXPORTUNFROZEN),)
    PREPPEDDEFFILE:=$(INTERMEDIATEPATH)/$(TARGET).prep
    CLEANTARGETS:=$(CLEANTARGETS) $(PREPPEDDEFFILE)
    define importlibtarget_prepfile
      $(PREPPEDDEFFILE): $(DEFFILE)
		$(call startrule,importlibtarget_prepfile,FORCESUCCESS) \
		$(PREPDEF) $(call dblquote,$(DEFFILE)) $(call dblquote,$(PREPPEDDEFFILE)) \
		$(call endrule,importlibtarget_prepfile)
    endef
    $(eval $(importlibtarget_prepfile))
  endif
endif

# ABIv2 .dso
ifneq ($(IMPORTLIBTARGET_DSO),) # check that we haven't tried to specify this target already

  # By Now we're committed to producing a target for this DSO so it's safe to
  # set the marker that will prevent any further targets from being made.
  $(eval $(BUILDMARKER_IMPORTLIBTARGET_DSO):=1)

  ifneq ($(EXPLICITVERSION),)
    TARGETS:=$(strip $(TARGETS) $(IMPORTLIBTARGETVERSIONED_DSO))

    # Add this importlibrary to our global targets
    LIBRARY:: $(IMPORTLIBTARGETVERSIONED_DSO)
    $(ALLTARGET):: $(IMPORTLIBTARGETVERSIONED_DSO)
    TARGET:: $(IMPORTLIBTARGETVERSIONED_DSO)

  else
    TARGETS:=$(strip $(TARGETS) $(IMPORTLIBTARGETVERSIONED_DSO) $(IMPORTLIBTARGET_DSO))

    # Add this importlibrary to our global targets
    LIBRARY:: $(IMPORTLIBTARGET_DSO)
    $(ALLTARGET):: $(IMPORTLIBTARGETVERSIONED_DSO) $(IMPORTLIBTARGET_DSO)
    TARGET:: $(IMPORTLIBTARGETVERSIONED_DSO) $(IMPORTLIBTARGET_DSO)


  endif



  ifneq ($(EXPORTUNFROZEN),) # Unfrozen  - warn and create .dso as side-effect of the final postlink
    $(info <warning project='$(PROJECT_META)' component='$(COMPONENT_META)'>EXPORTUNFROZEN present in $(PROJECT_META) - unfrozen exports will be represented in import library.</warning> )
    define importlibtarget_unfrozen
      $(IMPORTLIBTARGET_DSO): $(IMPORTLIBTARGETVERSIONED_DSO)
		$(call startrule,importlibtarget_unfrozen,FORCESUCCESS) \
		$(GNUCP) $$(call dblquote,$$<) $$(call dblquote,$$@) \
		$(call endrule,importlibtarget_unfrozen)
    endef

    define importlibtarget_unfrozen_ver
      $(IMPORTLIBTARGETVERSIONED_DSO): $(E32TARGET)
		$(call startrule,importlibversioned_unfrozen,FORCESUCCESS) \
		$(GNUCP) "$(GENERATED_DSO)" "$$@" \
		$(call endrule,importlibversioned_unfrozen)
    endef

    ifeq ($(EXPLICITVERSION),)
      # Generate the general dso if we aren't
      # being asked to make just the specific version.
      $(eval $(importlibtarget_unfrozen))
    endif

    $(eval $(importlibtarget_unfrozen_ver))
  else
    ifneq ($(DEFFILE),) # Frozen - use the def file and create .dso directly
      define importlibtarget_func
       $(IMPORTLIBTARGET_DSO): $(IMPORTLIBTARGETVERSIONED_DSO)
	   $(call startrule,importlibtarget,FORCESUCCESS) \
	   $(GNUCP) "$$<" "$$@" \
	   $(call endrule,importlibtarget)
      endef

      ifeq ($(EXPLICITVERSION),)
          # Generate the general dso if we aren't
          # being asked to make just the specific version.
          $(eval $(importlibtarget_func))
      endif

      define importlibtargetversioned_func
        $(IMPORTLIBTARGETVERSIONED_DSO): $(ELF2E32) $(PREPPEDDEFFILE)
	      $(call startrule,importlibversioned,FORCESUCCESS) \
	      $(ELF2E32) --sid=0x$(if $(SID),$(SID),$(if $(UID3),$(UID3),0))  --version=$(VERSION)  	   \
	 	  --definput="$(PREPPEDDEFFILE)" 				   \
	 	  --dso=$$(call dblquote,$$@) 				   \
	 	  --linkas=$(call dblquote,$(LINKASVERSIONED)) \
	      $(call endrule,importlibversioned)
      endef
      $(eval $(importlibtargetversioned_func))
    endif #  ifneq ($(DEFFILE),)
  endif #  ifneq ($(EXPORTUNFROZEN),)
endif #  ifneq ($(IMPORTLIBTARGET_DSO),)

# ABIv1 .lib
ifneq ($(IMPORTLIBTARGETVERSIONED_LIB),) # check that we haven't tried to specify this target already

  # By Now we're committed to producing a target for this DSO so it's safe to
  # set the marker that will prevent any further targets from being made.
  $(eval $(BUILDMARKER_IMPORTLIBTARGET_LIB):=1)

  define abiv1_generatelib

    ifeq ($(EXPLICITVERSION),)
      LIBRARY:: $(IMPORTLIBTARGETVERSIONED_LIB) $(IMPORTLIBTARGET_LIB)

    else
      LIBRARY:: $(IMPORTLIBTARGETVERSIONED_LIB)

    endif

    # If frozen, a prepped .def file is used as the basis for .lib creation
    # If unfrozen, .lib files are based on the .def file generated by the final postlink
    $(IMPORTLIBTARGETVERSIONED_LIB): $(if $(EXPORTUNFROZEN),$(E32TARGET),$(PREPPEDDEFFILE))
	$(call startrule,importlibversioned_abiv1) \
        if [ -f "$(EPOCROOT)/epoc32/tools/def2dll.pl" -a -f "$(if $(EXPORTUNFROZEN),$(call dblquote,$(GENERATED_DEFFILE)),$(PREPPEDDEFFILE))" ]; then \
                 $(PERL) $(EPOCROOT)/epoc32/tools/def2dll.pl \
		--path=$(IMPORTLIBPATH) \
		--bldpath=$(INTERMEDIATEPATH) \
		--import=$(notdir $(basename $(IMPORTLIBTARGETVERSIONED_LIB))) \
		--deffile="$(if $(EXPORTUNFROZEN),$(call dblquote,$(GENERATED_DEFFILE)),$(PREPPEDDEFFILE))" \
		--linkAs=$(call dblquote,$(LINKASVERSIONED)) \
		--inter ; fi \
	$(call endrule,importlibversioned_abiv1)

    ifeq ($(EXPLICITVERSION),)
      $(IMPORTLIBTARGET_LIB): $(IMPORTLIBTARGETVERSIONED_LIB)
	$(call startrule,importlibtarget_abiv1) \
	if [ -f $(EPOCROOT)/epoc32/tools/def2dll.pl ]; then $(GNUCP) "$$<" "$$@" ; fi \
	$(call endrule,importlibtarget_abiv1)
    endif
  endef

  $(eval $(abiv1_generatelib))
endif #  ifneq ($(IMPORTLIBTARGET_LIB),)
endif #  ($(or $(DEFFILE),$(EXPORTUNFROZEN)),)
endif #  ifneq ($(IMPORTLIBRARYREQUIRED),)


## POSTLINK ##################################################################

# Set up the name of the exports file if this is a customdll
EXPTARGET:=
ifneq ($(DOPOSTLINK),)
  ifneq ($(and $(or $(STATICLIBRARY),$(ARMLIBS),$(ARMRT)),$(DEFFILE)),)
    EXPTARGET:=$(INTERMEDIATE_PLATFORM_PATH)/$(notdir $(VER_E32IMPORTLIBBASE)).exp
  endif
endif

# Generating the import library is enough if TARGETTYPE=implib #############

ifneq ($(DOPOSTLINK),)
# Capabilities
FINAL_CAPABILITIES:=$(if $(CAPABILITY),$(CAPABILITY),NONE)

# Paging options for the old postlinker
POSTLINKER_PAGEDOPTION:=--defaultpaged
ifeq ($(PAGED),1)
  POSTLINKER_PAGEDOPTION:=--paged
endif
ifeq ($(PAGED),0)
  POSTLINKER_PAGEDOPTION:=--unpaged
endif

CLEANTARGETS:=$(CLEANTARGETS) $(E32TARGET)
CLEANTARGETS:=$(CLEANTARGETS) $(GENERATED_DEFFILE)
CLEANTARGETS:=$(CLEANTARGETS) $(GENERATED_DSO)

endif # ifneq ($(DOPOSTLINK),)

ifneq ($(TARGETTYPE),implib)

## CUSTOM DLLS ###############################################################
# exp file
#
# This tends to help getting exported objects
# out of the arm libs and into custom dlls.

ifneq ($(EXPTARGET),)
ifeq ($(TARGET_$(EXPTARGET)),)
# We only need one of these exptargets for UDEB and UREL
TARGET_$(EXPTARGET):=1

EXPTARGETASMFILE:=$(INTERMEDIATE_PLATFORM_PATH)/$(notdir $(VER_E32IMPORTLIBBASE)).s

define e32expgen_func
$(EXPTARGET): $(DEFFILE) $(ELF2E32)
	$(call startrule,expgen) \
	$(ELF2E32) \
	   --definput=$$(call dblquote,$(DEFFILE)) \
	   --dump=a \
	   --output=$(call dblquote,$(EXPTARGETASMFILE)) && \
	$(ASM) $(TARGET_ARCH_OPTION) $(AAPCS_OPTION) $(ASM_OUTPUT_OPTION) $$(call dblquote, $$@) $(EXPTARGETASMFILE) \
	$(call endrule,expgen)
endef

$(eval $(e32expgen_func))
CLEANTARGETS:=$(CLEANTARGETS) $(EXPTARGET) $(EXPTARGETASMFILE)
endif
endif




## SOURCE FILES ##############################################################

# Source files can be either C++ files (.cpp) or Assmbler-in-C++ files (.cia)
# We have to split the two because they have the same link stage, the compile
# stage is different for each.

CPPFILEEXTENSIONS:=.cpp .CPP .Cpp .CPp .CpP .cPP .cpP .cPp .cc .CC \
	.Cc .c++ .C++ .cxx .CXX .Cxx .cXx .CxX .CXx .cC .cXX .cxX
CFILEEXTENSIONS:=.c .C
CIAFILEEXTENSIONS:=.CIA .cia .Cia .cIa .cIA .ciA .CIa .CiA
ASMFILEEXTENSIONS:=.s .S


# Extract the CPP files from our sources
CPPFILES:=$(call extractfilesoftype,$(CPPFILEEXTENSIONS),$(SOURCE))
CFILES:=$(call extractfilesoftype,$(CFILEEXTENSIONS),$(SOURCE))
ASMFILES:=$(call extractfilesoftype,$(ASMFILEEXTENSIONS),$(SOURCE))

# Find out what assember-in-c files there are
# If appropriate, work out what CPP files will be created from the assembler files
CIAFILES:=$(call extractfilesoftype,$(CIAFILEEXTENSIONS),$(SOURCE))
CIA_CPPFILES:=
ifeq ($(TRANSFORM_CIA),1)
  CIA_CPPFILES:=$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(CIAFILEEXTENSIONS),_.cpp,$(CIAFILES)))
else

endif

## LINK ######################################################################
# Bring together all the .o files compiled from  .cpp, .c, .s and .cia files.
# These files are stored in the "non-releasable" output diretory.

define mapcpp2object
$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(CPPFILEEXTENSIONS),.o,$1))
endef

define mapc2object
$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(CFILEEXTENSIONS),.o,$1))
endef

define mapasm2object
$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(ASMFILEEXTENSIONS),.o,$1))
endef

define mapcia2object
$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(CIAFILEEXTENSIONS),_.o,$1))
endef

# Determine what object files will be linked by using the source files.
CPPFILES_LINKOBJECTS:=$(call mapcpp2object,$(CPPFILES))
CFILES_LINKOBJECTS:=$(call mapc2object,$(CFILES))
ifeq ($(TRANSFORM_CIA),1) 
  CIAFILES_LINKOBJECTS:=$(patsubst %_.cpp,%_.o,$(CIA_CPPFILES))
else
  CIAFILES_LINKOBJECTS:=$(call mapcia2object,$(CIAFILES))
endif
ASMFILES_LINKOBJECTS:=$(call mapasm2object,$(ASMFILES))

# Try to link object files in the order in which the source files were specified.
# This makes BC comparisons with non-Raptor builds easier.
# Use the order of the source list to establish the order of the object files:
LINKOBJECTS:=$(call relocatefiles,$(INTERMEDIATEPATH),$(SOURCE))
# Replace the file extensions of the Source files with .o (or _.o for cia files) now
# the list will contain the object files in the same order as the list of source files.
LINKOBJECTS:=$(foreach FILE,$(LINKOBJECTS),$(basename $(FILE))$(if $(filter $(addprefix %,$(CIAFILEEXTENSIONS)),$(FILE)),_).o)

ifneq ($(MULTIFILE_ENABLED),)
MULTIFILEOBJECT:=$(INTERMEDIATEPATH)/$(TARGET).$(POSTLINKFILETYPE)_$(VARIANTTYPE)_multifileobject.o
MULTIFILE_VIAFILE:=$(INTERMEDIATEPATH)/$(TARGET)_$(VARIANTTYPE)_multifile.via
endif

## Via file ####################################
# list of all objects to be linked
#
VIAFILE:=$(INTERMEDIATEPATH)/$(TARGET)_$(VARIANTTYPE)_objects.via
ifneq ($(GENERATELINKERFEEDBACK),)
FEEDBACKFILE:=$(INTERMEDIATEPATH)/$(TARGET)_$(VARIANTTYPE)_feedback.fdb
endif

# The groupin10 macro allows us to construct a via file, 10 objects at a time
# to avoid limits on argument lengths and sizes on Windows.
# It expands to a list of commands, each of which is on a separate line.
# This causes the shell to be invoked once for each line but each line should
# be shorter than the maximum allowed by windows.
define groupin10
	$(if $1,@echo -e $(foreach L,$(wordlist 1,10,$1),"$(L)\\n") >>$(VIAFILE),)
	$(if $1,$(call groupin10,$(wordlist 11,$(words $1),$1)),@true)
endef

################################################


## Link-type selection:
#	runtime static libraries link via AR
ifneq ($(ARTARGET),)
# Assuming that there are no libdeps in this case because this is probably one of the
# Runtime libraries which has no deps.

define artarget_func
$(ARTARGET): $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT),$(LINKOBJECTS)) $(STDCPPTAGFILE)
	$(if $(MULTIFILE_ENABLED),,@echo "$(STDCPPTAGFILE)" > $(VIAFILE);
	$(call groupin10,$(LINKOBJECTS)) ;)
	$(call startrule,ar,FORCESUCCESS) \
	$$(call dblquote,$(AR)) $(ARCHIVER_CREATE_OPTION) $$@ $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT),$(COMMANDFILE_OPTION)$(VIAFILE)) \
	$(if $(DUMPBCINFO),&& $(FROMELF) -v $$@  > $$@.elfdump,)  \
	$(call endrule,ar)
endef
$(eval $(artarget_func))

CLEANTARGETS:=$(CLEANTARGETS) $(VIAFILE) $(if $(DUMPBCINFO),$(ARTARGET).elfdump,)
endif



# Targettype is some type of DLL or EXE (or derivative)
ifneq ($(LINK_TARGET),)

located_ARMLIBS:=$(foreach L,$(ARMLIBS),$(wildcard $(RVCTLIB)/*/$(L)))
located_STATICLIBRARIES:=$(foreach L,$(STATICLIBRARY),$(STATIC_LIBRARY_DIR)/$(L).lib)
e32abiv2_LIBS:=$(EXPTARGET) $(LINKER_STUB_LIBRARY) $(if $(STATIC_RUNTIME_LIB),$(STATIC_RUNTIME_DIR)/$(STATIC_RUNTIME_LIB),) $(located_STATICLIBRARIES)
# DLLS and EXEs - These objects are linked by a linker
ifeq ($(ARMRT),)
# Some of the runtime libraries do not set ARMRT because of a circular reference
# problem; we need to stop these from linking to their own dso and not link to
# the STATIC_LIBS_LIST.
ifneq ($(findstring $(TARGET).dso,$(RUNTIME_LIBS_LIST)),)
# (almost) ARM RUNTIME LIBS
REDUCED_RUNTIME_LIBS_LIST:=$(subst $(TARGET).dso,,$(RUNTIME_LIBS_LIST))

ifeq ($(VARIANTTYPE),udeb)
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(IMPORTLIBPATH)/,$(LIBRARY_DEBUG)) $(addprefix $(RUNTIME_LIBS_PATH)/,$(REDUCED_RUNTIME_LIBS_LIST)) $(located_ARMLIBS)
else
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(IMPORTLIBPATH)/,$(LIBRARY)) $(addprefix $(RUNTIME_LIBS_PATH)/,$(REDUCED_RUNTIME_LIBS_LIST)) $(located_ARMLIBS)
endif

else
# NORMAL
#
ifeq ($(VARIANTTYPE),udeb)
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(IMPORTLIBPATH)/,$(LIBRARY_DEBUG))
else
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(IMPORTLIBPATH)/,$(LIBRARY))
endif
ifeq ($(HAS_DEDICATED_OP_NEWDEL_LIB),1)
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(RUNTIME_LIBS_PATH)/,$(NEWLIB))
endif
e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(RUNTIME_LIBS_PATH)/,$(RUNTIME_LIBS_LIST)) $(addprefix $(STATIC_LIBS_PATH)/,$(STATIC_LIBS_LIST)) $(located_ARMLIBS)

endif
else
# ARM RUNTIME LIBS
ifeq ($(VARIANTTYPE),udeb)
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(IMPORTLIBPATH)/,$(LIBRARY_DEBUG)) $(located_ARMLIBS)
else
  e32abiv2_LIBS:=$(e32abiv2_LIBS) $(addprefix $(IMPORTLIBPATH)/,$(LIBRARY)) $(located_ARMLIBS)
endif
endif

# NOTE: the groupin10 macro must be used before a call to the "startrule" macro
# because the code between startrule and endrule is packaged up into one
# commandline which would defeat the purpose of groupin10.
# This is undesirable because viafile generation commands appear
# outside the relevant tags but it is also unavoidable.
define linktarget_func
## The actual link target, dependencies and build step
$(E32TARGET): $(POSTLINKDEFFILE) $(ELF2E32) $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT) $(CIAFILES_LINKOBJECTS),$(LINKOBJECTS)) $(e32abiv2_LIBS) $(LINKER_ENTRYPOINT_LIBDEP) $(if $(SUPPORTS_STDCPP_NEWLIB),$(CHECKLIB)) $(if $(LINKERFEEDBACK_STAGE2),$(FEEDBACKFILE),) $(if $(HAVE_ORDERONLY),|,) $(EPOCROOT)/epoc32/build/TEM_LIB
	$(if $(MULTIFILE_ENABLED),,@echo -n "" > $(VIAFILE);
	$(call groupin10,$(LINKOBJECTS)) ;)
	$(call startrule,linkandpostlink) \
	$(if $(PERTURBSTARTTIME),$(RANSLEEP) $(PERTURBMSECS) ;,) \
	$(if $(SUPPORTS_STDCPP_NEWLIB),$(if $(located_STATICLIBRARIES),$(CHECKLIB) $(CHECKLIB_TYPE) --elf $(call dblquote,$(located_STATICLIBRARIES)) &&,),) \
	$(LD) $(LINKER_MISC_FLAGS) $(LINKER_DEFAULT_LIB_PATHS) $(SYMBIAN_LINK_FLAGS) $(if $(DEBUG_INFO),$(LINKER_DEBUG_OPTION),$(LINKER_NODEBUG_OPTION)) \
	  $(if $(ARMLIBS),$(LD_WARNINGS_SUPPRESSION_ARMLIBS),) \
	  $(SHARED_OBJECT_OPTION) $(SPLIT_OPTION) \
	  $(RW_BASE) \
	  $(LINKER_ARCH_OPTION) \
	  $(SYMVER_OPTION) $(SO_NAME_OPTION)=$(call dblquote,$(LINKASVERSIONED)) \
	  $(LINKER_ENTRYPOINT_SETTING) \
	  -o $$(call dblquote,$(LINK_TARGET)) \
	  $(if $(LTCG),$(LTCG_OPTION),) \
	  $(LINKER_SYMBOLS_OPTION) $(LINKER_SYMBOLS_FILE_OPTION)=$(call dblquote,$(MAPFILE)) \
  	  $(LINKEROPTION) \
	  $(if $(MULTIFILE_ENABLED),$(call dblquote,$(MULTIFILEOBJECT) $(CIAFILES_LINKOBJECTS)),$(COMMANDFILE_OPTION)$(call dblquote,$(VIAFILE))) \
      $(if $(GENERATELINKERFEEDBACK),$(FEEDBACK_OPTION)$(call dblquote,$(FEEDBACKFILE))) \
	  $(if $(LINKER_ADD_STATIC_RUNTIME),$(if $(STATIC_RUNTIME_LIB),$(LINKER_GROUP_START_OPTION) $(STATIC_RUNTIME_DIR)/$(STATIC_RUNTIME_LIB) $(LINKER_GROUP_END_OPTION),)) \
	  $(call dblquote,$(e32abiv2_LIBS)) $(LINKER_DEFAULT_LIBS) && \
	  $(ELF2E32) \
	  --sid=0x$(if $(SID),$(SID),$(if $(UID3),$(UID3),0)) \
	  --version=$(VERSION) \
	  --capability=$(FINAL_CAPABILITIES) \
	  --linkas=$(call dblquote,$(LINKASVERSIONED)) \
	  --fpu=$(if $(ARMFPU),$(ARMFPU),$(POSTLINKER_FPU_DEFAULT)) \
	  --targettype=$(POSTLINKTARGETTYPE) \
	  --output=$$(call dblquote,$$@) \
	  --elfinput=$(call dblquote,$(LINK_TARGET)) \
	  $(if $(UID1),--uid1=0x$(UID1),) \
	  $(if $(UID2),--uid2=0x$(UID2),) \
	  $(if $(UID3),--uid3=0x$(UID3),) \
	  $(if $(VENDORID),--vid=0x$(VENDORID),) \
	  $(if $(EXPTARGET),--customdlltarget,) \
	  $(if $(ARMLIBS),--excludeunwantedexports,) \
	  $(if $(EPOCALLOWDLLDATA),--dlldata,) \
	  $(if $(EPOCPROCESSPRIORITY),--priority=$(EPOCPROCESSPRIORITY),) \
	  $(if $(EPOCSTACKSIZE),--stack=0x$(EPOCSTACKSIZE),) \
	  $(if $(EPOCHEAPSIZEMIN),--heap=0x$(EPOCHEAPSIZEMIN)$(CHAR_COMMA)0x$(EPOCHEAPSIZEMAX),) \
	  $(if $(EPOCFIXEDPROCESS),--fixedaddress,) \
	  $(if $(EPOCDATALINKADDRESS),--datalinkaddress=$(EPOCDATALINKADDRESS),) \
	  $(if $(NAMEDSYMLKUP),--namedlookup,) \
	  $(if $(SMPSAFE),--smpsafe,) \
	  $(if $(POSTLINKDEFFILE),--definput=$(POSTLINKDEFFILE),) \
	  $(if $(EXPORTUNFROZEN),--unfrozen,) \
	  $(if $(AUTOEXPORTS),--sysdef=$(call dblquote,$(AUTOEXPORTS)),) \
	  $(if $(CANIGNORENONCALLABLE), \
	    $(if $(IMPORTLIBRARYREQUIRED),,--ignorenoncallable),) \
	  $(if $(CANHAVEEXPORTS), --defoutput=$(call dblquote,$(GENERATED_DEFFILE)) --dso=$(GENERATED_DSO)) \
	  $(if $(filter $(VARIANTTYPE),$(DEBUGGABLE)),--debuggable,) \
	  $(if $(POSTLINKER_SUPPORTS_WDP), \
	    --codepaging=$(PAGEDCODE_OPTION) --datapaging=$(PAGEDDATA_OPTION), \
	    $(POSTLINKER_PAGEDOPTION)) \
	  $(if $(NOCOMPRESSTARGET),--uncompressed, \
	    $(if $(INFLATECOMPRESSTARGET),--compressionmethod=inflate, \
	      $(if $(BYTEPAIRCOMPRESSTARGET),--compressionmethod=bytepair, \
	        --compressionmethod=$(POSTLINKER_COMPRESSION_DEFAULT)))) \
	  --libpath="$(call concat,$(PATHSEP)$(CHAR_SEMIC),$(strip $(RUNTIME_LIBS_PATH) $(STATIC_LIBS_PATH)))" \
	  $(if $(SAVESPACE),$(if $(EXPORTUNFROZEN),,&& { $(GNURM) -rf $(INTERMEDIATEPATH); true; })) \
	$(call endrule,linkandpostlink)

$(MAPFILE): $(E32TARGET)
$(LINK_TARGET): $(E32TARGET)
endef
ifneq ($(DOPOSTLINK),)
$(eval $(linktarget_func))
endif # ifneq ($(DOPOSTLINK),)

CLEANTARGETS:=$(CLEANTARGETS) $(VIAFILE) $(if $(GENERATELINKERFEEDBACK),$(FEEDBACKFILE)) $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT))
WHATRELEASE:=$(WHATRELEASE) $(MAPFILE)

endif # if TARGETTYPE lib


## Run trace compiler ##############################################
ifeq ($(UID3),)
 ifeq ($(UID2),)
  USE_TRACE_COMPILER:=
 else
  UID_TC:=$(UID2)
 endif
else
 UID_TC:=$(UID3)
endif

# USE_TRACE_COMPILER defaults to blank in Raptor config.
# Users can turn TC on by setting it to 1 in user config.
ifneq ($(USE_TRACE_COMPILER),)
  include $(FLMHOME)/tracecompiler.mk
  WHATRELEASE:=$(WHATRELEASE) $(TRACE_DICTIONARY) $(AUTOGEN_HEADER)
  ifneq ($(TRACE_PATH),)
      CDEFS:=$(CDEFS) OST_TRACE_COMPILER_IN_USE
  endif
endif

CC_CPPONLY_ARGS:=$(SYMBIAN_CCFLAGS) $(if $(DEBUG_INFO),-g) $(DEBUG_FORMAT) \
  $(RUNTIME_SYMBOL_VISIBILITY_OPTION) $(EXCEPTIONS) \
  $(CC_WARNINGS_CONTROL_OPTION) $(CC_ERRORS_CONTROL_OPTION) \
  $(TARGET_ARCH_OPTION) $(ENUM_OPTION) $(OWN_LIBRARY_OPTION) $(FPMODE_OPTION) \
  $(EXPORT_VTBL_OPTION) $(NO_UNALIGNED_ACCESS) $(VFE_OPTION) $(AAPCS_OPTION) \
  $(CPPONLYOPTION) $(INSTRUCTION_SET) \
  $(if $(ALWAYS_BUILD_AS_ARM),$(ARM_INSTRUCTION_SET),$(THUMB_INSTRUCTION_SET) $(call makemacrodef,-D,$(COMPILER_THUMB_DEFINES))) \
  $(COMPILER_FPU_OPTION)$(if $(ARMFPU),$(ARMFPU),$(COMPILER_FPU_DEFAULT))

## COMPILE CPP Files #################################################################

# For ARMCC we can compile all sourcefiles with one invocation
# The pathprep macro is used to make sure that forward slashes in options
# are not interpreted as being paths by CYGWIN on Windows.  On windows
# pathprep makes a forward slash into two.

# The majority of ARMCC arguments are common across all compiler invocations
# Order is significant here in that OPTION_REPLACE here and in ABLD should
# have the same impact
CC_CORE_ARGS:=$(SYMBIAN_CCFLAGS) $(if $(DEBUG_INFO),-g) $(DEBUG_FORMAT) \
  $(RUNTIME_SYMBOL_VISIBILITY_OPTION) $(EXCEPTIONS) \
  $(CC_WARNINGS_CONTROL_OPTION) $(CC_ERRORS_CONTROL_OPTION) \
  $(TARGET_ARCH_OPTION) $(ENUM_OPTION) $(OWN_LIBRARY_OPTION) $(FPMODE_OPTION) \
  $(EXPORT_VTBL_OPTION) $(NO_UNALIGNED_ACCESS) $(VFE_OPTION) $(AAPCS_OPTION) \
  $(COMPILE_ONLY_OPTION) $(INSTRUCTION_SET) \
  $(if $(ALWAYS_BUILD_AS_ARM),$(ARM_INSTRUCTION_SET),$(THUMB_INSTRUCTION_SET) $(call makemacrodef,-D,$(COMPILER_THUMB_DEFINES))) \
  $(COMPILER_FPU_OPTION)$(if $(ARMFPU),$(ARMFPU),$(COMPILER_FPU_DEFAULT))

ifeq ($(STDCPP),1)
SYSTEMINCLUDE:=$(SYSTEMINCLUDE) $(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(STDCPP_INCLUDE)))
endif

define option_replace
  # Process a single, combined, item of the form 'search<->replace' in order to modify the command line tool call
  # We split this into its component arguments for use in substitutions
  # Spaces will have been escaped elsewhere to maintain distinct words, so we resurrect these
  # after the split.
  SEARCH:=$(subst %20,$(CHAR_SPACE),$(word 1,$(subst <->,$(CHAR_SPACE),$(1))))
  REPLACE:=$(subst %20,$(CHAR_SPACE),$(word 2,$(subst <->,$(CHAR_SPACE),$(1))))

  # Depending on whether there's a wildcard in the search, we may require either a normal $(subst) or a $(patsubst)
  PATSUBST:=$$(if $$(findstring %,$$(SEARCH)),1,)

  ifeq ($$(PATSUBST),1)
    CC_CORE_ARGS:=$$(patsubst $$(SEARCH),$$(REPLACE),$$(CC_CORE_ARGS))
  else
    CC_CORE_ARGS:=$$(subst $$(SEARCH),$$(REPLACE),$$(CC_CORE_ARGS))
  endif
endef
$(foreach ITEM,$(OPTION_REPLACE_COMPILER),$(eval $(call option_replace,$(ITEM))))

define e32abiv2_compile

$(eval DEPENDFILENAME:=$(1).d)
$(eval DEPENDFILE:=$(wildcard $(DEPENDFILENAME)))

# $4 is for language specific options (e.g. C++ vs C)
$(1): $(2) $(PROJECT_META) $(if $(MULTIFILE_ENABLED),,$(if $(DEPENDFILE),,RESOURCE BITMAP EXPORT)) $(if $(LINKERFEEDBACK_STAGE2),$(FEEDBACKFILE),) | $(if $(USE_TRACE_COMPILER),$(TRACE_MARKER),)  
	$(call startrule,compile,,$(2))		\
		$(if $(PERTURBSTARTTIME), $(RANSLEEP) $(PERTURBMSECS) ;,) \
		$(if $(MULTIFILE_ENABLED), echo $(2) $(3) > $(MULTIFILE_VIAFILE) ;,) \
		$(CC) $(LICENSERETRY_OPTION) \
			$(CC_CORE_ARGS) \
			$(OPTION_COMPILER) $(if $(MULTIFILE_ENABLED),$(4),$(3)) \
			$(if $(LTCG),$(LTCG_OPTION),) \
			$(if $(USE_PROFILER_FEEDBACK),--profile=$(call dblquote,$(ARM_PROFILER_FILE)),) \
			$(call makemacrodef,-D,$(COMPILER_INTERWORK_DEFINES) $(CDEFS))				\
			$(if $(PREINCLUDE),$(PREINCLUDE_OPTION) ,)$(call concat, $(PREINCLUDE_OPTION) ,$(call dblquote,$(PREINCLUDE)))\
			$(if $(SET_ARMINC),$(if $(RVCTINC),$(COMPILER_SYSTEM_INCLUDE_OPTION)$(call dblquote,$(RVCTINC)),),)       \
			$(COMPILER_SYSTEM_INCLUDE_OPTION)$$(call dblquote,$$(<D))                                                      \
			$(if $(USERINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(USERINCLUDE)))      \
			$(if $(SYSTEMINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(SYSTEMINCLUDE)))  \
			$(if $(NOHIDEALL),--no_hide_all,) \
			$(if $(NO_DEPEND_GENERATE),,$(DEPEND_OPTION) $(call dblquote,$(1).d)) \
			$(if $(LINKERFEEDBACK_STAGE2),$(FEEDBACK_OPTION)$(call dblquote,$(FEEDBACKFILE))) \
			$(if $(MULTIFILE_ENABLED),--multifile $(OUTPUT_OPTION) $(MULTIFILEOBJECT) \
			--via $$(call dblquote, $(MULTIFILE_VIAFILE)),$(OUTPUT_OPTION) $$@ $$(call dblquote, $$<))  \
	$(call endrule,compile)

ifeq ($(NO_DEPEND_GENERATE),)
  CLEANTARGETS:=$$(CLEANTARGETS) $(DEPENDFILENAME)
endif

ifneq ($(DEPENDFILE),)
  ifeq ($(NO_DEPEND_INCLUDE),)
    ifeq ($(filter %CLEAN,$(call uppercase,$(MAKECMDGOALS))),)
      -include $(DEPENDFILE)
    endif
  endif
endif

# individual source file compilation
SOURCETARGET_$(call sanitise,$(2)): $(1)

endef

# Evaluate .cpp and .c files in one go for multifile, cannot do in separate steps since we have the same target.
# This implementation means the .c files will always get put at the end of the .via file. Maybe there is a better way to do this?
$(if $(MULTIFILE_ENABLED),$(eval $(call e32abiv2_compile,$(MULTIFILEOBJECT),$(CPPFILES),$(CFILES),$(CPP_LANG_OPTION))),$(foreach F,$(CPPFILES),$(eval $(call e32abiv2_compile,$(call mapcpp2object,$(F)),$(F),$(CPP_LANG_OPTION)))))
$(if $(MULTIFILE_ENABLED),,$(foreach F,$(CFILES),$(eval $(call e32abiv2_compile,$(call mapc2object,$(F)),$(F),$(C_LANG_OPTION)))))
ifneq ($(TRANSFORM_CIA),1)
  $(if $(MULTIFILE_ENABLED),,$(foreach F,$(CIAFILES),$(eval $(call e32abiv2_compile,$(call mapcia2object,$(F)),$(F),$(CPP_LANG_OPTION) $(COMPILER_CIA_FLAGS)))))
endif

CLEANTARGETS:=$(CLEANTARGETS) $(if $(MULTIFILE_ENABLED),$(MULTIFILE_VIAFILE) $(MULTIFILEOBJECT),$(CPPFILES_LINKOBJECTS) $(CFILES_LINKOBJECTS) $(CIAFILES_LINKOBJECTS)) $(if $(GENERATELINKERFEEDBACK),$(FEEDBACKFILE))

## Listing target ###################################################
# Very similar to compile, apart from the extra flags passed to the
# compile and different output options

define map2listfile
$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(CPPFILEEXTENSIONS) $(CFILEEXTENSIONS),.lis,$1))
endef


define e32abiv2_cpponly
# $1 is the sourcefile

$(eval CPPONLYTARGET:=$(strip $(call extractandmap,$(CPPFILEEXTENSIONS) $(CFILEEXTENSIONS),.$(subst _,.,$(call sanitise,$(FULLVARIANTPATH))).pre,$1)))

CPPONLY:: $(CPPONLYTARGET)

$(CPPONLYTARGET): $(1) $(PROJECT_META)  $(if $(DEPENDFILE),,RESOURCE BITMAP EXPORT)
	$(call startrule,e32cpponly,,$(1))		\
		$(if $(PERTURBSTARTTIME), $(RANSLEEP) $(PERTURBMSECS) ;,) \
		$(CC) $(LICENSERETRY_OPTION) $(SYMBIAN_CCFLAGS) \
			$(CC_CPPONLY_ARGS) \
			$(OPTION_COMPILER) 						\
			$(call makemacrodef,-D,$(COMPILER_INTERWORK_DEFINES) $(CDEFS))				\
			$(if $(PREINCLUDE),$(PREINCLUDE_OPTION) ,)$(call concat, $(PREINCLUDE_OPTION) ,$(call dblquote,$(PREINCLUDE)))\
			$(if $(SET_ARMINC),$(if $(RVCTINC),$(COMPILER_SYSTEM_INCLUDE_OPTION)$(call dblquote,$(RVCTINC)),),)       \
			$(COMPILER_SYSTEM_INCLUDE_OPTION)$$(call dblquote,$$(<D))                                                   \
			$(if $(USERINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(USERINCLUDE)))      \
			$(if $(SYSTEMINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(SYSTEMINCLUDE)))  \
			$(if $(NOHIDEALL),--no_hide_all,) \
			$$(call dblquote, $$<) $(OUTPUT_OPTION) $$(@) \
	$(call endrule,e32cpponly)

CLEANTARGETS:=$$(CLEANTARGETS) $(CPPONLYTARGET)
endef

ifneq ($(filter CPPONLY,$(call uppercase,$(MAKECMDGOALS))),)
$(foreach F,$(CPPFILES) $(CFILES),$(eval $(call e32abiv2_cpponly,$(F))))
endif

define e32abiv2_listing
# $1 is the sourcefile

$(eval LISTINGTARGET:=$(strip $(call extractandmap,$(CPPFILEEXTENSIONS) $(CFILEEXTENSIONS),.$(subst _,.,$(call sanitise,$(FULLVARIANTPATH))).$(TARGET).$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(POSTLINKFILETYPE)).lst,$1)))
$(eval DEPENDFILENAME:=$(call map2listfile,$1).d)
$(eval DEPENDFILE:=$(wildcard $(DEPENDFILENAME)))


LISTING:: $(LISTINGTARGET)

$(LISTINGTARGET): $(1) $(PROJECT_META)  $(if $(DEPENDFILE),,RESOURCE BITMAP EXPORT)
	$(call startrule,e32listing,,$(1))		\
		$(if $(PERTURBSTARTTIME), $(RANSLEEP) $(PERTURBMSECS) ;,) \
		$(CC) $(LICENSERETRY_OPTION) $(SYMBIAN_CCFLAGS) \
			$(CC_CORE_ARGS) \
			$(LISTING_OPTION)		            	\
			$(OPTION_COMPILER) 						\
			$(call makemacrodef,-D,$(COMPILER_INTERWORK_DEFINES) $(CDEFS))				\
			$(if $(PREINCLUDE),$(PREINCLUDE_OPTION) ,)$(call concat, $(PREINCLUDE_OPTION) ,$(call dblquote,$(PREINCLUDE)))\
			$(if $(SET_ARMINC),$(if $(RVCTINC),$(COMPILER_SYSTEM_INCLUDE_OPTION)$(call dblquote,$(RVCTINC)),),)       \
			$(COMPILER_SYSTEM_INCLUDE_OPTION)$$(call dblquote,$$(<D))                                                   \
			$(if $(USERINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(USERINCLUDE)))      \
			$(if $(SYSTEMINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$(call dblquote,$(SYSTEMINCLUDE)))  \
			$(if $(NOHIDEALL),--no_hide_all,) \
			$(if $(NO_DEPEND_GENERATE),,$(DEPEND_OPTION) $(call dblquote,$(DEPENDFILENAME))) \
			$$(call dblquote, $$<) $(OUTPUT_OPTION) $$(@) \
	$(call endrule,e32listing)

CLEANTARGETS:=$$(CLEANTARGETS) $(LISTINGTARGET)

ifeq ($(NO_DEPEND_GENERATE),))
  CLEANTARGETS:=$$(CLEANTARGETS) $(DEPENDFILENAME)
endif

ifneq ($(DEPENDFILE),)
  ifeq ($(NO_DEPEND_INCLUDE),)
    ifeq ($(filter %CLEAN,$(call uppercase,$(MAKECMDGOALS))),)
      -include $(DEPENDFILE)
    endif
  endif
endif

endef

# No point at all in generating listing targetsif we aren't going to make them
ifneq ($(filter LISTING,$(call uppercase,$(MAKECMDGOALS))),)
$(foreach F,$(CPPFILES) $(CFILES),$(eval $(call e32abiv2_listing,$(F))))
endif



# Function to execute FREEZE ###########################################
ifneq ($(SUPPORT_FREEZE),)

# Fivespaces variable created to ensure a suitable gap of space characters
# Is placed between the separate arguments. This fixes a problem in Cygwin, where
# separate arguments are interpreted as a single argument when passed to bash
FIVESPACES=$(BLANK)     $(BLANK)

FREEZEGUARD:=TARGET_$(TARGET)_$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(POSTLINKFILETYPE))_$(IMPORTLIBPATH)_EFREEZE

define e32freeze

FREEZE:: $(1)
	$(call startrule,freeze,,$(RESOLVED_DEFFILE)) \
	$(EFREEZE) $(EFREEZE_REMOVE_OPTION) "$(RESOLVED_DEFFILE)" $(FIVESPACES) $(call dblquote,$(GENERATED_DEFFILE)) \
	$(call endrule,freeze)
endef

# Only freeze once - udeb and urel cannot differ
ifeq ($($(FREEZEGUARD)),)
  # For most freezing activity we need the temporary .def file generated in the final post-link
  # that lists the current exports - FREEZE can therefore be dependent on the final post-linked binary,
  # with the side-effect that a build is triggered if someone tries to freeze without having built.
  #
  # However, there's one case where we don't want to be dependent on the post-linked binary in this way,
  # and that's when (a) there are missing exports, (b) the user's aware of them and (c) they're deliberately freezing to
  # remove them using EFREEZE's remove option.  Being dependent on the post-linked binary in this case, where ELF2E32
  # actually fails to generate a final binary, would mean that the freeze would never happen and post-linking would
  # just be continually re-attempted (to fail each time).
  #
  # So, as a special case, if the user is explicitly attempting to freeze and perform removals, we make FREEZE dependent
  # on the temporary .def file instead.  This has no rule to actually make it, but gives a hint as to what is wrong if
  # the users performs a freeze with remove without having explicitly built previously.
  #
  ifneq ($(EFREEZE_REMOVE_OPTION),)
    $(eval $(call e32freeze,$(GENERATED_DEFFILE)))
  else
    $(eval $(call e32freeze,$(E32TARGET)))
  endif
  $(FREEZEGUARD):=1
endif

endif

CLEANTARGETS:=$(CLEANTARGETS) $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT),$(CPPFILES_LINKOBJECTS) $(CFILES_LINKOBJECTS))

## ASSEMBLER FILES ###################################################################
# CIA VERSION      ############################################
define mapcia2xxx
$(call relocatefiles,$(INTERMEDIATEPATH),$(call extractandmap,$(CIAFILEEXTENSIONS),$2,$1))
endef

define e32abiv2_CIA2CPP

$(eval e32abiv2_OFILE:=$(call mapcia2xxx,$(1),_.o))
$(eval e32abiv2_PREFILE:=$(call mapcia2xxx,$(1),_.pre))
$(eval e32abiv2_CPPFILE:=$(call mapcia2xxx,$(1),_.cpp))
$(eval CLEANTARGETS:=$(CLEANTARGETS) $(e32abiv2_OFILE) $(e32abiv2_CPPFILE) $(e32abiv2_PREFILE))

$(e32abiv2_OFILE): $(e32abiv2_CPPFILE) $(PROJECT_META)
	$(call startrule,cia2cpp2o,,$(e32abiv2_CPPFILE)) \
		$(if $(PERTURBSTARTTIME),$(RANSLEEP) $(PERTURBMSECS) ;,) \
			$(CC) $(LICENSERETRY_OPTION) \
			$(CC_CORE_ARGS) \
			$(if $(LTCG),$(LTCG_OPTION),) \
			$(OPTION_COMPILER) \
			$(call makemacrodef,-D,$(COMPILER_INTERWORK_DEFINES) $(CDEFS) $(CIADEFS)) $(CPP_LANG_OPTION)      \
	 		$(if $(USERINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$$(call dblquote,$(USERINCLUDE)))     \
	 		$(if $(SYSTEMINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$$(call dblquote,$(SYSTEMINCLUDE))) \
	 		$$(call dblquote, $$<) $(OUTPUT_OPTION) $$@ \
	$(call endrule,cia2cpp2o)


# preprocessed CIA file to a CPP file
$(e32abiv2_CPPFILE): $(e32abiv2_PREFILE)
	$(call startrule,tranasm) \
	$(if $(CPPFILT),CPPFILT="$(CPPFILT)",) \
	$(TRANASM) --suppress-check --output="$$@" $$^ \
	$(call endrule,tranasm)

$(eval DEPENDFILENAME:=$(e32abiv2_PREFILE).d)
$(eval DEPENDFILE:=$(wildcard $(DEPENDFILENAME)))

# preprocess the cia file
$(eval e32abiv2_PREFILE_OPTIONS:= $(LICENSERETRY_OPTION) $(PREPROCESSOR_OPTION) $(CPP_OPTION) \
       $(SYMBIAN_CCFLAGS) $(call makemacrodef,-D,$(COMPILER_INTERWORK_DEFINES) $(CDEFS) $(CIADEFS)) $(CPP_LANG_OPTION) \
       $(if $(PREINCLUDE),$(PREINCLUDE_OPTION) ,)$$(call concat, $(PREINCLUDE_OPTION) ,$$(call dblquote,$(PREINCLUDE))) \
       $(if $(USERINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$$(call dblquote,$(USERINCLUDE))) \
       $(if $(SYSTEMINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$$(call dblquote,$(SYSTEMINCLUDE))) \
       $(if $(ARMINC),$(if $(RVCTINC), $(COMPILER_SYSTEM_INCLUDE_OPTION)$$(call dblquote,$(RVCTINC)),),) )


$(e32abiv2_PREFILE): $1 $(PROJECT_META) $(if $(DEPENDFILE),,RESOURCE BITMAP EXPORT)
	$(call startrule,cia2cpp,,$1) \
	$(if $(PERTURBSTARTTIME),$(RANSLEEP) $(PERTURBMSECS) ;,) \
	$(CC) $(e32abiv2_PREFILE_OPTIONS) $(OUTPUT_OPTION) $$@ $$(call dblquote,$1) \
	$(if $(NO_DEPEND_GENERATE),,&& $(CC) -M $(e32abiv2_PREFILE_OPTIONS) --depend_format=unix $(OUTPUT_OPTION) $$@ $$(call dblquote,$1) > $(call dblquote,$(e32abiv2_PREFILE).d)) \
	$(call endrule,cia2cpp)

ifeq ($(NO_DEPEND_GENERATE),)
  CLEANTARGETS:=$$(CLEANTARGETS) $(DEPENDFILENAME)
endif

ifneq ($(DEPENDFILE),)
  ifeq ($(NO_DEPEND_INCLUDE),)
    ifeq ($(filter %CLEAN,$(call uppercase,$(MAKECMDGOALS))),)
      -include $(DEPENDFILE)
    endif
  endif
endif

endef

# Create a rule for each cia file
ifeq ($(TRANSFORM_CIA),1)
  $(eval $(foreach e32abiv2_RULE,$(CIAFILES),$(call e32abiv2_CIA2CPP,$(e32abiv2_RULE))))
endif

# Pure assembler (.s files) ################################

e32abiv2_asm_OPTIONS:=$(LICENSERETRY_OPTION) \
  $(CC_CORE_ARGS) \
  $(OPTION_COMPILER) \
  $(call makemacrodef,-D,$(COMPILER_INTERWORK_DEFINES) $(CDEFS)) \
  $(if $(USERINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$$(call dblquote,$(USERINCLUDE)))     \
  $(if $(SYSTEMINCLUDE),$(COMPILER_SYSTEM_INCLUDE_OPTION),)$$(call concat, $(COMPILER_SYSTEM_INCLUDE_OPTION),$$(call dblquote,$(SYSTEMINCLUDE)))

# note that the --no_rtti option cannot be passed with the -M option
# so forcibly remove it when generating ASM dependencies.
#
define e32abiv2_asm

$(eval DEPENDFILENAME:=$(1).d)
$(eval DEPENDFILE:=$(wildcard $(DEPENDFILENAME)))

$(1): $(2) $(PROJECT_META) $(if $(DEPENDFILE),,RESOURCE BITMAP EXPORT)
	$(call startrule,asmcompile,,$(2)) \
		$(if $(PERTURBSTARTTIME),$(RANSLEEP) $(PERTURBMSECS) ;,) \
		$(CC) $(e32abiv2_asm_OPTIONS) \
		$(if $(NO_DEPEND_GENERATE),,$(DEPEND_OPTION) $(call dblquote,$(DEPENDFILENAME))) \
	 	$$(call dblquote, $$<) $(OUTPUT_OPTION) $$@ \
	$(call endrule,asmcompile)
ifeq ($(NO_DEPEND_GENERATE),)
	$(call startrule,asmdependencies) \
		$(CC) -M $(subst --no_rtti,,$(e32abiv2_asm_OPTIONS)) --depend_format=unix \
	  	$(OUTPUT_OPTION) $$@ $$(call dblquote,$2) > $(call dblquote,$(DEPENDFILENAME)) \
	$(call endrule,asmdependencies)
endif

ifeq ($(NO_DEPEND_GENERATE),)
  CLEANTARGETS:=$$(CLEANTARGETS) $(DEPENDFILENAME)
endif

ifneq ($(DEPENDFILE),)
  ifeq ($(NO_DEPEND_INCLUDE),)
    ifeq ($(filter %CLEAN,$(call uppercase,$(MAKECMDGOALS))),)
      -include $(DEPENDFILE)
    endif
  endif
endif

CREATABLEPATHS:=$$(CREATABLEPATHS) $(INTERMEDIATEPATH)

endef

$(eval $(foreach F,$(ASMFILES), $(call e32abiv2_asm,$(call mapasm2object,$(F)),$(F))))
CLEANTARGETS:=$(CLEANTARGETS) $(ASMFILES_LINKOBJECTS)

endif # ifneq ($(TARGETTYPE),implib)


########################## Build ROMFILE target ############################
EPOC_ROOT:=$(patsubst %/,%,$(EPOCROOT))
TOBLDINF:=$(dir $(subst :,,$(subst $(EPOC_ROOT)/,,$(COMPONENT_META))))

# Only build ROMFILE if asked
ifneq ($(filter ROMFILE,$(call uppercase,$(MAKECMDGOALS))),)
    ifeq ($(ROMFILE_$(call sanitise,$(TARGET).$(REQUESTEDTARGETEXT))),)
        ROMFILE_$(call sanitise,$(TARGET).$(REQUESTEDTARGETEXT)):=1
        ROMDIR:=$(EPOC_ROOT)/epoc32/rom/$(TOBLDINF)

        # Default values
        ROMFILETYPE:=file
        ROMFILE:=$(TARGET).$(REQUESTEDTARGETEXT)
        ROMPATH:=sys/bin/
        ROMDECORATIONS:=
        ROMFILETYPE_RAM:=data
        ROMFILE_RAM:=$(TARGET).$(REQUESTEDTARGETEXT)
        ROMPATH_RAM:=sys/bin/
        BUILDROMTARGET:=1
        ABIDIR:=MAIN

        $(eval $(call DoRomSet))

        ifneq ($(EPOCFIXEDPROCESS),)
            ROMDECORATIONS:=$(ROMDECORATIONS) fixed
        endif
        ifeq ($(PAGED),1)
            ROMDECORATIONS:=$(ROMDECORATIONS) paged
        endif
        ifeq ($(PAGED),0)
            ROMDECORATIONS:=$(ROMDECORATIONS) unpaged
        endif


        ifeq ($(TESTCODE),TRUE)
        	# Add 'TEST' to the .iby filename
        	ROMTEST:=test
            ifeq ($(TEST_OPTION),BOTH)
                DATATEXT:="data=/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).auto.bat test/$(MODULE).auto.bat"\n"data=/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).manual.bat test/$(MODULE).manual.bat"
            else
                ifneq ($(TEST_OPTION),NONE)
                    DATATEXT:="data=/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TEST_OPTION).bat test/$(MODULE).$(TEST_OPTION).bat"
                endif
            endif
        else
        	DATATEXT:=
        endif

        # ROMTARGET
        ifneq ($(ROMTARGET),)
            ifneq ($(words $(ROMTARGET)),1)
                ROMTARGETALL:=$(ROMTARGET)
                ROMTARGET:=$(word 1,$(ROMTARGET))
            endif

            ifeq ($(ROMTARGET),<none>)
                BUILDROMTARGET:=
            else
                ifneq ($(ROMTARGET),+)
                    ifneq ($(notdir $(ROMTARGET)),)
                        ROMFILE:=$(notdir $(ROMTARGET))
                    endif
                    ifneq ($(dir $(ROMTARGET)),./)
                        ROMPATH:=$(dir $(ROMTARGET))
                    endif
                endif
            endif
        endif
    endif

    ROMFILENAME:=$(ROMDIR)$(PLATFORM)$(ROMTEST).iby

    # RAMTARGET
    ifneq ($(RAMTARGET),)
        ROMDECORATIONS_RAM:=" attrib=r"
        ifneq ($(RAMTARGET),+)
            ifneq ($(notdir $(RAMTARGET)),)
                ROMFILE_RAM:=$(notdir $(RAMTARGET))
            endif
            ifneq ($(dir $(RAMTARGET)),./)
                ROMPATH_RAM:=$(dir $(RAMTARGET))
            endif
        endif
    endif

    define BuildRomfileTarget
        $(ALLTARGET)::ROMFILE
        ROMFILE::
	        $(call startrule,rombuild)	\
	        $(GNUMKDIR) -p $(ROMDIR) \
            $(if $(ROMFILE_CREATED_$(TOBLDINF)),,&& echo -e "// $(subst $(EPOC_ROOT)/,,$(ROMFILENAME))\n//\n$(DATATEXT)" > $(ROMFILENAME)) \
            $(if $(BUILDROMTARGET),&& echo "$(ROMFILETYPE)=/epoc32/release/##$(ABIDIR)##/##BUILD##/$(TARGET).$(REQUESTEDTARGETEXT)   $(1)$(ROMDECORATIONS)" >> $(ROMFILENAME))	\
	        $(if $(RAMTARGET),&& echo "$(ROMFILETYPE_RAM)=/epoc32/release/##$(ABIDIR)##/##BUILD##/$(TARGET).$(REQUESTEDTARGETEXT)   $(ROMPATH_RAM)$(ROMFILE_RAM)$(ROMDECORATIONS_RAM)" >> $(ROMFILENAME))	\
	        $(call endrule,buildromfiletarget)
    endef

    # When VARIANTTYPE changes, romfile is finished,
    # apart from if this is a new component......
    ifneq ($(PREVIOUSVARIANTTYPE),)
        ifneq ($(VARIANTTYPE),$(PREVIOUSVARIANTTYPE))
            ifneq ($(ROMFILE_CREATED_$(TOBLDINF)),)
                ROMFILEFINISHED:=1
            else
                ROMFILEFINISHED:=
            endif
        endif
    endif

    # When romfile is finished, don't continue to add to it
    ifeq ($(ROMFILEFINISHED),)
        $(eval $(call BuildRomfileTarget,$(ROMPATH)$(ROMFILE)))
    endif

    # Don't allow romfile to be recreated for every MMP
    ifeq ($(ROMFILE_CREATED_$(TOBLDINF)),)
        ROMFILE_CREATED_$(TOBLDINF):=1
    endif

    # Build other ROMTARGETs if there is more than one
    ifneq ($(ROMTARGETALL),)
        RAMTARGET:=
        $(foreach ROMTARGET,$(wordlist 2,$(words $(ROMTARGETALL)),$(ROMTARGETALL)),$(eval $(call BuildRomfileTarget,$(ROMTARGET))))
        ROMTARGETALL:=
    endif

    # Keep track of variant type while romfile is being created
    PREVIOUSVARIANTTYPE:=$(VARIANTTYPE)

    WHATRELEASE:=$(WHATRELEASE) $(ROMFILENAME)
endif

# Deal with test code batch files generation.
ifneq ($(TESTPATH),)

    CREATABLEPATHS:=$(CREATABLEPATHS) $(EPOCROOT)/epoc32/data/z/test/
    $(eval $(call MakeTestBatchFiles,$(TARGET),$(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH)))
    BATCHFILE_CREATED_$(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH):=1
    TARGET_CREATED_$(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH)_$(TARGET):=1
    WHATRELEASE:=$(WHATRELEASE) $(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH)
endif

###################### End of Build ROMFILE target ######################

# Feature Variation requires a .vmap file to be created for each binary
#
ifneq ($(FEATUREVARIANTNAME),)
ifneq ($(E32TARGET),)

OUTPUTVMAP:=$(E32TARGET).vmap
WHATRELEASE:=$(WHATRELEASE) $(OUPUTVMAP)

TARGET:: $(OUTPUTVMAP)
VMAPNEEDS:=$(E32TARGET) $(SOURCE) $(PROJECT_META)

BV_SOURCELIST:=$(addprefix -s ,$(SOURCE) $(PROJECT_META))
BV_FEATURELIST:=$(addprefix -f ,$(FEATURELISTFILES))
BV_USER_INCLUDES:=$(addprefix -u ,$(USERINCLUDE))
BV_SYSTEM_INCLUDES:=$(addprefix -x ,$(SYSTEMINCLUDE))

# translate double quoted macros because $(shell) messes them up in some make engines
BV_MACROLIST:=$(COMPILER_INTERWORK_DEFINES) $(CDEFS) $(if $(ALWAYS_BUILD_AS_ARM),,$(COMPILER_THUMB_DEFINES))
BV_DEFINES:=$(call makemacrodef,-D,$(subst ",__SBS__QUOTE__,$(BV_MACROLIST)))

# the script to generate our .vmap file and hash value
VMAPCOMMAND:=$(CREATEVMAP) -o $(OUTPUTVMAP) $(BV_FEATURELIST) $(BV_DEFINES) -p $(PREINCLUDE) $(BV_SOURCELIST) $(BV_USER_INCLUDES) $(BV_SYSTEM_INCLUDES) -c $(CREATEVMAPCPP)

# a recipe to create the .vmap from the "sources" with the createvmap script
$(call raptor_recipe,createvmap,$(OUTPUTVMAP),$(VMAPNEEDS),$(VMAPCOMMAND))

endif # E32TARGET != ""
endif # FEATUREVARIANTNAME != ""

########################### CONCLUSION ###################################

# make the output directories while reading makefile - some build engines prefer this
$(call makepath,$(CREATABLEPATHS))

## Clean up
$(call raptor_clean,$(CLEANTARGETS))

# For the --what option and the log file
$(call raptor_release,$(filter-out %.sym,$(WHATRELEASE)))

endif # DOBUILD

## The End