#
# Copyright (c) 1996 The University of Utah and
# the Computer Systems Laboratory at the University of Utah (CSL).
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation, and (3) all advertising
# materials mentioning features or use of this software display the following
# acknowledgement: ``This product includes software developed by the
# Computer Systems Laboratory at the University of Utah.''
#
# THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
# IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
# CSL requests users of this software to return to csl-dist@cs.utah.edu any
# improvements that they make and grant CSL redistribution rights.
#

# This makefile defines standard symbols and rules
# used by the makefiles in the various OS toolkit subdirectories.
# It is heavily dependent on GNU make running on something like Unix.
# Building things with different tools requires a different set of makefiles.
#
# OSKIT_SRCDIR must be set to the top-level directory of the OS toolkit.
# (The current directory is assumed to be the object directory.)
#
# OBJDIR must be set to the top-level object directory
# (i.e. a series of `..'s indicating how deep we are at the moment).
#
# DEFINES can be set to a string of -D options (e.g. -DDEBUG).
# INCDIRS can be a list of system include directories
#	  to be searched by #include <>'s.
# LIBDIRS can be a list of library directories.
#
# OSKIT_CPPFLAGS can be set to other flags for the C preprocessor
#		 and anything that uses it.
# OSKIT_CFLAGS can be set to other flags for the C compiler.
# OSKIT_LDFLAGS can be set to other flags for the linker.
#
# The standard flags variables (CFLAGS, CPPFLAGS, etc.)
# are used by the rules but never defined,
# so you can supply them on the make command line
# (e.g. `make CFLAGS=-save-temps').
#
ifndef _oskit_makerules_
_oskit_makerules_ = yes


# Include architecture-specific rules.
include $(OSKIT_SRCDIR)/GNUmakerules-$(HOST_ARCH)


# Where to get includes and libraries from.
INCDIRS += $(OBJDIR) $(OSKIT_SRCDIR) $(OSKIT_SRCDIR)/flux/c
LIBDIRS += $(OBJDIR)/lib

# Compilation flags.
# We prefix these with OSKIT_ rather than using the "normal" variables
# so that you can override the normal variables on the make command line
# in order to add options (e.g. 'make CFLAGS=-save-temps').
OSKIT_CPPFLAGS	+= -MD $(DEFINES) -I. $(addprefix -I,$(SRCDIRS)) -I- \
		    $(addprefix -I,$(INCDIRS)) -nostdinc
OSKIT_CFLAGS	+= $(OSKIT_CPPFLAGS) -g -O2 -Wall
OSKIT_LDFLAGS	+= $(addprefix -L,$(LIBDIRS))


# Where to find source files.
SRCDIRS := $(SRCDIRS)
space := $(empty) $(empty)
VPATH := $(subst $(space),:,$(SRCDIRS))

# First find a list of every file that might possibly be a source file,
# so we only have to scan the source directories once.
FILES := $(foreach DIR,$(SRCDIRS),$(wildcard $(DIR)/*))


# C source files
CFILES := $(filter %.c,$(FILES))

# How to compile them.
%.o: %.c
	$(CC) -c $(OSKIT_CFLAGS) $(CFLAGS) $<


# How to generate symbol header files,
# containing #define's for numeric constants
# related to C structures on the target machine.
# These are currently used in two ways:
#
# * When cross-compiling, MIG is compiled to be executed on the host,
#   but it needs to know the sizes of certain types on the target machine.
#   So a symbol header file is created with the cross-compiler,
#   and then used in compiling MIG for the host machine.
#
# * Assemblers don't know about C structures,
#   so machine-specific assembly language code
#   can use symbol header files instead.
%.symc: %.sym
	$(AWK) -f $(OSKIT_SRCDIR)/gensym.awk $< >$*.symc

%.symc.o: %.symc
	$(CC) -S $(OSKIT_CFLAGS) $(CFLAGS) -x c -o $@ $<

%.h: %.symc.o
	sed <$< -e 's/^[^*].*$$//' | \
		sed -e 's/^[*]/#define/' -e 's/mAgIc[^-0-9]*//' >$@

CLEAN_FILES += *.symc *.symc.o


# How to install files into their final resting places.
$(INSTALL_BINDIR)/%: %
	-mkdir -p $(INSTALL_BINDIR)
	$(INSTALL) $< $@

$(INSTALL_LIBDIR)/%: %
	-mkdir -p $(INSTALL_LIBDIR)
	$(INSTALL) $< $@

# Always fully build everything before trying to install anything
install: all


# Get rid of a bunch of nasty built-in implicit rules,
# to avoid bogus circular dependencies and make things go faster.
# Use the `-r' command line option to make to get even better performance.
.SUFFIXES:


# The generated object files have the same prefix names as the source files,
# except they live in the current (object) directory.
OBJFILES += $(patsubst %.c,%.o,$(notdir $(CFILES)))

# This is to eliminate duplicate files,
# which might appear when files are being overridden.
OBJFILES := $(sort $(OBJFILES))
CLEAN_FILES += $(OBJFILES)


# How to clean out the automatically built stuff in an object directory.
clean:
	rm -rf *.d *.bak tags TAGS depend $(CLEAN_FILES)

distclean: clean

# How to update the dependency file in an object directory.
# This funny bit of magic (hopefully the most obscure thing here)
# basically replaces the `md' program in ODE.
# The `sed' line removes the dependencies being replaced,
# the `for' line tacks the new dependencies to the end of the file,
# and then the individual dependency files are deleted.
comma := ,
depend: $(wildcard *.d)
	@if test -f depend; then sed $(patsubst %.d,-e '/^%\.o/$(comma)/^#/d',$^) <depend >depend.new; fi; true
	@(for file in $^ /dev/null; do (cat $$file; echo '#'); done) >>depend.new
	@mv -f depend.new depend
	@if test "" != "$^"; then rm -f $^; fi; true


# Include the dependency graph (if it exists).
-include depend


endif
