##############################################################
#
# This file includes all the test targets as well as all the
# non-default build rules and test recipes.
#
##############################################################


##############################################################
#
# Test targets
#
##############################################################

###### Place all generic definitions here ######

# This defines tests which run tools of the same name.  This is simply for convenience to avoid
# defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS).
# Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS.
TEST_TOOL_ROOTS := inscount0 inscount1 inscount2 proccount imageload staticcount detach malloctrace \
                   malloc_mt inscount_tls stack-debugger pinatrace itrace isampling safecopy invocation \
                   countreps nonstatica

# This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS.
TEST_ROOTS :=

# This defines a list of tests that should run in the "short" sanity. Tests in this list must also
# appear either in the TEST_TOOL_ROOTS or the TEST_ROOTS list.
# If the entire directory should be tested in sanity, assign TEST_TOOL_ROOTS and TEST_ROOTS to the
# SANITY_SUBSET variable in the tests section below (see example in makefile.rules.tmpl).
SANITY_SUBSET :=

# This defines the tools which will be run during the the tests, and were not already defined in
# TEST_TOOL_ROOTS.
TOOL_ROOTS :=

# This defines the static analysis tools which will be run during the the tests. They should not
# be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in
# TEST_ROOTS.
# Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library.
# This library provides a subset of the Pin APIs which allows the tool to perform static analysis
# of an application or dll. Pin itself is not used when this tool runs.
SA_TOOL_ROOTS :=

# This defines all the applications that will be run during the tests.
APP_ROOTS := fibonacci little_malloc thread_app

# This defines any additional object files that need to be compiled.
OBJECT_ROOTS :=

# This defines any additional dlls (shared objects), other than the pintools, that need to be compiled.
DLL_ROOTS :=

# This defines any static libraries (archives), that need to be built.
LIB_ROOTS :=

###### Place probe mode tests here ######
ifeq ($(PROBE),1)
    TEST_TOOL_ROOTS += replacesigprobed
endif

###### Place OS-specific definitions here ######

# Linux
ifeq ($(TARGET_OS),linux)
    TEST_TOOL_ROOTS += buffer_linux fork_jit_tool follow_child_tool strace emudiv
    TEST_ROOTS += statica
    SA_TOOL_ROOTS += statica
    APP_ROOTS += fork_app follow_child_app1 follow_child_app2 divide_by_zero
endif

# Mac
ifeq ($(TARGET_OS),mac)
    TEST_TOOL_ROOTS += fork_jit_tool follow_child_tool strace
    TEST_ROOTS += statica
    SA_TOOL_ROOTS += statica
    APP_ROOTS += fork_app follow_child_app1 follow_child_app2
endif

# Windows
ifeq ($(TARGET_OS),windows)
    TEST_TOOL_ROOTS += w_malloctrace buffer_windows emudiv
    APP_ROOTS += divide_by_zero
endif

###### Handle exceptions here ######

# TODO: These tests fail - fix and remove the following:
# See Mantis 2963
ifeq ($(TARGET),mic)
    TEST_TOOL_ROOTS := $(filter-out nonstatica emudiv, $(TEST_TOOL_ROOTS))
    TEST_ROOTS := $(filter-out statica, $(TEST_ROOTS))
    SA_TOOL_ROOTS := $(filter-out statica, $(SA_TOOL_ROOTS))
endif


##############################################################
#
# Test recipes
#
##############################################################

# This section contains recipes for tests other than the default.
# See makefile.default.rules for the default test rules.
# All tests in this section should adhere to the naming convention: <testname>.test

inscount_tls.test: $(OBJDIR)inscount_tls$(PINTOOL_SUFFIX) $(OBJDIR)thread_app$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)inscount_tls$(PINTOOL_SUFFIX) -- $(OBJDIR)thread_app$(EXE_SUFFIX) > $(OBJDIR)inscount_tls.out 2>&1
	$(RM) $(OBJDIR)inscount_tls.out

malloc_mt.test: $(OBJDIR)malloc_mt$(PINTOOL_SUFFIX) $(OBJDIR)thread_app$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)malloc_mt$(PINTOOL_SUFFIX) -- $(OBJDIR)thread_app$(EXE_SUFFIX) > $(OBJDIR)malloc_mt.out 2>&1
	$(RM) $(OBJDIR)malloc_mt.out

buffer_linux.test: $(OBJDIR)buffer_linux$(PINTOOL_SUFFIX) $(OBJDIR)thread_app$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)buffer_linux$(PINTOOL_SUFFIX) -- $(OBJDIR)thread_app$(EXE_SUFFIX) > $(OBJDIR)buffer_linux.out 2>&1
	$(RM) $(OBJDIR)buffer_linux.out

buffer_windows.test: $(OBJDIR)buffer_windows$(PINTOOL_SUFFIX) $(OBJDIR)thread_app$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)buffer_windows$(PINTOOL_SUFFIX) -emit 0 \
	  -- $(OBJDIR)thread_app$(EXE_SUFFIX) > $(OBJDIR)buffer_windows.out 2>&1
	$(RM) $(OBJDIR)buffer_windows.out

invocation.test: $(OBJDIR)invocation$(PINTOOL_SUFFIX) $(OBJDIR)little_malloc$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)invocation$(PINTOOL_SUFFIX) -- $(OBJDIR)little_malloc$(EXE_SUFFIX) > $(OBJDIR)invocation.out 2>&1
	$(RM) $(OBJDIR)invocation.out

# This tool is tested in "Debugger/makefile". However, leave this line because it is referenced in the user manual.
# The user may invoke make stack-debugger.test to build the tool and app shown in the manual.
# There is an intentional "empty" line which contains a tab character so this "test" will have an empty recipe.
stack-debugger.test: $(OBJDIR)stack-debugger$(PINTOOL_SUFFIX) $(OBJDIR)fibonacci$(EXE_SUFFIX)
	

# stand alone pin tool
statica.test: $(OBJDIR)statica$(SATOOL_SUFFIX)
	$(OBJDIR)statica$(SATOOL_SUFFIX) -i $(OBJDIR)statica$(SATOOL_SUFFIX) > $(OBJDIR)statica.dmp
	$(RM) $(OBJDIR)statica.dmp

nonstatica.test: $(OBJDIR)nonstatica$(PINTOOL_SUFFIX) $(TESTAPP)
	$(PIN) -t $(OBJDIR)nonstatica$(PINTOOL_SUFFIX) \
	  -- $(TESTAPP) makefile $(OBJDIR)nonstatica.makefile.copy > $(OBJDIR)nonstatica.dmp
	$(DIFF) makefile $(OBJDIR)nonstatica.makefile.copy
	$(RM) $(OBJDIR)nonstatica.makefile.copy $(OBJDIR)nonstatica.dmp

emudiv.test: $(OBJDIR)emudiv$(PINTOOL_SUFFIX) $(OBJDIR)divide_by_zero$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)emudiv$(PINTOOL_SUFFIX) -- $(OBJDIR)divide_by_zero$(EXE_SUFFIX) > $(OBJDIR)emudiv.out 2>&1
	$(QGREP) "Caught divide by zero exception" $(OBJDIR)emudiv.out
	$(RM) $(OBJDIR)emudiv.out

fork_jit_tool.test: $(OBJDIR)fork_jit_tool$(PINTOOL_SUFFIX) $(OBJDIR)fork_app$(EXE_SUFFIX)
	$(PIN) -t $(OBJDIR)fork_jit_tool$(PINTOOL_SUFFIX) -- $(OBJDIR)fork_app$(EXE_SUFFIX)

follow_child_tool.test: $(OBJDIR)follow_child_tool$(PINTOOL_SUFFIX) $(OBJDIR)follow_child_app1$(EXE_SUFFIX) $(OBJDIR)follow_child_app2$(EXE_SUFFIX)
	$(PIN) -follow_execv 1 -t $(OBJDIR)follow_child_tool$(PINTOOL_SUFFIX) \
	  -- $(OBJDIR)follow_child_app1$(EXE_SUFFIX) $(OBJDIR)follow_child_app2$(EXE_SUFFIX)


##############################################################
#
# Build rules
#
##############################################################

# This section contains the build rules for all binaries that have special build rules.
# See makefile.default.rules for the default build rules.

###### Special applications' build rules ######

$(OBJDIR)divide_by_zero$(EXE_SUFFIX): divide_by_zero_$(TARGET_OS).c
	$(APP_CC) $(APP_CXXFLAGS_NOOPT) $(COMP_EXE)$@ $< $(APP_LDFLAGS_NOOPT) $(APP_LIBS)

$(OBJDIR)thread_app$(EXE_SUFFIX): thread_$(OS_TYPE).c
	$(APP_CC) $(APP_CXXFLAGS) $(COMP_EXE)$@ $< $(APP_LDFLAGS) $(APP_LIBS)
