# This makefile requires the CXXWRAP_PREFIX and JL_SHARE to be set.
#
# make CXXWRAP_PREFIX=... JL_SHARE=...
#
BUILD_DIR = build
ROOT_CONFIG = root-config
UNAME=$(shell uname)

ROOT_LIBS = $(shell $(ROOT_CONFIG) --libs) -lGeom
ROOT_INC_DIR = $(shell $(ROOT_CONFIG) --incdir)

JULIA = julia

CPPFLAGS = -MMD -I. -I $(CXXWRAP_PREFIX)/include
#JCXX_HAS_RANGE must be set to 0 if libcxxwrap_julia_stl.so was compiled without std::ranges support
#JLCXX_HAS_RANGE = isdefined(CxxWrap.StdLib, :HAS_RANGES) ? 1 : 0
#Disable dependencies on std::ranges if libcxxwrap_julis_stl.so was compiled without it
ifeq ($(JLCXX_HAS_RANGES), 0)
   CPPFLAGS += -DJLCXX_FORCE_RANGES_OFF
endif
CXXFLAGS = $(patsubst -std=gnu%,,$(shell $(JL_SHARE)/julia-config.jl --cflags))
CXXFLAGS += $(shell $(ROOT_CONFIG) --cflags)
CXXFLAGS += -I$(VDT_DIR)/include
CXXFLAGS += -O2
CXXFLAGS += -Wno-c++20-extensions
#CXXFLAGS += -DVERBOSE_IMPORT #To enable the verbose mode of the libray loading
#CXXFLAGS += -Wall -O0 -g     #To compile with debugger infomation
LDFLAGS = $(shell $(JL_SHARE)/julia-config.jl --ldflags)
LDLIBS = $(shell $(JL_SHARE)/julia-config.jl --ldlibs) -L$(CXXWRAP_PREFIX)/lib -lcxxwrap_julia -lcxxwrap_julia_stl

CXX_IS_CLANG = $(shell $(CXX) -dM -E - < /dev/null | grep -c __clang__)

VERBOSE = no#use -DVERBOSE to enable verbosity
# Verbose output
ifeq ($(VERBOSE), no)
    Q = @
else
    Q =
endif

ifeq ($(UNAME),Darwin)
  SO_SUFFIX = .dylib
else
  SO_SUFFIX = .so
endif

ifneq ($(CXX_IS_CLANG), 0)
	CXXFLAGS += -ferror-limit=3
	PCH_SUFFIX=.pch
else #assuming gcc
	CXXFLAGS += -fmax-errors=3
	PCH_SUFFIX=.gch
endif


LINK.o = $(CXX) $(LDFLAGS) $(TARGET_ARCH)

.PHONY: all clean distclean run_demo run_demo2 check_root make_lib_from_objs

PRODUCTS = $(BUILD_DIR)/libroot_julia$(SO_SUFFIX)

#Define WRAPPER_CXX
#WRAPPER_CXX: = $(file < src/generated_cxx) Extra.cxx #does not work on MacOS
include generated_cxx.make

OBJS = $(addprefix $(BUILD_DIR)/, $(patsubst %.cxx,%.o, $(WRAPPER_CXX)))
DEPS = $(patsubst %.o,%.d, $(OBJS))

all: $(PRODUCTS)

clean:
	-$(RM) -r $(BUILD_DIR)

distclean:
	-$(RM) -r $(BUILD_DIR) build build.log
	-$(RM) $(PRODUCTS)

check_root:
ifeq ($(ROOT_LIBS),)
	$(error ERROR: "Command root-config not found. ROOT (http:://root.cern.ch) environment needs to be set")
endif

run_demo: all
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) JULIA_LOAD_PATH=.:@:@v#.#:@stdlib "$(JULIA)" -i demo_ROOT.jl

run_demo2: all
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) JULIA_LOAD_PATH=.:@:@v#.#:@stdlib "$(JULIA)" -i demo_TGraph.jl

test: all
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) \
JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. demo_ROOT.jl
	cmp demo_ROOT.png demo_ROOT-ref.png
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) \
JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. demo_TGraph.jl
	cmp demo_TGraph.png demo_TGraph-ref.png
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) \
JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. TTree_examples/write_tree1.jl \
&& JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. TTree_examples/read_tree1.jl
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) \
JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. TTree_examples/write_tree2.jl \
&& JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. -e 'import Pkg; Pkg.activate(;temp=true); Pkg.add("UnROOT"); include("TTree_examples/read_tree2.jl")'
	LD_LIBRARY_PATH=$(shell $(ROOT_CONFIG) --libdir) \
JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. TTree_examples/write_tree3.jl \
&& JULIA_LOAD_PATH=`pwd`/build/ROOT/src:$(JULIA_LOAD_PATH): "$(JULIA)" --project=.. TTree_examples/read_tree3.jl

#$(BUILD_DIR)/pch.h: 
#	$(Q) [ -d $(BUILD_DIR)/libROOT/build ] || mkdir -p $(BUILD_DIR)/libROOT/build
#	echo '#include "Wrapper.h"\n#include "jlROOT.h"\n#include "jlcxx/functions.hpp"\n#include "jlcxx/stl.hpp"\n' > $@
#
#$(BUILD_DIR)/%.h$(PCH_SUFFIX): $(BUILD_DIR)/%.h
#	@echo "Precompile the header files."
#	$(Q) $(COMPILE.cc) $(CPPFLAGS) -I src -x c++-header -o $@ $<

$(BUILD_DIR)/pch.h$(PCH_SUFFIX):
	@echo "Precompile the header files."
	$(Q) [ -d $(BUILD_DIR)/include ] || mkdir -p $(BUILD_DIR)/include
	$(Q)echo '#include "Wrapper.h"\n#include "jlROOT.h"\n#include "jlcxx/functions.hpp"\n#include "jlcxx/stl.hpp"\n' > $(BUILD_DIR)/include/pch.h
	$(Q) $(COMPILE.cc) -Isrc -x c++-header -o $@ $(BUILD_DIR)/include/pch.h

$(BUILD_DIR)/%.o: src/%.cxx $(BUILD_DIR)/pch.h$(PCH_SUFFIX)
	@echo "Make $(notdir $@)"
	$(Q) [ -d $(BUILD_DIR) ] || mkdir -p $(BUILD_DIR)
	$(Q) $(COMPILE.cc) -include $(BUILD_DIR)/pch.h -o $@ $<

$(BUILD_DIR)/libroot_julia$(SO_SUFFIX): $(OBJS)
	@echo "Make $(notdir $@)"
	$(Q) $(MAKE) check_root
	$(Q) $(LINK.o) -o $@ --shared -fPIC $(OBJS) $(ROOT_LIBS) $(LDLIBS)

echo_%:
	@echo "$* = $(subst ",\",$($*))"

-include $(DEPS)
