#!/usr/bin/make -f # # CONTENTS: # # 1. DEFINITIONS # 2. GENERATE FILES # Targets to auto-generate files # 3. PACKAGE BUILD # Mostly standard targets that are used during package build # 4. TEST SUITE # 5. MAINTAINER TARGETS # Convenience targets to be used by maintainers # Some are explained at https://wiki.debian.org/DebianScience/Sage # ############################################################################### # 1. DEFINITIONS ############################################################################### include /usr/share/dpkg/pkg-info.mk include /usr/share/dpkg/architecture.mk MAX_TEST_FAILURES_RERUN = $(shell expr 2 \* $(MAX_TEST_FAILURES)) ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) else NUMJOBS = 1 endif # Some buildds are a bit slow, see https://buildd.debian.org/status/logs.php?pkg=gcc-7 for a fuller list ifneq (,$(filter $(DEB_BUILD_ARCH),armel armhf mips mipsel mips64el)) export SAGE_TIMEOUT_LONG = 7200 else export SAGE_TIMEOUT_LONG = 3600 endif # Use ccache if pkg.sagemath.ccache build-profile is active. # Your rebuilds will be *much quicker*. ifneq (,$(filter pkg.sagemath.ccache,$(DEB_BUILD_PROFILES))) export PATH := /usr/lib/ccache:$(PATH) export CCACHE_DIR := $(CURDIR)/debian/ccache export CCACHE_BASEDIR := $(CURDIR)/debian/build $(shell mkdir -p "$(CCACHE_DIR)") endif ifeq (,$(filter pkg.sagemath.nolongcheck,$(DEB_BUILD_PROFILES))) SAGE_TEST_FLAGS_ARCH = --optional=sage,python2,memlimit --long SAGE_TEST_FLAGS_INDEP = --optional=sage,python2,memlimit,dochtml --long else SAGE_TEST_FLAGS_ARCH = --optional=sage,python2,memlimit SAGE_TEST_FLAGS_INDEP = --optional=sage,python2,memlimit,dochtml endif export SAGE_LOCAL = $(CURDIR)/debian/build/usr export PYTHONPATH = $(CURDIR)/debian/build/usr/lib/python2.7/dist-packages export DOT_SAGE = $(CURDIR)/debian/test export SAGE_SCRIPTS_DIR = $(CURDIR)/sage/src/bin LANGS = $(shell cd sage/src/doc && find . -mindepth 1 -maxdepth 1 -type d | grep -v common | cut -b3- | LC_ALL=C.UTF-8 LANG=C.UTF-8 sort) DOCS_INSTALL = $(LANGS:%=debian/sagemath-doc-%.install) DOCS_CONTROL = $(LANGS:%=debian/sagemath-doc-%.control) DOCS_DOC_BASE = $(LANGS:%=debian/sagemath-doc-%.doc-base) DOCS_OVERRIDES = $(LANGS:%=debian/sagemath-doc-%.lintian-overrides) DOCS_INSTALL_DIRS = $(LANGS:%=debian/sagemath-doc-%) ifneq (1,$(TRY_AVOID_REBUILD)) REBUILD_RULES = debian/rules endif %: dh $@ --with=python2,sphinxdoc ############################################################################### # 2. GENERATE FILES ############################################################################### binary build clean install: debian/control debian/control: debian/control.in $(DOCS_CONTROL) cat $^ > "$@" sed -i -e '/RUNTIME_DEPENDS/ {' -e 'r debian/control.runtime-depends' -e 'd' -e '}' "$@" sed -i -e '/RUNTIME_RECOMMENDS/ {' -e 'r debian/control.runtime-recommends' -e 'd' -e '}' "$@" sed -i -e '/JUPYTER_DEPENDS/ {' -e 'r debian/control.jupyter-depends' -e 'd' -e '}' "$@" debian/sagemath-doc-%.control: debian/sagemath-doc-LANG.control.in $(REBUILD_RULES) sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' < "$<" > "$@" debian/sagemath-doc-%.install: debian/sagemath-doc-LANG.install.in $(REBUILD_RULES) sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' < "$<" > "$@" debian/sagemath-doc-en.doc-base: debian/sagemath-doc-LANG.doc-base.in $(REBUILD_RULES) sed -e "s/LANGUAGE/$$(debian/lang.py en)/g" -e 's/LANG/en/g' -e 's/SUBDIR//g' < "$<" > "$@" debian/sagemath-doc-ca.doc-base: debian/sagemath-doc-LANG.doc-base.in $(REBUILD_RULES) sed -e "s/LANGUAGE/$$(debian/lang.py ca)/g" -e 's/LANG/ca/g' -e 's/SUBDIR/intro\//g' < "$<" > "$@" debian/sagemath-doc-%.doc-base: debian/sagemath-doc-LANG.doc-base.in $(REBUILD_RULES) if [ "$*" = "hu" -o "$*" = "it" -o "$*" = "tr" ]; then \ sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' -e 's/SUBDIR/a_tour_of_sage\//g' < "$<" > "$@"; \ else \ sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' -e 's/SUBDIR/tutorial\//g' < "$<" > "$@"; \ fi debian/sagemath-doc-%.lintian-overrides: debian/sagemath-doc-LANG.lintian-overrides.in \ $(wildcard debian/sagemath-doc-%.lintian-overrides.in) $(REBUILD_RULES) sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' < "$<" > "$@" if [ -f "debian/sagemath-doc-$*.lintian-overrides.in" ]; then \ sed -e "s/LANGUAGE/$$(debian/lang.py $*)/g" -e 's/LANG/$*/g' < "debian/sagemath-doc-$*.lintian-overrides.in" >> "$@"; \ fi ../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz: .git/modules/sage/HEAD cd sage && git archive --prefix=sagemath_$(DEB_VERSION_UPSTREAM)/sage/ \ --format=tar HEAD | xz -zf > ../../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz ../sagemath_$(DEB_VERSION).dsc: distclean-sage distclean ../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz debian/control dpkg-buildpackage -nc -d -uc -us -S ############################################################################### # 3. PACKAGE BUILD ############################################################################### prune: debian/control cd debian/pruner && autoconf -I m4 cd debian/pruner && ./configure --with-sage-root="$(CURDIR)/sage" cd sage && python ../debian/pruner/pruner.py touch prune run_build = \ MAKE='make -j$(NUMJOBS)' PREREQ_OPTIONS="--prefix=$(SAGE_LOCAL)" LDFLAGS="-Wl,-rpath,/usr/lib/$(DEB_HOST_MULTIARCH)/gap" \ $(MAKE) --directory=sage override_dh_auto_configure: prune override_dh_auto_build-arch: $(run_build) build cd sage && src/bin/sage-starts override_dh_auto_build-indep: ifeq (,$(filter nodoc,$(DEB_BUILD_OPTIONS))) $(run_build) doc cd debian/build/usr/share/doc/sagemath/html && \ for statdir in */*/_static; do ln -s /usr/share/javascript/mathjax "$$statdir"; done && \ for statdir in */_static; do ln -s /usr/share/javascript/mathjax "$$statdir"; done endif override_dh_auto_install: rm -rf debian/build/usr/var/tmp/sage/build # We built .pyo to make the docbuild/tests go faster, but as per Debian policy # we don't distribute them. find debian/build '(' -name '*.pyc' -o -name '*.pyo' ')' -delete rm -f debian/build/usr/bin/*.bat mkdir -p debian/tmp mv debian/build/* debian/tmp cp -f debian/adhoc/sage-env debian/tmp/usr/bin/ # Install sage-python23 which is required at runtime but located in build/bin. cp -f sage/build/bin/sage-python23 debian/tmp/usr/bin/ # Don't install sage-env-config. rm -f debian/tmp/usr/bin/sage-env-config # Install (renamed) icons. mkdir -p debian/tmp/usr/share/icons/hicolor/64x64/apps mkdir -p debian/tmp/usr/share/icons/hicolor/scalable/apps cp -f sage/src/ext/notebook-ipython/logo-64x64.png debian/tmp/usr/share/icons/hicolor/64x64/apps/sagemath.png cp -f sage/src/ext/notebook-ipython/logo.svg debian/tmp/usr/share/icons/hicolor/scalable/apps/sagemath.svg # Don't try to rmdir debian/build if it's a mountpoint, useful for doing builds in /run/shm mountpoint debian/build || rmdir debian/build # If we see "nodoc", don't clean the docs. This allows us to rebuild just the # non-docs without wiping away the docs we previously built, to save time. override_dh_auto_clean: ifneq (,$(filter nodoc,$(DEB_BUILD_OPTIONS))) dh_auto_clean -Dsage -- -k clean sagelib-clean misc-clean bootstrap-clean || true rm -rf sage/local sage/upstream else dh_auto_clean -Dsage -- maintainer-clean endif override_dh_install-indep: $(DOCS_INSTALL) $(DOCS_DOC_BASE) $(DOCS_OVERRIDES) dh_install --package sagemath-common -X.so dh_install --remaining-packages --list-missing # Basic version of deduplicating the docs, for a much smaller install size. # Upstream bug report is at https://trac.sagemath.org/ticket/22088 # Hard links do work in Debian packages, but only within packages. set -e; for d in $(DOCS_INSTALL_DIRS); do \ rdfind -outputname /dev/null -makehardlinks true "$$d"; \ done override_dh_python2-arch: dh_python2 dh_numpy --package sagemath # stop lintian complaining at us override_dh_shlibdeps: dh_shlibdeps -l debian/tmp/usr/lib override_dh_compress: # We probably don't need to install the pickle/doctree files but let's exempt # them from compression anyway for now, so the build goes quicker. dh_compress -X.pdf -X.pickle -X.doctree override_dh_sphinxdoc: # TODO: fix MathJax.js, Sage needs special treatment # `man dh_sphinxdoc` says symlinking translations.js is not yet supported # likewise, it seems not to recognise searchtools.js yet dh_sphinxdoc -XMathJax.js -Xtranslations.js -Xsearchtools.js # If we see "nodoc", don't clean the docs. This allows us to rebuild just the # non-docs without wiping away the docs we previously built, to save time. ifneq (,$(filter nodoc,$(DEB_BUILD_OPTIONS))) # Don't delete my precious docs debhelper! They took a whole fucking hour to build! preserve_docs = \ set -e; \ if [ -d $(2)/usr/share/doc ]; then \ mkdir -p debian/clean-tmp/usr/share; \ mv -t debian/clean-tmp/usr/share/ $(2)/usr/share/doc; \ fi; \ $(1); \ if [ -d debian/clean-tmp/usr/share/doc ]; then \ mkdir -p $(2)/usr/share; \ mv -t $(2)/usr/share/ debian/clean-tmp/usr/share/doc; \ rm -rf debian/clean-tmp; \ fi else preserve_docs = $(1) endif override_dh_clean: rm -f $(DOCS_INSTALL) $(DOCS_DOC_BASE) $(DOCS_OVERRIDES) rm -rf $(DOT_SAGE) $(call preserve_docs,dh_clean,debian/tmp) $(call preserve_docs,rm -rf debian/build/*,debian/build) override_dh_strip_nondeterminism: dh_strip_nondeterminism -X.png # On png files it sometimes fails claiming it's not a png file. ############################################################################### # 4. TEST SUITE ############################################################################### TESTS_MK = $(MAKE) -s --no-print-directory -f debian/tests.mk LOGFILE=$(LOGFILE) failed-tests%: @$(TESTS_MK) "$@" # We used to set this for i386 but it seems to be OK now. # Perhaps we should set it for armhf, let's see the buildd test results... ifneq (,$(filter $(DEB_BUILD_ARCH),)) IGNORE_FAILURES = | sed -e '0,/Timed out/{//d;}' -e '0,/Timed out/{//d;}' -e '0,/Timed out/{//d;}' else IGNORE_FAILURES = endif had-few-failures: if ! test -f $(LOGFILE); then echo "Error: log file $(LOGFILE) not found"; false; fi N_TEST_FAILURES="$$($(TESTS_MK) failed-tests-total-normal)"; \ if ! test $${N_TEST_FAILURES} -le $(MAX_TEST_FAILURES); then \ echo "Error: $${N_TEST_FAILURES} tests failed, up to $(MAX_TEST_FAILURES) failures are tolerated"; \ false; \ else \ echo "Success: $${N_TEST_FAILURES} tests failed, up to $(MAX_TEST_FAILURES) failures are tolerated"; \ fi if ! test -z "$$($(TESTS_MK) failed-tests-special $(IGNORE_FAILURES))"; then \ echo "Error: critical test failures (e.g. timeout, segfault, etc.)"; false; fi had-not-too-many-failures: echo "Checking number of failed tests to determine whether to rerun tests in series..." if ! test -f $(LOGFILE); then echo "Error: log file $(LOGFILE) not found"; false; fi N_TEST_FAILURES="$$($(TESTS_MK) failed-tests-total-normal)"; \ if ! test $${N_TEST_FAILURES} -le $(MAX_TEST_FAILURES_RERUN); then \ echo "No: $${N_TEST_FAILURES} tests failed, up to $(MAX_TEST_FAILURES_RERUN) failures are tolerated for rerun"; \ false; \ else \ echo "Yes: $${N_TEST_FAILURES} tests failed, up to $(MAX_TEST_FAILURES_RERUN) failures are tolerated for rerun"; \ fi run_tests = \ cd sage && ./sage -t -p $(NUMJOBS) --logfile=logs/ptestlong-$(1).log $(2) # If tests fail but not by too many more, then retry them once not in parallel # i386 seems to have issues running parallel tests - TODO: investigate this in more detail check_test_log = debian/rules -s LOGFILE=sage/logs/ptestlong-$(1).log MAX_TEST_FAILURES=$(3) run_tests_with_retry = \ $(run_tests); cd "$(CURDIR)" && \ if $(check_test_log) had-few-failures; then :; else \ $(check_test_log) had-not-too-many-failures && \ mv sage/logs/ptestlong-$(1).log sage/logs/ptestlong-$(1).log.1 && \ { $(run_tests) -p 1 -f; cd "$(CURDIR)" && \ $(check_test_log) had-few-failures; }; \ fi override_dh_auto_test-arch: ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) $(call run_tests_with_retry,arch,$(SAGE_TEST_FLAGS_ARCH) src/sage /usr/lib/python2.7/dist-packages/sagenb/,50) endif override_dh_auto_test-indep: ifeq (,$(filter nodoc,$(DEB_BUILD_OPTIONS))) ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) $(call run_tests_with_retry,indep,$(SAGE_TEST_FLAGS_INDEP) src/doc src/sage/misc/sagedoc.py,10) # Sometimes, parts of the docbuild fail with MemoryError or OSError but # Sage doesn't detect this. Here we detect it and fail the build if so. # Also filter out some false positives that are not hard errors. ! (grep Error sage/logs/dochtml.log | grep -v "citation not found: .*Error\|Citation \[.*Error\] is not referenced") endif endif # manual target to re-run only failed tests check-failed: $(call run_tests,all,--all -f) ############################################################################### # 5. MAINTAINER TARGETS ############################################################################### export-build-env: @echo export SAGE_LOCAL=$(SAGE_LOCAL) @echo export PYTHONPATH=$(PYTHONPATH) @echo export DOT_SAGE=$(DOT_SAGE) @echo export SAGE_SCRIPTS_DIR=$(SAGE_SCRIPTS_DIR) # If the docbuild fails and you want to try again, you should run this first. # Otherwise the docbuild gets slower and slower as it re-reads information from # its build directory. At least that's my (infinity0) impression; I didn't # investigate this in too much detail yet. clean-docbuild: rm -rf debian/build/usr/share/doc/sagemath distclean: # don't git reset --hard on purpose, so it's easier to test git clean -fdx distclean-sage: cd sage; git clean -fdx && git reset --hard HEAD && git submodule update --force reset: clean clean-docbuild QUILT_PATCHES=debian/patches quilt pop -af || true debian/rules distclean-sage QUILT_PATCHES=debian/patches quilt push -a build-dep-maint: sudo apt-get install --no-install-recommends equivs devscripts git iso-codes python quilt build-dep: debian/control if which aptitude >/dev/null; then sudo -E mk-build-deps -ir -t 'aptitude -R'; \ else sudo -E mk-build-deps -ir; fi get-orig-source: debian/rules ../sagemath_$(DEB_VERSION_UPSTREAM).orig.tar.xz ifneq (1,$(TRY_AVOID_REBUILD)) REBUILD_RELEASE = ../sagemath_$(DEB_VERSION).dsc endif SBUILD = sbuild --build-failed-commands '%SBUILD_SHELL' SBUILD_REPO_EXPERIMENTAL = --extra-repository="deb http://httpredir.debian.org/debian experimental main" # Sometimes this is necessary, if the mirrors have different versions for different architectures ifeq (1,$(SBUILD_USE_INCOMING)) SBUILD += --extra-repository="deb http://incoming.debian.org/debian-buildd buildd-unstable main" SBUILD_REPO_EXPERIMENTAL += --extra-repository="deb http://incoming.debian.org/debian-buildd buildd-experimental main" endif # If the sbuild rules fail for you, try these workarounds: # # 0 https://wiki.debian.org/sbuild#Using_aliases # if schroot complains about non-existent chroot # # 1 bottom of https://wiki.debian.org/DebianScience/Sage # for misc other fixes # # 2 echo "/var/cache/apt/archives /var/cache/apt/archives none rw,bind 0 0" >> /etc/schroot/sbuild/fstab # If you get download errors and sbuild isn't smart enough to ask apt to retry # release: $(REBUILD_RELEASE) cd .. && $(SBUILD) \ $(SBUILD_EXTRA_FLAGS) \ "sagemath_$(DEB_VERSION).dsc" release-experimental: $(REBUILD_RELEASE) cd .. && $(SBUILD) -d experimental \ $(SBUILD_REPO_EXPERIMENTAL) --build-dep-resolver=aspcud \ $(SBUILD_EXTRA_FLAGS) \ "sagemath_$(DEB_VERSION).dsc"