#
# Copyright (c) 1994, The University of Utah and
# the Computer Systems Laboratory at the University of Utah (CSL).
#
# 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.
#
#	Authors:
#	Bryan Ford, University of Utah CSS
#	Johannes Helander, Helsinki University of Technology
#	
# HISTORY
# $Log: $
#

###### OSF STUFF #####

ifdef OSF_ENVIRONMENT
LD = /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/ld -T /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/ldscripts/i386elf.x

CC = /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/gcc -B/afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/

AR = /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/ar

RANLIB = /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/ranlib

SIZE = /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/size

#STRIP = /afs/gr.osf.org/users/guest/sbox/nmk18b9/link/tools/at386/elf/bfd-strip --verbose
endif

#########################################################



DEFINES += -DMACH -DLITES

# Source directories in the generic source tree to search in
SRCDIRS += $(addprefix $(SRCDIR)/,$(SECTIONS))

# Compilation of Mach itself and its satellite programs
# should always use the global headers in the source directory
# instead of any that might already be in the installation directory.
INCDIRS += $(SRCDIR)/include $(OBJDIR)/include $(INSTALL_INCDIR) \
	   $(SRCDIR)/server $(INSTALL_INCDIR)/mach
LIBDIRS += ${OBJDIR}/liblites $(INSTALL_LIBDIR)

ifneq "${MACH_RELEASE_DIR}" ""
# $(MACH_RELEASE_DIR)/include/mach is where Mach4 has moved some
# necessary includes so make sure we check there
INCDIRS += $(MACH_RELEASE_DIR)/include $(MACH_RELEASE_DIR)/include/mach
LIBDIRS += $(MACH_RELEASE_DIR)/lib
endif

# Command to make multiple levels of directories in one shot.
# XXX install can do this too; would it be better?
# Perhaps a job for autoconf?
MKDIR = -mkdir -p

# Some of the rules below may be used to build things
# to be executed on either the host or the target.
# The COMPILE_FOR variable is used to select HOST_* or TARGET_* variables.
# Use TARGET_* by default.
ifndef COMPILE_FOR
COMPILE_FOR = TARGET
endif
TARGET_CC = $(CC)

# Search for mig and migcom in both the install directory and release
# directory. Migcom ought to be in libexec so we look there first.
# It has sometimes been put in lib so look there too.
MIGCOM := $(wildcard ${INSTALL_BINDIR}/migcom ${INSTALL_LIBEXECDIR}/migcom \
	${INSTALL_LIBDIR}/migcom ${MACH_RELEASE_DIR}/libexec/migcom \
	${MACH_RELEASE_DIR}/bin/migcom ${MACH_RELEASE_DIR}/lib/migcom)
MIGCOM := $(strip $(firstword ${MIGCOM}))
# search for mig in the install and release bin directories,
# default to just mig without specifying migcom at all.
MIG := $(wildcard ${INSTALL_BINDIR}/mig ${MACH_RELEASE_DIR}/bin/mig)
MIG := $(firstword ${MIG} mig)
ifneq "${MIGCOM}" ""
MIG := ${MIG} -migcom ${MIGCOM}
endif
MIG := ${MIG} -cc "${CPP}"

# crt0.o might have different names. Try a few and default to an invalid name.
CRT0 := $(wildcard ${INSTALL_LIBDIR}/mach_crt0.o ${MACH_RELEASE_DIR}/lib/crt0.o ${MACH_RELEASE_DIR}/ccs/lib/crt0.o)
CRT0 := $(firstword ${CRT0} crt0-not-found)
# libgcc is needed by all programs compiled by gcc.
LIBGCC := $(shell ${TARGET_CC} -print-libgcc-file-name)


# Compilation flags
ALL_CPPFLAGS	+= -MD $(DEFINES) -I- -I. $(addprefix -I,$(INCDIRS))
HOST_CPPFLAGS	+= $(ALL_CPPFLAGS)
TARGET_CPPFLAGS	+= -nostdinc $(ALL_CPPFLAGS)
HOST_CFLAGS	+= $(HOST_CPPFLAGS) $(ALL_CFLAGS) -O -W ${CHXXX}
ifndef TARGET_OPTIMIZE_CFLAGS
	TARGET_OPTIMIZE_CFLAGS = -O2
endif
TARGET_CFLAGS	+= $(TARGET_CPPFLAGS) $(ALL_CFLAGS) $(TARGET_OPTIMIZE_CFLAGS) -W ${CXXX}
#  -Wswitch -Wreturn-type -Wcomment -Wuninitialized

# MIG is never used to generate anything that will run on the host.
TARGET_MIGFLAGS	+= $(TARGET_CPPFLAGS)

ALL_LDFLAGS	+= $(addprefix -L,$(LIBDIRS))
HOST_LDFLAGS	+= $(ALL_LDFLAGS)
TARGET_LDFLAGS	+= $(ALL_LDFLAGS)
# -nostdlib

include $(OBJDIR)/conf/Makevar

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

# 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
ifdef COLLECT_CFILES
CFILES += $(filter %.c,$(FILES))
endif

# How to compile them.
%.o: %.c
	@echo
	$($(COMPILE_FOR)_CC) -c $(CPPFLAGS) $(CFLAGS) $($(COMPILE_FOR)_CFLAGS) $($(<F)_CFLAGS) $<

%_p.o: %.c
	@echo
	$($(COMPILE_FOR)_CC) -c $(CPPFLAGS) -DGPROF -pg $(CFLAGS) $($(COMPILE_FOR)_CFLAGS) $($(<F)_CFLAGS) $< -o $@


# Server-side presentation files
SRVFILES := $(filter %.srv,$(FILES))

# Client-side presentation files
CLIFILES := $(filter %.cli,$(FILES))

# Client-and-server presentation files
PRESFILES := $(filter %.pres,$(FILES))

ifdef COLLECT_CFILES
# C files automatically generated from these MIG definitions.
GEN_CFILES += \
	$(patsubst %.srv,%_server.c,$(notdir $(SRVFILES))) \
	$(patsubst %.cli,%_user.c,$(notdir $(CLIFILES))) \
	$(patsubst %.pres,%_user.c,$(notdir $(PRESFILES))) \
	$(patsubst %.pres,%_server.c,$(notdir $(PRESFILES)))
endif
CLEAN_FILES += $(GEN_CFILES) \
	$(patsubst %.srv,%_interface.h,$(notdir $(SRVFILES))) \
	$(patsubst %.cli,%.h,$(notdir $(CLIFILES))) \
	$(patsubst %.pres,%.h,$(notdir $(PRESFILES))) \

# How to generate MIG stubs from presentation files.
%_server.h %_server.c: %.srv
	@echo
	$(MIG) $(MIGFLAGS) $(TARGET_MIGFLAGS) -sheader $*_server.h -server $*_server.c -user /dev/null $<
%.h %_user.c: %.cli
	@echo
	$(MIG) $(MIGFLAGS) $(TARGET_MIGFLAGS) -header $*.h -user $*_user.c -server /dev/null $<

%.h %_user.c %_server.c: %.pres
	@echo
	$(MIG) $(MIGFLAGS) $(TARGET_MIGFLAGS) -header $*.h -user $*_user.c -server $*_server.c $<


# 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
	@echo
	$(AWK) -f $(SRCDIR)/conf/gensym.awk $< >$*.symc

%.symc.o: %.symc
	@echo
	$(TARGET_CC) -S $(CPPFLAGS) $(CFLAGS) \
		$(TARGET_CFLAGS) -x c -o $@ $<

%.h: %.symc.o
	@echo
	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) $(INSTALL_BINDIR)
	$(INSTALL) $< $@

$(INSTALL_LIBDIR)/%: %
	$(MKDIR) $(INSTALL_LIBDIR)
	$(INSTALL) $< $@

$(INSTALL_BOOTDIR)/%: %
	$(MKDIR) $(INSTALL_BOOTDIR)
	$(INSTALL) $< $@


# 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.
# Compile MIG files before other C source files,
# because they create header files used in the other sources.
# The $(sort)s are to eliminate duplicate files,
# which might appear when files are being overridden.
GEN_OBJFILES += \
	$(sort $(patsubst %.c,%.o,$(GEN_CFILES))) \
	$(sort $(patsubst %.c,%.o,$(notdir $(CFILES))))

# Sometimes pre-compiled object files are included in source directories
# because their source code is proprietary.
# Make sure we only clean the object files we generated.
OBJFILES += $(GEN_OBJFILES)
CLEAN_FILES += $(GEN_OBJFILES)


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


# 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
