######################################################################
# $Source: /fs/szdevel/src/cvsroot/GF/Glimmer3/src/c_make.gen,v $
# $Revision: 1.3 $
# $Date: 2006/05/26 14:11:12 $
######################################################################
######################################################################
# Module:
#
# c_make.gen
#
# Description:
#
# Generic makefile for C compilation and link
#
# Assumptions:
#
# This makefile requires the use of GNU make.
#
# It is assumed that the following working directories exist:
# <subsystem_level>/src
# <subsystem_level>/inc
# <subsystem_level>/obj
# <subsystem_level>/lib
# <subsystem_level>/bin
# (The obj, lib, bin, and inc directories will be created automatically
# if they do not already exist.)
#
# All objects created by this makefile will be placed immediately in:
# <subsystem_level>/obj
# All libraries created by this makefile will be placed immediately in:
# <subsystem_level>/lib
# All executables created by this makefile will be placed immediately in:
# <subsystem_level>/bin
# All include files belonging to this subsystem (not necessarily all
# include files required by this subsystem) are located immediately in:
# <subsystem_level>/inc
# Source files (and their associated makefiles) are contained
# directly or indirectly in <subsystem_level>/src:
# <subsystem_level>/src
# or
# <subsystem_level>/src/<component_level_1>
# or
# <subsystem_level>/src/<component_level_1>/.../<component_level_N>
# A makefile is located in the same directory as all source files
# that the makefile requires.
#
# This makefile is to be included at the end of a makefile that
# provides instance-specific definitions and dependencies, with the
# directive:
#
# include $(SEP_PATH)/makefiles/c_make.gen
#
# Variables defined by the instance-specific makefile:
# ----------------------------------------------------
#
# SOURCES =
# Lists all sources compiled by this makefile.
#
# OBJECTS =
# Lists all objects compiled by this makefile (i.e., one-to-one
# with SOURCES). OBJECTS can be listed explicitly or can be
# specified with the following definition:
#
# OBJECTS = $(patsubst %.c, %.o, $(SOURCES))
#
# LIBRARIES =
# Lists simple name (in "libx.a" form) of each library that is
# built by this makefile.
#
# PROGS =
# Lists each executable created by this makefile.
#
# INC_IMPORT_DIRS +=
# Lists directories containing header files that must be imported
# from other subsystems.
# Format is white-space-separated list of paths.
#
# LIB_IMPORT_DIRS +=
# Lists directories containing libraries that must be imported
# from other subsystems.
# Format is white-space-separated list of paths.
# Paths must be absolute (beginning with '/'). Path beginning
# with $(LOCAL_WORK) will work.
#
# LOCAL_WORK =
# Identifies the <subsystem_level> directory (parent of
# the inc, src, lib, obj, and bin subdirectories) with
# an absolute path.
# For a makefile located in
# <subsystem_level>/src/<component_level_1>
# the following definition would work:
# LOCAL_WORK = $(shell cd ../..; pwd)
#
# Dependencies defined in the instance-specific makefile:
# -------------------------------------------------------
#
# (1) Dependencies of OBJECTS on .h files will be automatically
# computed and the appropriate dependency lines will be
# automatically included. They need not be specified in
# the instance-specific makefile.
# (2) Dependencies of individual PROGS and LIBRARIES on objects
# and libraries must be explicitly specified. When specifying
# a dependency on a library, use the "libx.a" form, e.g.:
# my_target: abc.o def.o libxyz.a
# Use the simple name of each item on which there is a dependency
# (including dependencies on imported libraries). However,
# if a dependence on a standard library is explicitly specified,
# then the path to that standard library must be specified as
# part of the INC_IMPORT_DIRS.
#
# The included make.conf file:
# ----------------------------
#
# This makefile attempts to include another makefile, "make.conf"
# (but will execute correctly whether "make.conf" exists or not).
# "make.conf" serves two purposes:
# 1. It provides a way to override definitions in this
# generic makefile.
# 2. It provies a way to specify search paths for include files,
# objects, and libraries that the instance-specific makefile
# expects to exist but are "missing." For example, an expected
# object file might be "missing" from an individual programmer's
# working directory because the intention was to use an object
# file that was already compiled in a group working directory
# or a release directory. The make.conf search variables are:
# INC_SEARCH_PATH
# White-space-separated list of paths.
# Specifies where to look for "missing" header files.
# OBJ_SEARCH_PATH
# White-space-separated list of paths.
# Specifies where to look for "missing" object files that
# should be made by this makefile but cannot because the
# source files are "missing."
# LIB_SEARCH_PATH
# White-space-separated list of paths.
# Specifies where to look for "missing" library files.
# In a completely populated working directory (e.g., a directory
# from which a release is to be made), the makefile should work
# correctly without the existence of a make.conf file.
# It is also possible to redefine the LOCAL_WORK variable in the
# make.conf file to reflect a working directory depth that differs
# from the standard.
#
# Targets defined in this makefile:
# ---------------------------------
#
# objs
# libs
# progs
# clean
# clean_obj
# clean_lib
# clean_bin
# clean_dep
#
# Compile and link variables/flags:
# ---------------------------------
#
# The generic makefile makes use of the following compile and link
# variables/flags:
#
# CC (C compiler)
# CPPFLAGS (C preprocessor options [but not -I paths] )
# CFLAGS (C compiler options [but not -I paths] )
# CDEFS (C compiler defines [ -D ])
# CXX (C++ compiler)
# CXXFLAGS (C++ compiler options [but not -I paths] )
# CXXDEFS (C++ compiler defines [ -D ])
# AR (archive program [create binary libraries] )
# ARFLAGS (archive program options)
# LDFLAGS (linker options [but not -L paths] )
#
# There are three ways to override the values for these variables:
#
# 1. Assign values on the "make" command line.
# 2. Assign values in the make.conf file (or in a file included
# by the make.conf file).
# 3. Assign values to these variables in the environment.
#
# The order of precedence is as follows:
#
# - Environment variable overrides value in the generic makefile.
# - Value in make.conf overrrides value on environment.
# - Value on command line overrides value in make.conf.
#
######################################################################
#### Soft link programs
LINKS_PGM = /cm/cmtools/bin/links.pl
#### Set up paths
LOCAL_INC=$(LOCAL_WORK)/inc
LOCAL_BIN=$(LOCAL_WORK)/bin
LOCAL_LIB=$(LOCAL_WORK)/lib
LOCAL_OBJ=$(LOCAL_WORK)/obj
LOCAL_SYS_INC=$(SEP_PATH)/../SYS/inc
#### Various flags
#### Do not redefine if (a) passed in on command line, or (b)
#### defined in an environment variable.
ifneq "$(origin CC)" "environment"
CC = cc
endif
ifneq "$(origin CPPFLAGS)" "environment"
CPPFLAGS=
endif
ifneq "$(origin CFLAGS)" "environment"
CFLAGS =
endif
ifneq "$(origin CDEFS)" "environment"
CDEFS =
endif
ifneq "$(origin CXX)" "environment"
CXX = g++
endif
ifneq "$(origin CXXFLAGS)" "environment"
CXXFLAGS=
endif
ifneq "$(origin CXXDEFS)" "environment"
CXXDEFS= -D__cplusplus
endif
ifneq "$(origin AR)" "environment"
AR = ar
endif
ifneq "$(origin ARFLAGS)" "environment"
ARFLAGS = rvs
endif
ifneq "$(origin LDFLAGS)" "environment"
LDFLAGS =
endif
#### Delete default suffix rules
.SUFFIXES:
#### Include customization of flags and additional search paths
-include make.conf
#### Make expected directories
define make_expected_directories
if [ ! -e $(LOCAL_BIN) ] ; then mkdir $(LOCAL_BIN) ; fi ; \
if [ ! -e $(LOCAL_OBJ) ] ; then mkdir $(LOCAL_OBJ) ; fi ; \
if [ ! -e $(LOCAL_LIB) ] ; then mkdir $(LOCAL_LIB) ; fi ; \
if [ ! -e $(LOCAL_INC) ] ; then mkdir $(LOCAL_INC) ; fi ;
endef
dummy_expected_directories := $(shell $(make_expected_directories))
#### Set INC_DIRS for finding headers
INC_DIRS = $(patsubst %, -I%, \
$(strip $(LOCAL_INC) \
$(LOCAL_SYS_INC) \
$(INC_IMPORT_DIRS) \
$(INC_SEARCH_PATH)))
#### Set LD_DIRS for finding libraries
LD_DIRS = $(patsubst %, -L%, \
$(strip $(LOCAL_LIB) \
$(LIB_IMPORT_DIRS) \
$(LIB_SEARCH_PATH)))
#### VPATH
VPATH = $(shell pwd)$(patsubst %, :%, \
$(strip $(LOCAL_OBJ) \
$(LOCAL_LIB) \
$(LOCAL_BIN) \
$(LIB_IMPORT_DIRS) \
$(LIB_SEARCH_PATH)))
#### no target, make all!
default_target: all
#### Clean
clean: clean_obj clean_lib clean_bin clean_dep
clean_dep:
rm -f $(DEPS)
clean_obj:
-cd $(LOCAL_OBJ); rm -f $(OBJECTS)
clean_lib:
-cd $(LOCAL_LIB); rm -f $(LIBRARIES) $(IMPORTED_LIBRARIES)
clean_bin:
-cd $(LOCAL_BIN); rm -f $(PROGS)
#### Separate source types
C_OBJECTS := $(patsubst %.c, %.o, $(filter %.c, $(SOURCES)))
CXX_OBJECTS_CC := $(patsubst %.cc, %.o, $(filter %.cc, $(SOURCES)))
CXX_OBJECTS_C := $(patsubst %.C, %.o, $(filter %.C, $(SOURCES)))
CXX_OBJECTS := $(CXX_OBJECTS_CC) $(CXX_OBJECTS_C)
OBJECTS := $(C_OBJECTS) $(CXX_OBJECTS)
C_DEPS := $(patsubst %.c, %.d, $(filter %.c, $(SOURCES)))
CXX_DEPS_CC := $(patsubst %.cc, %.d, $(filter %.cc, $(SOURCES)))
CXX_DEPS_CPP := $(patsubst %.cpp, %.d, $(filter %.cpp, $(SOURCES)))
CXX_DEPS_C := $(patsubst %.C, %.d, $(filter %.C, $(SOURCES)))
CXX_DEPS := $(CXX_DEPS_CC) $(CXX_DEPS_C)
DEPS := $(C_DEPS) $(CXX_DEPS)
#### Generic object, lib, and bin commands
# Check for local pesence of source file to accommodate referencing
# of objects in other working directories.
#### *.c
$(C_OBJECTS): %.o: %.c
@ echo "@@@@@@@@@@@@@@@@@@@ " $< "@@@@@@@@@@@@@@@@@@@@@";
@ if [ -e $(notdir $<) ] ; then \
$(CC) $(CPPFLAGS) $(CDEFS) $(CFLAGS) -c \
$(INC_DIRS) -o $(LOCAL_OBJ)/$*.o $< ; \
else \
$(LINKS_PGM) $(LOCAL_OBJ) \
"$(patsubst %, :%, $(strip $(OBJ_SEARCH_PATH)))" $(notdir $@) ; \
fi ;
#### *.cc
$(CXX_OBJECTS_CC): %.o: %.cc
@ echo "@@@@@@@@@@@@@@@@@@@ " $< "@@@@@@@@@@@@@@@@@@@@@";
@ if [ -e $(notdir $<) ] ; then \
$(CXX) $(CPPFLAGS) $(CXXDEFS) $(CXXFLAGS) -c \
$(INC_DIRS) -o $(LOCAL_OBJ)/$*.o $< ; \
else \
$(LINKS_PGM) $(LOCAL_OBJ) \
"$(patsubst %, :%, $(strip $(OBJ_SEARCH_PATH)))" $(notdir $@) ; \
fi ;
#### *.C
$(CXX_OBJECTS_C): %.o: %.C
@ echo "@@@@@@@@@@@@@@@@@@@ " $< "@@@@@@@@@@@@@@@@@@@@@";
@ if [ -e $(notdir $<) ] ; then \
$(CXX) $(CPPFLAGS) $(CXXDEFS) $(CXXFLAGS) -c \
$(INC_DIRS) -o $(LOCAL_OBJ)/$*.o $< ; \
else \
$(LINKS_PGM) $(LOCAL_OBJ) \
"$(patsubst %, :%, $(strip $(OBJ_SEARCH_PATH)))" $(notdir $@) ; \
fi ;
#### To accommodate referencing of objects in other working directories.
$(SOURCES):
@echo $@ not present
$(LIBRARIES):
@ echo "################### " $@ "#####################";
@ cd $(LOCAL_OBJ); \
$(AR) $(ARFLAGS) $(LOCAL_LIB)/$(notdir $@) $+
$(PROGS):
@ echo "++++++++++++++++++++ " $@ "++++++++++++++++++++++";
@ if [ -z "$(filter $(CXX_OBJECTS), $(notdir $+))" ] ; then \
cd $(LOCAL_OBJ); \
if $(CC) -o $(LOCAL_BIN)/$(notdir $@) $(LDFLAGS) \
$(LD_DIRS) $(filter-out lib%.a, $+) \
$(patsubst lib%.a, -l%, $(filter lib%.a, $+)) ; then \
true; else rm -f $(LOCAL_BIN)/$(notdir $@); fi; \
else \
cd $(LOCAL_OBJ); \
if $(CXX) -o $(LOCAL_BIN)/$(notdir $@) $(LDFLAGS) \
$(LD_DIRS) $(filter-out lib%.a, $+) \
$(patsubst lib%.a, -l%, $(filter lib%.a, $+)) ; then \
true; else rm -f $(LOCAL_BIN)/$(notdir $@); fi; \
fi ;
#### For making dependencies
$(C_DEPS): %.d: %.c
@ if [ -e $(notdir $<) ] ; then \
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $(INC_DIRS) $< \
| sed '\''s/$*\\.o[ :]*/& $@/g'\'' > $@' ; \
fi ;
$(CXX_DEPS_CC): %.d: %.cc
@ if [ -e $(notdir $<) ] ; then \
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(INC_DIRS) $< \
| sed '\''s/$*\\.o[ :]*/& $@/g'\'' > $@' ; \
fi ;
$(CXX_DEPS_C): %.d: %.C
@ if [ -e $(notdir $<) ] ; then \
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(INC_DIRS) $< \
| sed '\''s/$*\\.o[ :]*/& $@/g'\'' > $@' ; \
fi ;
$(CXX_DEPS_CPP): %.d: %.cpp
@ if [ -e $(notdir $<) ] ; then \
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $(INC_DIRS) $< \
| sed '\''s/$*\\.o[ :]*/& $@/g'\'' > $@' ; \
fi ;
-include $(DEPS)
#### Specific target to make objects
objs: $(OBJECTS)
#### Specific target to make libraries
libs: $(LIBRARIES)
#### Specific target to make progs
progs: $(PROGS)
#### Specific target to make objects
#incs:
#### Phony
.PHONY: all clean clean_obj clean_lib clean_bin
# The following recurses the subdirectories that exist
define dosubdirs
echo "* Make Target is " $(TGT);
for i in $(SUBDIRS);\
do \
if [ -d $$i ]; then \
cd $$i;\
echo "##### Making Directory " `pwd` " " $(TGT) " #####";\
$(MAKE) $(TGT);\
cd ..;\
fi; \
done;
endef