sbsv2/raptor/lib/flm/resource.flm
author timothy.murphy@nokia.com
Fri, 30 Apr 2010 16:07:17 +0100
branchfix
changeset 511 7581d432643a
parent 488 bae97f326378
child 529 b74730c98ccc
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) 2007-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:
# Function Like Makefile (FLM) to create a resource header (.rsg)
# and resource files (.rsc, .r01, .r02 etc.)
#
#

## Parameters that are expected:
# TARGET
# TARGETPATH
# LANGUAGES
# HEADER
# HEADERONLY
# EPOCROOT
# MMPDEFS
# PRODUCT_INCLUDE
# SYSTEMINCLUDE
# USERINCLUDE
# GNUCPP
# GNUSED
# RCOMP
# OUTPUTPATH
# SOURCE
# BINCOPYDIRS


# The rss is pre-processed once for each language and results
# in a file with extension r$(LANGUAGE) where $(LANGUAGE) is
# either "sc" or a 2 (or more) digit number.
ifneq ($(TARGETPATH),)
RSCDIR:=$(subst //,/,$(EPOCROOT)/epoc32/data/z/$(TARGETPATH))
else
RSCDIR:=$(subst //,/,$(EPOCROOT)/epoc32/data)
endif
RESBASE:=$(RSCDIR)/$(TARGET_lower)

# Ensure that RELEASABLES and CLEANTARGETS cannot expand indefinitely in successive calls to this flm:
CLEANTARGETS:=
RELEASABLES:=

# There is only one resource header (.rsg) file and we only
# make that if we are asked.
RSGDIR:=$(EPOCROOT)/epoc32/include
ifneq ($(or $(HEADER),$(HEADERONLY)),)
        RESOURCEHEADER:=$(RSGDIR)/$(HEADER)

        # If there are multiple LANGUAGES then it is the last one in the list
        # which produces the header.
        HEADLANG:=$(lastword $(LANGUAGES:SC=sc))
else
        HEADLANG:=
    RESOURCEHEADER:=
endif

# we create intermediate .rpp and .d files
INTERBASE:=$(OUTPUTPATH)/$(TARGET_lower)

################################## localisation ###########################$(GNUMKDIR)#############
# Only make copies for full resource builds

# Initialise to prevent RELEASABLES spill-over between calls
DESTRPP:=
INFOFILE:=

ifeq ($(HEADERONLY),)

RSSBASENAME:=$(call lowercase,$(basename $(notdir $(SOURCE))))
DESTRPP:=$(EPOCROOT)/epoc32/localisation/$(RSSBASENAME)/rsc/$(RSSBASENAME).rpp
$(call makepath,$(EPOCROOT)/epoc32/localisation/$(RSSBASENAME)/rsc)

INFOFILE:=$(EPOCROOT)/epoc32/localisation/group/$(RSSBASENAME).info
# If there are MULTIPLE languages then copy the .rpp for the last one
RPPLANG:=$(lastword $(LANGUAGES:SC=sc))

# Copy .rpp files from epoc32/build/ to epoc32/localisation/x/rsc/x.rpp and create .info files in localisation
define CreateRppAndInfo

ifeq ($(RESOURCE_$(call sanitise,$(SOURCE))),)
RESOURCE_$(call sanitise,$(SOURCE)):=1

RESOURCE:: $(DESTRPP) $(INFOFILE)

$(DESTRPP): $(INTERBASE)_$(RPPLANG).rpp
	$(call startrule,rppfilecopy,FORCESUCCESS) \
	$(GNUCP) $$< $$@ \
	$(call endrule,rppfilecopy)

$(INFOFILE)::
	@if [ ! -d $(EPOCROOT)/epoc32/localisation/group ]; then $(GNUMKDIR) -p $(EPOCROOT)/epoc32/localisation/group; fi
	@if [ ! -f $$@ ]; then echo "DATADIR: /$(RSSBASENAME)" > $$@ ; fi
	@echo -e "\n/z$(TARGETPATH)/$(TARGET_lower).rsc : $(RSSBASENAME).rpp" >> $$@

endif
endef

$(eval $(call CreateRppAndInfo))
endif
################################# end of localisation ###################################

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

# common pre-processor options

# We really should be using -iquote with a recent cpp.  This is a note for when we do update:
#CPPOPT:=-nostdinc -undef -Wno-trigraphs -D_UNICODE -include $(PRODUCT_INCLUDE)\
# -I$(dir $(SOURCE)) $(foreach I, $(USERINCLUDE),-iquote $(I) ) $(foreach J,$(SYSTEMINCLUDE),-I $(J) )

CPPOPT:=-nostdinc -undef -Wno-trigraphs -D_UNICODE -include $(PRODUCT_INCLUDE)\
 -I$(dir $(SOURCE)) $(foreach I, $(USERINCLUDE),-I$(I) ) -I- $(foreach J,$(SYSTEMINCLUDE),-I$(J) )

CREATABLEPATHS:=$(RSCDIR) $(RSGDIR) $(OUTPUTPATH)

# We intend to generate the resource in an intermediate location and copy to the targetpath to
# ensure that when the "same" resource is built into separare target paths, it doesn't have to be 
# completely recreated each time - just copied.
RSCCOPYDIRS:=$(RSCDIR)

# additional binary resource copies performed based on BINCOPYDIRS
ifneq ($(BINCOPYDIRS),)
        RSCCOPYDIRS:=$(RSCCOPYDIRS) $(subst //,/,$(patsubst %,%/$(if $(TARGETPATH),/z/$(TARGETPATH),),$(BINCOPYDIRS)))
endif
CREATABLEPATHS:=$(CREATABLEPATHS) $(RSCCOPYDIRS)

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


define preprocessresource
# $(1) is the RPPFILE		(eg. /epoc32/build/xxx/b_sc.rpp)
# $(2) is the related RESOURCEFILE if any (eg. /a/b.rsc)
# $(3) is the LANGUAGE		(eg. sc or 01 or 02 ...)

  ifeq ($(TARGET_$(call sanitise,$1)),)
    TARGET_$(call sanitise,$1):=1
    $(if $(FLMDEBUG),$(info <debug>preprocessresource: $(1) for $(2) LANG:$(3)</debug>))


    # Correct dependency information when a header file can't be found.
    # If the c preprocessor can't find a dependency it appears as it did in the #include statement
    # e.g. "filename.mbg" or "filename.rsg" in the dependency file.
    # we can correct the dependencies by assuming that the file will be in epoc32\include as this is the default
    ifneq ($(NO_DEPEND_GENERATE),)
      # This version minimises the size of dependency files, to contain only .mbg and .rsg deps.
      # It allows resources to be built in the right order but doesn't impose the weight of
      # of full dependency information which can overwhelm make in large builds.
      # The strategy is to filter out lines (apart from the target line which is the first) which don't have .rsg or 
      # .mbg dependencies in them.   The first line can sometimes not contain the target but  
      # have a lonely "\" so we use a pattern to recognise the target line in order not to get confused. 
      DEPENDENCY_CORRECTOR:={ $(GNUSED) -n -r '/.*: +.$$$$/ p;\%\.((rsg)|(mbg))%I {s% ([^ \/]+\.((rsg)|(mbg)))% __EPOCROOT\/epoc32\/include\/\1%ig;s% [^_][^_][^E][^ ]+%%g;s%__EPOCROOT%$(EPOCROOT)%g; p}' && echo "" ; }
    else
      # Generate full dependency information
      DEPENDENCY_CORRECTOR:=$(GNUSED)  -r 's% ([^ \/]+\.((rsg)|(mbg)))% $(EPOCROOT)\/epoc32\/include\/\1%ig' 
    endif


    RESOURCE_DEPS:: $(1).d
    $(1).d: $(SOURCE)
	  $(call startrule,resourcedependencies,FORCESUCCESS) \
	  $(GNUCPP) -C -DLANGUAGE_$(3) -DLANGUAGE_$(subst sc,SC,$(3)) $(call makemacrodef,-D,$(MMPDEFS))\
	  $(CPPOPT) $(SOURCE) -M -MG -MT"$(1)" | \
	  $$(DEPENDENCY_CORRECTOR) >$$@ \
	  $(call endrule,resourcedependencies)

    ifeq "$(MAKEFILE_GROUP)" "RESOURCE"
    $(1): $(1).d
	  $(call startrule,resourcepreprocess,FORCESUCCESS) \
	  $(GNUCPP) -C -DLANGUAGE_$(3) -DLANGUAGE_$(subst sc,SC,$(3)) $(call makemacrodef,-D,$(MMPDEFS))\
	  $(CPPOPT) $(SOURCE) -o $$@ \
	  $(call endrule,resourcepreprocess)
    endif

    CLEANTARGETS:= $$(CLEANTARGETS) $(1)

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

    CLEANTARGETS:=$$(CLEANTARGETS) $(DEPENDFILENAME)
    ifneq "$(DEPENDFILE)" ""
      ifeq "$(filter %CLEAN,$(call uppercase,$(MAKECMDGOALS)))" ""
        ifeq "$(MAKEFILE_GROUP)" "RESOURCE"
          -include $(DEPENDFILE)
        endif
      endif
    endif

  endif
endef # preprocessresource #

###############################################################################
define copyresource
# $(1) is the source
# $(2) is the destination

RELEASABLES:=$$(RELEASABLES) $(2)

   ifeq ($(TARGET_$(call sanitise,$2)),)
           TARGET_$(call sanitise,$2):=1

        RESOURCE:: $2
        ## perform additional copies of binaries
        #
        $(2): $(1)
		$(call startrule,resourcecopy,FORCESUCCESS) \
		$(GNUCP) $$< $$@ \
		$(call endrule,resourcecopy)

   endif

endef # copyresource #

###############################################################################
define generateresource

# $(1) is the resource filename e.g. /a/b/resource.rsc
# $(2) is the preprocessed resource to make it from
# $(3) is the language e.g. sc or 01 or 02


        ifeq ($(TARGET_$(call sanitise,$1)),)
                TARGET_$(call sanitise,$1):=1

            $(if $(FLMDEBUG),$(info <debug>generateresource: $(1) from $(2) LANG:$(3)</debug>),)	
            $(if $(FLMDEBUG),$(info <debug>generateresource: copies: $(sort $(patsubst %,%/$(notdir $(1)),$(RSCCOPYDIRS)))</debug>))

            CLEANTARGETS:=$$(CLEANTARGETS) $(1)

            RESOURCE:: $(1)

            $(1): $(2) $(RCOMP)
			$(call startrule,resourcecompile,FORCESUCCESS) \
			$(RCOMP) -m045,046,047 -u -o$(1) -s$(2) && \
        		{ $(foreach F,$(sort $(patsubst %,%/$(notdir $(1)),$(RSCCOPYDIRS))),$(GNUCP) $(1) $(F) ; ) } \
			$(call endrule,resourcecompile)

        endif

#	Whether or not we have generated this resource for some other variant, check if there
#       are any new copies to be made for this variant. e.g. winscw requires that we make
#       some extra copies.  We tried to copy after running rcomp itself but we still need these
#       targets for the sake of dependencies or, for example if someone merely adds a new copy 
#       when the resource is up-to-date

        $(if $(FLMDEBUG),$(info <debug>resource copies of $(notdir $1) in: $(RSCCOPYDIRS)</debug>))
        $(foreach F,$(sort $(patsubst %,%/$(notdir $(1)),$(RSCCOPYDIRS))),$(call copyresource,$(1),$(F)))

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

endef # generateresource


###############################################################################
define generateresourceheader
# $(1) is the resource header	(eg. /epoc32/include/a.rsg)
# $(2) is the preprocessed resource to make it from
# $(3) is the language to use	(eg. sc)

		RELEASABLES:= $$(RELEASABLES) $(1)

        ifeq ($(TARGET_$(call sanitise,$1)),)
                TARGET_$(call sanitise,$1):=1
                $(if $(FLMDEBUG),$(info <debug>resourceheader: $(1) from $(2) LANG:$(3)</debug>))

                RESOURCE:: $(1)

                $(1): $(2) $(RCOMP)
			$(call startrule,resourceheader,FORCESUCCESS) \
			$(RCOMP) -m045,046,047 -u -h$(1) -s$(2) \
			$(call endrule,resourceheader)

        endif


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

endef

###############################################################################
## call the generator

# We always create at least the header
# even if we sometimes don't create the resources
ifneq ($(RESOURCEHEADER),)
        $(eval $(call generateresourceheader,$(RESOURCEHEADER),$(INTERBASE)_$(HEADLANG).rpp,$(HEADLANG)))
endif

ifeq ($(HEADERONLY),)
        # generate a resource file for each language
        # For sc we generate $(RESBASE).rsc and define LANGUAGE_SC and LANGUAGE_sc.
        $(foreach L,$(LANGUAGES:SC=sc),$(eval $(call preprocessresource,$(INTERBASE)_$(L).rpp,$(INTERBASE).r$(L),$(L))))

        ifeq "$(MAKEFILE_GROUP)" "RESOURCE"
            $(foreach L,$(LANGUAGES:SC=sc),$(eval $(call generateresource,$(INTERBASE).r$(L),$(INTERBASE)_$(L).rpp,$(L))))
        endif
else
        # No resources are going to be made so unless we specifically ask for it, there will be no
        # preprocessed file from which to create the header:

        $(eval $(call preprocessresource,$(INTERBASE)_$(HEADLANG).rpp,,$(HEADLANG)))

endif

###############################################################################
## .rfi generation in support of the gccxml build
## Note that .rfi files are created from the dependency files generated from preprocessing resources to create .rpp files
ifneq ($(RFIFILE),)
  RESOURCE:: $(RFIFILE)
  RELEASABLES:=$(RELEASABLES) $(RFIFILE)
  CREATABLEPATHS:=$(CREATABLEPATHS) $(dir $(RFIFILE))

  RPPFILES:=$(foreach L,$(LANGUAGES:SC=sc),$(INTERBASE)_$(L).rpp)
  $(eval $(call generaterfifile,$(RFIFILE),$(RPPFILES),$(addsuffix .d,$(RPPFILES))))
endif


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

# for the --what option and the log file
RELEASABLES:=$(RELEASABLES) $(DESTRPP) $(INFOFILE)
$(call raptor_release,$(RELEASABLES),RESOURCE)