VERSION=${VERSION}${DEVEL}

BUILDPREFIX =
PREFIX = /usr/local/parrot/${VERSION}
EXEC_PREFIX = $(PREFIX)
BINDIR = $(EXEC_PREFIX)/bin
LIBDIR = $(EXEC_PREFIX)/lib
INCLUDEDIR = $(EXEC_PREFIX)/include

# imcc dir
IMCC_DIR = imcc

# source dir
SRC = src

# Ops dir
OPS = ops

# Build tools
BUILD_TOOL = build_tools

# file containing main
PARROT_MAIN = $(IMCC_DIR)/main


# programs and utils used for build
RM_F = ${rm_f}
RM_RF = ${rm_rf}
AR_CR = ${ar} ${ar_flags}
RANLIB = ${ranlib}
LINK = ${link}
LD = ${ld}
LD_SHARED = ${ld_shared}
TOUCH  = $(PERL) -e ${PQ}open(A,q{>>$$_}) or die foreach @ARGV${PQ}
YACC = ${yacc}
LEX = ${lex}

# file extensions and util flags
O = ${o}
SO = ${so}
A = ${a}
LD_OUT = ${ld_out}
LD_SHARED_FLAGS=${ld_shared_flags}


INC=./${inc}

NONGEN_HEADERS = ${nongen_headers}

###############################################################################
#
# "STICKY" GENERATED FILES:
#
# These files are created when Configure.pl runs.
#
# We don't delete these on 'clean' only on 'realclean'.
# That way, we don't have to re-Configure.pl after making
# clean.
#
###############################################################################

GEN_MAKEFILES = Makefile classes/Makefile languages/Makefile docs/Makefile \
	languages/jako/Makefile languages/miniperl/Makefile \
	languages/scheme/Makefile languages/befunge/Makefile \
	languages/bf/Makefile imcc/Makefile \
	languages/ook/Makefile languages/perl6/Makefile \
	languages/urm/Makefile languages/tcl/Makefile

GEN_CONFIGS  = include/parrot/config.h include/parrot/platform.h \
	include/parrot/platform_interface.h \
	include/parrot/has_header.h \
	include/parrot/feature.h \
	lib/Parrot/Config.pm lib/Parrot/PMC.pm $(SRC)/platform.c \
	include/parrot/core_pmcs.h $(SRC)/core_pmcs.c \
	CFLAGS imcc/CFLAGS \
	libparrot.def

# most of these are generatey by config/gen/parrot_include.pl

GEN_PASM_INCLUDES = \
	runtime/parrot/include/signal.pasm	\
	${gen_pasm_includes}

STICKY_FILES = $(GEN_CONFIGS) $(GEN_MAKEFILES) myconfig $(GEN_PASM_INCLUDES)


###############################################################################
#
# "FLUID" GENERATED FILES:
#
# These files are created during the build process.
#
# We *do* delete these on 'clean'.
#
###############################################################################

GEN_OPSFILES =

GEN_HEADERS = $(INC)/vtable.h $(INC)/oplib/core_ops.h \
	$(INC)/oplib/core_ops_prederef.h \
	$(INC)/oplib/core_ops_switch.h

GEN_SOURCES = $(SRC)/core_ops.c $(SRC)/core_ops_prederef.c $(SRC)/fingerprint.c $(SRC)/nci.c \
              $(SRC)/core_ops_switch.c $(SRC)/jit_cpu.c $(SRC)/exec_cpu.c

GEN_MODULES = lib/Parrot/OpLib/core.pm

# the dependencies of jit_emit.h are done explicitely
# including this file in GEN_HEADERS causses unnecessary recompile of all
FLUID_FILES = $(GEN_OPSFILES) $(GEN_HEADERS) $(GEN_SOURCES) $(GEN_MODULES) $(INC)/jit_emit.h


###############################################################################
#
# OTHER FILE GROUPS:
#
###############################################################################

# these are private to the imcc subsystem
IMCC_H_FILES = \
	$(IMCC_DIR)/imc.h 	\
	$(IMCC_DIR)/stacks.h 	\
	$(IMCC_DIR)/cfg.h 	\
	$(IMCC_DIR)/class.h 	\
	$(IMCC_DIR)/instructions.h 	\
	$(IMCC_DIR)/debug.h 	\
	$(IMCC_DIR)/sets.h 	\
	$(IMCC_DIR)/symbol.h 	\
	$(IMCC_DIR)/symreg.h 	\
	$(IMCC_DIR)/pbc.h 	\
	$(IMCC_DIR)/optimizer.h 	\
	$(IMCC_DIR)/parser.h 	\
	$(IMCC_DIR)/imcparser.h

IMCC_O_FILES = \
	$(IMCC_DIR)/imcparser$(O) 	\
	$(IMCC_DIR)/imclexer$(O) 	\
	$(IMCC_DIR)/imc$(O) 	\
	$(IMCC_DIR)/stacks$(O) 	\
	$(IMCC_DIR)/symbol$(O) 	\
	$(IMCC_DIR)/class$(O) 	\
	$(IMCC_DIR)/symreg$(O) 	\
	$(IMCC_DIR)/instructions$(O) 	\
	$(IMCC_DIR)/cfg$(O) 	\
	$(IMCC_DIR)/sets$(O) 	\
	$(IMCC_DIR)/debug$(O) 	\
	$(IMCC_DIR)/optimizer$(O) 	\
	$(IMCC_DIR)/pbc$(O) 	\
	$(IMCC_DIR)/parser_util$(O)	\
	$(IMCC_DIR)/jit$(O) 	\
	$(IMCC_DIR)/pcc$(O)

GENERAL_H_FILES = $(NONGEN_HEADERS) $(GEN_HEADERS) ${cg_h}


ALL_H_FILES = $(GENERAL_H_FILES)

CLASS_PMC_FILES = ${pmc_classes_pmc}

CLASS_O_FILES = ${pmc_classes_o}

ENCODING_O_FILES = encodings/singlebyte$(O) encodings/utf8$(O) \
	encodings/utf16$(O) encodings/utf32$(O)

CHARTYPE_O_FILES = chartypes/unicode$(O) chartypes/usascii$(O)

IO_O_FILES = io/io$(O) io/io_buf$(O) io/io_unix$(O) io/io_win32$(O) \
	io/io_stdio$(O) io/io_passdown$(O)

INTERP_O_FILES = $(SRC)/exceptions$(O) $(SRC)/global_setup$(O) $(SRC)/interpreter$(O)  \
	$(SRC)/register$(O) $(SRC)/core_ops$(O) $(SRC)/core_ops_prederef$(O) $(SRC)/core_ops_switch$(O) \
	$(SRC)/memory$(O) $(SRC)/objects$(O) ${exec_o} \
	$(SRC)/packfile$(O) $(SRC)/stacks$(O) $(SRC)/string$(O) $(SRC)/sub$(O) $(SRC)/encoding$(O) \
	$(SRC)/chartype$(O) $(SRC)/runops_cores$(O) $(SRC)/trace$(O) $(SRC)/pmc$(O) $(SRC)/key$(O) $(SRC)/hash$(O) \
	$(SRC)/core_pmcs$(O) $(SRC)/platform$(O) ${jit_o} \
	${gc_o} $(SRC)/rx$(O) $(SRC)/rxstacks$(O) $(SRC)/intlist$(O) $(SRC)/list$(O) \
	$(SRC)/embed$(O) $(SRC)/warnings$(O)  ${cg_o} \
	$(SRC)/packout$(O) $(SRC)/byteorder$(O) $(SRC)/debug$(O) $(SRC)/smallobject$(O) \
	$(SRC)/headers$(O) $(SRC)/dod$(O) $(SRC)/method_util$(O) $(SRC)/exit$(O) \
	$(SRC)/misc$(O) $(SRC)/spf_render$(O) $(SRC)/spf_vtable$(O) $(SRC)/datatypes$(O) $(SRC)/fingerprint$(O) \
	$(SRC)/nci$(O) $(SRC)/cpu_dep$(O) ${asmfun_o} $(SRC)/tsq$(O) $(SRC)/longopt$(O) $(SRC)/events$(O) \
	$(SRC)/dynext$(O) $(SRC)/utils$(O) $(SRC)/vtables$(O) $(SRC)/mmd$(O) $(SRC)/extend$(O)

O_FILES = $(INTERP_O_FILES) $(IO_O_FILES) $(CLASS_O_FILES) \
	$(ENCODING_O_FILES) $(CHARTYPE_O_FILES) \
	$(IMCC_O_FILES)

OPS_FILES = ${ops} $(GEN_OPSFILES)

###############################################################################
#
# BUILD TOOL CONFIGURATIONS:
#
# DO NOT ADD C COMPILER FLAGS HERE
# Add them in Configure.pl--look for the
# comment 'ADD C COMPILER FLAGS HERE'
#
###############################################################################

CFLAGS = ${ccflags} ${cc_debug} ${ccwarn} ${cc_inc} ${cc_hasjit} ${cg_flag} ${gc_flag}

LINKFLAGS = ${linkflags} ${link_debug} ${ld_debug}
LDFLAGS = ${ldflags} ${ld_debug}

C_LIBS = ${libs}

CC = ${cc}
PERL = ${perl}

# Make directory; do not die if dir exists.
MKDIR = $(PERL) -e ${PQ}-d or mkdir $$_,0777 or die foreach @ARGV${PQ}

###############################################################################
#
# BUILD TARGET CONFIGURATIONS:
#
###############################################################################

TEST_PROG = ${test_prog}${exe}
TEST_PROG_SO = ${test_prog}_so${exe}
LIBPARROT = ${blib_lib_libparrot_a}
# utils
DIS=disassemble${exe}
PDUMP = pdump${exe}
PINFO = pbc_info${exe}
PDB = pdb${exe}

# lclint has changed name to splint at v3.0
LINT = splint

# note: +distinctinternalnames with +externalnamelen at 8 characters
#       (the ANSI standard) is not going to fly for us.
LINTFLAGS = -weak +showscan +showsummary +posixstrictlib -abstract +aliasunique +ansireserved +ansireservedinternal +assignexpose +bitwisesigned +boolcompare +booltype BOOLVAL +casebreak -castfcnptr -charint +continuecomment +controlnestdepth 15 +cppnames +declundef +distinctinternalnames +evalorder +fielduse +forcehints -globs +imptype +includenest 8 +incondefs +incondefslib +linelen 9999 +longintegral +macroassign +macroempty +macroredef +matchanyintegral +nestedextern +noeffect +readonlystrings +realcompare +shadow -type

# slightly weaker, more realistic variant.
LINTFLAGS2 = $(LINTFLAGS) -ansireserved -retvalother -bitwisesigned

# added to lint target to simplify experimentation,
# ex: make LINTOPTS='-posixstrictlibs +posixlibs' lint
LINTOPTS =

###############################################################################
#
# MAKE CONFIGURATION:
#
###############################################################################

#
# This is set to  MAKE=$make if your $make command doesn't
# do it for you.
#
${make_set_make}
MAKE_C = ${make_c}

.c$(O) :
	@$(PERL) tools/dev/cc_flags.pl ./CFLAGS $(CC) $(CFLAGS) -I$(@D) ${cc_o_out}$@ -c $<

all : flags_dummy $(TEST_PROG) docs

world: all parrot_utils

parrot_utils: $(PDUMP) $(DIS) $(PINFO) $(PDB)

flags_dummy:
	echo Compiling with:
	@$(PERL) tools/dev/cc_flags.pl ./CFLAGS echo $(CFLAGS) xx$(O) -c xx.c


mops : examples/assembly/mops${exe} examples/mops/mops${exe}

$(TEST_PROG) : $(PARROT_MAIN)$(O) $(GEN_HEADERS) $(LIBPARROT) lib/Parrot/OpLib/core.pm
	$(LINK) ${ld_out}$(TEST_PROG) $(LINKFLAGS) $(PARROT_MAIN)$(O) $(LIBPARROT) $(C_LIBS)

lib_deps_object : $(O_FILES)
	$(PERL) tools/dev/lib_deps.pl object $(O_FILES)

lib_deps_source : $(GENERAL_H_FILES)
	$(PERL) tools/dev/lib_deps.pl source all_source

lib_deps : lib_deps_object lib_deps_source

check_source : $(GENERAL_H_FILES)
	$(PERL) tools/dev/check_source_standards.pl all_source

###############################################################################
#
# Shared Library Targets:
#
###############################################################################

shared : $(GEN_HEADERS) blib/lib/libparrot$(SO) $(LIBPARROT)
static : $(GEN_HEADERS) $(LIBPARROT)

# XXX changes don't always propagate into libparrot
# e.g. when I change debug:fataly to xfataly, nm still shows the old symbol
# and parrot builds fine (except for the unproto warning
# so always delete the lib -leo

$(LIBPARROT) : $(O_FILES)
	$(RM_F) $@
	$(MKDIR) blib blib/lib
	$(AR_CR) ${ar_out}$@ ${ar_extra} $(O_FILES)
	$(RANLIB) $@

blib/lib/libparrot$(SO) : $(O_FILES)
	$(MKDIR) blib blib/lib
	$(LD) $(LD_SHARED) $(LD_SHARED_FLAGS) $(LDFLAGS) $(LD_OUT)blib/lib/libparrot$(SO) $(O_FILES) $(C_LIBS)

$(TEST_PROG_SO) : $(PARROT_MAIN)$(O) blib/lib/libparrot$(SO) lib/Parrot/OpLib/core.pm
	$(LINK) $(LINKFLAGS) $(LD_OUT)$(TEST_PROG) $(PARROT_MAIN)$(O) $(LIBPARROT) $(C_LIBS)

# XXX The dependancies on SO.MAJOR.MINOR and SO.VERSION are removed
#     because those should be done at "make install" and not "make shared"
#     It also makes the task of getting this working on win32 much easier. :)
#
#blib/lib/libparrot$(SO).${VERSION} : $(O_FILES)
#	$(MKDIR) blib blib/lib
#	$(LD) $(LD_SHARED) -Wl,-soname,libparrot$(SO).${MAJOR} $(LDFLAGS) $(LD_OUT)blib/lib/libparrot$(SO).${VERSION} $(O_FILES)
#
#blib/lib/libparrot$(SO).${MAJOR}.${MINOR} : blib/lib/libparrot$(SO).${VERSION}
#	$(RM_F) $@
#	cd blib/lib; ln -s libparrot$(SO).${VERSION} libparrot$(SO).${MAJOR}.${MINOR}
#
#blib/lib/libparrot$(SO).${MAJOR} : blib/lib/libparrot$(SO).${MAJOR}.${MINOR}
#	$(RM_F) $@
#	cd blib/lib; ln -s libparrot$(SO).${MAJOR}.${MINOR} libparrot$(SO).${MAJOR}
#
#blib/lib/libparrot$(SO) : blib/lib/libparrot$(SO).${MAJOR}
#	$(RM_F) $@
#	cd blib/lib; ln -s libparrot$(SO).${MAJOR} libparrot$(SO)
#
#blib/lib/libcore_prederef$(SO).${VERSION} : core_ops_prederef$(O)
#	$(LD) $(LD_SHARED) -Wl,-soname,libparrot$(SO).${MAJOR} $(LDFLAGS) $(LD_OUT)blib/lib/libcore_prederef$(SO).${VERSION} core_ops_prederef$(O)
#
#blib/lib/libcore_prederef$(SO).${MAJOR}.${MINOR} : blib/lib/libcore_prederef$(SO).${VERSION}
#	$(RM_F) $@
#	cd blib/lib; ln -s libcore_prederef$(SO).${VERSION} libcore_prederef$(SO).${MAJOR}.${MINOR}
#
#blib/lib/libcore_prederef$(SO).${MAJOR} : blib/lib/libcore_prederef$(SO).${MAJOR}.${MINOR}
#	$(RM_F) $@
#	cd blib/lib; ln -s libcore_prederef$(SO).${MAJOR}.${MINOR} libcore_prederef$(SO).${MAJOR}
#
#blib/lib/libcore_prederef$(SO) : blib/lib/libcore_prederef$(SO).${MAJOR}
#	$(RM_F) $@
#	cd blib/lib; ln -s libcore_prederef$(SO).${MAJOR} libcore_prederef$(SO)


#
# Parrot Debugger
#

$(SRC)/pdb$(O) : $(GENERAL_H_FILES)

$(PDB) : $(SRC)/pdb$(O) $(LIBPARROT)
	$(LINK) ${ld_out}$(PDB) $(SRC)/pdb$(O) $(LINKFLAGS) $(LIBPARROT) $(C_LIBS)

#
# Parrot Disassembler
#

$(SRC)/disassemble$(O) : $(GENERAL_H_FILES)

$(DIS) : $(SRC)/disassemble$(O) $(LIBPARROT)
	$(LINK) ${ld_out}$(DIS) $(SRC)/disassemble$(O) $(LINKFLAGS) $(LIBPARROT) $(C_LIBS)

#
# Parrot Dump
#

$(PDUMP) : $(SRC)/pdump$(O) $(SRC)/packdump$(O) $(LIBPARROT)
	$(LINK) ${ld_out}$(PDUMP) $(SRC)/pdump$(O) $(SRC)/packdump$(O) $(LINKFLAGS) $(LIBPARROT) $(C_LIBS)


# pbc_info
$(PINFO) : $(SRC)/pbc_info$(O) $(LIBPARROT)
	$(LINK) ${ld_out}$(PINFO) $(SRC)/pbc_info$(O) $(LINKFLAGS) $(LIBPARROT) $(C_LIBS)

###############################################################################
#
# Other Dependencies and Build Rules:
#
###############################################################################

$(PARROT_MAIN)$(O) : $(PARROT_MAIN).c $(GENERAL_H_FILES)

lib/Parrot/OpLib/core.pm : $(OPS_FILES) $(BUILD_TOOL)/ops2pm.pl \
	lib/Parrot/OpsFile.pm lib/Parrot/Op.pm $(OPS)/ops.num
	$(PERL) $(BUILD_TOOL)/ops2pm.pl $(OPS_FILES)

$(SRC)/fingerprint.c : $(BUILD_TOOL)/fingerprint_c.pl PBC_COMPAT
	$(PERL) $(BUILD_TOOL)/fingerprint_c.pl > $(SRC)/fingerprint.c

###############################################################################
#
# Examples (Assembly):
#
###############################################################################

examples/assembly/mops.pbc : examples/assembly/mops.pasm
	$(MAKE_C) examples/assembly mops.pbc

examples/assembly/mops.c : examples/assembly/mops.pbc $(BUILD_TOOL)/pbc2c.pl
	$(PERL) $(BUILD_TOOL)/pbc2c.pl examples/assembly/mops.pbc > examples/assembly/mops.c

examples/assembly/mops${exe} : examples/assembly/mops$(O) $(LIBPARROT)
	$(LINK) $(LINKFLAGS) ${ld_out}examples/assembly/mops${exe} examples/assembly/mops$(O) $(LIBPARROT) $(C_LIBS)

examples/assembly/life.pbc : examples/assembly/life.pasm
	$(MAKE_C) examples/assembly life.pbc

examples/assembly/life.c : examples/assembly/life.pbc $(BUILD_TOOL)/pbc2c.pl
	$(PERL) $(BUILD_TOOL)/pbc2c.pl examples/assembly/life.pbc > examples/assembly/life.c

examples/assembly/life${exe} : examples/assembly/life$(O) $(LIBPARROT)
	$(LINK) $(LINKFLAGS) ${ld_out}examples/assembly/life${exe} examples/assembly/life$(O) $(LIBPARROT) $(C_LIBS)

###############################################################################
#
# Examples (MOPS) - Comparative:
#
###############################################################################

examples/mops/mops$(O) : examples/mops/mops.c

examples/mops/mops${exe} : examples/mops/mops$(O)
	$(LINK) $(LINKFLAGS) ${ld_out}examples/mops/mops${exe} \
	examples/mops/mops$(O) $(LIBPARROT) $(C_LIBS)


###############################################################################
#
# Dependencies:
#
###############################################################################

$(SRC)/global_setup$(O) : $(GENERAL_H_FILES)

$(SRC)/pmc$(O) : $(GENERAL_H_FILES)

$(SRC)/hash$(O) : $(GENERAL_H_FILES)

$(SRC)/intlist$(O) : $(GENERAL_H_FILES)

$(SRC)/list$(O) : $(GENERAL_H_FILES)

$(SRC)/jit$(O) : $(GENERAL_H_FILES) ${jit_h} $(INC)/jit_emit.h

$(SRC)/jit_debug$(O) : $(GENERAL_H_FILES) ${jit_h}

$(SRC)/jit_debug_xcoff$(O) : $(GENERAL_H_FILES) ${jit_h}

$(SRC)/jit_cpu$(O): $(GENERAL_H_FILES) ${jit_h} $(INC)/jit_emit.h

$(SRC)/exec$(O) : $(GENERAL_H_FILES) ${exec_h} ${jit_h} $(INC)/jit_emit.h

$(SRC)/exec_cpu$(O): $(GENERAL_H_FILES) ${exec_h} ${jit_h} $(INC)/jit_emit.h

$(SRC)/exec_start$(O) : $(GENERAL_H_FILES) ${exec_h}

$(SRC)/exec_save$(O) : $(GENERAL_H_FILES) ${exec_h}

$(SRC)/key$(O) : $(GENERAL_H_FILES)

$(SRC)/smallobject$(O) : $(GENERAL_H_FILES)

$(SRC)/headers$(O) : $(GENERAL_H_FILES)

$(SRC)/dod$(O) : $(GENERAL_H_FILES)

$(SRC)/resources$(O) : $(GENERAL_H_FILES)

$(SRC)/platform$(O) : $(GENERAL_H_FILES)

$(SRC)/core_pmcs$(O) : $(GENERAL_H_FILES)

$(SRC)/trace$(O) : $(GENERAL_H_FILES)

$(SRC)/debug$(O) : $(GENERAL_H_FILES) $(INC)/debug.h

$(SRC)/method_util$(O) : $(GENERAL_H_FILES)

$(SRC)/string$(O) : $(GENERAL_H_FILES)

$(SRC)/longopt$(O) : $(GENERAL_H_FILES)

$(SRC)/chartype$(O) : $(GENERAL_H_FILES)

$(SRC)/encoding$(O) : $(GENERAL_H_FILES)

chartype/usascii$(O) : $(GENERAL_H_FILES)

chartype/unicode$(O) : $(GENERAL_H_FILES)

$(SRC)/dynext$(O) : $(GENERAL_H_FILES)

$(SRC)/exceptions$(O) : $(GENERAL_H_FILES)

encoding/singlebyte$(O) : $(GENERAL_H_FILES)

encoding/utf8$(O) : $(GENERAL_H_FILES)

encoding/utf16$(O) : $(GENERAL_H_FILES)

encoding/utf32$(O) : $(GENERAL_H_FILES)

$(SRC)/events$(O) : $(GENERAL_H_FILES)

$(SRC)/extend$(O) : $(GENERAL_H_FILES) $(INC)/extend.h

$(SRC)/interpreter$(O) : $(SRC)/interpreter.c $(GENERAL_H_FILES) ${jit_h}

io/io$(O) : $(GENERAL_H_FILES) io/io_private.h

io/io_buf$(O) : $(GENERAL_H_FILES) io/io_private.h

io/io_unix$(O) : $(GENERAL_H_FILES) io/io_private.h

io/io_win32$(O) : $(GENERAL_H_FILES) io/io_private.h

io/io_stdio$(O) : $(GENERAL_H_FILES) io/io_private.h

io/io_passdown$(O) : $(GENERAL_H_FILES) io/io_private.h

$(SRC)/memory$(O) : $(GENERAL_H_FILES)

$(SRC)/mmd$(O) : $(GENERAL_H_FILES) $(INC)/mmd.h

$(SRC)/objects$(O) : $(GENERAL_H_FILES)

$(SRC)/packfile$(O) : $(GENERAL_H_FILES)

$(SRC)/packout$(O) : $(GENERAL_H_FILES)

$(SRC)/parrot$(O) : $(GENERAL_H_FILES)

$(SRC)/register$(O) : $(GENERAL_H_FILES)

$(SRC)/rx$(O) : $(GENERAL_H_FILES)

$(SRC)/rxstacks$(O) : $(GENERAL_H_FILES)

$(SRC)/stacks$(O) : $(GENERAL_H_FILES)

$(SRC)/tsq$(O) : $(GENERAL_H_FILES)

$(SRC)/embed$(O) : $(GENERAL_H_FILES) $(INC)/debug.h

$(SRC)/core_ops$(O) : $(GENERAL_H_FILES) $(SRC)/core_ops.c

$(SRC)/dataypes$(O) : $(GENERAL_H_FILES) $(SRC)/dataypes.c

$(SRC)/exit$(O) : $(GENERAL_H_FILES) $(SRC)/exit.c

$(SRC)/nci$(O) : $(GENERAL_H_FILES) $(SRC)/nci.c

$(SRC)/vtables$(O) : $(GENERAL_H_FILES) $(SRC)/vtables.c

$(SRC)/cpu_dep$(O) : $(GENERAL_H_FILES)

$(SRC)/nci.c : $(SRC)/call_list.txt $(BUILD_TOOL)/build_nativecall.pl
	$(PERL) $(BUILD_TOOL)/build_nativecall.pl $(SRC)/call_list.txt

#core_ops depends upon config.h so that it gets updated along with updates to config.h's version numbers
$(SRC)/core_ops.c $(INC)/oplib/core_ops.h : $(OPS_FILES) $(BUILD_TOOL)/ops2c.pl lib/Parrot/OpsFile.pm lib/Parrot/Op.pm $(INC)/config.h lib/Parrot/OpLib/core.pm
	$(PERL) $(BUILD_TOOL)/ops2c.pl C --core

$(SRC)/core_ops_prederef$(O) : $(GENERAL_H_FILES) $(SRC)/core_ops_prederef.c

$(SRC)/core_ops_prederef.c $(INC)/oplib/core_ops_prederef.h : $(OPS_FILES) $(BUILD_TOOL)/ops2c.pl lib/Parrot/OpsFile.pm lib/Parrot/Op.pm $(INC)/config.h lib/Parrot/OpLib/core.pm
	$(PERL) $(BUILD_TOOL)/ops2c.pl CPrederef --core

$(SRC)/core_ops_switch$(O) : $(GENERAL_H_FILES) $(SRC)/core_ops_switch.c

$(SRC)/core_ops_switch.c $(INC)/oplib/core_ops_switch.h : $(OPS_FILES) $(BUILD_TOOL)/ops2c.pl lib/Parrot/OpsFile.pm lib/Parrot/Op.pm $(INC)/config.h lib/Parrot/OpLib/core.pm
	$(PERL) $(BUILD_TOOL)/ops2c.pl CSwitch --core

${cg_c}

${gc_c}

$(SRC)/warnings$(O) : $(GENERAL_H_FILES)

$(SRC)/misc$(O) : $(GENERAL_H_FILES)

$(SRC)/utils$(O) : $(GENERAL_H_FILES)

$(SRC)/spf_render$(O) : $(GENERAL_H_FILES)

$(SRC)/spf_vtable$(O) : $(GENERAL_H_FILES)

# $(STICKY_FILES) : Configure.pl
#	$(PERL) Configure.pl

$(INC)/vtable.h : vtable.tbl $(BUILD_TOOL)/vtable_h.pl
	$(PERL) $(BUILD_TOOL)/vtable_h.pl

$(INC)/jit_emit.h: jit/${jitcpuarch}/jit_emit.h
	$(PERL) -MFile::Copy=cp -e ${PQ}cp q|jit/${jitcpuarch}/jit_emit.h|, q|$(INC)/jit_emit.h|${PQ}
$(INC)/exec_dep.h: jit/${jitcpuarch}/exec_dep.h
	$(PERL) -MFile::Copy=cp -e ${PQ}cp q|jit/${jitcpuarch}/exec_dep.h|, q|$(INC)/exec_dep.h|${PQ}
$(SRC)/jit_cpu.c: lib/Parrot/OpLib/core.pm $(INC)/jit_emit.h \
		jit/${jitcpuarch}/core.jit $(BUILD_TOOL)/jit2h.pl
	$(PERL) $(BUILD_TOOL)/jit2h.pl ${jitcpuarch} $(SRC)/jit_cpu.c
$(SRC)/exec_cpu.c: lib/Parrot/OpLib/core.pm $(INC)/jit_emit.h \
		jit/${jitcpuarch}/core.jit ${exec_h} $(INC)/exec_dep.h $(BUILD_TOOL)/jit2h.pl
	$(PERL) $(BUILD_TOOL)/jit2h.pl ${jitcpuarch} $(SRC)/exec_cpu.c

######## imcc files deps
#
# The .flag files are needed because we are keeping some derived files in CVS,
# which does not keep accurate timestamps on the files, relative to each other.
# Note that YACC or LEX may be null commands, so we must `touch` all the
# target files, instead of just the .flag files.

$(IMCC_DIR)/imcc.y.flag $(IMCC_DIR)/imcparser.c $(IMCC_DIR)/imcparser.h: $(IMCC_DIR)/imcc.y
	$(YACC) $(IMCC_DIR)/imcc.y -d -o $(IMCC_DIR)/imcparser.c
	$(TOUCH) $(IMCC_DIR)/imcc.y.flag $(IMCC_DIR)/imcparser.c $(IMCC_DIR)/imcparser.h

$(IMCC_DIR)/imcc.l.flag $(IMCC_DIR)/imclexer.c: $(IMCC_DIR)/imcc.l
	$(LEX) -o$(IMCC_DIR)/imclexer.c $(IMCC_DIR)/imcc.l
	$(TOUCH) $(IMCC_DIR)/imcc.l.flag $(IMCC_DIR)/imclexer.c

$(IMCC_O_FILES) : $(IMCC_H_FILES) $(ALL_H_FILES)


################ docs, test and maintainer targets

docs : docs.dummy

docs.dummy :
	$(MAKE_C) docs

languages : languages.dummy

languages.dummy :
	$(MAKE_C) languages

languages-test :
	$(MAKE_C) languages test

# If anything in the classes directory is out of date,
# then run `make` in sub-dir to rebuild only the out of date files.
$(CLASS_O_FILES) : $(CLASS_PMC_FILES) $(NONGEN_HEADERS)
	$(MAKE_C) classes


###############################################################################
#
# Testing Targets:
#
###############################################################################

# The --running-make-test argument is currently used by long-running tests
# to disable GC_DEBUG.
EXTRA_TEST_ARGS = --gc-debug --running-make-test
TEST_FILES = t/op/*.t t/pmc/*.t t/native_pbc/*.t
SRC_TEST_FILES = t/src/*.t

test : $(TEST_PROG) test_prep testb test_imcc src_tests

fulltest : $(TEST_PROG) test_prep fulltest_dummy fulltest_imcc

.PHONY: fulltest_dummy
fulltest_dummy : src_tests testg testP testj testS testb testr

# Common prep for all test targets
test_prep : $(LIBPARROT) $(TEST_PROG)

# src tests
src_tests :
	$(PERL) t/harness $(SRC_TEST_FILES)

# normal (cgoto) runloop
testg :
	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS) $(TEST_FILES)

# prederef / CGP runloop
testP :
	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS) -P $(TEST_FILES)

# JIT core
testj :
	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS) -j $(TEST_FILES)

# switched core
testS :
	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS) -S $(TEST_FILES)

# bounds checking slow core
testb :
	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS) -b $(TEST_FILES)

# normal core, write and run pbc
testr :
	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS) --run-pbc $(TEST_FILES)
mopstest :
	$(TEST_PROG) $(TEST_PROG_ARGS) examples/assembly/mops.pasm

lifetest :
	$(TEST_PROG) $(TEST_PROG_ARGS) examples/assembly/life.pasm

test_imcc :
	$(MAKE_C) $(IMCC_DIR) test

fulltest_imcc :
	$(MAKE_C) $(IMCC_DIR) test
	$(MAKE_C) $(IMCC_DIR) testj
	$(MAKE_C) $(IMCC_DIR) testP
	$(MAKE_C) $(IMCC_DIR) testS
	$(MAKE_C) $(IMCC_DIR) testb
	$(MAKE_C) $(IMCC_DIR) testr

# For reporting success or failure with different configurations
ok:
	$(PERL) tools/dev/genrpt.pl --ok

okfile:
	$(PERL) tools/dev/genrpt.pl --ok --File parrot.ok

nok:
	$(PERL) tools/dev/genrpt.pl --nok

nokfile:
	$(PERL) tools/dev/genrpt.pl --nok --File parrot.nok

###############################################################################
#
# Cleaning Targets:
#
###############################################################################

clean : testclean progclean
	${cg_r}
	$(RM_F) *.s *~ $(FLUID_FILES) \
	        examples/assembly/mops${exe} examples/assembly/mops.c \
	        examples/assembly/mops$(O) examples/assembly/mops.pbc \
	        examples/mops/mops$(O) examples/mops/mops${exe}
	$(MAKE_C) docs clean
	$(MAKE_C) classes clean
	$(MAKE_C) languages clean

progclean:
	$(RM_F) $(O_FILES) \
	        $(TEST_PROG) $(PARROT_MAIN)$(O) \
	        $(PDUMP) $(SRC)/pdump$(O) $(SRC)/packdump$(O) $(SRC)/pbc_info$(O) $(PINFO) \
	        $(PDB) $(SRC)/pdb$(O) \
	        $(DIS) $(SRC)/disassemble$(O)
	$(RM_RF) blib
	$(MAKE_C) classes progclean

testclean :
	$(RM_F) t/op/*.pasm t/op/*.pbc t/op/*.out t/op/*.o t/op/*.stabs.s \
	        t/pmc/*.pasm t/pmc/*.pbc t/pmc/*.out t/pmc/*.o t/pmc/*.stabs.s \
	        t/stress/*.pasm t/stress/*.pbc t/stress/*.out t/stress/*.o t/stress/*.stabs.s \
	        t/src/*_* \
		t/op/*.imc t/pmc/*.imc
	$(MAKE_C) $(IMCC_DIR) testclean

realclean : clean
	$(RM_F) $(STICKY_FILES)

distclean :
	$(PERL) "-MExtUtils::Manifest=filecheck" -le ${PQ}sub ExtUtils::Manifest::_maniskip{sub{0}};$$ExtUtils::Manifest::Quiet=1;unlink $$_ for filecheck()${PQ}

cvsclean :
	$(PERL) "-MExtUtils::Manifest=filecheck" -le ${PQ}sub ExtUtils::Manifest::_maniskip{sub{0}};$$ExtUtils::Manifest::Quiet=1; do { unlink $$_ unless $$_ =~ m!(?:CVS/|\.cvs)! } for filecheck()${PQ}

reconfig :
	$(MAKE) clean; $(PERL) Configure.pl --reconfig

manitest :
	$(PERL) "-MExtUtils::Manifest=fullcheck" -e fullcheck

###############################################################################
#
# CVS Targets:
#
###############################################################################

update :
	cvs -q update -dP

rsync :
	rsync -av cvs.perl.org::parrot-HEAD .

status :
	cvs -n -q upd -dP

lint : ${test_prog}
	$(LINT) ${cc_inc} ${cc_hasjit} "-Iclasses" $(LINTFLAGS) $(LINTOPTS) `echo $(O_FILES) | sed ${PQ}s/\.o/\.c/g${PQ}`
	$(LINT) ${cc_inc} $(LINTFLAGS) $(LINTOPTS) $(PARROT_MAIN).c

lint2 : ${test_prog}
	$(LINT) ${cc_inc} ${cc_hasjit} "-Iclasses" $(LINTFLAGS2) $(LINTOPTS) `echo $(O_FILES) | sed ${PQ}s/\.o/\.c/g${PQ}`
	$(LINT) ${cc_inc} $(LINTFLAGS2) $(LINTOPTS) $(PARROT_MAIN).c


###############################################################################
#
# installation
#
###############################################################################

install :
	$(PERL) tools/dev/install_files.pl --buildprefix=$(BUILDPREFIX) --prefix=$(PREFIX) --exec-prefix=$(EXEC_PREFIX) --bindir=$(BINDIR) --libdir=$(LIBDIR) --includedir=$(INCLUDEDIR) MANIFEST MANIFEST.generated | sh

###############################################################################
#
# release targets (probably unix only)
#
###############################################################################

release : MANIFEST MANIFEST.generated
	[ -d parrot-$(VERSION) ] || ln -s . parrot-$(VERSION)
	cp MANIFEST MANIFEST.real
	grep -v DEVELOPING MANIFEST.real > MANIFEST
	tar zcvf parrot-$(VERSION).tar.gz $$(perl -lane 'print"parrot-$(VERSION)/$$F[0]"unless!length||/#/' MANIFEST)
	mv MANIFEST.real MANIFEST
	rm parrot-$(VERSION)

rpms : release
	sudo cp parrot-$(VERSION).tar.gz /usr/src/*/SOURCES
	sudo cp parrot.spec /usr/src/*/SPECS
	cd /usr/src/*/SPECS ${make_and} sudo rpm -ba parrot.spec

###############################################################################
#
# miniparrot targets:
#
###############################################################################

miniparrot-prebuild : $(GEN_CONFIGS) $(FLUID_FILES)
	@tools/dev/rebuild_miniparrot.pl --action=clean
	@tools/dev/rebuild_miniparrot.pl --action=prebuild_classes $(CLASS_O_FILES)
	@tools/dev/rebuild_miniparrot.pl --action=copy_src $(GEN_CONFIGS) $(FLUID_FILES) $(ALL_H_FILES)
	@tools/dev/rebuild_miniparrot.pl --action=copy_src classes/*.h $(PARROT_MAIN).c $(INC)/debug.h
	@tools/dev/rebuild_miniparrot.pl --action=copy_src_from_obj $(O_FILES)
	@tools/dev/rebuild_miniparrot.pl --action=write_buildscripts --executable=parrot $(O_FILES) $(PARROT_MAIN)$(O)

miniparrot-update :
	tools/dev/rebuild_miniparrot.pl

###############################################################################
#
# exec:
#
###############################################################################

exec : $(SRC)/exec_start$(O) $(LIBPARROT)
	$(LINK) ${ld_out}$(EXEC) $(LINKFLAGS) $(EXEC)$(O) $(SRC)/exec_start$(O) $(LIBPARROT) $(C_LIBS)

exec_so : $(SRC)/exec_start$(O) blib/lib/libparrot$(SO)
	$(LINK) ${ld_out}$(EXEC) $(LINKFLAGS) $(EXEC)$(O) $(SRC)/exec_start$(O) -lparrot $(C_LIBS) -pthread

###### OS depend targets ##########
# libnci.so used by t/pmc/nci.t

$(SRC)/libnci$(O): $(SRC)/nci_test.c

libnci.so: $(SRC)/nci_test$(O)
	$(LD) $(LD_SHARED) $(LDFLAGS) \
	    $(LD_OUT)$@ $(SRC)/nci_test$(O)

libnci.dll: $(SRC)/nci_test$(O)
	$(LD) $(LD_SHARED) libnci.def $(LDFLAGS) \
	    $(LD_OUT)$@ $(SRC)/nci_test$(O)

# ctags

tags:
	ctags -R --links=no .

# test the EXEC stuff

testexec: hello-parrot hello-clean

hello-clean:
	@$(RM_F) hello.pasm hello$(O) hello

hello-parrot: hello

hello.pasm:
	echo 'print "Hello World\n"' > hello.pasm
	echo  'end' >> hello.pasm

hello.pbc:	hello.pasm
	parrot -o hello.pbc hello.pasm

hello$(O):	hello.pbc
	parrot -o hello$(O) hello.pbc

hello:	hello$(O)
	$(MAKE) EXEC=hello exec
	./hello
