#==========================================================================#
# This is a 'makefile.in' template with '@CXX@' and '@CXXFLAGS@' parameters.
# This makefile requires GNU make.
#==========================================================================#

# The '../scripts/make-build-header.sh' script searches for the next two
# lines to figure out the compiler and compilation flags.  This information
# is then used to generate corresponding macros in 'build.hpp'.

CXX=@CXX@
CXXFLAGS=@CXXFLAGS@

CC=@CC@
CFLAGS=@CFLAGS@

LIBS=@LIBS@
CONTRIB=@CONTRIB@
IPASIR=@IPASIR@

############################################################################
#    It is usually not necessary to change anything below this line!       #
############################################################################

SRC_APP=cadical.cpp mobical.cpp

SRC_IPASIR=src/ipasir.cpp
SRC_SOLVER=$(subst ../src/,,$(sort $(wildcard ../src/*.cpp)))
SRC_CONTRIB=$(subst ../contrib/,,$(sort $(wildcard ../contrib/*.cpp)))
SRC_C=$(subst ../src/,,$(sort $(wildcard ../src/*.c)))

FILT_SOLVER=$(filter-out $(SRC_APP),$(SRC_SOLVER))
FILT_SOLVER:=$(if $(filter-out no,$(IPASIR)),$(FILT_SOLVER),$(filter-out $(SRC_IPASIR), $(FILT_SOLVER)))
FILT_CONTRIB=$(if $(filter-out no,$(CONTRIB)),$(SRC_CONTRIB),)
OBJ_SOLVER=$(FILT_SOLVER:.cpp=.o)
OBJ_CONTRIB=$(FILT_CONTRIB:.cpp=.o) $(SRC_C:.c=.o)

# Include for the current build directory is required for including the
# generated build header 'build.hpp'.

DIR=../$(shell pwd|sed -e 's,.*/,,')
COMPILE_CPP=$(CXX) $(CXXFLAGS) -I$(DIR) -I../src
COMPILE_CCC=$(CC) $(CFLAGS) -I$(DIR) -I../src

#--------------------------------------------------------------------------#

all: @GOALS@

#--------------------------------------------------------------------------#

.SUFFIXES: .cpp .o .c


%.o: ../*/%.c ../src/*.h makefile
	$(COMPILE_CCC) -x c -c $< -o $@


%.o: ../*/%.cpp ../src/*.hpp makefile
	$(COMPILE_CPP) -c $<

#--------------------------------------------------------------------------#

# Application binaries (the stand alone solver 'cadical' and the model based
# tester 'mobical') and the library are the main build targets.

cadical: cadical.o libcadical.a makefile
	$(COMPILE_CPP) -o $@ $< -L. libcadical.a $(LIBS)

cadical-dynamic: cadical.o libcadical.so makefile
	$(COMPILE_CPP) -o $@ $< -L. libcadical.so $(LIBS)

mobical: mobical.o libcadical.a makefile $(LIBS)
	$(COMPILE_CPP) -o $@ $< -L. libcadical.a

libcadical.a: $(OBJ_SOLVER) $(OBJ_CONTRIB) makefile
	ar rc $@ $(OBJ_SOLVER) $(OBJ_CONTRIB)

libcadical.so: $(OBJ_SOLVER) $(OBJ_CONTRIB) $(LIBS) makefile
	$(COMPILE_CPP) -shared -o $@ $(OBJ_SOLVER) $(OBJ_CONTRIB) $(LIBS)

#--------------------------------------------------------------------------#

# Note that 'build.hpp' is generated and resides in the build directory.

build.hpp: always
	../scripts/make-build-header.sh > build.hpp

version.o: build.hpp

update:
	../scripts/update-version.sh

#--------------------------------------------------------------------------#

# These two 'C' interfaces include '.h' headers and thus require explicitly
# defined additional dependencies.

ccadical.o: ../src/ccadical.h
ipasir.o: ../src/ipasir.h ../src/ccadical.h


#--------------------------------------------------------------------------#

analyze: all
	$(COMPILE_CPP) --analyze ../src/*.cpp
	$(COMPILE_CPP) --analyze ../contrib/*.cpp

format:
	clang-format -i ../*/*.[ch]pp
	clang-format -i ../*/*.[ch]
	clang-format -i ../test/*/*.[ch]pp
	clang-format -i ../test/*/*.[ch]

clean:
	rm -f *.o *.a cadical mobical makefile build.hpp
	rm -f *.gcda *.gcno *.gcov gmon.out

test: all
	CADICALBUILD="$(DIR)" $(MAKE) -j1 -C ../test

#--------------------------------------------------------------------------#

.PHONY: all always analyze clean test update format
