#!/usr/bin/make -f DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk include /usr/share/dpkg/architecture.mk OS_ID := $(shell grep -E "^ID" /etc/os-release | sed "s/^ID=//") DEB_SOURCE_PACKAGE := $(strip $(shell egrep '^Source: ' debian/control | cut -f 2 -d ':')) DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ') DEB_EPOCH := $(shell echo $(DEB_VERSION) | cut -d: -f1) DEB_NOEPOCH_VERSION := $(shell echo $(DEB_VERSION) | cut -d: -f2-) DEB_UPSTREAM_VERSION := $(shell echo $(DEB_NOEPOCH_VERSION) | sed 's/-[^-]*$$//') DEB_STRIPPED_UPSTREAM_VERSION = $(shell echo $(DEB_UPSTREAM_VERSION) | sed -e 's/\+dfsg.*$$//p') DEBIAN_VERSION_ID := $(OS_ID)_$(DEB_VERSION) DOLFINX_RELEASE_VERSION=$(DEB_STRIPPED_UPSTREAM_VERSION) DOLFINX_MAJOR_VERSION=$(shell echo $(DOLFINX_RELEASE_VERSION) | sed "s/^\([^.]*\)\..*$$/\1/") DOLFINX_MINOR_VERSION=$(shell echo $(DOLFINX_RELEASE_VERSION) | sed "s/^\([^.]*\)\.\([^.]*\)\..*$$/\2/") DOLFINX_VERSION=$(DOLFINX_MAJOR_VERSION).$(DOLFINX_MINOR_VERSION) DOLFINX_NEXT_VERSION=$(DEB_EPOCH):$(DOLFINX_MAJOR_VERSION).$(shell echo $$(( $(DOLFINX_MINOR_VERSION) + 1 )) ) # dolfinx depends on the nanobind version it was built against, # if nanobind.h will be used in C++ code fragments in python scripts. # But nanobind follows semantic versioning, so should have backwards compatibility # with minor and patch version updates. # Extract nanobind version from nanobind-dev NANOBIND_DEB_VERSION=$(shell dpkg -s nanobind-dev | awk '/Version:/ {print $$2}') # extract the current nanobind version X.Y.Z (drop epoch and debian package version) NANOBIND_UPSTREAM_VERSION=$(shell echo $(NANOBIND_DEB_VERSION) | sed "s/^.[^:]*://; s/-[^-]*$$//") NANOBIND_X_VERSION=$(shell echo $(NANOBIND_UPSTREAM_VERSION) | sed "s/^\([^.]*\).*/\1/") NANOBIND_X_Y_VERSION=$(shell echo $(NANOBIND_UPSTREAM_VERSION) | sed "s/^\(.*\)\.\([^.]*\)$$/\1/") NANOBIND_VERSION=$(NANOBIND_X_Y_VERSION) NANOBIND_NEXT_VERSION=$(shell echo $$(( $(NANOBIND_X_VERSION) + 1 )) ) # Allow test programs that use OpenMPI to run export OMPI_MCA_plm_rsh_agent=/bin/false export OMPI_MCA_btl_base_warn_component_unused=0 include /usr/share/mpi-default-dev/debian_defaults ENABLE_MPI=ON ifeq ($(findstring $(DEB_BUILD_ARCH),$(OPENMPI_ARCHITECTURES)),) MPIEXEC_PARAMS= else MPIEXEC_PARAMS=--oversubscribe endif DOLFINX_HOME = $(CURDIR)/$(DEB_SRCDIR) USCAN_DESTDIR := $(CURDIR) PY3VER_DEFAULT := $(shell py3versions -dv) BUILDDIR_REAL = $(CURDIR)/obj-$(DEB_HOST_GNU_TYPE)-real BUILDDIR_COMPLEX = $(CURDIR)/obj-$(DEB_HOST_GNU_TYPE)-complex NPROC := $(shell nproc) PARALLEL = $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) N_CPU = $(or $(PARALLEL),$(NPROC),1) # MPI tests are set up to run on 3 processes. Spread them leanly over the available processors (don't have more than 2 tests using one processor). # e.g. run 1 MPI test at a time over 1-3 processors, or 2 tests at a time over 4-6 processors, or 3 tests over 7-9 processors, etc. N_MPI := 3 N_MPI_TESTS = $(shell echo $$(( ($(N_CPU)+$(N_MPI)-1)/$(N_MPI) )) ) ifeq (nocheck,$(findstring nocheck,$(DEB_BUILD_OPTIONS))) RUNTEST=no endif # some arches just aren't keeping up at all, and fail non-MPI tests ARCH_SKIP_ALL_TESTS_LIST = mips64el hurd-i386 m68k sh4 # monitor slow python tests export PYBUILD_TEST_ARGS = --durations=20 empty := space := $(empty)$(empty) # GJK (test_cube_distance in test_gjk) fails to converge on many arches SKIP_GJK_TEST_ARCH_LIST = armel armhf mips64el sparc64 ifneq (,$(findstring $(space)$(DEB_HOST_ARCH)$(space), $(space)$(SKIP_GJK_TEST_ARCH_LIST)$(space))) SKIP_TEST_LIST += test_cube_distance endif # test_nonlinear_pde does not converge on some arches # "Newton solver did not converge because maximum number of iterations reached" SKIP_NONLINEAR_PDE_TEST_ARCH_LIST = mips64el ppc64 ifneq (,$(findstring $(space)$(DEB_HOST_ARCH)$(space), $(space)$(SKIP_NONLINEAR_PDE_TEST_ARCH_LIST)$(space))) SKIP_TEST_LIST += test_nonlinear_pde endif # skip slowest tests on riscv64, which is most of them ifneq (,$(findstring $(DEB_HOST_ARCH), riscv64)) SKIP_TEST_LIST += test_symmetry test_curl_curl_eigenvalue test_higher_order_function test_eigen_assembly \ test_assembler test_fem_pipeline test_dof_permuting test_dofmap test_element_integrals test_xdmf_function \ test_assemble_submesh test_interpolation test_petsc_discrete_operators test_mesh test_higher_order_mesh endif export PYBUILD_TEST_ARGS += $(shell \ SKIP_TESTS=""; \ list_initialised=0; \ for t in $(SKIP_TEST_LIST); do \ if [ $${list_initialised} = 0 ]; then \ SKIP_TESTS=$$t; \ list_initialised=1; \ else \ SKIP_TESTS="$${SKIP_TESTS} or $$t"; \ fi; \ done; \ if [ "x$${SKIP_TESTS}" != "x" ]; then \ SKIP_TESTS="not ( $${SKIP_TESTS} )"; \ fi; \ echo "-k \"$${SKIP_TESTS}\"") # extract PETSc version from petsc-dev PETSC_DEB_VERSION=$(shell dpkg -s petsc-dev | awk '/Version:/ {print $2}') # extract the current PETSc version PETSC_UPSTREAM_VERSION=$(shell pkg-config --modversion PETSc) # "Major" version is the first number in the upstream version (major.minor.release) PETSC_MAJOR_VERSION=$(shell echo $(PETSC_UPSTREAM_VERSION) | sed "s/^\([^.]*\)\..*$$/\1/") # "Minor" version is the second number in the upstream version (major.minor.release) PETSC_MINOR_VERSION=$(shell echo $(PETSC_UPSTREAM_VERSION) | sed "s/^\([^.]*\)\.\([^.]*\)\..*$$/\2/") PETSC_VERSION=$(PETSC_MAJOR_VERSION).$(PETSC_MINOR_VERSION) PETSC_VERSION_NEXT=$(shell echo $(PETSC_MAJOR_VERSION).$$(($(PETSC_MINOR_VERSION)+1))) SLEPC_UPSTREAM_VERSION=$(shell pkg-config --modversion SLEPc) # SLEPc version must match PETSc SLEPC_VERSION=$(PETSC_VERSION) SLEPC_VERSION_NEXT=$(PETSC_VERSION_NEXT) PETSC_DIR_BASE=/usr/lib/petscdir/petsc$(PETSC_VERSION)/$(DEB_HOST_MULTIARCH) SLEPC_DIR_BASE=/usr/lib/slepcdir/slepc$(SLEPC_VERSION)/$(DEB_HOST_MULTIARCH) export PETSC_DIR_REAL=$(PETSC_DIR_BASE)-real SLEPC_DIR_REAL=$(SLEPC_DIR_BASE)-real export PETSC_DIR_COMPLEX=$(PETSC_DIR_BASE)-complex SLEPC_DIR_COMPLEX=$(SLEPC_DIR_BASE)-complex DEB_CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) ifeq ($(DEB_HOST_ARCH),mips64el) DEB_CXXFLAGS += -Wno-error=maybe-uninitialized endif CMAKE_OPTS := \ -D CMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ -D BUILD_SHARED_LIBS:BOOL=ON \ -D CMAKE_SKIP_RPATH:BOOL=ON \ -D CMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=OFF \ -D DOLFINX_ENABLE_TRILINOS:BOOL=OFF \ -D DOLFINX_ENABLE_HDF5:BOOL=ON \ -D HDF5_C_COMPILER_EXECUTABLE:FILEPATH=/usr/bin/h5pcc \ -D DOLFINX_ENABLE_PARMETIS:BOOL=OFF \ -D DOLFINX_ENABLE_SCOTCH:BOOL=ON \ -D DOLFINX_ENABLE_DOCS:BOOL=OFF \ -D DOLFINX_ENABLE_MPI:BOOL=$(ENABLE_MPI) \ -D MPIEXEC_PARAMS:STRING="$(MPIEXEC_PARAMS)" \ -D CMAKE_CXX_FLAGS:STRING="-fpermissive" \ -D DOLFINX_EXTRA_CXX_FLAGS:STRING="$(DEB_CXXFLAGS)" \ -D DEBIAN_VERSION_ID=$(DEBIAN_VERSION_ID) \ $(XSIMD_CONFIG) %: dh $@ --buildsystem=cmake --with python3,sphinxdoc override_dh_compress: dh_compress -X.py -X.cpp -X.h -X.pdf -X.ufl override_dh_auto_clean: dh_auto_clean --builddir=$(BUILDDIR_REAL) dh_auto_clean --builddir=$(BUILDDIR_COMPLEX) rm -rf python/build-real python/build-complex rm -rf debian/tmp-real debian/tmp-complex rm -rf python/fenics_dolfinx.egg-info rm -rf python/doc/build python/doc/source/generated rm -rf cpp/doc/latex cpp/doc/html cpp/doc/xml rm -f $(CURDIR)/python/doc/source/demos override_dh_auto_configure: PETSC_DIR=$(PETSC_DIR_REAL) SLEPC_DIR=$(SLEPC_DIR_REAL) dh_auto_configure --builddir=$(BUILDDIR_REAL) -D$(CURDIR)/cpp -- $(CMAKE_OPTS) PETSC_DIR=$(PETSC_DIR_COMPLEX) SLEPC_DIR=$(SLEPC_DIR_COMPLEX) dh_auto_configure --builddir=$(BUILDDIR_COMPLEX) -D$(CURDIR)/cpp -- $(CMAKE_OPTS) override_dh_auto_build: PETSC_DIR=$(PETSC_DIR_REAL) SLEPC_DIR=$(SLEPC_DIR_REAL) dh_auto_build --builddir=$(BUILDDIR_REAL) PETSC_DIR=$(PETSC_DIR_COMPLEX) SLEPC_DIR=$(SLEPC_DIR_COMPLEX) dh_auto_build --builddir=$(BUILDDIR_COMPLEX) override_dh_auto_test-arch: echo "Tests must be run after installation" override_dh_auto_test-indep: debian/tmp-real: dh_auto_install --builddir=$(BUILDDIR_REAL) --destdir=debian/tmp-real cp COPYING.LESSER python for build in real; do \ PATH=$(CURDIR)/debian/tmp-$${build}/usr/bin:$$PATH \ PETSC_DIR=$(PETSC_DIR_BASE)-$${build} SLEPC_DIR=$(SLEPC_DIR_BASE)-$${build} \ CXXFLAGS="$(DEB_CXXFLAGS) -isystem $(CURDIR)/debian/tmp-$${build}/usr/include" \ VERBOSE=1 \ ADIOS2_ALWAYS_USE_MPI=1 \ PUSIMP_EXPECT_DOLFINX_IN_CWD=1 \ pybuild --dir=$(CURDIR)/python --dest-dir=$(CURDIR)/debian/tmp-$${build} --system=pyproject --name=dolfinx-$${build} --test-pytest; \ done override_dh_auto_install-indep: debian/tmp-real dh_auto_install -i --builddir=$(BUILDDIR_COMPLEX) --destdir=debian/tmp-complex (cd cpp/doc; doxygen) (cd python/doc; \ mkdir -p build/pkgconfig; \ cp $(CURDIR)/debian/tmp-real/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/dolfinx_real.pc build/pkgconfig; \ sed "s|prefix=/usr|prefix=$(CURDIR)/debian/tmp-real/usr|" -i build/pkgconfig/dolfinx_real.pc; \ PYTHONPATH=$(CURDIR)/debian/tmp-real/usr/lib/python$(PY3VER_DEFAULT)/dist-packages \ PKG_CONFIG_PATH=`pwd`/build/pkgconfig:$${PKG_CONFIG_PATH} \ LD_LIBRARY_PATH=$(CURDIR)/debian/tmp-real/usr/lib/$(DEB_HOST_MULTIARCH)/:$${LD_LIBRARY_PATH} \ XDG_CACHE_HOME=`pwd`/build \ RDMAV_FORK_SAFE=1 \ python3 -m sphinx -W -b html source/ .pybuild/html/) dh_numpy3 -i override_dh_auto_install-arch: debian/tmp-real dh_auto_install -a --builddir=$(BUILDDIR_COMPLEX) --destdir=debian/tmp-complex cp COPYING.LESSER python dh_numpy3 -a for build in complex; do \ PATH=$(CURDIR)/debian/tmp-$${build}/usr/bin:$$PATH \ PETSC_DIR=$(PETSC_DIR_BASE)-$${build} SLEPC_DIR=$(SLEPC_DIR_BASE)-$${build} \ CXXFLAGS="$(DEB_CXXFLAGS) -isystem $(CURDIR)/debian/tmp-$${build}/usr/include" \ VERBOSE=1 \ PUSIMP_EXPECT_DOLFINX_IN_CWD=1 \ pybuild --dir=$(CURDIR)/python --dest-dir=$(CURDIR)/debian/tmp-$${build} --system=pyproject --name=dolfinx-$${build} --test-pytest; \ done chrpath -d $(CURDIR)/debian/tmp*/usr/lib/python*/dist-packages/dolfinx/*.so sed -i "s/-D_FORTIFY_SOURCE=2//g" $(CURDIR)/debian/tmp*/usr/lib/$(DEB_BUILD_MULTIARCH)/pkgconfig/dolfinx*.pc sed -i "s|-DNDEBUG||g" $(CURDIR)/debian/tmp*/usr/lib/$(DEB_BUILD_MULTIARCH)/pkgconfig/dolfinx*.pc if [ "x$(RUNTEST)" != "xno" ]; then \ case " $(ARCH_SKIP_ALL_TESTS_LIST) " in \ *\ $(DEB_HOST_ARCH)\ *) echo "ALL tests have been disabled on $(DEB_HOST_ARCH)";; \ *) set -e; \ export CTEST_OUTPUT_ON_FAILURE=1; \ for build in real complex; do \ echo "== testing $$build number build =="; \ builddir=$(CURDIR)/obj-$(DEB_HOST_GNU_TYPE)-$${build}; \ for mytest in test demo; do \ echo "running tests from $$mytest for $$build build"; \ testdir=$${builddir}/run_$${mytest}; \ mkdir -p $$testdir; \ cd $$testdir; \ if [ "x$(SKIP_TEST_LIST)" != "x" ]; then echo "set(CTEST_CUSTOM_TESTS_IGNORE $(SKIP_TEST_LIST) )" >> CTestCustom.cmake; fi; \ PETSC_DIR=$(PETSC_DIR_BASE)-$${build} SLEPC_DIR=$(SLEPC_DIR_BASE)-$${build} cmake -DCMAKE_MODULE_PATH=$(CURDIR)/debian/tmp-$${build}/usr/lib/$(DEB_BUILD_MULTIARCH)/cmake/dolfinx \ -DDOLFINX_DIR=$(CURDIR)/debian/tmp-$${build}/usr/lib/$(DEB_BUILD_MULTIARCH)/cmake/dolfinx \ -DMPIEXEC_PARAMS:STRING="$(MPIEXEC_PARAMS)" \ $(CURDIR)/cpp/$${mytest}; \ make all VERBOSE=1; \ OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 make test VERBOSE=1; \ done; \ cd $(CURDIR); \ done; \ esac; \ fi override_dh_install-arch: dh_install -a sed "s/set(CMAKE_IMPORT_FILE_VERSION 1)/set(CMAKE_IMPORT_FILE_VERSION 1)\n\nif(PETSC_SCALAR_COMPLEX)\n set(LIB_NAME_EXT \"_complex\")\nelse()\n set(LIB_NAME_EXT \"_real\")\nendif()/; \ s/libdolfinx_real.so/libdolfinx\$${LIB_NAME_EXT}.so/g" \ -i debian/libdolfinx-dev/usr/lib/$(DEB_HOST_MULTIARCH)/cmake/dolfinx/DOLFINXTargets-relwithdebinfo.cmake override_dh_python3-arch: dh_python3 -a dh_numpy3 -a mkdir -p debian/python3-dolfinx-real/$(PETSC_DIR_REAL)/lib mv debian/python3-dolfinx-real/usr/lib/python3 debian/python3-dolfinx-real/$(PETSC_DIR_REAL)/lib rm -rf debian/python3-dolfinx-real/$(PETSC_DIR_REAL)/lib/python3/dist-packages/dolfinx_utils mkdir -p debian/python3-dolfinx-complex/$(PETSC_DIR_COMPLEX)/lib mv debian/python3-dolfinx-complex/usr/lib/python3 debian/python3-dolfinx-complex/$(PETSC_DIR_COMPLEX)/lib rm -rf debian/python3-dolfinx-complex/$(PETSC_DIR_COMPLEX)/lib/python3/dist-packages/dolfinx_utils # set petsc:Depends to something like "libpetsc-real3.8-dev, libslepc-real3.8-dev, python-petsc4py (>= 3.8), python-petsc4py (<< 3.9), python-slepc4py (>= 3.8), python-slepc4py (<< 3.9)" PETSC_DEV_DEPENDS="libpetsc-real$(PETSC_VERSION)-dev, libslepc-real$(SLEPC_VERSION)-dev" PETSC_COMPLEX_DEV_DEPENDS="libpetsc-complex$(PETSC_VERSION)-dev, libslepc-complex$(SLEPC_VERSION)-dev" # slepc4py version must match petsc4py (using the PETSc minor version, not the patch release) PETSC4PY_DEPENDS_PY3=python3-petsc4py, python3-slepc4py, python3-petsc4py-real (>= $(PETSC_VERSION)), python3-petsc4py-real (<< $(PETSC_VERSION_NEXT)), python3-slepc4py-real (>= $(SLEPC_VERSION)), python3-slepc4py-real (<< $(SLEPC_VERSION_NEXT)) PETSC4PY_COMPLEX_DEPENDS_PY3=python3-petsc4py, python3-slepc4py, python3-petsc4py-complex (>= $(PETSC_VERSION)), python3-petsc4py-complex (<< $(PETSC_VERSION_NEXT)), python3-slepc4py-complex (>= $(SLEPC_VERSION)), python3-slepc4py-complex (<< $(SLEPC_VERSION_NEXT)) override_dh_gencontrol: echo "python3-petsc4py-real:Depends=$(PETSC4PY_DEPENDS_PY3)" >> debian/python3-dolfinx-real.substvars echo "python3-petsc4py-complex:Depends=$(PETSC4PY_COMPLEX_DEPENDS_PY3)" >> debian/python3-dolfinx-complex.substvars echo "python-petsc4py-alt:Depends=$(PETSC4PY_DEPENDS_PY3)" >> debian/libdolfinx-dev.substvars dh_gencontrol -- -Vpetsc:Depends=$(PETSC_DEV_DEPENDS) -Vpetsc-complex:Depends=$(PETSC_COMPLEX_DEV_DEPENDS) -Vdolfinx:Next-Upstream-Version=$(DOLFINX_NEXT_VERSION)~ \ -Vnanobind:Upstream-Version=$(NANOBIND_VERSION) -Vnanobind:Next-Upstream-Version=$(NANOBIND_NEXT_VERSION) # dbgsym-migration was introduced for dolfin 2017.2 (don't update the version to a later version) override_dh_strip: dh_strip --package=libdolfinx-real$(DOLFINX_VERSION) -Xcomplex -Xpython dh_strip --package=libdolfinx-complex$(DOLFINX_VERSION) -Xreal -Xpython dh_strip --package=python3-dolfinx-real # python module so files are already stripped by pybuild override_dh_dwz: dh_dwz -Xcpp.cpython # https://stackoverflow.com/a/18793112/353337 override_dh_shlibdeps: dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info .PHONY: get-orig-source override_dh_strip