#*************************************************************************
# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
#     National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
#     Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution. 
#*************************************************************************
#
#  CONFIG_COMMON
#
#  This file is to be maintained by the community.
#
# Common Configuration Information

#-------------------------------------------------------
# POSIX is OS default
POSIX=YES

#-------------------------------------------------------
# Divider symbol
DIVIDER = .

#-------------------------------------------------------
# Build architectures

# CROSS1 will be defined only when CROSS_COMPILER_HOST_ARCHS is NOT defined
CROSS1 = $(CROSS_COMPILER_TARGET_ARCHS$(word 1,$(CROSS_COMPILER_HOST_ARCHS)))

# CROSS2 will be defined only when CROSS_COMPILER_HOST_ARCHS is defined
# and EPICS_HOST_ARCH is one of it's words
CROSS2 = $(CROSS_COMPILER_TARGET_ARCHS$(filter-out 1,$(words $(filter $(EPICS_HOST_ARCH),$(CROSS_COMPILER_HOST_ARCHS)))))

BUILD_ARCHS = $(EPICS_HOST_ARCH) $(CROSS1) $(CROSS2)

#-------------------------------------------------------
# Default for perl if it's on the PATH,
# otherwise override this in os/CONFIG_SITE.<host_arch>.Common
PERL=perl

#-------------------------------------------------------
# dbst based database optimization default
DB_OPT = NO

#-------------------------------------------------------
# Check configure/RELEASE file for consistency
CHECK_RELEASE_YES = checkRelease
CHECK_RELEASE_NO = noCheckRelease
CHECK_RELEASE_WARN = warnRelease

#-------------------------------------------------------
# GNU directory
# GNU_DIR definition is here because it is used to find
# READLINE library even if GNU compiler is not used
GNU_DIR = /usr

#-------------------------------------------------------
# Directories

INSTALL_LOCATION            = $(TOP)

INSTALL_LOCATION_LIB        = $(INSTALL_LOCATION)/lib
INSTALL_LOCATION_BIN        = $(INSTALL_LOCATION)/bin

INSTALL_HOST_BIN            = $(INSTALL_LOCATION_BIN)/$(EPICS_HOST_ARCH)
INSTALL_HOST_LIB            = $(INSTALL_LOCATION_LIB)/$(EPICS_HOST_ARCH)

INSTALL_INCLUDE             = $(INSTALL_LOCATION)/include
INSTALL_DOC                 = $(INSTALL_LOCATION)/doc
INSTALL_HTML                = $(INSTALL_LOCATION)/html
INSTALL_TEMPLATES           = $(INSTALL_LOCATION)/templates
INSTALL_DBD                 = $(INSTALL_LOCATION)/dbd
INSTALL_DB                  = $(INSTALL_LOCATION)/db
INSTALL_CONFIG              = $(INSTALL_LOCATION)/configure
INSTALL_JAVA                = $(INSTALL_LOCATION)/javalib

# Directory for OS independant build created files
COMMON_DIR = ../O.Common

# IOC's absolute path to $(TOP), may be overridden inside the application
IOCS_APPL_TOP               = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))

#-------------------------------------------------------
# Make echo output - suppress echoing if make's '-s' flag is set
NOP = :
ECHO = @$(if $(findstring s,$(patsubst T_A=%,,$(MAKEFLAGS))),$(NOP),echo)

#-------------------------------------------------------
ifdef T_A

INSTALL_LIB                 = $(INSTALL_LOCATION_LIB)/$(T_A)
INSTALL_SHRLIB              = $(INSTALL_LOCATION_LIB)/$(T_A)
INSTALL_TCLLIB              = $(INSTALL_LOCATION_LIB)/$(T_A)
INSTALL_BIN                 = $(INSTALL_LOCATION_BIN)/$(T_A)

#Directories for libraries
SHRLIB_SEARCH_DIRS          = $(INSTALL_LIB)

#-------------------------------------------------------
# Ext, app, and module configure dir targets
CONFIG_INSTALLS += ../RULES_BUILD ../RELEASE*

#-------------------------------------------------------
# Cross compile default, HOST or CROSS, CONFIG.crossCommon will override
BUILD_CLASS = HOST

#-------------------------------------------------------
# Build defaults, CONFIG_SITE, CONFIG, or os/CONFIG* will override
STATIC_BUILD=NO
SHARED_LIBRARIES=YES
HOST_OPT=YES
CROSS_OPT=YES
HOST_WARN=YES
CROSS_WARN=YES
GNU=NO

#-------------------------------------------------------
# Run checkRelease in $(TOP)/configure/O.*
CONFIG_TARGETS += $(CHECK_RELEASE_$(CHECK_RELEASE))

#-------------------------------------------------------
# Prefix and suffix
DEP=.d
OBJ = .
CMPLR_SUFFIX=
CMPLR_PREFIX=
LIB_PREFIX=
SHRLIB_PREFIX= $(LIB_PREFIX)

#--------------------------------------------------
# vpath directories
POSIX_YES = os/posix
GENERIC_SRC_DIRS = .. $(SRC_DIRS)
OS_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \
       $(addprefix $(dir)/, os/$(OS_CLASS) $(POSIX_$(POSIX)) os/default ))
ALL_SRC_DIRS = $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS)

#--------------------------------------------------
# compile line include directories
INSTALL_INCLUDES += \
       -I$(INSTALL_INCLUDE)/os/$(OS_CLASS) \
       -I$(INSTALL_INCLUDE)
SRC_INCLUDES = -I$(COMMON_DIR) $(addprefix -I, $(wildcard $(ALL_SRC_DIRS)))

#--------------------------------------------------
# Target filename definitions
OBJSNAME = $(addsuffix $(OBJ),$(basename $(OBJS)))
PRODNAME = $(addsuffix $(EXE),$(basename $(PROD)))
TESTPRODNAME = $(addsuffix $(EXE),$(basename $(TESTPROD)))

SHRLIBNAME = $(SHRLIBNAME_$(SHARED_LIBRARIES))

JAVA =
JAR =

#--------------------------------------------------
# obj files

TARGET_OBJS =  $($*_OBJLIBS) $($*_LDOBJS) $(addsuffix $(OBJ),$(basename $($*_OBJS) $($*_SRCS)))

PRODUCT_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(USR_OBJS) $(PROD_OBJS)))
PROD_LD_OBJS = $(USR_OBJLIBS) $(PROD_OBJLIBS) $(TARGET_OBJS) $(PRODUCT_OBJS)

LIBRARY_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(LIB_SRCS) $(LIBSRCS) $(USR_OBJS) $(LIB_OBJS)))
LIBRARY_LD_OBJS = $(USR_OBJLIBS) $(LIB_OBJLIBS) $(TARGET_OBJS) $(LIBRARY_OBJS)

#--------------------------------------------------
# WIN95/NT resource files

TARGET_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $($*_RCS))),)

PROD_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(PROD_RCS))),)
PROD_LD_RESS = $(TARGET_RESS) $(PROD_RESS)

LIBRARY_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(LIB_RCS) $(LIBRARY_RCS))),)
LIBRARY_LD_RESS = $(TARGET_RESS) $(LIBRARY_RESS)

#--------------------------------------------------
# WIN95/NT source browser
PROD_BAF = $(addsuffix $(BAF), $(basename $(PROD)))
LIB_BAF=$(addsuffix $(BAF),$(basename $(LIBRARY)))

#--------------------------------------------------
# C preprocessor, compiler, and linker flag defaults

# Target architecture specific flags
ARCH_DEP_CPPFLAGS =
ARCH_DEP_CFLAGS =
ARCH_DEP_CXXFLAGS = $(ARCH_DEP_CFLAGS)
ARCH_DEP_LDFLAGS =
ARCH_DEP_LDLIBS =

# Target operating system specific flags
OP_SYS_CPPFLAGS =
OP_SYS_CFLAGS =
OP_SYS_CXXFLAGS = $(OP_SYS_CFLAGS)
OP_SYS_LDFLAGS =
OP_SYS_INCLUDES =

# Makefile specific flags
USR_INCLUDES =
USR_CFLAGS =
USR_CXXFLAGS =
USR_LDFLAGS =
USR_LIBS =
USR_CPPFLAGS =
USR_DBDFLAGS =
USR_ARFLAGS =

# Variables to be set only on the command-line:
# CMD_INCLUDES =
# CMD_CFLAGS =
# CMD_CXXFLAGS =
# CMD_LDFLAGS =
# CMD_CPPFLAGS =
# CMD_DBFLAGS =
# CMD_DBDFLAGS =
# CMD_ARFLAGS =

# Debug specific options
DEBUG_CPPFLAGS =
DEBUG_CFLAGS =
DEBUG_CXXFLAGS = $(DEBUG_CFLAGS)
DEBUG_LDFLAGS =
DEBUG_LDLIBS =

# Target specific options
TARGET_INCLUDES = $($(basename $@)_INCLUDES_$(T_A))
TARGET_CFLAGS = $($(basename $@)_CFLAGS_$(T_A))
TARGET_CXXFLAGS = $($(basename $@)_CXXFLAGS_$(T_A))
TARGET_CPPFLAGS = $($(basename $@)_CPPFLAGS_$(T_A))

TARGET_INCLUDES += $($(basename $@)_INCLUDES_$(OS_CLASS)) $($(basename $@)_INCLUDES)
TARGET_CFLAGS += $($(basename $@)_CFLAGS_$(OS_CLASS)) $($(basename $@)_CFLAGS)
TARGET_CXXFLAGS += $($(basename $@)_CXXFLAGS_$(OS_CLASS)) $($(basename $@)_CXXFLAGS)
TARGET_CPPFLAGS += $($(basename $@)_CPPFLAGS_$(OS_CLASS)) $($(basename $@)_CPPFLAGS)

TARGET_LDFLAGS = $($*_LDFLAGS)

# Warnings flags
WARN_CPPFLAGS = $(WARN_CPPFLAGS_$($(BUILD_CLASS)_WARN))
WARN_CFLAGS = $(WARN_CFLAGS_$($(BUILD_CLASS)_WARN))
WARN_CXXFLAGS = $(WARN_CXXFLAGS_$($(BUILD_CLASS)_WARN))

# Optimization flags
OPT_CPPFLAGS = $(OPT_CPPFLAGS_$($(BUILD_CLASS)_OPT))
OPT_CFLAGS = $(OPT_CFLAGS_$($(BUILD_CLASS)_OPT))
OPT_CXXFLAGS = $(OPT_CXXFLAGS_$($(BUILD_CLASS)_OPT))

# Static build flags
STATIC_CFLAGS = $(STATIC_CFLAGS_$(STATIC_BUILD))
STATIC_CXXCFLAGS = $(STATIC_CXXFLAGS_$(STATIC_BUILD))
STATIC_LDFLAGS = $(STATIC_LDFLAGS_$(STATIC_BUILD))
STATIC_LDLIBS = $(STATIC_LDLIBS_$(STATIC_BUILD))

#--------------------------------------------------
# cflags for shared library src files (from SHRLIB_CFLAGS)
LIBRARY_SRCS=$(basename $(foreach lib,$(LIBRARY) $(LOADABLE_LIBRARY),$($(lib)_OBJSNAME) $(LIBRARY_OBJS)))
LIBRARY_SRC_CFLAGS=$($(patsubst $*,SHRLIB,$(findstring $*,$(LIBRARY_SRCS)))_CFLAGS)

#--------------------------------------------------
# prefix, suffix, and ldflags for loadable shared libraries 
TARGET_LIB_LDFLAGS=$($(patsubst $*,LOADABLE_,$(findstring $*,$(LOADABLE_LIBRARY)))SHRLIB_LDFLAGS)
LOADABLE_SHRLIB_PREFIX=$(SHRLIB_PREFIX)
LOADABLE_SHRLIB_SUFFIX=$(SHRLIB_SUFFIX)

#--------------------------------------------------
# Command-line input support default
COMMANDLINE_LIBRARY = EPICS
OP_SYS_LDLIBS += $(LDLIBS_$(COMMANDLINE_LIBRARY))
OP_SYS_LDFLAGS += $(LDFLAGS_$(COMMANDLINE_LIBRARY))
RUNTIME_LDFLAGS += $(RUNTIME_LDFLAGS_$(COMMANDLINE_LIBRARY))

#--------------------------------------------------
# Flags

INCLUDES = -I. $(SRC_INCLUDES) $(INSTALL_INCLUDES) $(RELEASE_INCLUDES)\
 $(TARGET_INCLUDES) $(USR_INCLUDES) $(CMD_INCLUDES) $(OP_SYS_INCLUDES)\
 $($(BUILD_CLASS)_INCLUDES)

CFLAGS = $($(BUILD_CLASS)_CFLAGS) $(POSIX_CFLAGS) $(OPT_CFLAGS)\
 $(DEBUG_CFLAGS) $(PIPE_CFLAGS) $(WARN_CFLAGS) $(TARGET_CFLAGS)\
 $(USR_CFLAGS) $(CMD_CFLAGS) $(ARCH_DEP_CFLAGS) $(CODE_CFLAGS)\
 $(STATIC_CFLAGS) $(OP_SYS_CFLAGS) $(LIBRARY_SRC_CFLAGS) $(HDEPENDS_CFLAGS)

CXXFLAGS = $($(BUILD_CLASS)_CXXFLAGS) $(POSIX_CXXFLAGS) $(OPT_CXXFLAGS)\
 $(DEBUG_CXXFLAGS) $(PIPE_CFLAGS) $(WARN_CXXFLAGS) $(TARGET_CXXFLAGS)\
 $(USR_CXXFLAGS) $(CMD_CXXFLAGS) $(ARCH_DEP_CXXFLAGS) $(CODE_CXXFLAGS)\
 $(STATIC_CXXCFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS) $(HDEPENDS_CFLAGS)

LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS)\
 $(POSIX_LDFLAGS) $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS)\
 $($(BUILD_CLASS)_LDFLAGS) $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS)

LDLIBS = $(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS)\
 $(GNU_LDLIBS_$(GNU))

CPPFLAGS = $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\
 $(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS) $(BASE_CPPFLAGS) $(TARGET_CPPFLAGS)\
 $(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\
 $(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS)

#--------------------------------------------------
# ar definition default
ARFLAGS =
ARCMD = $(AR) $(ARFLAGS) $(USR_ARFLAGS) $(CMD_ARFLAGS) $@  $(LIBRARY_LD_OBJS)

#--------------------------------------------------
# 'Munch' link-edit
MUNCH_CMD = $(LD) $(MUNCH_LDFLAGS) -o $@ $^

#--------------------------------------------------
# LEX default options
#
# Allow 8-bit characters
LEXOPT += -8
# Generate an "interactive" scanner, solves problems at EOF.
LEXOPT += -I

#--------------------------------------------------
# Build compile line here

PATH_FILTER = $(1)
COMPILE.c = $(CC) -c $(CPPFLAGS) $(CFLAGS) $(call PATH_FILTER,$(INCLUDES))
COMPILE.cpp = $(CCC) -c $(CPPFLAGS) $(CXXFLAGS) $(call PATH_FILTER,$(INCLUDES))

#--------------------------------------------------
# C preprocessor command
PREPROCESS.cpp = $(CPP) $(CPPFLAGS) $(INCLUDES) $< > $@

#--------------------------------------------------
# Header dependency file generation

HDEPENDS = YES
HDEPENDS_METHOD = CMD

HDEPENDSFLAGS = -m $*$(DEP) $(INCLUDES) $@ $<
HDEPENDSCMD = -$(MKMF) $(HDEPENDS_FLAGS) $(HDEPENDSFLAGS)

HDEPENDS_CMD_NO = $(ECHO) ""
HDEPENDS_CMD_YES = $(if $(filter CMD,$(HDEPENDS_METHOD)),$(HDEPENDSCMD),$(HDEPENDS_CMD_NO))
HDEPENDS_CMD = $(HDEPENDS_CMD_$(HDEPENDS))

HDEPENDSCFLAGS = -MMD
HDEPENDS_CFLAGS_YES = $(if $(filter CFLAGS,$(HDEPENDS_METHOD)),$(HDEPENDSCFLAGS))
HDEPENDS_CFLAGS = $(HDEPENDS_CFLAGS_$(HDEPENDS))

#--------------------------------------------------
# depends definition

TARGET_SRCS = $(foreach name, $(TESTPROD) $(PROD) $(LIBRARY) $(LOADABLE_LIBRARY), $($(name)_SRCS))
SRC_FILES = $(LIB_SRCS) $(LIBSRCS) $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(TARGET_SRCS)
HDEPENDS_FILES_YES = $(addsuffix $(DEP),$(notdir $(basename $(SRC_FILES))))
HDEPENDS_FILES = $(if $(filter NO,$(HDEPENDS)),,$(HDEPENDS_FILES_YES))

#---------------------------------------------------------------
# Names of installed items
#
#	each list starts with the destination directory name(s)
#	to make sure it's there

INSTALL_PROD= $(PRODNAME:%= $(INSTALL_BIN)/%)
INSTALL_LIBS= $(LIBNAME:%=$(INSTALL_LIB)/%)
INSTALL_MUNCHS= $(MUNCHNAME:%=$(INSTALL_BIN)/%)
INSTALL_SHRLIBS= $(SHRLIBNAME:%=$(INSTALL_SHRLIB)/%)
INSTALL_LOADABLE_SHRLIBS= $(LOADABLE_SHRLIBNAME:%=$(INSTALL_SHRLIB)/%)
INSTALL_DLL_LINK_LIBS=$(DLL_LINK_LIBNAME:%=$(INSTALL_LIB)/%)
INSTALL_TCLLIBS=$(TCLLIBNAME:%=$(INSTALL_TCLLIB)/%)
INSTALL_TCLINDEX=$(TCLINDEX:%=$(INSTALL_TCLLIB)/%)
INSTALL_SCRIPTS = $(SCRIPTS:%= $(INSTALL_BIN)/%)
INSTALL_OBJS = $(OBJSNAME:%= $(INSTALL_BIN)/%)

INSTALL_DOCS = $(DOCS:%= $(INSTALL_DOC)/%)
INSTALL_HTMLS = $(HTMLS:%= $(INSTALL_HTML)/$(HTMLS_DIR)/%)

INSTALL_TEMPLATE = $(addprefix $(INSTALL_TEMPLATES_SUBDIR)/, \
                   $(subst $(CONFIG),top/configure,$(TEMPLATES)))
INSTALL_CONFIGS = $(CONFIGS:%= $(INSTALL_CONFIG)/%)

INSTALL_BIN_INSTALLS = $(addprefix $(INSTALL_BIN)/,$(notdir $(BIN_INSTALLS)))
INSTALL_LIB_INSTALLS = $(addprefix $(INSTALL_LIB)/,$(notdir $(LIB_INSTALLS)))

#---------------------------------------------------------------
# Installed file permissions
BIN_PERMISSIONS = 555
LIB_PERMISSIONS = 444
SHRLIB_PERMISSIONS = 555
INSTALL_PERMISSIONS = 444

#---------------------------------------------------------------
#
# auto determine the directory paths that things are installed to
# RULES:
# 1) found in any one of several os specific area
#       => install to $(INSTALL_INCLUDE)/os/$(OS_CLASS)
# 2) not foundin (1) and found in generic area
#       => install to $(INSTALL_INCLUDE)
# 3) not found in (1) or (2) then may be (not yet) computer generated
#       => install into $(INSTALL_INCLUDE)/os/$(OS_CLASS) and let
#       build rules work on vpath
#
# These rules guarantee that the users include from
# no more than two directories
#
INSTALL_INC += $(foreach inc, $(INC), \
    $(firstword \
        $(OS_INSTALL_INC) \
        $(GENERIC_INSTALL_INC) \
        $(GENERATED_INSTALL_INC) ) )
INSTALL_INC += $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INC_$(OS_CLASS)) )

#
# Rule 1
#
OS_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INSTALL_INC_ggg) )
INSTALL_INC_ggg = $(foreach dir, $(OS_SRC_DIRS), $(INSTALL_INC_fff)  )
INSTALL_INC_fff = $(subst $(dir)/, , $(INSTALL_INC_eee) )
INSTALL_INC_eee = $(wildcard $(addsuffix /$(inc), $(dir)) )

#
# Rule 2
#
GENERIC_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/, $(INSTALL_INC_ccc) )
INSTALL_INC_ccc = $(foreach dir, .. $(SRC_DIRS), $(INSTALL_INC_bbb)  )
INSTALL_INC_bbb = $(subst $(dir)/, , $(INSTALL_INC_aaa) )
INSTALL_INC_aaa = $(wildcard $(addsuffix /$(inc), $(dir)) )

#
# Rule 3
#
GENERATED_INSTALL_INC = $(INSTALL_INCLUDE)/$(inc)

COMMON_INC += $(filter $(COMMON_DIR)/%, $(foreach file, $(INC), \
    $(firstword  $(SOURCE_INC) $(COMMON_DIR)/$(file) ) ) )
SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) )
SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa)  )
SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) )
 
endif
