TESTNAMES_ALL = $(basename $(TESTSRC_ALL))
SMOKE_TIMEOUT=timeout --foreground 30s

all: $(TESTNAME)

.PRECIOUS: %.o %.ll %.ll.s %.s %.s.o

.PHONY: prerequisites

ifneq ($(SCRIPT_INIT),)
prerequisites:
	@echo "<<< $(SCRIPT_INIT) <<<"
	. ./$(SCRIPT_INIT)
	@echo ">>> $(SCRIPT_INIT) >>>"
endif

# ----- Demo compile and link in one step, no object code saved
$(TESTNAME): prerequisites $(TESTSRC_ALL)
ifdef nvidia_targets
	$(CC) $(make_options) $(nvidia_targets) $(march) $(cuda) -o $@
else ifdef march
	$(CC) $(make_options) $(march) -o $@
else ifdef make_options
	$(CC) $(make_options) -o $@
else
	$(SETENV) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(OMP_FLAGS) $(wordlist 2,$(words $^),$^) -o $@ $(LINK_FLAGS)
endif

run: $(TESTNAME)
	$(RUNENV) $(RUNPROF) ./$(TESTNAME) 2>&1 | tee $@.log

check: $(TESTNAME)
	path=`pwd`; \
	base=`basename $$path`; \
	if   ($(SMOKE_TIMEOUT) ./$(TESTNAME)> /dev/null 2>&1); then \
		echo $$base $$test_num return code: $$? >> ../check-omp5.txt; \
		echo  "" >> ../check-omp5.txt; \
		echo $$base $$test_num  >> ../passing-tests.txt; \
	else	echo $$base $$test_num return code: $$? >> ../check-omp5.txt; \
		echo  "" >> ../check-omp5.txt; \
		echo $$base $$test_num  >> ../failing-tests.txt; \
	fi


# ----- Demo compile and link to object file
ifneq ($(TESTNAME), $(findstring $(TESTNAME),$(TESTNAMES_ALL)))
.PHONY: $(TESTNAME).o
$(TESTNAME).o: $(addsuffix .o, $(TESTNAMES_ALL))
endif

%.o: %.c*
	$(SETENV) $(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) $(OMP_FLAGS) $^ -o $@

obin: $(TESTNAME).o
	$(SETENV) $(CC) $(OMP_FLAGS) $(LINK_FLAGS) $(addsuffix .o, $(TESTNAMES_ALL)) -o $@

run_obin: obin
	$(RUNENV) $(RUNPROF) ./obin 2>&1 | tee $@.log

help:
	@echo
	@echo "Compiler:		$(OMP_BIN)"
	@echo "LLVM Tool Chain:	$(AOMP)/bin"
	@echo "Offload Targets:	$(TARGET)"
	@echo "Host Target:		$(AOMP_CPUTARGET)"
	@echo "Application Binary:	$(TESTNAME)"
	@echo 
	@echo "This Makefile supports the following flags:"
	@echo 
	@echo "	make $(TESTNAME).ll    // Compile pass only		: -c -S -emit-llvm"
	@echo "	make $(TESTNAME).ll.s  // Backend pass only		: -c -S"
	@echo "	make $(TESTNAME).ll.o  // Assemble pass only		: -c"
	@echo "	make llbin      // Link pass only"
	@echo "	make run_llbin  // Execute llbin"
	@echo 
	@echo "	make $(TESTNAME).s     // Compile & Backend passes	: -c -S"
	@echo "	make $(TESTNAME).s.o   // Assemble pass only		: -c"
	@echo "	make sbin       // Link pass only"
	@echo "	make run_sbin   // Execute sbin"
	@echo 
	@echo "	make $(TESTNAME).o     // Compile, Backend, Assemble	: -c"
	@echo "	make obin       // Link pass only"
	@echo "	make run_obin   // Execute obin"
	@echo 
	@echo "	make            // All passes, build $(TESTNAME)"
	@echo "	make run        // Execute $(TESTNAME) binary"
	@echo 
	@echo "	make clean"
	@echo "	make clean_log"
	@echo "	make help"
	@echo 
	@echo " Environment variables to control compilation & execution"
	@echo "    VERBOSE=1        See lots of compiler messages and driver actions"
	@echo "    TEMPS=1          Do not delete intermediate files"
	@echo "    OFFLOAD_DEBUG=1-4  Runtime diagnostics:"
	@echo "       1 - LIBOMPTARGET"
	@echo "       2 - LIBOMPTARGET_DEVICE_RTL_DEBUG"
	@echo "       3 - LIBOMPTARGET AND LIBOMPTARGET_DEVICE_RTL_DEBUG"
	@echo "       4 - ATMI debug only"
	@echo
	@echo " Compile Environment:  $(SETENV)"
	@echo
	@echo " Run Environment:      $(RUNENV)"
	@echo
	@echo " Compile Flags:        $(CFLAGS) $(EXTRA_CFLAGS)"
	@echo
	@echo " OMP Compile Flags:    $(OMP_FLAGS) $(EXTRA_OMP_FLAGS)"
	@echo
	@echo " Link Flags:           $(LINK_FLAGS) $(EXTRA_LDFLAGS)"
	@echo

#  ----   Demo compilation to LLVM IR and backend steps
ifneq ($(TESTNAME), $(findstring $(TESTNAME),$(TESTNAMES_ALL)))
.PHONY: $(TESTNAME).ll
$(TESTNAME).ll: $(addsuffix .ll, $(TESTNAMES_ALL))
endif

%.ll: %.c*
	$(SETENV) $(CC) -c -S -emit-llvm $(CFLAGS) $(EXTRA_CFLAGS) $(OMP_FLAGS) $^ -o $@

ifneq ($(TESTNAME), $(findstring $(TESTNAME),$(TESTNAMES_ALL)))
.PHONY: $(TESTNAME).ll.s
$(TESTNAME).ll.s: $(addsuffix .ll.s, $(TESTNAMES_ALL))
endif

%.ll.s: %.ll
	$(SETENV) $(CC) -c -S $(OMP_FLAGS) $^ -o $@

ifneq ($(TESTNAME), $(findstring $(TESTNAME),$(TESTNAMES_ALL)))
.PHONY: $(TESTNAME).ll.o
$(TESTNAME).ll.o: $(addsuffix .ll.o, $(TESTNAMES_ALL))
endif

%.ll.o: %.ll.s
	$(SETENV) $(CC) -c $(OMP_FLAGS) $^ -o $@

llbin: $(addsuffix .ll.o, $(TESTNAMES_ALL))
	$(SETENV) $(CC) $(OMP_FLAGS) $(LINK_FLAGS) $^ -o $@

run_llbin: llbin
	$(RUNENV) $(RUNPROF) ./llbin 2>&1 | tee $@.log

#  ----   Demo compilation to assembler/final LL and assembly steps
ifneq ($(TESTNAME), $(findstring $(TESTNAME),$(TESTNAMES_ALL)))
.PHONY: $(TESTNAME).s
$(TESTNAME).s: $(addsuffix .s, $(TESTNAMES_ALL))
endif

%.s: %.c*
	$(SETENV) $(CC) -c -S $(CFLAGS) $(EXTRA_CFLAGS) $(OMP_FLAGS) $^ -o $@

ifneq ($(TESTNAME), $(findstring $(TESTNAME),$(TESTNAMES_ALL)))
.PHONY: $(TESTNAME).s.o
$(TESTNAME).s.o: $(addsuffix .s.o, $(TESTNAMES_ALL))
endif

%.s.o: %.s
	$(SETENV) $(CC) -c $(OMP_FLAGS) $^ -o $@

sbin: $(addsuffix .s.o, $(TESTNAMES_ALL))
	$(SETENV) $(CC) $(OMP_FLAGS) $(LINK_FLAGS) $^ -o $@

run_sbin: sbin
	$(RUNENV) $(RUNPROF) ./sbin 2>&1 | tee $@.log

# Cleanup anything this makefile can create
clean::
	rm -f $(TESTNAME) $(TESTNAME).a llbin sbin obin *.i *.ii *.bc *.lk a.out-* *.ll *.s *.o *.log

clean_log:
	rm -f *.log
