##
# Models (to be passed through stanc)
##

STAN_TARGETS = $(patsubst %.stan,%$(EXE),$(wildcard $(patsubst %$(EXE),%.stan,$(MAKECMDGOALS))))

CMDSTAN_MAIN ?= src/cmdstan/main.cpp
CMDSTAN_MAIN_O = $(patsubst %.cpp,%$(STAN_FLAGS).o,$(CMDSTAN_MAIN))

$(CMDSTAN_MAIN_O) : $(CMDSTAN_MAIN)
	@echo ''
	@echo '--- Compiling the main object file. This might take up to a minute. ---'
	@mkdir -p $(dir $@)
	$(COMPILE.cpp) $(OUTPUT_OPTION) $<

##
# Precompiled model header
##
$(STAN)src/stan/model/model_header$(STAN_FLAGS).d : $(STAN)src/stan/model/model_header.hpp
	$(COMPILE.cpp) $(DEPFLAGS) $<
$(STAN)src/stan/model/model_header$(STAN_FLAGS).d : DEPTARGETS = -MT $(patsubst %.d,%.hpp.gch,$@) -MT $@
$(STAN)src/stan/model/model_header$(STAN_FLAGS).hpp.gch : $(STAN)src/stan/model/model_header.hpp
	@echo ''
	@echo '--- Compiling pre-compiled header. This might take a few seconds. ---'
	$(COMPILE.cpp) $< $(OUTPUT_OPTION)

ifeq ($(CXX_TYPE),clang)
CXXFLAGS_PROGRAM += -include-pch $(STAN)src/stan/model/model_header$(STAN_FLAGS).hpp.gch
$(STAN_TARGETS) examples/bernoulli/bernoulli$(EXE) $(patsubst %.stan,%$(EXE),$(wildcard src/test/test-models/*.stan)) : %$(EXE) : $(STAN)src/stan/model/model_header$(STAN_FLAGS).hpp.gch
endif

ifneq ($(findstring allow_undefined,$(STANCFLAGS))$(findstring allow-undefined,$(STANCFLAGS)),)
$(STAN_TARGETS) examples/bernoulli/bernoulli$(EXE) $(patsubst %.stan,%$(EXE),$(wildcard src/test/test-models/*.stan)) : CXXFLAGS_PROGRAM += -include $(USER_HEADER)
endif

##
# Model executable
##

ifdef STAN_OPENCL
STANCFLAGS+= --use-opencl
endif

%.hpp : %.stan bin/stanc$(EXE)
	@echo ''
	@echo '--- Translating Stan model to C++ code ---'
	$(WINE) bin/stanc$(EXE) $(STANCFLAGS) --o=$(subst  \,/,$@) $(subst  \,/,$<)

%.d: %.hpp

.PRECIOUS: %.hpp
%$(EXE) : %.hpp $(CMDSTAN_MAIN_O) $(LIBSUNDIALS) $(MPI_TARGETS) $(TBB_TARGETS) $(PRECOMPILED_MODEL_HEADER)
	@echo ''
	@echo '--- Compiling, linking C++ code ---'
	$(COMPILE.cpp) $(CXXFLAGS_PROGRAM) -x c++ -o $(subst  \,/,$*).o $(subst \,/,$<)
	$(LINK.cpp) $(subst \,/,$*.o) $(CMDSTAN_MAIN_O) $(LDLIBS) $(LIBSUNDIALS) $(MPI_TARGETS) $(TBB_TARGETS) $(subst \,/,$(OUTPUT_OPTION))
	$(RM) $(subst  \,/,$*).o
ifeq ($(OS),Windows_NT)
ifneq ($(notdir $(shell where tbb.dll)),tbb.dll)
	@echo 'Intel TBB is not in PATH.'
	@echo 'Consider calling '
	@echo '$(HELP_MAKE) install-tbb'
	@echo 'to avoid copying Intel TBB library files.'
	@if ! [[ -f "$(@D)/tbb.dll" ]]; then \
		cp -v $(TBB_TARGETS) $(@D); \
	else \
		echo 'Using existing $(@D)/tbb.dll'; \
	fi
endif
endif

##
# Dependencies file
##
ifneq (,$(STAN_TARGETS))
$(patsubst %$(EXE),%.d,$(STAN_TARGETS)) : DEPTARGETS += -MT $(patsubst %.d,%$(EXE),$@) -include $< -include $(CMDSTAN_MAIN)
-include $(patsubst %$(EXE),%.d,$(STAN_TARGETS))
-include $(patsubst %.cpp,%$(STAN_FLAGS).d,$(CMDSTAN_MAIN))
ifeq ($(PRECOMPILED_HEADERS),true)
-include $(STAN)src/stan/model/model_header$(STAN_FLAGS).d
endif
endif
