# RCG Makefile

SHELL = /bin/sh

top_srcdir := `readlink -m @top_srcdir@`
srcdir := `readlink -m @srcdir@`
bld_dir:= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
models_dir:= $(bld_dir)/models
bld_utils_dir:= $(bld_dir)/utils
linux_version := '@linux_version@'
VPATH=$(srcdir)

prefix      = @prefix@
exec_prefix = @exec_prefix@
bindir      = @bindir@
infodir     = @infodir@
mandir      = @mandir@
infodir     = @infodir@
libdir      = @libdir@
datarootdir      = @datarootdir@

CXX=@CXX@
CC=@CC@
LIBS=@LIBS@
DEBUGFLAGS=-g
PERFORMANCEFLAGS=-DNDEBUG -g -O5
RELEASEFLAGS=-DNDEBUG -DNPROBE -g -O5
#DEBUGFLAGS=-DNDEBUG -O5 -unroll=16
DEVFLAGS=@DEVFLAGS@
NUM_BUILD_THREDS?=1

define DIE
(tail $(bld_log); cat $(err_log) && /bin/false)
endef

%: clean-%

	@# Set path variables so we don't need the whole path everywhere
	$(eval model_bld_dir := $(bld_dir)/models/$@/)
	$(eval target_dir := $(model_bld_dir)/target/)
	$(eval model_log_dir := $(bld_dir)/models/$@/logs)
	$(eval err_log := $(model_log_dir)/$@_error.log)
	$(eval bld_log := $(model_log_dir)/$@.log)
	$(eval kern_bld_dir := $(model_bld_dir)/kernel_mod/)
	$(eval us_bld_dir := $(model_bld_dir)/userspace/)
	$(eval epics_dir := $(model_bld_dir)/epics/)
	$(eval epics_src_dir := $(epics_dir)/src/)
	$(eval epics_build_dir := $(target_dir)/$@epics/)
	$(eval bld_info_dir := $(target_dir)/build_info/)
	$(eval target_bin_dir := $(target_dir)/bin/)



	@mkdir -p $(bld_utils_dir)/epics/util $(models_dir) $(epics_dir)/fmseq $(models_dir)/$@/include $(model_log_dir)
	@mkdir -p $(target_dir)/ $(target_bin_dir)/
	@ln -fs $(srcdir)/src/epics/util/lib $(bld_utils_dir)/epics/util > /dev/null 2>&1 || /bin/true
	@ln -fs $(srcdir)/src/epics/simLink $(bld_utils_dir)/epics > /dev/null 2>&1 || /bin/true
	@ln -fs $(srcdir)/src/epics/util/Makefile.kernel $(bld_utils_dir)/epics/util > /dev/null 2>&1 || /bin/true
	@ln -fs $(srcdir)/src/epics/util/Userspace_CMakeLists.cmake $(bld_utils_dir)/epics/util > /dev/null 2>&1
	@cp $(srcdir)/support/symvers/ModuleIOP.symvers $(models_dir)/
	@cp $(srcdir)/src/epics/util/checkForErrors.sh $(bld_utils_dir)

	@echo Parsing the model $@...
	@srcdir=$(srcdir)/src/epics/util/ make -C $(bld_utils_dir)/epics/util -sf Makefile $@ > $(bld_log) 2>$(err_log) || $(DIE)
	@echo Done
	@/bin/rm -rf $(epics_dir)/$@epics-medm
	@/bin/rm -rf $(epics_dir)/$@epics-config
	@/bin/mv -f  $(epics_src_dir)/medm $(epics_dir)/$@epics-medm
	@/bin/mv -f  $(epics_src_dir)/config $(epics_dir)/$@epics-config
	@/bin/rm -rf $(epics_build_dir)/ $(epics_src_dir)/;

	@echo Building EPICS sequencers...
	@env RCG_SRC_DIR=$(srcdir) PERL5LIB=$(srcdir)/src/epics/util make -f $(epics_dir)/Makefile.$@epics >> $(bld_log) 2>>$(err_log) || $(DIE)
	@echo Done
	@($(srcdir)/src/epics/util/nameLengthChk.pl $@ $(epics_src_dir)/ $(epics_build_dir)/ ) >> $(bld_log) 2>>$(err_log) || $(DIE)
	@/bin/mkdir -p $(epics_src_dir)
	@/bin/mv -f $(epics_dir)/$@epics-medm $(epics_src_dir)/medm
	@/bin/mv -f $(epics_dir)/$@epics-config $(epics_src_dir)/config
	

ifndef RCG_BUILD_NO_KOBJ
	@echo Building front-end Linux kernel module $@...
	@make -j $(NUM_BUILD_THREDS) -C $(kern_bld_dir) >> $(bld_log) 2>>$(err_log) || $(DIE)
	@$(srcdir)/src/epics/util/checkUndefined.pl $(err_log) >> $(bld_log) 2>>$(err_log) || $(DIE)
	@mv $(kern_bld_dir)/$@.ko $(target_bin_dir)
	@echo Done
endif

ifdef RCG_BUILD_USP
	@echo Building front-end user space object $@...
	@if [ ! -L $(us_bld_dir)/src ]; then ln -s $(srcdir)/src/ $(us_bld_dir)/src; fi
	@mkdir -p $(us_bld_dir)/build
	@cmake -B$(us_bld_dir)/build/ -S$(us_bld_dir) -DMODEL_NAME=$@ >> $(bld_log) 2>>$(err_log) || $(DIE)
	@make -j $(NUM_BUILD_THREDS) -C $(us_bld_dir)/build >> $(bld_log) 2>>$(err_log) || $(DIE)
	@mv $(us_bld_dir)/build/$@ $(target_bin_dir)
	@echo Done
endif

	@#Save build config and source files for traceability
	@/bin/mkdir -p $(bld_info_dir)
	@echo $(srcdir) > $(bld_info_dir)/rcg_location.txt
	@(cd $(srcdir) && git rev-parse HEAD) > $(bld_info_dir)/rcg_git_hash.txt
	@(cd $(srcdir) && git --no-pager diff) > $(bld_info_dir)/rcg_git_diff.txt
	@echo Build date `date` > $(bld_info_dir)/build.txt
	@echo Compiled on `hostname` >> $(bld_info_dir)/build.txt
	@echo RCG_LIB_PATH=${RCG_LIB_PATH} >> $(bld_info_dir)/build.txt
	@tar Ccf $(srcdir) - --exclude rcg.tar.gz --exclude $(epics_build_dir)/   . | gzip > $(bld_info_dir)/rcg.tar.gz
	@cp $(epics_dir)/sources.$@ $(bld_info_dir)/src_locations.txt
	@cp $(bld_log) $(bld_info_dir)
	@cp $(err_log) $(bld_info_dir)
	@sort $(epics_dir)/sources.$@ | uniq |  tar czTf - $(bld_info_dir)/sources.tar.gz > /dev/null 2>&1

	@echo RCG source code directory:
	@echo $(srcdir)
	@echo The following files were used for this build:
	@sort $(epics_dir)/sources.$@ | uniq
	@echo
	@echo  Successfully compiled $@
	@echo '***********************************************'
	@echo  Compile Warnings, found in $(model_log_dir)/$@_warnings.log:
	@echo '***********************************************'
	@cat   $(model_log_dir)/$@_warnings.log 
	@echo '***********************************************'


all: 
	/bin/true

.PHONY : doc
doc:	
	(cd doc && bash ./doxScript && doxygen doxygen.cfg)

reclean:
	-/bin/rm -rf build config src target

clean-%:
	@system=$(subst clean-,,$@); echo Cleaning $${system}...; \
        /bin/rm -rf  models/$${system}/target/; \
        (make -siC $(models_dir)/$${system}/Makefile clean 2>/dev/null); echo Done;

install-adclist-%:
	@system=$(subst install-adclist-,,$@); $(srcdir)/install-adclist $${system} $(srcdir)

install-%:
	@system=$(subst install-,,$@); $(srcdir)/install $${system} $(srcdir)

uninstall-%:
	@system=$(subst uninstall-,,$@); $(srcdir)/uninstall $${system} $(srcdir)


MDL_MODELS = $(shell if [ -e /etc/rt.sh ]; then /etc/rt.sh; fi)


World: $(MDL_MODELS)
	@echo Successfully compiled $(MDL_MODELS)

startWorld:
	@echo $(patsubst %,start% \;,$(MDL_MODELS))

killWorld:
	@echo $(patsubst %,kill% \;,$(MDL_MODELS))

showWorld:
	@echo $(MDL_MODELS)

# Extract all "ai" Epics record (setpoints) and print SQL commands to insert into the Archiver database
settingsWorld:
	@for i in $(MDL_MODELS); do grep grecord\(ai /opt/rtcds/lho/h1/target/$$i/$${i}epics/db/H1/$${i}1.db; done | sed 's/grecord(ai,"\(.*\)")/\1/g' | awk "{ printf \"insert into channel (name, grp_id) values ('%s', 1);\n\", \$$0 }"

cleanWorld: $(patsubst %,clean-%,$(MDL_MODELS))
	@echo Cleaned $(MDL_MODELS)

installWorld: $(patsubst %,install-%,$(MDL_MODELS)) 
	@echo Installed $(MDL_MODELS)

installAdclistWorld: $(patsubst %,install-adclist-%,$(MDL_MODELS)) 
	@echo Installed $(MDL_MODELS)

# For test builds of IFO models
cdstest:=$(USERAPPS_DIR)/cds/test/scripts
TST_MODELS = $(shell if [ -e $(cdstest)/rt-allmodels.sh ]; then $(cdstest)/rt-allmodels.sh; fi)

WorldTest: $(TST_MODELS)
	@echo Successfully compiled $(TST_MODELS)

showWorldTest:
	@echo $(TST_MODELS)

cleanWorldTest: $(patsubst %,clean-%,$(TST_MODELS))
	@echo Cleaned $(TST_MODELS)

installWorldTest: $(patsubst %,install-%,$(TST_MODELS)) 
	@echo Installed $(TST_MODELS)

# Show all predefined preprocessor definitions
dump_predefines:
	gcc -E -dM -x c /dev/null
