# ex: se wm=0 ts=0 sw=2:
#
# $Id: GNUmakemaster,v 1.4 1992/04/28 20:04:46 steve Exp $
#
# Master GNU Makefile for Unidata software


################################################################################
# HOW TO SEARCH FOR TARGETS:
#
# Because indentation is used in this makefile to denote structure, it is 
# necessary to allow for leading spaces when searching for targets.  For 
# example, when searching for the target `install' from within vi(1), use 
# /^ *install/ rather than /^install/.


################################################################################
# NAMING CONVENTIONS FOR VARIABLES:
#
# UPPERCASE
#     You may override UPPERCASE variables -- either in an individual
#     makefile, on the make(1) command-line, or as an environment variable.
#
# lowercase:
#     You should not attempt to override lowercase variables -- unless
#     you know what you're doing.


################################################################################
# VOLATILE VARIABLES:
#
# The following variables are expected to be very makefile-dependent.  You may
# set them in individual makefiles, on the make(1) command-line, or as
# environment variables.

#	BINFILES	List of files to be installed in the installation
#			bin-directory.  Default is $(PROGRAMS).
#	BUILD_DIR	Pathname of directory in which to construct the 
#			library (should not contain subdirectory).  Default is
#			current directory.
#	CPPFLAGS	C preprocessor options
#	CFLAGS		C compiler options
#	ETCFILES	List of files to be installed in the installation
#			etc-directory (e.g. `udunits.dat').  Default is 
#			nothing.
#	GARBAGE		List of files to be removed by `clean' target.  May be
#			wildcarded.  Standard stuff is handled by this 
#			makefile.
#	INCFILES	List of files to be installed in the installation
#			header-file directory (e.g. `netcdf.inc').  Default is
#			everything in $(MANIFEST) with a `.h' suffix.
#	INCSUB		Subdirectory of the installation include-directory in
#			which to put special header-files (e.g. `udposix/').
#			Default is no sub-directory.  Only used if $(INCFILES)
#			is non-empty.
#	LDFLAGS		ld(1) options
#	LINTFLAGS	lint(1) options
#	LINTLIBES	lint(1) libraries (i.e. .ln's) to be searched
#	LOADLIBES 	ld(1) libraries
#	LIBRARY		library name (e.g. `netcdf')
#	LIBFILES	List of files to be installed in the installation
#			library-directory (e.g. runtime data-files).  Default 
#			is the library (if one was built).
#	LIBOBJS		List of .o's that will go into the library.  Default
#			is everything that can.
#	LIBSUB		Subdirectory of the installation library-directory in
#			which to put special runtime files (e.g. `fortc/').
#			Default is no sub-directory.  Only used if $(LIBFILES)
#			is non-empty.
#	MANFILES	List of manuals to be installed.  Default is everything
#			in $(MANIFEST) with a `.1', `.3', or `.8' suffix.
#	MAJOR_NO	Major release-number.  Used with $(MINOR_NO) to set 
#			SunOS sharable-library version-ID.
#	MANIFEST	List of pathnames comprising the distribution.  Default
#			is everything in the current directory.
#	MINOR_NO	Minor release-number.  Used with $(MAJOR_NO) to set
#			SunOS sharable-library version-ID.
#	NAME		Name of this distribution component.
#	PATCH_NO	Patch-number.  Used with $(MAJOR_NO) and $(MINOR_NO) to
#			set distribution release-ID.
#	PROGRAMS	List of programs (i.e. applications) to be built.
#	SA_OBJS		List of .o's that must go into the .sa portion of a 
#			SunOS sharable-library
#	SUBDIRS		List of subdirectories in which to perform recursive 
#			make(1)s


################################################################################
# DEFAULT VALUES FOR VARIABLES:
#
# You should modify the definitions in this section if they do not suit your
# environment.


# The following utility yields the absolute pathname of a pathname.
#
abspath		:= $(THIS_DIR)abspath


# Root of the installation.  This will have installation sub-directories
# (e.g. "bin", "include", "etc", "lib", "man") hanging off it (the
# sub-directories will be created if they don't exist).  If undefined,
# then the root of the installation will be the parent of the directory
# containing this file.
#
ifndef INSTROOT
  INSTROOT	:= $(shell $(abspath) $(THIS_DIR)../)
else
  # Ensure that $(INSTROOT) has a trailing `/'
  ifneq (, $(notdir $(INSTROOT)))
    override INSTROOT	:= $(INSTROOT)/
  endif
endif


# Type of operating-system.  Supported values include:
#    aix_3.1
#    domainos_10.2
#    domainos_10.3.2
#    domainos_10.3.5
#    hpux_8.0
#    irix_3.3.2
#    nextos_2.0
#    nextos_2.1
#    sunos_4.0.3
#    sunos_4.1
#    sunos_4.1.1
#    ultrix_3.5
#    ultrix_4.0
#    ultrix_4.1
#    ultrix_4.2
#    unicos_5.1.9
#    unicos_5.1.11
#
ifndef OS
  OS		:= sunos_4.1.1
endif


# The name of the operating-system (i.e. without version information):
#
os_name		:= $(firstword $(subst _, ,$(OS)))


# Default type of compilation and linking.  Value values are
#	debug		For debugging software.  Defines the C preprocessor
#			symbol `DEBUG', undefines `NDEBUG', and causes
#			generation and use of debugging symbol tables.
#			Uses the `_debug/' subdirectory.
#
#	profile		For profiling software by gprof(1).
#			Uses the `_profile/' subdirectory.
#
#	optimize	For generating optimized software.
#			Uses the `_optimize/' subdirectory.
#
ifndef VARIANT
  VARIANT	:= debug#		One of {debug profile optimize}
endif


# Compiler optimization levels (e.g. "3").  Values will depend on the 
# particular platform/compiler combination.  On every platform I've 
# encountered, leaving this undefined allows the compiler to choose
# an appropriate level.
#
ifndef CC_OPTLEVEL
  CC_OPTLEVEL	:=#	C compiler optimization level
endif
ifndef FC_OPTLEVEL
  FC_OPTLEVEL	:=#	Fortran compiler optimization level
endif


# Whether the C compiler correctly handles simultaneous use of the `-c' and 
# `-o' options (AIX's doesn't):
#
ifeq (aix, $(os_name))
  no_cc_minus_c_minus_o	:= yes
endif


# X11 header-file and library directories:
#
# NB: Because X11 header-files are included by lines of the form
# `#include "X11/..."', $(x11_incdir) should be the pathname of the 
# directory that contains the `X11/' header-file subdirectory (e.g.
# `/usr/include').
#
ifndef x11_incdir
  ifdef OPENWINHOME
    x11_incdir		:= $(OPENWINHOME)/include
  else
    ifeq (hpux, $(os_name))
      x11_incdir        := /usr/include/X11R4
    else
      x11_incdir        := /usr/include
    endif
  endif
endif
ifndef x11_libdir
  ifdef OPENWINHOME
    x11_libdir	:= $(OPENWINHOME)/lib
  else
    ifeq (hpux, $(os_name))
      x11_libdir        := /usr/lib/X11R4
    else
      ifeq (ultrix, $(os_name))
        x11_libdir	:=
      else
        x11_libdir	:= /usr/lib/X11
      endif
    endif
  endif
endif


# Library type.  Supported values are
#	sharable	Creates both a sharable and non-sharable library
#	nonsharable	Creates only a non-sharable library
# Sharable libraries are the default for AIX and for SunOS release 4.1[.*].
# For all other operating-systems, the default is nonsharable libraries.
#
ifndef LIBTYPE
  ifeq (aix, $(os_name))
    LIBTYPE	:= sharable
  else
    ifneq (, $(findstring sunos_4.1, $(OS)))
      LIBTYPE	:= sharable
    else
      LIBTYPE	:= nonsharable
    endif
  endif
endif
#
# Because SunOS's dbx(1) has problems with sharable libraries, we create 
# only non-sharable ones if the debugging variant is selected.
#
ifeq (sunos_sharable_debug,$(findstring sunos,$(os_name))_$(findstring \
	sharable,$(LIBTYPE))_$(findstring debug, $(VARIANT)))
  override LIBTYPE	= nonsharable
endif


# Miscellaneous utilities:
#
ifndef CO
  CO		:= co#		RCS "checkout" utility.
endif
ifndef INSTALL
  INSTALL	:= install -c#	BSD "install" utility (must "copy"; not "move").
endif
ifndef RANLIB
  ifeq (aix, $(os_name))
    RANLIB	:=		# AIX's ar(1) includes ranlib(1) function
  else
    ifeq (unicos, $(OS_NAME))
      RANLIB	:=		# UNICOS's ar(1) includes ranlib(1) function
    else
      ifeq (irix, $(OS_NAME))
        RANLIB	:=		# IRIX's ar(1) includes ranlib(1) function
      else
        RANLIB	:= ranlib
      endif
    endif
  endif
endif
ifndef TBL
  TBL		:= $(shell which tbl)#		find it if possible
  ifneq (1, $(words $(TBL)))
    TBL		:= cat
  endif
endif
ifndef NEQN
  NEQN		:= $(shell which neqn)#		find it if possible
  ifneq (1, $(words $(NEQN)))
    NEQN	:= cat
  endif
endif
ifndef TROFF
  ifeq (sunos, $(os_name))
    TROFF	:= ptroff
  else
    TROFF	:= troff
  endif
endif
ifndef ECHO
  ECHO		= echo#	echo with newline
endif
ifndef ECHON
  ECHON		= /bin/echo -n#	echo with no newline (echo -n)
endif
#
# The following utility generates FORTRAN-callable C functions from platform-
# independent source-code.  It's part Unidata's UDAPE portability package.
#
ifndef FORTC
  FORTC		:= fortc
endif


ifndef CATMAN
  # We don't use AIX's catman(8) because it sticks *everything* (including
  # system-supplied manual pages) into every `whatis' file it creates.
  ifneq (aix, $(os_name))
    # We don't use the ULTRIX catman(8) because it doesn't know how to handle 
    # private, non-"/usr/man" directories (via the `-M' option).
    ifneq (ultrix, $(os_name))
      # We don't use HPUX's catman(8) for the same reason.
      ifneq (hpux, $(os_name))
        CATMAN	:= $(wildcard /usr/etc/catman)
      endif
    endif
  endif
endif


################################################################################
################################################################################
#
# IT SHOULD NOT BE NECESSARY TO CHANGE ANYTHING BELOW
#
################################################################################
################################################################################


################################################################################
# DEFINITIONS USED IN MORE THAN ONE SECTION OF THIS MAKEFILE:


# Distribution manifest.  This should be set in the individual makefiles.
#
ifndef MANIFEST
  MANIFEST	:= $(wildcard *)
endif


# Individual installation directories:
#
inst_bindir	:= $(INSTROOT)bin/
inst_etcdir	:= $(INSTROOT)etc/
inst_incdir	:= $(INSTROOT)include/
inst_libdir	:= $(INSTROOT)lib/
inst_mandir	:= $(INSTROOT)man/


# Support for dependencies in other directories:
#
variant_dir	:= $(VARIANT:%=_%/)
VPATH		:= $(variant_dir)


# C sources:
#
csrcs	:= $(filter %.c,$(MANIFEST)) \
	     $(patsubst %.fc, %.c, $(filter %.fc, $(MANIFEST))) \
	     $(patsubst %.y,  %.c, $(filter %.y,  $(MANIFEST))) \
	     $(patsubst %.l,  %.c, $(filter %.l,  $(MANIFEST)))


# FORTRAN sources:
#
fsrcs	:= $(sort $(strip \
	     $(patsubst %.F,  %.f, $(filter %.F,  $(MANIFEST)))))


# Header-files:
#
hsrcs	:= $(filter %.h,$(MANIFEST))


# General garbage to be removed by the `clean' target (this variable is
# augmented as appropriate by the various rules):
#
override GARBAGE	:= $(GARBAGE) a.out core $(variant_dir)*.o *.log *~ \
			   *.bak


# lint(1) products:
#
lintobjs	:= $(sort $(strip \
		      $(patsubst %.c,  %.ln, $(filter %.c,  $(MANIFEST))) \
		      $(patsubst %.fc, %.ln, $(filter %.fc, $(MANIFEST)))))


# Action to install something.
#
define install
  $(INSTALL) $? $@
endef
#  @rm -f $@
#  umask $(UMASK); cp -p $? $@ 


# Release identifiers:
#
ifeq (file, $(origin VERSION_FILE))
  ifndef MAJOR_NO
    MAJOR_NO	:=  $(shell test -f $(VERSION_FILE) && sed -n \
                       '/.*[^0-9]\([0-9][0-9]*\)\.[0-9][0-9]*.*/s//\1/p;q' \
                       $(VERSION_FILE))
  endif
  ifndef MINOR_NO
    MINOR_NO	:=  $(shell test -f $(VERSION_FILE) && sed -n \
                       '/.*[^0-9][0-9][0-9]*\.\([0-9][0-9]*\).*/s//\1/p;q' \
                       $(VERSION_FILE))
  endif
endif
release_no	:= $(MAJOR_NO)$(MINOR_NO:%=.%)$(PATCH_NO:%=.%)


################################################################################
# ADJUSTMENTS TO PASSED-IN VOLATILE VARIABLES:
#
# Sometimes they're not defined and need to be; othertimes, they must be 
# adjusted.


# Basic name for this component:
#
dirname		:= $(notdir $(shell pwd))
ifneq (file, $(origin NAME))
  ifeq (file, $(origin BUILD_DIR))
    NAME	:= $(notdir $(shell cd $(BUILD_DIR); pwd))
  else
    NAME	:= $(dirname)
  endif
endif


# Adjust lint(1) variables:
#
ifneq (udape, $(LIBRARY))
  LINTLIBES	:= $(LINTLIBES:-ludape=\
			$(wildcard $(inst_libdir)lint/llib-ludape.ln))
endif
ifeq (sunos, $(os_name))
  LINTLIBES	:= $(strip $(LINTLIBES) -lansic -lposix)
  LINTFLAGS	:= $(strip $(LINTFLAGS) -n)
endif


# Adjust C preprocessor option references.  The following modifications will
# be made:
#	-I/udposix	-> -I$(inst_incdir)udposix
#	-I/X11		-> -I$(x11_incdir)
#	_OS		-> $(OS)
#	_INST_ETCDIR	-> $(inst_etcdir)
# In addition:
#	1. The installation include-directory will be added to the header-file
#	   search path.
#	2. Trailing `/'s will be removed from all `-I' specifications.
#
CPPFLAGS	:= $(CPPFLAGS:-I/udposix=-I$(inst_incdir)udposix)
CPPFLAGS	:= $(CPPFLAGS:-I/X11=-I$(x11_incdir))
CPPFLAGS	:= $(subst _OS,$(OS), $(CPPFLAGS))
CPPFLAGS	:= $(subst _INST_ETCDIR,$(inst_etcdir), $(CPPFLAGS))
CPPFLAGS	:= $(CPPFLAGS) $(inst_incdir:%/=-I%)
CPPFLAGS	:= $(CPPFLAGS:-I%/=-I%)


# Adjust compiler and linker options based on requested product type:
#
ifneq (, $(findstring debug, $(VARIANT)))
  #
  # Debugging variant:
  #
  ifeq (, $(findstring -g, $(CFLAGS)))
    override CFLAGS	:= $(strip $(CFLAGS) -g)
  endif
  ifeq (, $(findstring -g, $(FFLAGS)))
    override FFLAGS	:= $(strip $(FFLAGS) -g)
  endif
  # SunOS's dbx(1) has problems with shared-libraries, so:
  ifeq (sunos, $(os_name))
    override LDFLAGS	:= $(strip $(LDFLAGS) -Bstatic)
    override LOADLIBES	:= $(strip $(LOADLIBES) -lg)
  endif
else
  ifneq (, $(findstring profile, $(VARIANT)))
    #
    # Profiling variant:
    #
    ifeq (, $(findstring -p, $(CFLAGS)))
      override CFLAGS	:= $(strip $(CFLAGS) -pg -O)
    endif
    ifeq (, $(findstring -p, $(FFLAGS)))
      override FFLAGS	:= $(strip $(FFLAGS) -pg -O)
    endif
    ifeq (, $(findstring -p, $(LDFLAGS)))
      # SunOS ld(1) can't handle profiling and sharable libraries 
      # simultaneously.
      override LDFLAGS	:= $(strip $(LDFLAGS) -Bstatic)
    endif
  else
    ifneq (, $(findstring optimize, $(VARIANT)))
      #
      # Optimized variant:
      #
      ifeq (, $(findstring -O, $(CFLAGS)))
        override CFLAGS	:= $(strip $(CFLAGS) -O$(CC_OPTLEVEL))
      endif
      ifeq (, $(findstring -O, $(FFLAGS)))
        override FFLAGS	:= $(strip $(FFLAGS) -O$(FC_OPTLEVEL))
      endif
    endif
  endif
endif


# Library construction in other than the current working directory:
#
lib_build_dir	:= $(BUILD_DIR)$(variant_dir)
ifndef BUILD_DIR
  build_in_cwd	:= yes
else
  build_in_cwd	:=
endif


# Adjust references to load-libraries.  The following modifications will be
# made:
#	-l$(LIBRARY)	-> -L$(lib_build_dir) -l$(LIBRARY) \
#			   -L$(inst_libdir) -L$(LIBRARY)
#	-ludape		-> -L$(inst_libdir) -ludape  (except when in the
#						      UDAPE source-directory)
#	-lX11		-> -L$(x11_libdir) -lX11
#	-L_INST_LIBDIR	-> -L$(inst_libdir)
#	_VARIANT_DIR	-> $(variant_dir)
# And:
#	1. If linking on a SunOS platform, relative library search pathnames 
#	   are converted to absolute pathnames to handle relocation of 
#	   applications linked against a sharable library.
#	2. Trailing `/'s will be removed from all `-L' specifications.
#	3. On an HPUX platform, all `-L' specifications will be changed to
#	   `-Wl,-L'.
#
override LOADLIBES	:= $(LOADLIBES:-l$(LIBRARY)=-L$(lib_build_dir) \
				       -l$(LIBRARY) -L$(inst_libdir) \
				       -l$(LIBRARY))
ifneq (udape, $(LIBRARY))
  override LOADLIBES	:= $(LOADLIBES:-ludape=-L$(inst_libdir) -ludape)
endif
override LOADLIBES	:= $(LOADLIBES:-lX11=$(x11_libdir:%=-L%) -lX11)
override LOADLIBES	:= $(LOADLIBES:-L_INST_LIBDIR=-L$(inst_libdir))
override LOADLIBES	:= $(subst _VARIANT_DIR,$(variant_dir), $(LOADLIBES))
ifeq (sunos, $(os_name))
  override LOADLIBES	:= $(LOADLIBES:-L..%=-L$(PWD)/..%)
endif
override LOADLIBES	:= $(LOADLIBES:-L%/=-L%)
ifeq (hpux, $(os_name))
  override LOADLIBES	:= $(LOADLIBES:-L%=-Wl,-L%)
endif


################################################################################
################################################################################
# RULES:
################################################################################
################################################################################


# The default target:
#
.PHONY:			all
all::


################################################################################
# DIRECTORY CREATION:


# The `-p' option isn't available under AIX.
#
%/:
  ifeq (aix, $(os_name))
	mkdir $(patsubst %/,%,$@)
  else
	mkdir -p $(patsubst %/,%,$@)
  endif
.PRECIOUS:	%/


################################################################################
# AUTOMATIC DEPENDENCY MAINTENANCE:


dep_files	= $(sort $(strip \
		      $(patsubst %.c,  .%.dep, $(filter %.c,  $(MANIFEST))) \
		      $(patsubst %.y,  .%.dep, $(filter %.y,  $(MANIFEST))) \
		      $(patsubst %.l,  .%.dep, $(filter %.l,  $(MANIFEST))) \
		      $(patsubst %.cc, .%.dep, $(filter %.cc, $(MANIFEST))) \
		      $(patsubst %.yy, .%.dep, $(filter %.yy, $(MANIFEST))) \
		      $(patsubst %.ll, .%.dep, $(filter %.ll, $(MANIFEST)))))
#
# There doesn't appear to be any portable way to get the C++ compiler to
# generate dependencies: the following line doesn't work
#	$(C++) $(CPPFLAGS) -E -C -M $<
# Hence, we use makedepend(1).
.%.dep:		%.cc
	@touch $@
	makedepend $(CPPFLAGS) $(C++SYSINC) -f$@ $<
	@rm -f $@.bak

  # The following can't be done under AIX because that platform's C compiler 
  # won't output dependencies (i.e. there is no equivalent to the `-M' option).
  #
  ifneq (aix, $(os_name))
    ifeq (ultrix_cc, $(os_name)_$(CC))
      gen_dep_flag	:= -Em
    else
      gen_dep_flag	:= -M
    endif
    .%.dep:		%.c
	$(CC) $(CPPFLAGS) $(gen_dep_flag) $< \
		| fmt -1 \
		| sed '/^$*\.o/d;/:/d;/^\.\.\//d;/^\//d' \
		| awk '{print "$$(variant_dir)$*.o: " $$1}' > $@

  endif	# we're not on an AIX platform

  ifdef dep_files
    depend:	$(dep_files)
	cat $^ > $@
  endif

# Include the dependancy-file.
#
ifneq (, $(wildcard depend))
  include depend
endif


#########################################################################
# TAGS:


tags:		$(csrcs) $(hsrcs)
	ctags -t $^


#########################################################################
# LINT(1):

.PHONY:		lint

lint::


# FORTRAN lint(1) support (such as it is):
#
ifdef fsrcs
  lint::	$(fsrcs:%.f=$(variant_dir)%.o)
  $(fsrcs:.f=.lint): \
  %.lint:	$(variant_dir)%.o
endif

ifdef lintobjs

ifdef LIBRARY
  lint::	$(lintobjs)
  ifdef build_in_cwd
    lint::	lintlib
    lintname	:= $(LIBRARY)
  endif
endif


# Individual lint object:
#
%.ln:			%.c
	$(LINT) -c $(CPPFLAGS) $(filter-out -n, $(LINTFLAGS)) $<
override GARBAGE	:= $(GARBAGE) *.ln


# Lint library:
#
.PHONY:			lintlib
lintlib:		llib-l$(lintname).ln
llib-l$(lintname).ln:	$(lintobjs)
	$(LINT) $(CPPFLAGS) $(LINTFLAGS) -o $(lintname) $^

endif	# lintobjs defined above


#########################################################################
# VGRIND(1):


%.vg:		%.c
	vgrind -s11 %<

%.vg:		%.h
	vgrind -s11 %<


#########################################################################
# FORTC(1):

%.c:	%.fc
	$(FORTC) $< > $@

override GARBAGE	:= $(GARBAGE) \
			   $(patsubst %.fc, %.c, $(filter %.fc, $(MANIFEST)))


#########################################################################
# YACC(1):


# The sed(1)-line is necessary to avoid `redeclaration of malloc()' messages
# from the /usr/5bin/cc SunOS 4.1.1 compiler (and perhaps others).
#
%.c %.h:	%.y
	$(YACC) $(YFLAGS) -d $<
	sed '/extern *char *\*malloc(), *\*realloc();/d' < y.tab.c > $@
	rm y.tab.c
	mv y.tab.h $*.h


#######################################################################
# COMPILATION:


#--------------------------------------------------------------------------
# C COMPILATION:


# C preprocessor output to standard-output.
#
%.cpp:		%.c
	$(CPP) $(CPPFLAGS) $<


# Compilation into a separate directory:
#
define cc_norm
	@-test -d $(dir $@) || mkdir -p $(dir $@) > /dev/null 2>&1
	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
endef
define cc_norm_mv
	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< 
	@-test -d $(dir $@) || mkdir -p $(dir $@) > /dev/null 2>&1
	mv $(<:.c=.o) $@
endef
define cc_pic_mv
	$(CC) -c -pic $(CFLAGS) $(CPPFLAGS) $< 
	@-test -d $(dir $@) || mkdir -p $(dir $@) > /dev/null 2>&1
	mv $(<:.c=.o) $@
endef

ifdef no_cc_minus_c_minus_o
  define cco
	$(cc_norm_mv)
  endef
else
  define cco
	$(cc_norm)
  endef
endif

ifdef variant_dir
  $(variant_dir)%.o:	%.c
	$(cco)
endif

ifeq (sunos, $(os_name))
    #
    # The SunOS C compiler wants the output file to have a `.o' extension;
    # hence, we do an explicit move.
    #
  $(variant_dir)%.sa:	%.c
	$(cc_pic_mv)
  $(variant_dir)%.so:	%.c
	$(cc_pic_mv)
endif


#--------------------------------------------------------------------------
# FORTRAN COMPILATION:


# Compilation into a separate directory:
#
define fc_norm
	@-test -d $(dir $@) || mkdir -p $(dir $@) > /dev/null 2>&1
	$(FC) -c $(FFLAGS) $< -o $@
endef
define fc_norm_mv
	$(FC) -c $(FFLAGS) $< 
	@-test -d $(dir $@) || mkdir -p $(dir $@) > /dev/null 2>&1
	mv $(<:.c=.o) $@
endef
define fc_pic_mv
	$(FC) -c -pic $(FFLAGS) $< 
	@-test -d $(dir $@) || mkdir -p $(dir $@) > /dev/null 2>&1
	mv $(<:.c=.o) $@
endef

ifdef no_fc_minus_c_minus_o
  define fco
	$(fc_norm_mv)
  endef
else
  define fco
	$(fc_norm)
  endef
endif

$(variant_dir)%.o:	%.f
	$(fco)

%.f:			%.F
	$(CPP) $(CPPFLAGS) -DUD_FORTRAN_SOURCE $< > $@

override GARBAGE	:= $(GARBAGE) \
			   $(patsubst %.F, %.f, $(filter %.F, $(MANIFEST)))

ifeq (sunos, $(os_name))
    #
    # The SunOS C compiler wants the output file to have a `.o' extension;
    # hence, we do an explicit move.
    #
  $(variant_dir)%.sa:	%.f
	$(fc_pic_mv)
  $(variant_dir)%.so:	%.f
	$(fc_pic_mv)
endif


################################################################################
# LIBRARIES:


ifdef LIBRARY	# {

lib_objs	:=
sa_objs		:=
so_objs		:=
build_lib_a	:=
build_lib_a	:=
install_lib_a	:=


# Library objects:
#
# Ensure that the following variable is not inherited from the environment of a
# parent make(1) and that it's set if at all possible.
#
ifneq (file, $(origin LIBOBJS))
  LIBOBJS	:= $(sort $(strip \
			$(patsubst %.c,  %.o, $(filter %.c,  $(MANIFEST))) \
			$(patsubst %.fc, %.o, $(filter %.fc, $(MANIFEST))) \
			$(patsubst %.F,  %.o, $(filter %.F,  $(MANIFEST))) \
			$(patsubst %.f,  %.o, $(filter %.f,  $(MANIFEST)))))
endif

ifdef LIBOBJS	# {

.PHONY:		library

lib_objs		:= $(patsubst ./%, %, \
				$(join $(dir $(LIBOBJS)), \
				    $(addprefix $(variant_dir), \
					$(notdir $(LIBOBJS)))))

all::		$(lib_objs)

override GARBAGE	:= $(GARBAGE) $(lib_objs)

.PHONY:		lib_objs
lib_objs:	$(lib_objs)

libname			:= $(LIBRARY)
lib_a			:= lib$(libname).a
build_lib_a		:= $(lib_build_dir)$(lib_a)
override GARBAGE	:= $(GARBAGE) $(lib_build_dir)lib*.a

# Action to run ranlib(1) (or not).
#
ifdef RANLIB
  define ranlib
	$(RANLIB) $@
  endef
endif

# Regular libraries are built as follows: 1) for each leaf node, sources are
# compiled into objects in the build-directory; 2) at the build-directory
# node, the objects are placed in the library (which may need to be created) 
# residing in the variant subdirectory of the build-directory; and 
# 3) ranlib(1) is run on the build-library.  These steps are modified for
# building sharable-libraries under AIX, but the directories are the same.

library:		$(dir $(build_lib_a)) $(build_lib_a)

ifeq (aix_sharable, $(os_name)_$(LIBTYPE))	# {
  lib_o			:= $(lib_build_dir)lib$(libname)
  ifdef build_in_cwd
    $(build_lib_a):	$(lib_o)
	$(AR) r $@ $?
  endif

  # Adjust references to the X11 library.
  #
  LIBO_LIBS	:= $(LIBO_LIBS:-lX11=-L$(x11_libdir) -lX11)

  $(lib_o):		$(lib_objs)
	/usr/ucb/nm -g $(lib_objs) | \
	    awk '$$(NF-1) == "D" {print $$NF}' > shlib.exp
	ld -bE:shlib.exp -T512 -H512 -bM:SRE -o $@ $(lib_objs) $(LIBO_LIBS) -lc
	rm shlib.exp
  override GARBAGE	:= $(GARBAGE) $(lib_o)
else	# } aix_sharable not defined below {
  ifdef build_in_cwd
    $(build_lib_a):	$(lib_objs)
	$(AR) r $@ $?
	$(ranlib)
  endif
endif	# } aix_sharable not defined above

install_lib_a		:= $(inst_libdir)$(lib_a)
ifdef build_in_cwd
  install::		$(install_lib_a)
endif

$(install_lib_a):	$(build_lib_a)
	$(install)
	$(ranlib)

override GARBAGE	:= $(GARBAGE) $(lib_objs)

#----------------------------------------------------------------------
# SunOS sharable-library:


ifeq (sunos_sharable, $(os_name)_$(LIBTYPE))	# {

  # Ensure that the following variable is not inherited from the environment of
  # a parent make(1).
  #
  ifneq (file, $(origin SA_OBJS))
    SA_OBJS	:=
  endif

  ifdef SA_OBJS
    sa_objs		:= $(patsubst ./%, %, \
				$(join $(dir $(SA_OBJS)), \
				    $(addprefix $(variant_dir), \
					$(notdir $(SA_OBJS:.o=.sa)))))
    lib_objs:		$(sa_objs)
  endif
  ifdef LIBOBJS
    so_objs		:= $(patsubst ./%, %, \
				$(join $(dir $(LIBOBJS)), \
				    $(addprefix $(variant_dir), \
					$(notdir $(LIBOBJS:.o=.so)))))
    lib_objs:		$(sa_objs) $(so_objs)
  endif

  override GARBAGE	:= $(GARBAGE) $(lib_objs)

# Profiling and sharable-libraries are incompatible under SunOS; hence ...

ifneq (profile, $(VARIANT))	# {

  # The ".sa" component of a SunOS sharable-library is built as follows: 
  # 1) the appropriate objects are compiled into the position-independent
  # subdirectory of the current working directory; 2) these objects are added
  # to the .sa library in the variant subdirectory of the build-directory (the
  # .sa build-library, which might have to be created); and 3) ranlib(1) is 
  # run on the .sa build-library.

  ifdef SA_OBJS		# {
    lib_sa		:= lib$(libname).sa.$(MAJOR_NO).$(MINOR_NO)
    build_lib_sa	:= $(lib_build_dir)$(lib_sa)

    library:		$(build_lib_sa)

    ifdef build_in_cwd
      $(build_lib_sa):	$(sa_objs)
	$(AR) r $@ $?
	$(ranlib)
    endif
    inst_lib_sa		:= $(inst_libdir)$(lib_sa)
    ifdef build_in_cwd
      install::		$(inst_lib_sa)
    endif
    $(inst_lib_sa):	$(build_lib_sa)
	$(install)
	$(ranlib)
  endif			# }


  # The ".so" component of a SunOS sharable-library is built as follows: 
  # 1) the appropriate objects are compiled into the variant subdirectory of
  # the build-directory; and 2) the logical Makefile associated with the 
  # build-directory adds these objects to the .so library, which it creates 
  # in the same variant subdirectory of the build-directory.

  lib_so		:= lib$(libname).so.$(MAJOR_NO).$(MINOR_NO)
  build_lib_so		:= $(lib_build_dir)$(lib_so)

  library:		$(build_lib_so)

  ifdef build_in_cwd
    $(build_lib_so):	$(so_objs)
	ld -assert pure-text -o $@ $(so_objs)
  endif

  inst_lib_so		:= $(inst_libdir)$(lib_so)
  ifdef build_in_cwd
    install::		$(inst_lib_so)
  endif
  $(inst_lib_so):	$(build_lib_so)
	$(install)

  override GARBAGE	:= $(GARBAGE) $(variant_dir)*.sa
  override GARBAGE	:= $(GARBAGE) $(variant_dir)*.so
  ifdef build_in_cwd
    override GARBAGE	:= $(GARBAGE) $(variant_dir)lib*.sa.*
    override GARBAGE	:= $(GARBAGE) $(variant_dir)lib*.so.*
  endif

endif	# } profile variant above

all::		$(sa_objs) $(so_objs)

endif	# } sunos_sharable above

ifdef build_in_cwd
  all::		library
endif

endif	# } LIBOBJS defined above

endif	# } LIBRARY defined above

all::		$(LIBFILES)

#######################################################################
# PROGRAMS:
#
# Application programs that depend upon more than one object-file should 
# have their object-file dependencies listed in pure-dependency lines in the
# individual makefiles in order to enable this makefile to correctly link 
# everything together using the `$^' automatic variable.  Be sure to use 
# $(variant_dir) in the dependency-line.  For example:
#
#	$(variant_dir)foo:	$(variant_dir)foo.o $(variant_dir)bar.o
#
# Note that such pure-dependency lines will have to be placed after the
# `include' of the master makefile in order to have `variant_dir' defined.


# Ensure that the following variable is not inherited from the environment of
# a parent make(1).
#
ifneq (file, $(origin PROGRAMS))
  PROGRAMS	:=
endif


ifdef PROGRAMS	# {

  ifdef lintobjs
    lint::	lintprog

    # Program lint:
    #
    .PHONY:			lintprog
    lintprog:		$(lintobjs)
	$(LINT) $(CPPFLAGS) $(LINTFLAGS) $^ $(LINTLIBES)

  endif	# lintobjs defined above

  programs	:= $(addprefix $(variant_dir), $(PROGRAMS))

  # By default, we don't build a program that's part of a library distribution
  # because it probably uses the library (which might no exist if the library
  # is split across several subdirectories).
  #
  ifndef LIBRARY
    all::		$(programs)
  endif

  ifdef variant_dir
    .PHONY:		$(PROGRAMS)
    $(PROGRAMS): %:	$(variant_dir)%
  endif

  ifdef LIBRARY
    $(programs):	$(lib_build_dir)
  endif

  $(programs): \
  $(variant_dir)%:	$(variant_dir)%.o
	@if [ -f $*.f -o -f $*.F ]; then \
	    cmd='$(FC) $(FFLAGS) $(LDFLAGS) $(sort $(filter-out %/, $^)) \
		$(LOADLIBES) -o $@'; \
	else \
	    cmd='$(CC) $(CFLAGS) $(LDFLAGS) $(sort $(filter-out %/, $^)) \
		$(LOADLIBES) -o $@'; \
	fi; \
	echo $$cmd; \
	$$cmd


  override GARBAGE	:= $(GARBAGE) $(programs)
endif	# } PROGRAMS defined above


#######################################################################
# MANUAL-PAGES:


# Ensure that the following variable is not inherited from the environment of
# a parent make(1) and that it's set if at all possible.
# Because this variable appears as a `target', it is necessary to strip-off
# any leading spaces.
#
ifneq (file, $(origin MANFILES))
  MANFILES	:= $(strip \
		     $(filter %.1, $(MANIFEST)) $(filter %.3, $(MANIFEST)) \
		     $(filter %.8, $(MANIFEST)))
endif


# Installed manuals.
#
ifdef MANFILES # {
  install::	manuals

  manuals:	$(inst_mandir)

  chap1_manuals	:= $(filter %.1, $(MANFILES))
  chap3_manuals	:= $(filter %.3, $(MANFILES))
  chap8_manuals	:= $(filter %.8, $(MANFILES))

  # Routine to install a manual.  It
  #	1. Modifies the RCS `$Date' keyword into something more appropriate
  #	   to a manual-page; and
  #	2. Runs the manual through tbl(1) and neqn(1) prior to installing.
  # NB: According to the SunOS tbl(1) manual-page, tbl(1) should precede 
  # neqn(1).
  #
  define install_manual
    sed \
    '/^\.TH/s/$$D\ate: \([0-9]*\)\/\([0-9]*\)\/\([0-9]*\).*\$$/\1-\2-\3/' \
	$< | $(TBL) | $(NEQN) > $@
  endef

  ifdef chap1_manuals
    mandir	:= $(inst_mandir)man1/
    manuals:	$(mandir) $(addprefix $(mandir), $(chap1_manuals))
  endif
  ifdef chap3_manuals
    mandir	:= $(inst_mandir)man3/
    manuals:	$(mandir) $(addprefix $(mandir), $(chap3_manuals))
  endif
  ifdef chap8_manuals
    mandir	:= $(inst_mandir)man8/
    manuals:	$(mandir) $(addprefix $(mandir), $(chap8_manuals))
  endif

  $(inst_mandir)man1/%:		%
	$(install_manual)
  $(inst_mandir)man3/%:		%
	$(install_manual)
  $(inst_mandir)man8/%:		%
	$(install_manual)

endif	# } MANFILES defined above


#######################################################################
# INSTALLATION:
#
# Some installation rules for specific products (e.g. libraries) 
# are in other sections of this file.

.PHONY:		install
install::


# Program installation:
#
  # Ensure that the following variable is not inherited from the environment 
  # of a parent make(1) and that it's defined if at all possible.
  #
  ifneq (file, $(origin BINFILES))
    BINFILES	:= $(PROGRAMS)
  endif

  ifdef BINFILES
    install::		$(inst_bindir) $(BINFILES:%=$(inst_bindir)%)
    #
    # Try the variant sub-directory before the current directory.
    #
    $(inst_bindir)%:	$(variant_dir)%
	  $(install)
    $(inst_bindir)%:	%
	  $(install)
  endif


# Installed header-file.
#
  # Ensure that the following variable is not inherited from the environment 
  # of a parent make(1) and that it's set if at all possible.
  #
  ifneq (file, $(origin INCFILES))
    INCFILES	:= $(filter %.h, $(MANIFEST))
  endif

  ifdef INCFILES
    install::	$(inst_incdir) $(inst_incdir)$(INCSUB) \
		$(addprefix $(inst_incdir)$(INCSUB), \
			    $(sort $(dir $(INCFILES)))) \
		$(INCFILES:%=$(inst_incdir)$(INCSUB)%)
  endif
  $(inst_incdir)%.h:		%.h
	  $(install)
  $(inst_incdir)udposix/%.h:	%.h
	  $(install)


ifeq (file, $(origin LIBFILES))
  install::	$(inst_libdir) \
		$(addprefix $(inst_libdir), $(LIBSUB)) \
		$(addprefix $(inst_libdir)$(LIBSUB), $(LIBFILES))
endif


# Install something in the current working directory into a library
# subdirectory.  The $(install) script doesn't work for some reason: the 
# ${?,^,<} variables are empty.
#
$(inst_libdir)$(LIBSUB)%:	%
	$(INSTALL) $< $@
#	$(install)


# Install something in the current variant directory into a library
# subdirectory.  The $(install) script doesn't work for some reason: the 
# ${?,^,<} variables are empty.
#
$(inst_libdir)%:	$(addprefix $(variant_dir), $(@F))
	$(INSTALL) $< $@
#	$(install)


# Installed "etc/" file.
#
ifdef ETCFILES
  install::	$(inst_etcdir) $(inst_etcdir)$(ETCSUB)	\
		$(addprefix $(inst_etcdir)$(ETCSUB),	\
			    $(sort $(dir $(ETCFILES))))	\
		$(ETCFILES:%=$(inst_etcdir)$(ETCSUB)%)
endif
$(inst_etcdir)%:		%
	$(install)


#######################################################################
# DOCUMENTATION:


# PostScript from TeX device-independent file:
# 
%.ps:		%.dvi
	dvips $(DVIPS_FLAGS) -o $@ $<
override GARBAGE	:= $(GARBAGE) *.ps *.dvi *.gs *.aux *.cp *.fn *.ky \
			   *.pg *.toc *.tp *.vr


# Hard-copy from PostScript:
#
%.hc:		%.ps
	lpr $<


# Preview PostScript:
#
ps_previewer	:= /local/src/gnu/gs/gs
%.preview:	%.ps
	$(ps_previewer) $<


#######################################################################
# RECURSIVE MAKE(1)S:


define recurse
  @echo ""
  @cd $(@D); \
    PWD=`pwd`; export PWD; \
    echo "making \`$(@F)' in $$PWD"; \
    $(MAKE) $(@F)
  @echo ""
  @echo returning to `pwd`
endef


# Ensure that the following variable is not inherited from the environment 
# of a parent make(1).
#
ifneq (file, $(origin SUBDIRS))
  SUBDIRS	:=
endif


# Recursive makes in multiple sub-directories:
#
ifdef SUBDIRS # {
#  .PHONY:		$(SUBDIRS)
#  $(SUBDIRS):
#	@echo ""
#	@cd $@; \
#	    echo "making \`$(GOAL)' in `pwd`"; \
#	    $(MAKE) $(GOAL)
#	@echo ""
#	@echo returning to `pwd`

  subdirs/%:		FORCE
	@$(MAKE) $(addsuffix /$(@F), $(SUBDIRS))

  # Recursive makes of a specific target in a specific subdirectory:
  #
  $(SUBDIRS:%=%/all) \
  $(SUBDIRS:%=%/lint) \
  $(SUBDIRS:%=%/clean) \
  $(SUBDIRS:%=%/dist-tree) \
  $(SUBDIRS:%=%/install): \
  %:                   FORCE
	$(recurse)


  ifdef RECURSE
    $(addsuffix /%, $(SUBDIRS)):	FORCE
	$(recurse)
  endif
	

else	# } { SUBDIRS defined above
  subdirs/%:
	;
endif	# } SUBDIRS not defined above


#########################################################################
# CLEANUP:


.PHONY:		clean realclean

clean::
	rm -f $(sort $(wildcard $(GARBAGE)))
realclean::	clean
	rm -f tags .*.dep


#########################################################################
# DISTRIBUTIONS (for UPC use only):


# Distribution directories:
#
ifndef FTPROOT
  FTPROOT	:= /home/ftp/
else
  ifneq (, $(notdir $(FTPROOT)))
    override FTPROOT	:= $(FTPROOT)/
  endif
endif
ifndef DISTROOT
  DISTROOT	:= $(FTPROOT)sdm/
else
  ifneq (, $(notdir $(DISTROOT)))
    override DISTROOT	:= $(DISTROOT)/
  endif
endif


tardir		:= $(FTPROOT)pub/
distdir		:= $(DISTROOT)$(shell pwd | sed 's|.*/sdm/||;s|.*/ldm/||')/

#ifneq (ldm, $(shell whoami))

#dist dist-tree:
#	su ldm -c "$(MAKE) $@"

#else		# user is LDM

.PHONY:			dist
ifeq (file, $(origin MANIFEST))
  override MANIFEST	:= $(MANIFEST) $(wildcard GNUmake*) $(wildcard depend)
  dist:			$(distdir) $(addprefix $(distdir), $(MANIFEST))
#else
#  dist:
#	$(MAKE) -f dist.mk unix-dist
endif


.PHONY:		dist-tree
dist-tree:	dist FORCE
      ifdef SUBDIRS
	@for dir in $(SUBDIRS); do \
	    echo ""; \
	    test -d $(distdir)$$dir || (mkdir -p $(distdir)$$dir \
		&& echo "created \`$(distdir)$$dir/'"); \
	    (cd $$dir; \
		echo "making \`$@' in `pwd`"; \
		$(MAKE) $@ ); \
	    echo ""; \
	    echo returning to `pwd`; \
	done
      endif

$(distdir)%::	% #ensure_archdir
	@if [ -d "$<" ]; then \
	    test -d $@ || \
		(mkdir -p $(patsubst %/,%,$@) && echo "Created \`$@/'"); \
	    chmod 755 $@; \
	else \
	    cmp -s $< $@ || \
		(rm -f $@; cp  $< $@ && chmod u+w,go-w $@ && \
		 echo "updated \`$@'"); \
	    true; \
	fi


# Ensure that we're in the archive directory.
#
.PHONY:		ensure_archdir
ensure_archdir:
	@archdir=`cd RCS/..; pwd`; \
	    test $$archdir = `pwd` \
		|| (echo "Not in archive directory \`$$archdir'"; exit 1)


#endif		# User is LDM

.PHONY:		ftp
ftp:		$(tardir)$(NAME)$(release_no).tar.Z

#
# NB: The '-h' flag in the following rule causes symbolic links to be
# instantiated as actual files.
#
.PHONY:		$(tardir)$(NAME)$(release_no).tar.Z
$(tardir)$(NAME)$(release_no).tar.Z:
	tar chf - -C $(patsubst %/, %, $(dir $(distdir))) \
	    $(patsubst ./%, %, $(notdir $(distdir))) | compress > $@


#########################################################################
# MISCELLANEOUS:


# Obtain a file from the RCS archive iff it doesn't exist.
#
%::			RCS/%,v
	@test -f $@ || co $@


# Write the origin of a variable to standard output.
#
%.origin:
	@echo '$(origin $*)'


# Write the value of a variable to standard output (THIS IS VERY USEFUL).
# This rule should follow all variable definitions.
#
%.echo:
	@echo '$($*)'


FORCE:
