# Makefile rules for making .o files from source files

#############################################################################
#
# Yacc conversion rules.
#
# Files are converted to source form,  then added to CFILES or C++FILES to
# be compiled into .o files.  A file foo.y becomes foo.$(YEXTENSION) (see
# variable list below).  If YEXTENSION contains a 'C' then the file is added
# to C++FILES, otherwise it goes to CFILES.  A substitution string may be
# added to all 'yy' and 'YY' symbols in the yacc output so that multiple yacc
# parsers can be linked into one program.  
#
# Variables:
#   YFILES = list of .y files to be yacc'ed 
#   YEXTENSION = extension to put on yacc'ed files (default = tab.c)
#   YFLAGS = command line flags to yacc
#
ifneq (,$(YFILES))

# Instead of adding the list of yacc-generated files to the CFILES or
# C++FILES lists, we must generate a new list that's compiled via a
# separate rule.  This allows us to use different options (for
# instance, to eliminate optimization, which seems to trouble some
# compilers, particularly gcc).

# We must then process YCFILES and YC++FILES before we process CFILES
# and C++FILES, so yacc will get called before any of the C files are
# compiled, in case one of the C files wants to include y.tab.h.

ifneq (,$(findstring cxx,$(YEXTENSION)))
  YC++FILES := $(patsubst %.yxx, %.$(YEXTENSION), $(YFILES))
else
  YCFILES := $(patsubst %.yxx, %.$(YEXTENSION), $(YFILES))
endif

$(YCFILES) $(YC++FILES) : %.$(YEXTENSION) : %.yxx
	$(YACC) $(YFLAGS) $<
	mv y.tab.c $@
	mv y.tab.h $(patsubst %.$(YEXTENSION), %.h, $@)

clean::
	rm -f $(YCFILES) $(YC++FILES)
	
endif



#############################################################################
#
# Lex conversion rules.
#
# Files are converted to source form,  then added to CFILES or C++FILES to
# be compiled into .o files.  A file foo.l becomes foo.$(LEXTENSION) (see
# variable list below).  If LEXTENSION contains a 'C' then the file is added
# to C++FILES, otherwise it goes to CFILES.  A substitution string may be
# added to all 'yy' and 'YY' symbols in the lex output so that multiple lex
# analyzers can be linked into one program.  
#
# Variables:
#   LFILES = list of .l files to be lex'ed (from user Makefile)
#   LEXTENSION = extension to put on lex'ed files (default = yy.c)
#   LFLAGS = command line flags to lex
#
ifneq (,$(LFILES))

LCFILES := $(patsubst %.lxx, %.$(LEXTENSION), $(LFILES))
ifneq (,$(findstring cxx,$(LEXTENSION)))
C++FILES := $(C++FILES) $(LCFILES)
else
CFILES := $(CFILES) $(LCFILES)
endif

# We must strip out the reference to unistd.h that flex so annoyingly
# puts in its generated code.
$(LCFILES) : %.$(LEXTENSION) : %.lxx
	$(LEX) $(LFLAGS) $<
	sed '/#include <unistd.h>/d' lex.yy.c > $@
	rm lex.yy.c

clean:: 
	rm -f $(LCFILES)
	
endif

#############################################################################
#
# .cpp -> .cxx conversion rules.
#

ifneq (,$(CPPFILES))

CPPCFILES := $(patsubst %.cpp, %.cxx, $(CPPFILES))
C++FILES := $(C++FILES) $(CPPCFILES)

$(CPPCFILES) : %.cxx : %.cpp
	cp $< $@
	chmod 666 $@

clean::
	rm -f $(CPPCFILES)

endif



#############################################################################
#
# C/C++ Conversion rules.
#

# Clear ALLOFILES
ALLOFILES = 
SUPERALLOFILES = 

ifneq (,$(YCFILES))
  SUPERALLOFILES += $(YCFILES:%.c=__%.o_file_find_me)
endif
ifneq (,$(YC++FILES))
  SUPERALLOFILES += $(YC++FILES:%.cxx=__%.o_file_find_me)
endif
ifneq (,$(CFILES))
  SUPERALLOFILES += $(CFILES:%.c=__%.o_file_find_me)
endif
ifneq (,$(C++FILES))
  SUPERALLOFILES += $(C++FILES:%.cxx=__%.o_file_find_me)
endif
ifeq (,$(NO_INTERROGATE))
  ifneq (,$(IGATESCAN))
    ifeq (,$(IGATEFILE))
      SUPERALLOFILES += __$(TARGET).o_file_find_me
    else
      SUPERALLOFILES += $(IGATEFILE:%.cxx=__%.o_file_find_me)
    endif
  endif
endif

NTCFILETYPE =
NTC++FILETYPE =

ifneq (,$(YCFILES))

ifeq (WIN32_VC,$(PENV_COMPILER))
  YCOFILES := $(YCFILES:%.c=$(ODIR)/%.obj)
  NTCFILETYPE := -Tc
  $(YCOFILES): $(ODIR)/%.obj : %.c
else # NON-WIN32_VC
  YCOFILES := $(YCFILES:%.c=$(ODIR)/%.o)
  $(YCOFILES): $(ODIR)/%.o : %.c
endif # WIN32_VC
	@if [ ! -d $(ODIR) ]; then mkdir $(ODIR); fi
	$(CC) -c $(IPATH) $(SYS_IPATH) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(CFLAGS) $(NTCFILETYPE) $< -o $@

ALLOFILES := $(ALLOFILES) $(YCOFILES)
endif

ifneq (,$(YC++FILES))

ifeq (WIN32_VC,$(PENV_COMPILER))
  YC++OFILES := $(YC++FILES:%.cxx=$(ODIR)/%.obj)
  NTC++FILETYPE := -Tp
  $(YC++OFILES): $(ODIR)/%.obj : %.cxx
else # NON-WIN32_VC
  YC++OFILES := $(YC++FILES:%.cxx=$(ODIR)/%.o)
  $(YC++OFILES): $(ODIR)/%.o : %.cxx
endif # WIN32_VC
	@if [ ! -d $(ODIR) ]; then mkdir $(ODIR); fi
	$(C++) -c $(IPATH) $(SYS_IPATH) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) $< -o $@

ALLOFILES := $(ALLOFILES) $(YC++OFILES)
endif

ifneq (,$(CFILES))

ifeq (WIN32_VC,$(PENV_COMPILER))
  COFILES := $(CFILES:%.c=$(ODIR)/%.obj)
  NTCFILETYPE := -Tc
  $(COFILES): $(ODIR)/%.obj : %.c
else # NON-WIN32_VC
  COFILES := $(CFILES:%.c=$(ODIR)/%.o)
  $(COFILES): $(ODIR)/%.o : %.c
endif # WIN32_VC
	@if [ ! -d $(ODIR) ]; then mkdir $(ODIR); fi
	$(CC) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(CFLAGS) $(NTCFILETYPE) $< -o $@

ALLOFILES := $(ALLOFILES) $(COFILES)
endif


ifneq (,$(C++FILES))

ifeq (WIN32_VC,$(PENV_COMPILER))
  C++OFILES := $(C++FILES:%.cxx=$(ODIR)/%.obj)
  NTC++FILETYPE := -Tp
  $(C++OFILES): $(ODIR)/%.obj : %.cxx
else # NON-WIN32_VC
  C++OFILES := $(C++FILES:%.cxx=$(ODIR)/%.o)
  $(C++OFILES): $(ODIR)/%.o : %.cxx
endif # WIN32_VC
	@if [ ! -d $(ODIR) ]; then mkdir $(ODIR); fi
ifeq (OSX,$(PENV))
	$(C++) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) -DFILE_SYM_NAME=__$(subst .,_,$@)_file_find_me -DALL_FILE_SYMS_NAME="\"$(subst .,_,$(SUPERALLOFILES))\"" $< -o $@
else  # OSX
	$(C++) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) $< -o $@
endif # OSX

ALLOFILES := $(ALLOFILES) $(C++OFILES)
endif

ifneq (,$(NO_INTERROGATE))
  IGATESCAN :=
  IGATEMSCAN :=
endif

ifeq (,$(IGATELIBRARY))
IGATELIBRARY := $(basename $(BASETARGET))
endif

ifneq (,$(IGATESCAN))

ifeq (,$(IGATEFILE))
IGATEFILE := $(BASETARGET).cxx
endif

ifeq (,$(IGATEMODULE))
IGATEMODULE := $(DEFERRED_TARGET)
endif
ifeq (,$(IGATEMODULE))
IGATEMODULE := $(patsubst lib%,%,$(IGATELIBRARY))
endif

ifeq (,$(IGATEDBFILE))
IGATEDBFILE := $(basename $(BASETARGET)).in
endif

ifeq (WIN32_VC,$(PENV_COMPILER))
  IGATEOFILE := $(IGATEFILE:%.cxx=$(ODIR)/%.obj)
  NTC++FILETYPE := -Tp
else # NON-WIN32_VC
  IGATEOFILE := $(IGATEFILE:%.cxx=$(ODIR)/%.o)
endif

IGATENFILES := $(wildcard $(IGATESCAN:%.h=%.N))
$(IGATEFILE): $(IGATESCAN) $(IGATENFILES)
	$(INTERROGATE) $(IGATESYSPATH) $(IPATH) $(IGATEFLAGS) $(COMPILE_DEFS) -module "$(IGATEMODULE)" -library "$(IGATELIBRARY)" -oc $@ -od $(IGATEDBFILE) -fnames -string -refcount -assert -promiscuous -python $(IGATESCAN)
$(IGATEOFILE): $(IGATEFILE)
	@if [ ! -d $(ODIR) ]; then mkdir $(ODIR); fi
ifeq (OSX,$(PENV))
	$(C++) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) -DFILE_SYM_NAME=__$(subst .,_,$@)_file_find_me -DALL_FILE_SYMS_NAME="\"$(subst .,_,$(SUPERALLOFILES))\"" $< -o $@
else  # OSX
	$(C++) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) $< -o $@
endif # OSX
ALLOFILES := $(ALLOFILES) $(IGATEOFILE)

clean::
	rm -f $(IGATEOFILE) $(IGATEFILE) $(IGATEDBFILE)

endif

ifneq (,$(IGATEMSCAN))
IGATEMC := $(basename $(BASETARGET)).module.cxx
ifeq (WIN32_VC,$(PENV_COMPILER))
  IGATEMO := $(IGATEMC:%.cxx=%.obj)
else
  IGATEMO := $(IGATEMC:%.cxx=%.o)
endif
$(IGATEMC): $(wildcard $(CTPROJROOT)/etc/*.in)
	interrogate_module -oc $@ -module "$(IGATEMSCAN)" -library "$(IGATELIBRARY)" -python $(CTPROJROOT)/etc/*.in

$(IGATEMO): $(IGATEMC)
	@if [ ! -d $(ODIR) ]; then mkdir $(ODIR); fi
ifeq (OSX,$(PENV))
	$(C++) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) -DFILE_SYM_NAME=__$(subst .,_,$@)_file_find_me -DALL_FILE_SYMS_NAME="\"$(subst .,_,$(SUPERALLOFILES))\"" $< -o $@
else  # OSX
	$(C++) -c $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $(NTC++FILETYPE) $< -o $@
endif # OSX
ALLOFILES := $(ALLOFILES) $(IGATEMO)

clean::
	rm -f $(IGATEMO) $(IGATEMC)
endif # IGATEMSCAN

ifeq (,$(USE_DEFERRED))
  DEFERRED_FILES :=
endif

ifneq (,$(DEFERRED_FILES))
include $(wildcard $(patsubst %,$(CTPROJROOT)/deferred/Deferred.%.*,$(DEFERRED_FILES)))
endif


ifneq (,$(ALLOFILES))
clean::
	rm -f $(ALLOFILES)
endif


$(TARGET): $(ALLOFILES)

ifeq (Linux,$(PENV))
DO_GNU_AUTO_DEP = yes
endif

ifneq (,$(DO_GNU_AUTO_DEP))

#############################################################################
#
# GNU Auto-dependency rules.
#

%.d: %.c
	$(SHELL) -ec '$(CC) -M $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(CFLAGS) $< \
	  | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
	  [ -s $@ ] || rm -f $@'

%.d: %.cxx
	$(SHELL) -ec '$(C++) -M $(IPATH) $(SYS_IPATH) $(OPTIMIZE_FLAGS) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $< \
	  | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
	  [ -s $@ ] || rm -f $@'

ifneq (,$(IGATEOFILE))
include $(IGATEOFILE:.o=.d)

$(IGATEOFILE:.o=.d) : $(IGATEOFILE:.o=.cxx)
	$(SHELL) -ec '$(C++) -M $(IPATH) $(SYS_IPATH) $(COMPILE_FLAGS) $(COMPILE_DEFS) $(C++FLAGS) $< \
	  | sed '\''s/\($*\)\.o[ :]*$</\1.o $@ $< : /g'\'' > $@; \
	  [ -s $@ ] || rm -f $@'

clean::
	rm -f $(IGATEOFILE:.o=.d)
endif

ifneq (,$(YCFILES))
include $(YCFILES:.c=.d)

clean::
	rm -f $(YCFILES:.c=.d)
endif

ifneq (,$(YC++FILES))
include $(YC++FILES:.cxx=.d)

clean::
	rm -f $(YC++FILES:.cxx=.d)
endif

ifneq (,$(CFILES))
include $(CFILES:.c=.d)

clean::
	rm -f $(CFILES:.c=.d)
endif

ifneq (,$(C++FILES))
include $(C++FILES:.cxx=.d)

clean::
	rm -f $(C++FILES:.cxx=.d)
endif

endif  # (,$(DO_GNU_AUTO_DEP))
