#! /usr/bin/make -f

include /usr/share/dpkg/architecture.mk

# eventually add -O3 -march=native -mtune=native
export DEB_BUILD_MAINT_OPTIONS = qa=-bug-implicit-func
export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_CXXFLAGS_MAINT_APPEND  = -Wall -pedantic
export DEB_FFLAGS_MAINT_APPEND  = -std=legacy
export DEB_LDFLAGS_MAINT_STRIP = -Wl,-Bsymbolic-functions

# DEB_BUILD_MAINT_OPTIONS qa is ignored on powerpc, Bug#1082275
ifeq ($(DEB_HOST_ARCH),powerpc)
  DEB_CFLAGS_MAINT_APPEND += -Wno-error=implicit-function-declaration
endif

ifneq (,$(wildcard /usr/share/mpi-default-dev/debian_defaults))
include /usr/share/mpi-default-dev/debian_defaults
endif
DEFAULT_MPI=$(ARCH_DEFAULT_MPI_IMPL)

empty :=
space := $(empty)$(empty)

export MPI_SUPPORTED=
ifneq (,$(findstring $(space)$(DEB_HOST_ARCH)$(space), $(space)$(OPENMPI_AVAILABLE_ARCHITECTURES)$(space)))
  MPI_SUPPORTED += openmpi
endif
ifneq (,$(findstring $(space)$(DEB_HOST_ARCH)$(space), $(space)$(MPICH_AVAILABLE_ARCHITECTURES)$(space)))
  MPI_SUPPORTED += mpich
endif

include /usr/share/dpkg/pkg-info.mk
SCALAPACK_UPSTREAM_VERSION=$(DEB_VERSION_UPSTREAM)
SCALAPACK_X_Y_VERSION=$(shell echo $(SCALAPACK_UPSTREAM_VERSION) | sed "s/^\(.*\)\.\([^.]*\)$$/\1/")
export SCALAPACK_SOVERSION=$(SCALAPACK_X_Y_VERSION)

# 64-bit build is not supported on all arches
ifeq (64,$(DEB_HOST_ARCH_BITS))
  BIT_BUILDS = 32 64
else
  BIT_BUILDS = 32
  export DH_OPTIONS += \
	-Nlibscalapack64-mpi-dev \
	-Nlibscalapack64-openmpi-dev -Nlibscalapack64-openmpi${SCALAPACK_SOVERSION} \
	-Nlibscalapack64-mpich-dev -Nlibscalapack64-mpich${SCALAPACK_SOVERSION}
endif

%:
	dh $@ --buildsystem=cmake

export PRTE_MCA_plm_ssh_agent=/bin/false                #workaround to start MPI-applications in chroot

export NUMJOBS=1
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
export NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
endif

extra_flags += \
 -DBUILD_SHARED_LIBS=ON \
 -DSCALAPACK_BUILD_TESTS=ON \
 -DBLA_VENDOR=Generic

# BLA_SIZEOF_INTEGER is a cmake FindLAPACK variable to find 32- or 64-bit interfaces
extra_64bit_flags += \
	-DLIBNAME_SUFFIX=64 \
	-DBLA_SIZEOF_INTEGER=8

common_Fortran_FLAGS=-cpp
Fortran_FLAGS_64=-fdefault-integer-8 -DTEST_INT64=1
C_FLAGS_64=-DInt=long

execute_after_dh_clean:
	cd BLACS/INSTALL; rm -rf xintface Makefile CMakeCache.txt cmake_install.cmake CMakeFiles
	cd PBLAS; rm -f TESTING/PB_Cabort.c TESTING/PB_Cwarn.c TIMING/PB_Cabort.c TIMING/PB_Cwarn.c
	rm -rf build*-openmpi build*-mpich

override_dh_auto_configure-indep:
override_dh_auto_build-indep:
override_dh_auto_install-indep:
override_dh_auto_test-indep:


override_dh_auto_configure-arch:
	for flavor in $(MPI_SUPPORTED); do \
	for BITS in $(BIT_BUILDS); do \
	  if [ $$BITS = 64 ]; then \
	    LIBNAME_SUFFIX=64; \
	    bit_flags='$(extra_64bit_flags)'; \
	    extra_C_FLAGS="$(C_FLAGS_64)"; \
	    extra_Fortran_FLAGS="$(Fortran_FLAGS_64)"; \
	  else \
	    LIBNAME_SUFFIX=; \
	    bit_flags=; \
	    extra_C_FLAGS=; \
	    extra_Fortran_FLAGS=; \
	  fi; \
	  echo "Configure for libscalapack$${LIBNAME_SUFFIX}-$${flavor}" ; \
	  dh_auto_configure --builddirectory=build$${LIBNAME_SUFFIX=}-$${flavor} -- $(extra_flags) $${bit_flags} \
	    "-DCMAKE_C_FLAGS=$(CFLAGS) $${extra_C_FLAGS}"  \
	    "-DCMAKE_Fortran_FLAGS=$(FFLAGS) $(common_Fortran_FLAGS) $${extra_Fortran_FLAGS}" \
	    -DMPI_C_COMPILER=mpicc.$$flavor -DMPI_Fortran_COMPILER=mpif90.$$flavor \
	    -DMPIEXEC_EXECUTABLE=/usr/bin/mpiexec.$$flavor -DMPI_FLAVOR=$$flavor ; \
	done; done

override_dh_auto_build-arch:
	for flavor in $(MPI_SUPPORTED); do \
	for BITS in $(BIT_BUILDS); do \
	  if [ $$BITS = 64 ]; then \
	    LIBNAME_SUFFIX=64; \
	  else \
	    LIBNAME_SUFFIX=; \
	  fi; \
	  echo "Building libscalapack$${LIBNAME_SUFFIX}-$${flavor}" ; \
	  dh_auto_build -O--parallel --builddirectory=build$${LIBNAME_SUFFIX}-$${flavor} ; \
	done; done

override_dh_auto_install-arch:
	echo "scalapack-mpi-dev=libscalapack-$(DEFAULT_MPI)-dev" > debian/libscalapack-mpi-dev.substvars
	echo "scalapack64-mpi-dev=libscalapack64-$(DEFAULT_MPI)-dev" > debian/libscalapack64-mpi-dev.substvars
	for flavor in $(MPI_SUPPORTED); do \
	for BITS in $(BIT_BUILDS); do \
	  if [ $$BITS = 64 ]; then \
	    LIBNAME_SUFFIX=64; \
	  else \
	    LIBNAME_SUFFIX=; \
	  fi; \
	  echo "Installing scalapack$${LIBNAME_SUFFIX}-$${flavor}" ; \
	  dh_auto_install -O--parallel --builddirectory=build$${LIBNAME_SUFFIX}-$${flavor} ; \
	done; done

execute_after_dh_install-arch:
	dh_missing --list-missing
	# test executables contain RUNPATH. Remove it.
	chrpath -d debian/scalapack-mpi-test/usr/lib/$(DEB_HOST_MULTIARCH)/scalapack/*-tests/x*
	chrpath -d debian/scalapack-mpi-test/usr/lib/$(DEB_HOST_MULTIARCH)/scalapack/*-tests/PBLAS/*tst
	chrpath -d debian/scalapack-mpi-test/usr/lib/$(DEB_HOST_MULTIARCH)/scalapack/*-tests/PBLAS/TIMING/*tim


# add --max-parallel=1 to force test in sequential mode
# MPICH testsuite disabled as some tests fail -- why???

# Note: openmpi tests routinely (but unreproducibly) fail on some buildds,
# so don't let test failure halt the build on these arches (but let the tests run)
ARCH_TEST_IGNORE_FAILURE=mips64el

# On some other arches, openmpi3 tests never exit (don't even timeout),
# so skip their tests altogether until a workaround or fix is known.
ARCH_NO_OPENMPI_TEST_LIST=armel armhf i386 mipsel powerpc

# The hppa build does complete, but takes a full day to timeout on half the openmpi3 tests.
# That's too long, so add it to the no-test list
ARCH_NO_OPENMPI_TEST_LIST += hppa

# complex evr tests often time out, and are significantly slower than other tests
# even if they do pass. Skip them both.
SKIP_TESTS_COMMON=x[cz]heevr

# no current general 32-bit skips (see *MPI skips below)
SKIP_TESTS_32 ?=

# xssep, xsgsep and xssyevr are known to fail in the 64-bit build (see README)
# xdsyevr passes but is slow, skip it
SKIP_TESTS_64=xssep xsgsep xssyevr xdsyevr xCbtest xFbtest

# xsllt times out with OpenMPI, but xdllt, xdlu time out with MPICH.
# but all pass in the 64-bit builds. Weird.
SKIP_TESTS_OPENMPI=xsllt
SKIP_TESTS_MPICH=xdllt xdlu

override_dh_auto_test-arch:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
	N_TEST_JOBS=`echo "x=$(NUMJOBS)/4; if (x>1) x else 1" | bc` ; \
	exclude_tests=""; \
	for t in $(SKIP_TESTS_COMMON); do \
	  if [ "x$${exclude_tests}" = "x" ]; then \
	    exclude_tests="$$t"; \
	  else \
	    exclude_tests="$${exclude_tests}|$$t"; \
	  fi; \
	done; \
	for BITS in $(BIT_BUILDS); do \
	  if [ $$BITS = 64 ]; then \
	    LIBNAME_SUFFIX=64; \
	    for t in $(SKIP_TESTS_64); do \
	        exclude_tests="$${exclude_tests}|$$t"; \
	    done; \
	  else \
	    LIBNAME_SUFFIX=; \
	    for t in $(SKIP_TESTS_32); do \
	        exclude_tests="$${exclude_tests}|$$t"; \
	    done; \
	  fi; \
	  for flavor in $(MPI_SUPPORTED); do \
	    echo "Running tests for libscalapack$${LIBNAME_SUFFIX}-$${flavor}" ; \
	    echo '************************************************'; \
	    echo "****** TESTING $$flavor BUILD ($${BITS}-bit integers)"; \
	    echo '************************************************'; \
	    for testDir in PBLAS/TESTING PBLAS/TIMING TESTING; do \
	      testfile=build$${LIBNAME_SUFFIX}-$${flavor}/$${testDir}/CTestTestfile.cmake; \
	      if ! grep -q separate_arguments.*ENV.*MPIEXEC_PREFLAGS $$testfile ; then \
	        sed '0,/add_test/ s/add_test/separate_arguments(MPIEXEC_PREFLAGS NATIVE_COMMAND $$ENV{MPIEXEC_PREFLAGS})\nadd_test/' -i $$testfile; \
	        sed 's/"$${MPIEXEC_PREFLAGS}"/$${MPIEXEC_PREFLAGS}/' -i $$testfile; \
	      fi; \
	    done; \
	    RUNTESTS=yes; \
	    if [ "$$flavor" = "openmpi" ]; then \
	      MPIEXEC_PREFLAGS="--allow-run-as-root --oversubscribe"; \
	      case " $(ARCH_NO_OPENMPI_TEST_LIST) " in \
	        *\ $(DEB_HOST_ARCH)\ *) RUNTESTS=no;; \
	      esac; \
	      for t in $(SKIP_TESTS_OPENMPI); do \
	          exclude_tests="$${exclude_tests}|$$t"; \
	      done; \
	    else \
	      unset MPIEXEC_PREFLAGS; \
	      for t in $(SKIP_TESTS_MPICH); do \
	          exclude_tests="$${exclude_tests}|$$t"; \
	      done; \
	    fi; \
	    if [ "$$RUNTESTS" = "yes" ]; then \
	      echo "skipping tests: $${exclude_tests}"; \
	      ( LD_LIBRARY_PATH=$(CURDIR)/debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH):$(LD_LIBRARY_PATH) \
	        MPIEXEC_PREFLAGS="$${MPIEXEC_PREFLAGS}" dh_auto_test --max-parallel=$${N_TEST_JOBS} --builddirectory=build$${LIBNAME_SUFFIX}-$${flavor} \
			-- ARGS\+="--exclude-regex \"$${exclude_tests}\"" \
			2>&1 | tee build$${LIBNAME_SUFFIX}-$${flavor}/dh_auto_test.log ) || /bin/true; \
	    else \
	      echo Tests have been disabled on $(DEB_HOST_ARCH) | tee build$${LIBNAME_SUFFIX}-$${flavor}/dh_auto_test.log; \
	    fi; \
	    echo '************************************************'; \
	    echo "****** TESTING OF $$flavor BUILD ($${BITS}-bit integers) IS COMPLETE"; \
	    echo '************************************************'; \
	  done; \
	done
	# mpich has been found to Fail some tests but openmpi should not, so only check the openmpi test logs.
	# openmpi may Timeout on slower arches, so only register actual Fails (or SegFaults), assigning them return value 2
	# Test only on linux, since openmpi on other OS (kfreebsd, hurd) does not support fakeroot
	#
	# Tests are hardwired to 4 processors, so ignore failure if less than 4 are used.
	#
	# Test failures in the 64-bit integer builds are reported but do not currently halt the build.
	#
	if [ "$$DEB_BUILD_ARCH_OS" = "linux" ] && $$( grep -qE "Failed|SegFault" build-openmpi/dh_auto_test.log ); then \
	  if [ $(NUMJOBS) -lt 4 ]; then \
	    echo Tests are hardwired to 4 processes. Only $(NUMJOBS) processes were used for the build, so test failures will be ignored.; \
	  fi; \
	  echo "OpenMPI tests failed:"; \
	  grep -E "\(Failed\)|\(SEGFAULT\)" build-openmpi/dh_auto_test.log; \
	  if [ $(NUMJOBS) -ge 4 ]; then \
	    case " $(ARCH_TEST_IGNORE_FAILURE) " in \
	      *\ $(DEB_HOST_ARCH)\ *) echo Test failures ignored on $(DEB_HOST_ARCH);; \
	      *) return 2;; \
	    esac; \
	  fi; \
	fi
endif
