if ! $(VariantRules_INCLUDED) {
VariantRules_INCLUDED = TRUE ;

include [ FDirName $(SUBDIR) PlatformRules ] ;

VARIANTS ?= DEV ;

#########

# Rules for generating flags based on the variant.
# The valid variants are:
#   DEV
#   OPTIMIZED
#   PROFILE
#   COVERAGE
#   CUSTOM

# If CUSTOM variant is set these variables control 
# whether the corresponding flag is used:
#     EUROPA_DEBUG
#     EUROPA_OPTIMIZED
#     EUROPA_PROFILE
#     EUROPA_COVERAGE
#     EUROPA_WARN
#########

# C++Flags for the variant
rule FVariantC++Flags
{
  local variant = $(1) ;

  switch $(variant) {
  case DEV :
    return $(DEBUG_FLAGS) -DDEBUG_MESSAGE_SUPPORT $(WARNING_FLAGS) $(EXTRA_DEFS) ;
  case OPTIMIZED :
    return $(OPTIMIZE_FLAGS) $(WARNING_FLAGS) $(EXTRA_DEFS) ;
  case PROFILE :
    return $(OPTIMIZE_FLAGS) $(PROFILE_FLAGS) $(WARNING_FLAGS) $(EXTRA_DEFS) ;
  case COVERAGE :
    return $(COVERAGE_FLAGS) $(WARNING_FLAGS) $(EXTRA_DEFS) ;
  case CUSTOM :
    local flags ;
    if $(EUROPA_DEBUG) {
      flags += $(DEBUG_FLAGS) ;
    }
    if $(EUROPA_DEBUG_MESSAGE) {
      flags += -DDEBUG_MESSAGE_SUPPORT ;
    }
    if $(EUROPA_OPTIMIZED) {
      flags += $(OPTIMIZE_FLAGS) ;
    }
    if $(EUROPA_PROFILE) {
      flags += $(PROFILE_FLAGS) ;
    }
    if $(EUROPA_COVERAGE) {
      flags += $(COVERAGE_FLAGS) ;
    }
    if $(EUROPA_WARN) {
      flags += $(WARNING_FLAGS) ;
    }
    flags += $(EXTRA_DEFS) ;
    return $(flags) ;
  case * :
    Exit FVariantC++Flags unknown variant: $(variant) ;
  }
}

# CFlags for the variant
rule FVariantCFlags
{
  local variant = $(1) ;

  return [ FVariantC++Flags $(variant) ] ;
}

# LinkFlags for the variant
rule FVariantLinkFlags
{
  local variant = $(1) ;

  switch $(variant) {
  case DEV :
    return $(THREADED_LINK_FLAGS) ;
  case OPTIMIZED :
    return $(THREADED_LINK_FLAGS) ;
  case PROFILE :
    return $(PROFILE_FLAGS) $(THREADED_LINK_FLAGS) ;
  case COVERAGE :
    return $(COVERAGE_FLAGS) $(THREADED_LINK_FLAGS) ;
  case CUSTOM :
    local flags = $(THREADED_LINK_FLAGS) ;
    if $(EUROPA_PROFILE) {
      flags += $(PROFILE_FLAGS) ;
    }
    if $(EUROPA_COVERAGE) {
      flags += $(COVERAGE_FLAGS) ;
    }
    return $(flags) ;
  case * :
    Exit FVariantLinkFlags unknown variant: $(variant) ;
  }
}

# Modify the name for the variant
rule FVariantName
{
  local name = $(1) ;
  local variant = $(2) ;

  switch $(variant) {
  case DEV :
    return $(name)_g ;
  case OPTIMIZED :
    return $(name)_o ;
  case PROFILE :
    return $(name)_o_p ;
  case COVERAGE :
    # gcov, at least, requires object files to be named with same "root" as the source ...
    return $(name) ;
  case CUSTOM :
    local name = $(name) ;
    if $(EUROPA_COVERAGE) {
      # ... so ignore the other variants here:
      return $(name) ;
    }
    if $(EUROPA_DEBUG) {
      name = $(name)_g ;
    }
    if $(EUROPA_OPTIMIZED) {
      name = $(name)_o ;
    }
    if $(EUROPA_PROFILE) {
      name = $(name)_p ;
    }
    return $(name) ;
  case * :
    Exit FVariantName unknown variant: $(variant) ;
  }
}

# Name of the subdir to store object files.
#   Should always be passed $(VARIANTS).
rule ObjectsSubdirName
{
  switch $(1) {
  case COVERAGE :
    return obj_cov ;
  case CUSTOM :
    if $(EUROPA_COVERAGE) {
      return obj_cov ;
    }
    return objects ;
  case * :
    return objects ;
  }
}

# if the custom variant is the same as one of others,
# don't replicate its dependencies
local custom_name = [ FVariantName name : CUSTOM ] ;
if [ FVariantName name : DEV ] = $(custom_name) {
  ALL_VARIANTS = DEV OPTIMIZED PROFILE COVERAGE ;
} else if [ FVariantName name : OPTIMIZED ] = $(custom_name) {
  ALL_VARIANTS = DEV OPTIMIZED PROFILE COVERAGE ;
} else if [ FVariantName name : PROFILE ] = $(custom_name) {
  ALL_VARIANTS = DEV OPTIMIZED PROFILE COVERAGE ;
} else if [ FVariantName name : COVERAGE ] = $(custom_name) {
  ALL_VARIANTS = DEV OPTIMIZED PROFILE COVERAGE ;
} else {
  # Note: this is still incorrect if CUSTOM _includes_ COVERAGE (and some other variant).
  ALL_VARIANTS = DEV OPTIMIZED PROFILE COVERAGE CUSTOM ;
}

}
