# -*- Makefile -*-
# DROPS Make configuration file
#
# created 1996/04/20 by hohmuth
# $Id: Makeconf,v 1.81 2002/11/26 14:42:23 reuther Exp $
#

SYSTEM= $(shell uname)

CROSS=	1

ifdef CROSS

  CPPFLAGS+=	-DCROSS

  ifeq ($(SYSTEM),Linux)

    SYSTEM_TARGET=
    FLOPPY=/dev/fd0

  else

    ifeq ($(SYSTEM),FreeBSD)

      FLOPPY=/dev/rfd0.1440

    else

      SYSTEM_TARGET=i386-linux-

    endif

    ifeq ($(SYSTEM),AIX)

      SHELL=/bin/bash
      export SHELL

    endif

  endif

endif

ifdef NDEBUG
  CPPFLAGS+=	-DNDEBUG
endif

ifdef DEBUG
  CPPFLAGS+=	-DDEBUG

ifndef NO_DEBUG_ERRORS
  CPPFLAGS +=	-DDEBUG_ERRORS
endif

ifndef NO_DEBUG_ASSERTION
  CPPFLAGS +=	-DDEBUG_ASSERTIONS
endif
endif

ifdef OPT
  CPPFLAGS+=	-O$(OPT)
else
  CPPFLAGS+=	-O2
endif

ifdef ASM
  CPPFLAGS+=	-S
endif

ifdef PRE
  CPPFLAGS+=	-E
endif

ifneq (${CDPATH},)
$(warning Please do not export CDPATH in your shell!!)
$(warning CDPATH only makes sense in interactive mode.)
$(warning Change "export CDPATH=<dirs>" to "CDPATH=<dirs>")
$(warning in your shell init script .bashrc, .profile, ...)
$(error Please fix that error)

endif

# default architecture
CPPFLAGS += -DARCH_X86

# default L4 API version
ifeq ($(L4_API),)
  L4_API = L4V2
endif

CPPFLAGS += -DL4_API_$(L4_API) $(USER_CPPFLAGS)

AWKP=	gawk --posix
CC=	$(SYSTEM_TARGET)gcc
CXX=	$(SYSTEM_TARGET)g++
AS=	$(SYSTEM_TARGET)as
LD=	$(SYSTEM_TARGET)ld
AR=	$(SYSTEM_TARGET)ar
NM=	$(SYSTEM_TARGET)nm
RANLIB=	$(SYSTEM_TARGET)ranlib
SIZE=	$(SYSTEM_TARGET)size
STRIP=	$(SYSTEM_TARGET)strip
OBJCOPY=$(SYSTEM_TARGET)objcopy
RM=	rm -f
CP=	cp
INSTALL=$(SYSTEM_TARGET)install
PWD=	pwd
INDENT=	indent -sob
YACC=	byacc
LEX=	flex

DROPS_CC = L4DIR=$(L4DIR) $(firstword \
				$(wildcard $(L4DIR)/tool/gcc-wrap/drops-gcc \
				  $(DROPS_STDDIR)/tool/bin/drops-gcc \
				  ) false )
DROPS_CXX= L4DIR=$(L4DIR) $(firstword \
				$(wildcard $(L4DIR)/tool/gcc-wrap/drops-c++ \
				  $(DROPS_STDDIR)/tool/bin/drops-c++ \
				  ) false )

# a cross-assembler groking Intel syntax and MASM-style macros
KAS=	$(DOSWRAP) $(DOSAS)
KLD=	$(DOSWRAP) $(DOSLD)
DOSWRAP=dos
DOSAS=	386asm
DOSLD=	386link

#DOSAS=	masm
#DOSLD=	link

DROPS_STDDIR=		/home/drops
DROPS_STDLIBDIR=	$(DROPS_STDDIR)/lib
DROPS_STDINCDIR=	$(DROPS_STDDIR)/include
DEFAULT_ARCH	= x86
DEFAULT_CPU	= 586
DEFAULT_L4API	= l4v2

ifeq (${L4DIR},)
ifeq (${L4_DIR},)
  L4DIR = $(shell pwd)
else
  L4DIR = ${L4_DIR}
endif
endif

ifeq (${OSKITDIR},)
ifeq (${OSKIT_DIR},)
  OSKITDIR = $(L4DIR)/../oskit
else
  OSKITDIR = ${OSKIT_DIR}
endif
endif

ifeq (${OSKIT10DIR},)
ifeq (${OSKIT10_DIR},)
  OSKIT10DIR = $(L4DIR)/../oskit10
else
  OSKIT10DIR = ${OSKIT10_DIR}
endif
endif

# As long as there is no backward-compatibility package for OSKit 1.0, the 
# default include and library paths will still use the old OSKit (0.60).
# The default can be overrided by defining OSKIT10 before including Makeconf
ifeq ($(OSKIT10),)
# use old OSKit
L4ALL_LIBDIR=	$(addprefix -L, \
		  $(PRIVATE_LIBDIR) \
		  $(L4DIR)/lib/$(DEFAULT_ARCH)_$(DEFAULT_CPU)/$(DEFAULT_L4API) \
		  $(L4DIR)/lib/$(DEFAULT_ARCH)_$(DEFAULT_CPU) \
		  $(L4DIR)/lib \
		  $(OSKITDIR)/lib \
		  $(DROPS_STDLIBDIR))
L4ALL_INCDIR=	-nostdinc \
		$(addprefix -I, \
		  $(PRIVATE_INCDIR) \
		  $(L4DIR)/include/$(DEFAULT_ARCH)/$(DEFAULT_L4API) \
		  $(L4DIR)/include/$(DEFAULT_ARCH) $(L4DIR)/include \
		  $(OSKITDIR) $(OSKITDIR)/flux/c \
		  $(DROPS_STDINCDIR) $(DROPS_STDINCDIR)/flux/c )
else
# use OSKit 1.0
L4ALL_LIBDIR=	$(addprefix -L, \
		  $(PRIVATE_LIBDIR) \
		  $(L4DIR)/lib/$(DEFAULT_ARCH)_$(DEFAULT_CPU)/$(DEFAULT_L4API) \
		  $(L4DIR)/lib/$(DEFAULT_ARCH)_$(DEFAULT_CPU) \
		  $(L4DIR)/lib \
		  $(OSKIT10DIR)/lib \
		  $(DROPS_STDLIBDIR))
L4ALL_INCDIR=	-nostdinc \
		$(addprefix -I, \
		  $(PRIVATE_INCDIR) \
		  $(L4DIR)/include/$(DEFAULT_ARCH)/$(DEFAULT_L4API) \
		  $(L4DIR)/include/$(DEFAULT_ARCH) $(L4DIR)/include \
		  $(OSKIT10DIR) $(OSKIT10DIR)/oskit/c \
		  $(DROPS_STDINCDIR) $(DROPS_STDINCDIR)/oskit/c )
endif

L4_INSTALL_DIR=		$(DROPS_STDDIR)

OBJS	= $(SRC_S:.S=.o) $(SRC_CPP:.cpp=.o) $(SRC_C:.c=.o) $(SRC_CC:.cc=.o)
OBJS_P	= $(SRC_S:.S=.p.o) $(SRC_CPP:.cpp=.p.o) $(SRC_C:.c=.p.o) $(SRC_CC:.cc=.p.o)
OBJS_PR = $(SRC_S:.S=.pr.o) $(SRC_CPP:.cpp=.pr.o) $(SRC_C:.c=.pr.o) $(SRC_CC:.cc=.pr.o)
OBJS_SO	= $(SRC_S:.S=.p.o) $(SRC_CPP:.cpp=.p.o) $(SRC_C:.c=.p.o) $(SRC_CC:.cc=.p.o)
SRC_ALL = $(SRC_S) $(SRC_CPP) $(SRC_C) $(SRC_CC)
ifeq ($(filter clean cleanall,$(MAKECMDGOALS)),)
DEPS	= $(foreach file,$(OBJS) $(OBJS_P) $(OBJS_PR), $(dir $(file)).$(notdir $(file)).d)
else
DEPS    = /dev/null
endif

LIBDEPS	= $(foreach file, \
                    $(patsubst -l%,lib%.a,$(filter-out -L%,$(L4_LIB))) \
		    $(patsubst -l%,lib%.so,$(filter-out -L%,$(L4_LIB))),\
                    $(word 1, $(foreach dir, \
                           $(patsubst -L%,%,\
                           $(filter -L%,$(L4_LIB) $(L4ALL_LIBDIR))),\
                      $(wildcard $(dir)/$(file)))))

CPPFLAGS +=	$(L4ALL_INCDIR) \
		$(INCLUDES)

# output formating
# set VERBOSE=@ to prevent command lines 
VERBOSE=
COMP_MESSAGE=	@echo -e "  ... Making $@"
COMP_P_MESSAGE=	@echo -e "  ... Making PIC $@"
COMP_PR_MESSAGE=@echo -e "  ... Making PROFILE $@"
LINK_MESSAGE=	@echo -e "  ==> Linking $@"
DEP_MESSAGE=	@echo -e "  ... Building dependencies for $<"
CLEAN_MESSAGE=	@echo -e "  ... Removing created files"
CLEANALL_MESSAGE=@echo -e "  ... Removing all created files"
INST_MESSAGE=	@echo -e "  ... Installing $(^F)"

DEPEND_IGNORE_ERRORS= false
DEPEND_VERBOSE= @
DEPEND_EXTEND_CMD = $(AWKP) '			\
/^[^:]*: ..*/{					\
	while(sub("\\\\$$","")){		\
		getline nextline ;		\
		$$0=$$0 " " nextline		\
	}					\
	split($$0,field,": ");			\
	sub("^$(*F).o","$*.s $*.E $@",field[1]);	\
	nr=split(field[2],deps) ;		\
	for(i=1;i<=nr;){			\
	  printf("ifeq ($$(shell test y \\\n");	\
	  for(j=0; j<100 && i+j<=nr; j++){	\
	    printf("-a -r %s \\\n", deps[i+j]);	\
	  }					\
	  printf("&& echo y),)");		\
	  printf("\n%s: FORCE\nelse\n%s: Makefile \\\n",	\
	  	field[1],field[1]);		\
	  for(j=0; j<100 && i+j<=nr; j++){	\
	    printf("%s \\\n",deps[i+j]);	\
	  }					\
	  printf("\nendif\n");			\
	  i+=j;					\
	}					\
}'
DEPEND_EXTEND_FUNC = ( $(DEPEND_EXTEND_CMD) < $(1) > $(2).new && rm -f $(1) && mv $(2).new $(2) ) || ( rm -f $(1) $(2).new $(2) ; $(DEPEND_IGNORE_ERRORS) )

.PHONY: FORCE

%.o:	%.cc
	$(COMP_MESSAGE)
	$(VERBOSE)$(CXX) -c -MD $(CPPFLAGS) $(CXXFLAGS) $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $*).$(notdir $@).d)

%.o:	%.c
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -c -MD $(CPPFLAGS) $(CFLAGS) $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $@).$(notdir $@).d)

%.p.o:	%.c
	$(COMP_P_MESSAGE)
	$(VERBOSE)$(CC) -c -MD $(CPPFLAGS) $(CFLAGS) -fPIC $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $@).$(notdir $@).d)

%.pr.o:	%.c
	$(COMP_PR_MESSAGE)
	$(VERBOSE)$(CC) -c -MD $(CPPFLAGS) $(CFLAGS) -DPROFILE -pg $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $@).$(notdir $@).d)

%.o:	%.S
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -c -MD $(CPPFLAGS) $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $@).$(notdir $@).d)

%.p.o:	%.S
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -c -MD $(CPPFLAGS) -fPIC $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $@).$(notdir $@).d)

%.pr.o:	%.S
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -c -MD $(CPPFLAGS) -DPROFILE -pg $< -o $@
	$(DEPEND_VERBOSE)$(call DEPEND_EXTEND_FUNC, $(*F).d, $(dir $@).$(notdir $@).d)

%:	%.o 
	$(LINK_MESSAGE)
	$(VERBOSE)$(LD) $(LDFLAGS) -o $@ crt0.o $<

%.E:	%.c
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -E $(CPPFLAGS) $(CFLAGS) $< -o $@
	$(VERBOSE)$(INDENT) -o $@ $@

%.E:	%.cc
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -E $(CPPFLAGS) $(CXXFLAGS) $< -o $@
	$(VERBOSE)$(INDENT) -sob -o $@ $@

%.S:	%.c
	$(COMP_MESSAGE)
	$(VERBOSE)$(CC) -S $(CFLAGS) $(CPPFLAGS) $< -o $@

-include $(L4DIR)/Makeconf.local

ifeq ($(USE_EMPHASIZE_PHASES),1)
ifneq (,$(findstring ${TERM},vt100 xterm linux console))
  EMPHSTART = '\033[34m'
  EMPHSTOP  = '\033[0m'
else
  EMPHSTART =
  EMPHSTOP  =
endif
endif

# Compiler options for both C and C++ (later folded into both CFLAGS
# and CXXFLAGS)
ifeq ($(NOSTDL4),)
  GCC_FLAGS = -g -Wall -Wstrict-prototypes -Wmissing-prototypes \
	-Wmissing-declarations
else
  GCC_FLAGS = -g -Wall -Wstrict-prototypes
endif

# only work around strength reduction bug(s) on older gcc versions
GCC_FLAGS += $(shell PATH=$(PATH); if ! $(CC) -S -march=i486 -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strength-reduce"; fi)

CPUCHECK = $(wildcard $(L4DIR)/include/l4/cpucheck.h)

ifdef OPT_486
GCC_FLAGS += $(shell PATH=$(PATH); if $(CC) -S -march=i486 -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i486"; else echo "-m486"; fi)
CPPFLAGS += -DCPU=486
else
ifdef OPT_586
GCC_FLAGS += $(shell PATH=$(PATH); if $(CC) -S -march=i586 -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
CPPFLAGS += -DCPU=586
else
ifdef OPT_686
GCC_FLAGS += $(shell PATH=$(PATH); if $(CC) -S -march=i686 -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi)
CPPFLAGS += -DCPU=686
else
ifdef OPT_K6
GCC_FLAGS += $(shell PATH=$(PATH); if $(CC) -S -march=k6 -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; fi)
CPPFLAGS += -DCPU=586
else
ifdef OPT_K7
GCC_FLAGS += $(shell PATH=$(PATH); if $(CC) -S -march=athlon -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else  if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686 -malign-functions=4";  fi fi)
CPPFLAGS += -DCPU=686
else
CPUCHECK =
endif
endif
endif
endif
endif

ifneq ($(CPUCHECK),)
CPPFLAGS += -include $(CPUCHECK)
endif

CFLAGS=	$(GCC_FLAGS)
CXXFLAGS= $(GCC_FLAGS)


# If TARGET_STAT is defined then use optional global pkg/STATIC file
# for determining the relocation address of a static linked application.
#
# If RELOC_ADDR is set then it does override the pkg/STATIC entry.
#
# if LDSCRIPT is not set then use defaut main_stat.ld at crtx/lib/src
#
# If DEFAULT_RELOC is set and RELOC_ADDR is not and there is no entry in
# pkg/STATIC, use DEFAULT_RELOC as the relocation address.
#
# LDDEPS contains dependencies to
ifneq ($(TARGET_STAT),)

ifeq ($(RELOC_ADDR),)
ifneq ($(wildcard $(L4DIR)/pkg/STATIC),)
RELOC_ADDR = $(shell awk -v prog=$(TARGET_STAT) "/^[^\#]/{if(\$$2==prog){print \$$1; exit}}" < $(L4DIR)/pkg/STATIC )
LDDEPS += $(L4DIR)/pkg/STATIC
endif
endif

ifeq ($(RELOC_ADDR),)
ifeq ($(DEFAULT_RELOC),)
$(error No relocation address for $(TARGET_STAT) in $(L4DIR)/pkg/STATIC)
else
RELOC_ADDR = $(DEFAULT_RELOC)
endif
endif

LINK_MESSAGE=	@echo -e "  ==> Linking $@ to static address $(RELOC_ADDR)"

ifeq ($(LDSCRIPT),)
LDSCRIPT = $(L4DIR)/lib/$(DEFAULT_ARCH)_$(DEFAULT_CPU)/$(DEFAULT_L4API)/main_stat.ld
endif

LDDEPS += $(LDSCRIPT)

LDFLAGS = -Ttext $(RELOC_ADDR) -T $(LDSCRIPT)
GCC_LDFLAGS = -Wl,-Ttext,$(RELOC_ADDR)
endif

