# SPDX-License-Identifier: BSD-2-Clause
# 
# Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# makefile for libcifpp

.PHONY: firstTarget
firstTarget: all

CXX					= @CXX@
CXXFLAGS			= @BOOST_CPPFLAGS@ \
					  @CPPFLAGS@ \
					  @CXXFLAGS@ \
					  @PTHREAD_CFLAGS@
LDFLAGS				= @BOOST_LDFLAGS@ \
					  @LDFLAGS@ \
					  @LIBS@
LIBS				= @PTHREAD_LIBS@ \
					  @BOOST_IOSTREAMS_LIB@ \
					  @BOOST_DATE_TIME_LIB@ \
					  @BOOST_REGEX_LIB@ \
					  @LIBS@

prefix				= $(DESTDIR)@prefix@
exec_prefix			= @exec_prefix@
libdir				= @libdir@
includedir			= @includedir@
datarootdir			= @datarootdir@
datadir				= @datadir@
docdir				= @docdir@
pkgconfigdir		= $(libdir)/pkgconfig

CCP4DIR				= @CCP4@
CLIBD				= $(CCP4DIR:%=%/lib/data)

CACHE_DIR			= $(DESTDIR)@DATA_CACHE_DIR@
DATA_DIR			= @DATA_LIB_DIR@
CRON_DIR			= $(DESTDIR)/etc/cron.weekly

DEFINES				+= CACHE_DIR='"$(CACHE_DIR)"' DATA_DIR='"$(DATA_DIR)"'
DEFINES				+= USE_RSRC=@USE_RSRC@

GNUmakefile: config.status GNUmakefile.in
	$(SHELL) ./config.status

LIB_NAME			= @PACKAGE_NAME@
LIB_VERSION			= @LIBCIF_LT_VERSION@
LIB_CURRENT			= @LIBCIF_LT_CURRENT@
LIB_TARGET			= $(LIB_NAME).la
VERSION             = @LIBCIF_SEMANTIC_VERSION@
DIST_NAME           = @PACKAGE_NAME@-$(subst :,.,$(VERSION))

# libtool stuff

LIBTOOL_DEPS = @LIBTOOL_DEPS@
libtool: $(LIBTOOL_DEPS)
	$(SHELL) ./config.status libtool

LIBTOOL = $(SHELL) @abs_top_builddir@/libtool
CXXCOMPILE = $(LIBTOOL) --silent --tag=CXX --mode=compile $(CXX) $(CXXFLAGS)
CXXLINK = $(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) $(CXXFLAGS) $(LDFLAGS) -version-info $(LIB_VERSION) -o $@

# main build variables
CXXFLAGS            += -Wall -Wno-multichar -I include

# Use the DEBUG flag to build debug versions of the code
DEBUG               = @DEBUG@

ifeq "$(DEBUG)" "1"
DEFINES				+= DEBUG
CXXFLAGS            += -g -O0
LDFLAGS				+= -g
else
CXXFLAGS			+= -O2
DEFINES				+= NDEBUG
endif

# targets

VPATH += src:test

CXXFLAGS			+= $(DEFINES:%=-D%)

OBJDIR = obj
ifeq "$(DEBUG)" "1"
	OBJDIR	:= $(OBJDIR).dbg
endif

$(OBJDIR):
	mkdir -p $(OBJDIR)

OBJECTS		= $(OBJDIR)/AtomType.lo \
			  $(OBJDIR)/Cif2PDB.lo \
			  $(OBJDIR)/Cif++.lo \
			  $(OBJDIR)/CifParser.lo \
			  $(OBJDIR)/CifUtils.lo \
			  $(OBJDIR)/CifValidator.lo \
			  $(OBJDIR)/Compound.lo \
			  $(OBJDIR)/PDB2Cif.lo \
			  $(OBJDIR)/PDB2CifRemark3.lo \
			  $(OBJDIR)/Point.lo \
			  $(OBJDIR)/Secondary.lo \
			  $(OBJDIR)/Structure.lo \
			  $(OBJDIR)/Symmetry.lo \
			  $(OBJDIR)/TlsParser.lo

ifneq "$(CCP4DIR)" ""

# Special rules to generate symmetry operation number table
tools/symop-map-generator: tools/symop-map-generator.cpp

src/SymOpTable_data.cpp: tools/symop-map-generator $(CLIBD)/symop.lib
	tools/symop-map-generator $@

$(OBJDIR)/Symmetry.lo: src/SymOpTable_data.cpp

endif

# We have development releases and official releases, for each we
# maintain different versioning schemes.

ifneq "x@UPDATE_REVISION@" "x"

REVISION = $(shell git log --pretty=format:%h --max-count=1)
REVISION_FILE = version-info-$(REVISION).txt

$(REVISION_FILE):
	rm -f version-info-*.txt
	@ echo libcifpp-version: $(VERSION) > $@
	@ git describe --match=build --dirty >> $@
	@ git log --pretty=medium --date=iso8601 -1 >> $@

src/revision.hpp: $(REVISION_FILE)
	@ echo 'const char kRevision[] = R"(' > $@
	@ cat $? >> $@
	@ echo ')";' >> $@

else

src/revision.hpp:
	@ echo 'const char kRevision[] = R"(' > $@
	@ echo libcifpp-version: $(VERSION) >> $@
	@ echo Date:   $$(TZ=GMT date +"%Y-%m-%d") >> $@
	@ echo ')";' >> $@

endif

$(OBJDIR)/CifUtils.o: src/revision.hpp

$(OBJDIR)/CifUtils.lo: src/revision.hpp
$(LIB_TARGET): $(OBJECTS)
	$(CXXLINK) -rpath $(libdir) $(OBJECTS) $(LIBS)

.PHONY: lib
lib: $(LIB_TARGET)

.PHONY: all
all: $(LIB_TARGET)

-include $(OBJECTS:%.lo=%.d)

$(OBJECTS:.lo=.d):

$(OBJDIR)/%.lo: %.cpp | $(OBJDIR)
	@ echo ">>" $<
	@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(OBJDIR)/$*.d -c -o $@ $<

$(OBJDIR)/%.o: %.cpp | $(OBJDIR)
	@ echo ">>" $<
	@ $(CXX) $(CXXFLAGS) -MT $@ -MD -MP -MF $(OBJDIR)/$*.d -c -o $@ $<

.PHONY: clean
clean:
	rm -rf .libs $(OBJDIR)/* $(LIB_TARGET)
	rm -f $(TESTS:%=test/%-test)

.PHONY: distclean
distclean: clean
	rm -f libtool config.lt
	rm -f config.status config.cache config.log configure.lineno config.status.lineno
	rm -f GNUmakefile

# Test rules

define TEST_template =

-include $$(OBJDIR)/$(1)-test.d

$(1)_OBJECTS = $$(OBJDIR)/$(1)-test.o

test/$(1)-test: $(LIB_TARGET) $$($(1)_OBJECTS)
	@ echo ">>> building $(1)-test"
	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcifpp -lboost_program_options $(LIBS)

.PHONY: $(1)-test
$(1)-test: test/$(1)-test
	cd test; LD_LIBRARY_PATH=../.libs ./$(1)-test $$($(1)_PARAMS)

endef

TESTS = unit # pdb2cif

$(foreach part,$(TESTS),$(eval $(call TEST_template,$(part))))

.PHONY: test
test: $(TESTS:%=%-test)

HEADERS = \
	AtomType.hpp \
	CifParser.hpp \
	Compound.hpp \
	PDB2CifRemark3.hpp \
	Structure.hpp \
	Cif2PDB.hpp \
	CifUtils.hpp \
	Point.hpp \
	Symmetry.hpp \
	Cif++.hpp \
	CifValidator.hpp \
	PDB2Cif.hpp \
	Secondary.hpp \
	TlsParser.hpp

.PHONY: install
install: lib
	install -d $(libdir)
	$(LIBTOOL) --mode=install install $(LIB_TARGET) $(libdir)
	install -d $(datadir)/libcifpp
	install -m644 rsrc/isomers.txt $(datadir)/libcifpp;
	gzip -f $(datadir)/libcifpp/isomers.txt
	for d in mmcif_ddl.dic mmcif_pdbx_v50.dic; do \
		install -m644 rsrc/$$d $(datadir)/libcifpp; \
		gzip -f $(datadir)/libcifpp/$$d; \
	done
	install -d $(CRON_DIR)
	install -m755 tools/update-dictionary-script $(CRON_DIR)/libcifpp
	install -d $(includedir)/cif++
	for f in $(HEADERS); do install include/cif++/$$f $(includedir)/cif++/$$f; done
	install -d $(pkgconfigdir)
	install -m 644 $(LIB_NAME).pc $(pkgconfigdir)/$(LIB_NAME).pc

dist-clean: clean

.PHONY: dist
dist:
	rm -rf $(DIST_NAME)
	mkdir $(DIST_NAME)
	git archive trunk | tar -x -C $(DIST_NAME)
	tar czf $(DIST_NAME).tgz $(DIST_NAME)
	rm -rf $(DIST_NAME)

FORCE:
